From c4dfe8794347ffec53ed764170bc6b6b9fb5872e Mon Sep 17 00:00:00 2001 From: Marco Date: Fri, 10 Nov 2023 14:25:27 +0100 Subject: [PATCH 01/38] event ValidatorExited -> indexed owner --- contracts/interfaces/ISSVClusters.sol | 2 +- test/helpers/gas-usage.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/interfaces/ISSVClusters.sol b/contracts/interfaces/ISSVClusters.sol index 07546dcf..b3d82d87 100644 --- a/contracts/interfaces/ISSVClusters.sol +++ b/contracts/interfaces/ISSVClusters.sol @@ -119,5 +119,5 @@ interface ISSVClusters is ISSVNetworkCore { * @param operatorIds The operator IDs managing the validator. * @param publicKey The public key of the exiting validator. */ - event ValidatorExited(address owner, uint64[] operatorIds, bytes indexed publicKey); + event ValidatorExited(address indexed owner, uint64[] operatorIds, bytes publicKey); } diff --git a/test/helpers/gas-usage.ts b/test/helpers/gas-usage.ts index 536812e7..534ec15e 100644 --- a/test/helpers/gas-usage.ts +++ b/test/helpers/gas-usage.ts @@ -88,7 +88,7 @@ const MAX_GAS_PER_GROUP: any = { [GasGroup.DEPOSIT]: 77500, [GasGroup.WITHDRAW_CLUSTER_BALANCE]: 94500, [GasGroup.WITHDRAW_OPERATOR_BALANCE]: 64900, - [GasGroup.VALIDATOR_EXIT]: 41500, + [GasGroup.VALIDATOR_EXIT]: 42200, [GasGroup.LIQUIDATE_CLUSTER_4]: 129300, [GasGroup.LIQUIDATE_CLUSTER_7]: 170500, From b979f71232461d587fbcfc1c0c1f00520460fb5b Mon Sep 17 00:00:00 2001 From: Mohsen-T Date: Fri, 17 Nov 2023 17:14:14 +0100 Subject: [PATCH 02/38] fix: added a test case in balance.ts --- hardhat.config.ts | 61 ++++----- test/sanity/balances.ts | 297 +++++++++++++++++++++++++++++----------- 2 files changed, 249 insertions(+), 109 deletions(-) diff --git a/hardhat.config.ts b/hardhat.config.ts index 7b2d5eb2..08662e0f 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -1,7 +1,7 @@ import 'dotenv/config'; import { HardhatUserConfig } from 'hardhat/config'; -import { NetworkUserConfig } from "hardhat/types"; +import { NetworkUserConfig } from 'hardhat/types'; import '@nomicfoundation/hardhat-toolbox'; import '@openzeppelin/hardhat-upgrades'; import 'hardhat-tracer'; @@ -14,39 +14,38 @@ import './tasks/upgrade'; type SSVNetworkConfig = NetworkUserConfig & { ssvToken: string; -} - +}; const config: HardhatUserConfig = { // Your type-safe config goes here mocha: { - timeout: 40000000000000000 + timeout: 40000000000000000, }, solidity: { compilers: [ { - version: "0.8.4", + version: '0.8.4', }, { version: '0.8.18', settings: { optimizer: { enabled: true, - runs: 10000 - } - } - } + runs: 10000, + }, + }, + }, ], }, networks: { ganache: { chainId: 1337, - url: "http://127.0.0.1:8585", - ssvToken: process.env.SSVTOKEN_ADDRESS // if empty, deploy SSV mock token + url: 'http://127.0.0.1:8585', + ssvToken: process.env.SSVTOKEN_ADDRESS, // if empty, deploy SSV mock token } as SSVNetworkConfig, hardhat: { - allowUnlimitedContractSize: true - } + allowUnlimitedContractSize: true, + }, }, etherscan: { // Your API key for Etherscan @@ -54,20 +53,20 @@ const config: HardhatUserConfig = { apiKey: process.env.ETHERSCAN_KEY, customChains: [ { - network: "holesky", + network: 'holesky', chainId: 17000, urls: { - apiURL: "https://api-holesky.etherscan.io/api", - browserURL: "https://holesky.etherscan.io" - } - } - ] + apiURL: 'https://api-holesky.etherscan.io/api', + browserURL: 'https://holesky.etherscan.io', + }, + }, + ], }, gasReporter: { - enabled: true, + enabled: false, currency: 'USD', - gasPrice: 0.3 - } + gasPrice: 0.3, + }, }; if (process.env.GOERLI_ETH_NODE_URL) { @@ -82,13 +81,13 @@ if (process.env.GOERLI_ETH_NODE_URL) { ...config.networks, goerli_development: { ...sharedConfig, - ssvToken: '0x6471F70b932390f527c6403773D082A0Db8e8A9F' + ssvToken: '0x6471F70b932390f527c6403773D082A0Db8e8A9F', } as SSVNetworkConfig, goerli_testnet: { ...sharedConfig, - ssvToken: '0x3a9f01091C446bdE031E39ea8354647AFef091E7' + ssvToken: '0x3a9f01091C446bdE031E39ea8354647AFef091E7', } as SSVNetworkConfig, - } + }; } if (process.env.HOLESKY_ETH_NODE_URL) { @@ -103,13 +102,13 @@ if (process.env.HOLESKY_ETH_NODE_URL) { ...config.networks, holesky_development: { ...sharedConfig, - ssvToken: '0x68A8DDD7a59A900E0657e9f8bbE02B70c947f25F' + ssvToken: '0x68A8DDD7a59A900E0657e9f8bbE02B70c947f25F', } as SSVNetworkConfig, holesky_testnet: { ...sharedConfig, - ssvToken: '0xad45A78180961079BFaeEe349704F411dfF947C6' + ssvToken: '0xad45A78180961079BFaeEe349704F411dfF947C6', } as SSVNetworkConfig, - } + }; } if (process.env.MAINNET_ETH_NODE_URL) { @@ -121,9 +120,9 @@ if (process.env.MAINNET_ETH_NODE_URL) { accounts: [`0x${process.env.MAINNET_OWNER_PRIVATE_KEY}`], gasPrice: +(process.env.GAS_PRICE || ''), gas: +(process.env.GAS || ''), - ssvToken: '0x9D65fF81a3c488d585bBfb0Bfe3c7707c7917f54' - } as SSVNetworkConfig - } + ssvToken: '0x9D65fF81a3c488d585bBfb0Bfe3c7707c7917f54', + } as SSVNetworkConfig, + }; } export default config; diff --git a/test/sanity/balances.ts b/test/sanity/balances.ts index 876cecf3..f22e51f8 100644 --- a/test/sanity/balances.ts +++ b/test/sanity/balances.ts @@ -4,13 +4,19 @@ import * as utils from '../helpers/utils'; import { expect } from 'chai'; import { trackGas, GasGroup } from '../helpers/gas-usage'; -let ssvNetworkContract: any, ssvViews: any, cluster1: any, minDepositAmount: any, burnPerBlock: any, networkFee: any, initNetworkFeeBalance: any; +let ssvNetworkContract: any, + ssvViews: any, + cluster1: any, + minDepositAmount: any, + burnPerBlock: any, + networkFee: any, + initNetworkFeeBalance: any; // Declare globals describe('Balance Tests', () => { beforeEach(async () => { // Initialize contract - const metadata = (await helpers.initializeContract()); + const metadata = await helpers.initializeContract(); ssvNetworkContract = metadata.contract; ssvViews = metadata.ssvViews; @@ -28,99 +34,161 @@ describe('Balance Tests', () => { // cold register await helpers.coldRegisterValidator(); - cluster1 = await helpers.registerValidators(4, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + cluster1 = await helpers.registerValidators(4, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [ + GasGroup.REGISTER_VALIDATOR_NEW_STATE, + ]); initNetworkFeeBalance = await ssvViews.getNetworkEarnings(); }); + it.only('Check cluster balance with removing operator', async () => { + //await utils.progressBlocks(1); + const operatorIds = cluster1.args.operatorIds; + const cluster = cluster1.args.cluster; + for (let i = 1; i <= 4; i++) { + await ssvNetworkContract.connect(helpers.DB.owners[0]).removeOperator(5 - i); + // await ssvNetworkContract.connect(helpers.DB.owners[0]).removeOperator(i); + let balance = await ssvViews.getBalance(helpers.DB.owners[4].address, operatorIds, cluster); + console.log(balance.toString()); + } + }); + it('Check cluster balance in three blocks, one after the other', async () => { await utils.progressBlocks(1); - expect(await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster)).to.equal(minDepositAmount - burnPerBlock); + expect( + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), + ).to.equal(minDepositAmount - burnPerBlock); await utils.progressBlocks(1); - expect(await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster)).to.equal(minDepositAmount - burnPerBlock * 2); + expect( + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), + ).to.equal(minDepositAmount - burnPerBlock * 2); await utils.progressBlocks(1); - expect(await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster)).to.equal(minDepositAmount - burnPerBlock * 3); + expect( + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), + ).to.equal(minDepositAmount - burnPerBlock * 3); }); it('Check cluster balance in two and twelve blocks, after network fee updates', async () => { await utils.progressBlocks(1); - expect(await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster)).to.equal(minDepositAmount - burnPerBlock); + expect( + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), + ).to.equal(minDepositAmount - burnPerBlock); const newBurnPerBlock = burnPerBlock + networkFee; await ssvNetworkContract.updateNetworkFee(networkFee * 2); await utils.progressBlocks(1); - expect(await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster)).to.equal(minDepositAmount - burnPerBlock * 2 - newBurnPerBlock); + expect( + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), + ).to.equal(minDepositAmount - burnPerBlock * 2 - newBurnPerBlock); await utils.progressBlocks(1); - expect(await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster)).to.equal(minDepositAmount - burnPerBlock * 2 - newBurnPerBlock * 2); + expect( + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), + ).to.equal(minDepositAmount - burnPerBlock * 2 - newBurnPerBlock * 2); await utils.progressBlocks(10); - expect(await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster)).to.equal(minDepositAmount - burnPerBlock * 2 - newBurnPerBlock * 12); + expect( + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), + ).to.equal(minDepositAmount - burnPerBlock * 2 - newBurnPerBlock * 12); }); it('Check DAO earnings in three blocks, one after the other', async () => { await utils.progressBlocks(1); - expect(await ssvViews.getNetworkEarnings() - initNetworkFeeBalance).to.equal(networkFee * 2); + expect((await ssvViews.getNetworkEarnings()) - initNetworkFeeBalance).to.equal(networkFee * 2); await utils.progressBlocks(1); - expect(await ssvViews.getNetworkEarnings() - initNetworkFeeBalance).to.equal(networkFee * 4); + expect((await ssvViews.getNetworkEarnings()) - initNetworkFeeBalance).to.equal(networkFee * 4); await utils.progressBlocks(1); - expect(await ssvViews.getNetworkEarnings() - initNetworkFeeBalance).to.equal(networkFee * 6); + expect((await ssvViews.getNetworkEarnings()) - initNetworkFeeBalance).to.equal(networkFee * 6); }); it('Check DAO earnings in two and twelve blocks, after network fee updates', async () => { await utils.progressBlocks(1); - expect(await ssvViews.getNetworkEarnings() - initNetworkFeeBalance).to.equal(networkFee * 2); + expect((await ssvViews.getNetworkEarnings()) - initNetworkFeeBalance).to.equal(networkFee * 2); const newNetworkFee = networkFee * 2; await ssvNetworkContract.updateNetworkFee(newNetworkFee); await utils.progressBlocks(1); - expect(await ssvViews.getNetworkEarnings() - initNetworkFeeBalance).to.equal(networkFee * 4 + newNetworkFee * 2); + expect((await ssvViews.getNetworkEarnings()) - initNetworkFeeBalance).to.equal(networkFee * 4 + newNetworkFee * 2); await utils.progressBlocks(1); - expect(await ssvViews.getNetworkEarnings() - initNetworkFeeBalance).to.equal(networkFee * 4 + newNetworkFee * 4); + expect((await ssvViews.getNetworkEarnings()) - initNetworkFeeBalance).to.equal(networkFee * 4 + newNetworkFee * 4); await utils.progressBlocks(10); - expect(await ssvViews.getNetworkEarnings() - initNetworkFeeBalance).to.equal(networkFee * 4 + newNetworkFee * 24); + expect((await ssvViews.getNetworkEarnings()) - initNetworkFeeBalance).to.equal(networkFee * 4 + newNetworkFee * 24); }); it('Check operators earnings in three blocks, one after the other', async () => { await utils.progressBlocks(1); - expect(await ssvViews.getOperatorEarnings(1)).to.equal(helpers.CONFIG.minimalOperatorFee * 2 + helpers.CONFIG.minimalOperatorFee * 2); - expect(await ssvViews.getOperatorEarnings(2)).to.equal(helpers.CONFIG.minimalOperatorFee * 2 + helpers.CONFIG.minimalOperatorFee * 2); - expect(await ssvViews.getOperatorEarnings(3)).to.equal(helpers.CONFIG.minimalOperatorFee * 2 + helpers.CONFIG.minimalOperatorFee * 2); - expect(await ssvViews.getOperatorEarnings(4)).to.equal(helpers.CONFIG.minimalOperatorFee * 2 + helpers.CONFIG.minimalOperatorFee * 2); + expect(await ssvViews.getOperatorEarnings(1)).to.equal( + helpers.CONFIG.minimalOperatorFee * 2 + helpers.CONFIG.minimalOperatorFee * 2, + ); + expect(await ssvViews.getOperatorEarnings(2)).to.equal( + helpers.CONFIG.minimalOperatorFee * 2 + helpers.CONFIG.minimalOperatorFee * 2, + ); + expect(await ssvViews.getOperatorEarnings(3)).to.equal( + helpers.CONFIG.minimalOperatorFee * 2 + helpers.CONFIG.minimalOperatorFee * 2, + ); + expect(await ssvViews.getOperatorEarnings(4)).to.equal( + helpers.CONFIG.minimalOperatorFee * 2 + helpers.CONFIG.minimalOperatorFee * 2, + ); await utils.progressBlocks(1); - expect(await ssvViews.getOperatorEarnings(1)).to.equal(helpers.CONFIG.minimalOperatorFee * 4 + helpers.CONFIG.minimalOperatorFee * 2); - expect(await ssvViews.getOperatorEarnings(2)).to.equal(helpers.CONFIG.minimalOperatorFee * 4 + helpers.CONFIG.minimalOperatorFee * 2); - expect(await ssvViews.getOperatorEarnings(3)).to.equal(helpers.CONFIG.minimalOperatorFee * 4 + helpers.CONFIG.minimalOperatorFee * 2); - expect(await ssvViews.getOperatorEarnings(4)).to.equal(helpers.CONFIG.minimalOperatorFee * 4 + helpers.CONFIG.minimalOperatorFee * 2); + expect(await ssvViews.getOperatorEarnings(1)).to.equal( + helpers.CONFIG.minimalOperatorFee * 4 + helpers.CONFIG.minimalOperatorFee * 2, + ); + expect(await ssvViews.getOperatorEarnings(2)).to.equal( + helpers.CONFIG.minimalOperatorFee * 4 + helpers.CONFIG.minimalOperatorFee * 2, + ); + expect(await ssvViews.getOperatorEarnings(3)).to.equal( + helpers.CONFIG.minimalOperatorFee * 4 + helpers.CONFIG.minimalOperatorFee * 2, + ); + expect(await ssvViews.getOperatorEarnings(4)).to.equal( + helpers.CONFIG.minimalOperatorFee * 4 + helpers.CONFIG.minimalOperatorFee * 2, + ); await utils.progressBlocks(1); - expect(await ssvViews.getOperatorEarnings(1)).to.equal(helpers.CONFIG.minimalOperatorFee * 6 + helpers.CONFIG.minimalOperatorFee * 2); - expect(await ssvViews.getOperatorEarnings(2)).to.equal(helpers.CONFIG.minimalOperatorFee * 6 + helpers.CONFIG.minimalOperatorFee * 2); - expect(await ssvViews.getOperatorEarnings(3)).to.equal(helpers.CONFIG.minimalOperatorFee * 6 + helpers.CONFIG.minimalOperatorFee * 2); - expect(await ssvViews.getOperatorEarnings(4)).to.equal(helpers.CONFIG.minimalOperatorFee * 6 + helpers.CONFIG.minimalOperatorFee * 2); + expect(await ssvViews.getOperatorEarnings(1)).to.equal( + helpers.CONFIG.minimalOperatorFee * 6 + helpers.CONFIG.minimalOperatorFee * 2, + ); + expect(await ssvViews.getOperatorEarnings(2)).to.equal( + helpers.CONFIG.minimalOperatorFee * 6 + helpers.CONFIG.minimalOperatorFee * 2, + ); + expect(await ssvViews.getOperatorEarnings(3)).to.equal( + helpers.CONFIG.minimalOperatorFee * 6 + helpers.CONFIG.minimalOperatorFee * 2, + ); + expect(await ssvViews.getOperatorEarnings(4)).to.equal( + helpers.CONFIG.minimalOperatorFee * 6 + helpers.CONFIG.minimalOperatorFee * 2, + ); }); it('Check cluster balance with removed operator', async () => { await ssvNetworkContract.removeOperator(1); - expect(await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster)).not.equals(0); + expect( + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), + ).not.equals(0); }); it('Check cluster balance with not enough balance', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation + 10); - expect(await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster)).to.be.equals(0); + expect( + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), + ).to.be.equals(0); }); it('Check cluster balance in a non liquidated cluster', async () => { await utils.progressBlocks(1); - expect(await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster)).to.equal(minDepositAmount - burnPerBlock); + expect( + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), + ).to.equal(minDepositAmount - burnPerBlock); }); it('Check cluster balance in a liquidated cluster reverts "ClusterIsLiquidated"', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation - 1); - const liquidatedCluster = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[6]).liquidate( - cluster1.args.owner, - cluster1.args.operatorIds, - cluster1.args.cluster - )); + const liquidatedCluster = await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[6]) + .liquidate(cluster1.args.owner, cluster1.args.operatorIds, cluster1.args.cluster), + ); const updatedCluster = liquidatedCluster.eventsByName.ClusterLiquidated[0].args; - expect(await ssvViews.isLiquidated(updatedCluster.owner, updatedCluster.operatorIds, updatedCluster.cluster)).to.equal(true); - await expect(ssvViews.getBalance(helpers.DB.owners[4].address, updatedCluster.operatorIds, updatedCluster.cluster)).to.be.revertedWithCustomError(ssvViews, 'ClusterIsLiquidated'); + expect( + await ssvViews.isLiquidated(updatedCluster.owner, updatedCluster.operatorIds, updatedCluster.cluster), + ).to.equal(true); + await expect( + ssvViews.getBalance(helpers.DB.owners[4].address, updatedCluster.operatorIds, updatedCluster.cluster), + ).to.be.revertedWithCustomError(ssvViews, 'ClusterIsLiquidated'); }); it('Check operator earnings, cluster balances and network earnings"', async () => { @@ -132,9 +200,13 @@ describe('Balance Tests', () => { // progress blocks in the process await utils.progressBlocks(1); - expect(await ssvViews.getOperatorEarnings(1)).to.equal(helpers.CONFIG.minimalOperatorFee * 3 + helpers.CONFIG.minimalOperatorFee); - expect(await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster)).to.equal(minDepositAmount - burnPerBlock); - expect(await ssvViews.getNetworkEarnings() - initNetworkFeeBalance).to.equal(networkFee * 2); + expect(await ssvViews.getOperatorEarnings(1)).to.equal( + helpers.CONFIG.minimalOperatorFee * 3 + helpers.CONFIG.minimalOperatorFee, + ); + expect( + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), + ).to.equal(minDepositAmount - burnPerBlock); + expect((await ssvViews.getNetworkEarnings()) - initNetworkFeeBalance).to.equal(networkFee * 2); const newNetworkFee = networkFee * 2; await ssvNetworkContract.updateNetworkFee(newNetworkFee); @@ -142,35 +214,65 @@ describe('Balance Tests', () => { const newBurnPerBlock = helpers.CONFIG.minimalOperatorFee * 4 + newNetworkFee; await utils.progressBlocks(1); - expect(await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster)).to.equal(minDepositAmount - burnPerBlock * 2 - newBurnPerBlock); - expect(await ssvViews.getNetworkEarnings() - initNetworkFeeBalance).to.equal(networkFee * 4 + newNetworkFee * 2); + expect( + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), + ).to.equal(minDepositAmount - burnPerBlock * 2 - newBurnPerBlock); + expect((await ssvViews.getNetworkEarnings()) - initNetworkFeeBalance).to.equal(networkFee * 4 + newNetworkFee * 2); const minDep2 = minDepositAmount * 2; const cluster2 = await helpers.registerValidators(4, 1, minDep2.toString(), [3, 4, 5, 6]); await utils.progressBlocks(2); - expect(await ssvViews.getOperatorEarnings(1)).to.equal(helpers.CONFIG.minimalOperatorFee * 8 + helpers.CONFIG.minimalOperatorFee * 8); - expect(await ssvViews.getOperatorEarnings(3)).to.equal(helpers.CONFIG.minimalOperatorFee * 8 + helpers.CONFIG.minimalOperatorFee * 8 + helpers.CONFIG.minimalOperatorFee * 2); - - expect(await ssvViews.getOperatorEarnings(5)).to.equal(helpers.CONFIG.minimalOperatorFee * 6 + helpers.CONFIG.minimalOperatorFee * 5); - expect(await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster)).to.equal(minDepositAmount - burnPerBlock * 2 - newBurnPerBlock * 5); - expect(await ssvViews.getBalance(helpers.DB.owners[4].address, cluster2.args.operatorIds, cluster2.args.cluster)).to.equal(minDep2 - newBurnPerBlock * 2); + expect(await ssvViews.getOperatorEarnings(1)).to.equal( + helpers.CONFIG.minimalOperatorFee * 8 + helpers.CONFIG.minimalOperatorFee * 8, + ); + expect(await ssvViews.getOperatorEarnings(3)).to.equal( + helpers.CONFIG.minimalOperatorFee * 8 + + helpers.CONFIG.minimalOperatorFee * 8 + + helpers.CONFIG.minimalOperatorFee * 2, + ); + + expect(await ssvViews.getOperatorEarnings(5)).to.equal( + helpers.CONFIG.minimalOperatorFee * 6 + helpers.CONFIG.minimalOperatorFee * 5, + ); + expect( + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), + ).to.equal(minDepositAmount - burnPerBlock * 2 - newBurnPerBlock * 5); + expect( + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster2.args.operatorIds, cluster2.args.cluster), + ).to.equal(minDep2 - newBurnPerBlock * 2); // cold cluster + cluster1 * networkFee (4) + (cold cluster + cluster1 * newNetworkFee (5 + 5)) + cluster2 * newNetworkFee (2) - expect(await ssvViews.getNetworkEarnings() - initNetworkFeeBalance).to.equal(networkFee * 4 + newNetworkFee * 5 + newNetworkFee * 4 + newNetworkFee * 3); + expect((await ssvViews.getNetworkEarnings()) - initNetworkFeeBalance).to.equal( + networkFee * 4 + newNetworkFee * 5 + newNetworkFee * 4 + newNetworkFee * 3, + ); await ssvNetworkContract.updateNetworkFee(networkFee); await utils.progressBlocks(4); - expect(await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster)).to.equal(minDepositAmount - burnPerBlock * 2 - newBurnPerBlock * 6 - burnPerBlock * 4); - expect(await ssvViews.getBalance(helpers.DB.owners[4].address, cluster2.args.operatorIds, cluster2.args.cluster)).to.equal(minDep2 - newBurnPerBlock * 3 - burnPerBlock * 4); - - expect(await ssvViews.getOperatorEarnings(1)).to.equal(helpers.CONFIG.minimalOperatorFee * 14 + helpers.CONFIG.minimalOperatorFee * 12); - expect(await ssvViews.getOperatorEarnings(3)).to.equal(helpers.CONFIG.minimalOperatorFee * 14 + helpers.CONFIG.minimalOperatorFee * 12 + helpers.CONFIG.minimalOperatorFee * 7); - expect(await ssvViews.getOperatorEarnings(5)).to.equal(helpers.CONFIG.minimalOperatorFee * 11 + helpers.CONFIG.minimalOperatorFee * 10); + expect( + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), + ).to.equal(minDepositAmount - burnPerBlock * 2 - newBurnPerBlock * 6 - burnPerBlock * 4); + expect( + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster2.args.operatorIds, cluster2.args.cluster), + ).to.equal(minDep2 - newBurnPerBlock * 3 - burnPerBlock * 4); + + expect(await ssvViews.getOperatorEarnings(1)).to.equal( + helpers.CONFIG.minimalOperatorFee * 14 + helpers.CONFIG.minimalOperatorFee * 12, + ); + expect(await ssvViews.getOperatorEarnings(3)).to.equal( + helpers.CONFIG.minimalOperatorFee * 14 + + helpers.CONFIG.minimalOperatorFee * 12 + + helpers.CONFIG.minimalOperatorFee * 7, + ); + expect(await ssvViews.getOperatorEarnings(5)).to.equal( + helpers.CONFIG.minimalOperatorFee * 11 + helpers.CONFIG.minimalOperatorFee * 10, + ); // cold cluster + cluster1 * networkFee (4) + (cold cluster + cluster1 * newNetworkFee (6 + 6)) + cluster2 * newNetworkFee (3) + (cold cluster + cluster1 + cluster2 * networkFee (4 + 4 + 4)) - expect(await ssvViews.getNetworkEarnings() - initNetworkFeeBalance).to.equal(networkFee * 4 + newNetworkFee * 6 + newNetworkFee * 6 + newNetworkFee * 3 + networkFee * 12); + expect((await ssvViews.getNetworkEarnings()) - initNetworkFeeBalance).to.equal( + networkFee * 4 + newNetworkFee * 6 + newNetworkFee * 6 + newNetworkFee * 3 + networkFee * 12, + ); }); it('Check operator earnings and cluster balance when reducing operator fee"', async () => { @@ -179,36 +281,75 @@ describe('Balance Tests', () => { await utils.progressBlocks(2); - expect(await ssvViews.getOperatorEarnings(1)).to.equal(helpers.CONFIG.minimalOperatorFee * 4 + helpers.CONFIG.minimalOperatorFee + newFee * 2); - expect(await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster)).to.equal(minDepositAmount - burnPerBlock - ((helpers.CONFIG.minimalOperatorFee * 3 + networkFee) * 2) - newFee * 2); + expect(await ssvViews.getOperatorEarnings(1)).to.equal( + helpers.CONFIG.minimalOperatorFee * 4 + helpers.CONFIG.minimalOperatorFee + newFee * 2, + ); + expect( + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), + ).to.equal(minDepositAmount - burnPerBlock - (helpers.CONFIG.minimalOperatorFee * 3 + networkFee) * 2 - newFee * 2); }); it('Check cluster balance after withdraw and deposit"', async () => { await utils.progressBlocks(1); - expect(await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster)).to.equal(minDepositAmount - burnPerBlock); - - await helpers.DB.ssvToken.connect(helpers.DB.owners[4]).approve(helpers.DB.ssvNetwork.contract.address, minDepositAmount * 2); - let validator2 = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).registerValidator( - helpers.DataGenerator.publicKey(3), - [1, 2, 3, 4], - helpers.DataGenerator.shares(4), - minDepositAmount * 2, - cluster1.args.cluster - )); + expect( + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), + ).to.equal(minDepositAmount - burnPerBlock); + + await helpers.DB.ssvToken + .connect(helpers.DB.owners[4]) + .approve(helpers.DB.ssvNetwork.contract.address, minDepositAmount * 2); + let validator2 = await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[4]) + .registerValidator( + helpers.DataGenerator.publicKey(3), + [1, 2, 3, 4], + helpers.DataGenerator.shares(4), + minDepositAmount * 2, + cluster1.args.cluster, + ), + ); let cluster2 = validator2.eventsByName.ValidatorAdded[0]; - expect(await ssvViews.getBalance(helpers.DB.owners[4].address, cluster2.args.operatorIds, cluster2.args.cluster)).to.equal(minDepositAmount * 3 - burnPerBlock * 3); + expect( + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster2.args.operatorIds, cluster2.args.cluster), + ).to.equal(minDepositAmount * 3 - burnPerBlock * 3); - validator2 = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).withdraw(cluster2.args.operatorIds, helpers.CONFIG.minimalOperatorFee, cluster2.args.cluster)); + validator2 = await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[4]) + .withdraw(cluster2.args.operatorIds, helpers.CONFIG.minimalOperatorFee, cluster2.args.cluster), + ); cluster2 = validator2.eventsByName.ClusterWithdrawn[0]; - expect(await ssvViews.getBalance(helpers.DB.owners[4].address, cluster2.args.operatorIds, cluster2.args.cluster)).to.equal(minDepositAmount * 3 - burnPerBlock * 4 - burnPerBlock - helpers.CONFIG.minimalOperatorFee); - - await helpers.DB.ssvToken.connect(helpers.DB.owners[4]).approve(helpers.DB.ssvNetwork.contract.address, minDepositAmount); - validator2 = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).deposit(helpers.DB.owners[4].address, cluster2.args.operatorIds, helpers.CONFIG.minimalOperatorFee, cluster2.args.cluster)); + expect( + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster2.args.operatorIds, cluster2.args.cluster), + ).to.equal(minDepositAmount * 3 - burnPerBlock * 4 - burnPerBlock - helpers.CONFIG.minimalOperatorFee); + + await helpers.DB.ssvToken + .connect(helpers.DB.owners[4]) + .approve(helpers.DB.ssvNetwork.contract.address, minDepositAmount); + validator2 = await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[4]) + .deposit( + helpers.DB.owners[4].address, + cluster2.args.operatorIds, + helpers.CONFIG.minimalOperatorFee, + cluster2.args.cluster, + ), + ); cluster2 = validator2.eventsByName.ClusterDeposited[0]; await utils.progressBlocks(2); - expect(await ssvViews.getBalance(helpers.DB.owners[4].address, cluster2.args.operatorIds, cluster2.args.cluster)).to.equal(minDepositAmount * 3 - burnPerBlock * 8 - burnPerBlock * 5 - helpers.CONFIG.minimalOperatorFee + helpers.CONFIG.minimalOperatorFee); + expect( + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster2.args.operatorIds, cluster2.args.cluster), + ).to.equal( + minDepositAmount * 3 - + burnPerBlock * 8 - + burnPerBlock * 5 - + helpers.CONFIG.minimalOperatorFee + + helpers.CONFIG.minimalOperatorFee, + ); }); -}); \ No newline at end of file +}); From 71d61a03f34593ab278bb930192baf13ddbf89f8 Mon Sep 17 00:00:00 2001 From: Mohsen-T Date: Mon, 27 Nov 2023 09:32:14 +0100 Subject: [PATCH 03/38] fix: reviewed the balance calculation when an operator is removed --- contracts/SSVNetworkViews.sol | 3 +++ contracts/interfaces/ISSVViews.sol | 2 ++ contracts/modules/SSVOperators.sol | 1 + contracts/modules/SSVViews.sol | 5 +++++ contracts/test/SSVViewsT.sol | 3 +++ test/sanity/balances.ts | 13 ++++++++----- 6 files changed, 22 insertions(+), 5 deletions(-) diff --git a/contracts/SSVNetworkViews.sol b/contracts/SSVNetworkViews.sol index 5da979a6..26fa8834 100644 --- a/contracts/SSVNetworkViews.sol +++ b/contracts/SSVNetworkViews.sol @@ -108,6 +108,9 @@ contract SSVNetworkViews is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVViews /*******************************/ /* DAO External View Functions */ /*******************************/ + function getNetworkFeeIndex() external view returns (uint256) { + return ssvNetwork.getNetworkFeeIndex(); + } function getNetworkFee() external view override returns (uint256) { return ssvNetwork.getNetworkFee(); diff --git a/contracts/interfaces/ISSVViews.sol b/contracts/interfaces/ISSVViews.sol index b635013c..07184e5b 100644 --- a/contracts/interfaces/ISSVViews.sol +++ b/contracts/interfaces/ISSVViews.sol @@ -85,6 +85,8 @@ interface ISSVViews is ISSVNetworkCore { Cluster memory cluster ) external view returns (uint256 balance); + function getNetworkFeeIndex() external view returns (uint256); + /// @notice Gets the network fee /// @return networkFee The fee associated with the network (SSV) function getNetworkFee() external view returns (uint256 networkFee); diff --git a/contracts/modules/SSVOperators.sol b/contracts/modules/SSVOperators.sol index b27455f7..638ca8f4 100644 --- a/contracts/modules/SSVOperators.sol +++ b/contracts/modules/SSVOperators.sol @@ -62,6 +62,7 @@ contract SSVOperators is ISSVOperators { operator.snapshot.balance = 0; operator.validatorCount = 0; operator.fee = 0; + operator.whitelisted = false; s.operators[operatorId] = operator; diff --git a/contracts/modules/SSVViews.sol b/contracts/modules/SSVViews.sol index 48a7fc17..11874e04 100644 --- a/contracts/modules/SSVViews.sol +++ b/contracts/modules/SSVViews.sol @@ -9,6 +9,7 @@ import "../libraries/CoreLib.sol"; import "../libraries/ProtocolLib.sol"; import "../libraries/SSVStorage.sol"; import "../libraries/SSVStorageProtocol.sol"; +import "hardhat/console.sol"; contract SSVViews is ISSVViews { using Types64 for uint64; @@ -163,6 +164,10 @@ contract SSVViews is ISSVViews { /* DAO External View Functions */ /*******************************/ + function getNetworkFeeIndex() external view override returns (uint256) { + return SSVStorageProtocol.load().currentNetworkFeeIndex(); + } + function getNetworkFee() external view override returns (uint256) { return SSVStorageProtocol.load().networkFee.expand(); } diff --git a/contracts/test/SSVViewsT.sol b/contracts/test/SSVViewsT.sol index b9d756ff..8fd729af 100644 --- a/contracts/test/SSVViewsT.sol +++ b/contracts/test/SSVViewsT.sol @@ -166,6 +166,9 @@ contract SSVViewsT is ISSVViews { /*******************************/ /* DAO External View Functions */ /*******************************/ + function getNetworkFeeIndex() external view override returns (uint256) { + return SSVStorageProtocol.load().currentNetworkFeeIndex(); + } function getNetworkFee() external view override returns (uint256) { return SSVStorageProtocol.load().networkFee.expand(); diff --git a/test/sanity/balances.ts b/test/sanity/balances.ts index f22e51f8..c7f467b8 100644 --- a/test/sanity/balances.ts +++ b/test/sanity/balances.ts @@ -41,14 +41,17 @@ describe('Balance Tests', () => { }); it.only('Check cluster balance with removing operator', async () => { - //await utils.progressBlocks(1); const operatorIds = cluster1.args.operatorIds; const cluster = cluster1.args.cluster; - for (let i = 1; i <= 4; i++) { - await ssvNetworkContract.connect(helpers.DB.owners[0]).removeOperator(5 - i); - // await ssvNetworkContract.connect(helpers.DB.owners[0]).removeOperator(i); + let prevBalance: any; + for (let i = 1; i <= 13; i++) { + await ssvNetworkContract.connect(helpers.DB.owners[0]).removeOperator(i); let balance = await ssvViews.getBalance(helpers.DB.owners[4].address, operatorIds, cluster); - console.log(balance.toString()); + let networkFee = await ssvViews.getNetworkFee(); + if (i > 4) { + expect(prevBalance - balance).to.equal(networkFee); + } + prevBalance = balance; } }); From 68cc9a89c0a302723863500f3058e8f36fb0b669 Mon Sep 17 00:00:00 2001 From: Mohsen-T <61871540+Mohsen-T@users.noreply.github.com> Date: Mon, 27 Nov 2023 16:39:42 +0700 Subject: [PATCH 04/38] Update balances.ts --- test/sanity/balances.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/sanity/balances.ts b/test/sanity/balances.ts index c7f467b8..c47b19a7 100644 --- a/test/sanity/balances.ts +++ b/test/sanity/balances.ts @@ -40,7 +40,7 @@ describe('Balance Tests', () => { initNetworkFeeBalance = await ssvViews.getNetworkEarnings(); }); - it.only('Check cluster balance with removing operator', async () => { + it('Check cluster balance with removing operator', async () => { const operatorIds = cluster1.args.operatorIds; const cluster = cluster1.args.cluster; let prevBalance: any; From 6951d2881724f3655f204d2966895d3e32e8a2ff Mon Sep 17 00:00:00 2001 From: Mohsen-T Date: Tue, 28 Nov 2023 19:44:08 +0100 Subject: [PATCH 05/38] fix: added a test case --- contracts/SSVNetworkViews.sol | 5 +- contracts/interfaces/ISSVViews.sol | 2 - contracts/modules/SSVOperators.sol | 1 - contracts/modules/SSVViews.sol | 5 -- contracts/test/SSVViewsT.sol | 3 - test/sanity/balances.ts | 95 ++++++++++++++++++++---------- 6 files changed, 65 insertions(+), 46 deletions(-) diff --git a/contracts/SSVNetworkViews.sol b/contracts/SSVNetworkViews.sol index 26fa8834..84bcfa9c 100644 --- a/contracts/SSVNetworkViews.sol +++ b/contracts/SSVNetworkViews.sol @@ -108,10 +108,7 @@ contract SSVNetworkViews is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVViews /*******************************/ /* DAO External View Functions */ /*******************************/ - function getNetworkFeeIndex() external view returns (uint256) { - return ssvNetwork.getNetworkFeeIndex(); - } - + function getNetworkFee() external view override returns (uint256) { return ssvNetwork.getNetworkFee(); } diff --git a/contracts/interfaces/ISSVViews.sol b/contracts/interfaces/ISSVViews.sol index 07184e5b..b635013c 100644 --- a/contracts/interfaces/ISSVViews.sol +++ b/contracts/interfaces/ISSVViews.sol @@ -85,8 +85,6 @@ interface ISSVViews is ISSVNetworkCore { Cluster memory cluster ) external view returns (uint256 balance); - function getNetworkFeeIndex() external view returns (uint256); - /// @notice Gets the network fee /// @return networkFee The fee associated with the network (SSV) function getNetworkFee() external view returns (uint256 networkFee); diff --git a/contracts/modules/SSVOperators.sol b/contracts/modules/SSVOperators.sol index 638ca8f4..b27455f7 100644 --- a/contracts/modules/SSVOperators.sol +++ b/contracts/modules/SSVOperators.sol @@ -62,7 +62,6 @@ contract SSVOperators is ISSVOperators { operator.snapshot.balance = 0; operator.validatorCount = 0; operator.fee = 0; - operator.whitelisted = false; s.operators[operatorId] = operator; diff --git a/contracts/modules/SSVViews.sol b/contracts/modules/SSVViews.sol index 11874e04..48a7fc17 100644 --- a/contracts/modules/SSVViews.sol +++ b/contracts/modules/SSVViews.sol @@ -9,7 +9,6 @@ import "../libraries/CoreLib.sol"; import "../libraries/ProtocolLib.sol"; import "../libraries/SSVStorage.sol"; import "../libraries/SSVStorageProtocol.sol"; -import "hardhat/console.sol"; contract SSVViews is ISSVViews { using Types64 for uint64; @@ -164,10 +163,6 @@ contract SSVViews is ISSVViews { /* DAO External View Functions */ /*******************************/ - function getNetworkFeeIndex() external view override returns (uint256) { - return SSVStorageProtocol.load().currentNetworkFeeIndex(); - } - function getNetworkFee() external view override returns (uint256) { return SSVStorageProtocol.load().networkFee.expand(); } diff --git a/contracts/test/SSVViewsT.sol b/contracts/test/SSVViewsT.sol index 8fd729af..b9d756ff 100644 --- a/contracts/test/SSVViewsT.sol +++ b/contracts/test/SSVViewsT.sol @@ -166,9 +166,6 @@ contract SSVViewsT is ISSVViews { /*******************************/ /* DAO External View Functions */ /*******************************/ - function getNetworkFeeIndex() external view override returns (uint256) { - return SSVStorageProtocol.load().currentNetworkFeeIndex(); - } function getNetworkFee() external view override returns (uint256) { return SSVStorageProtocol.load().networkFee.expand(); diff --git a/test/sanity/balances.ts b/test/sanity/balances.ts index c47b19a7..ed13863e 100644 --- a/test/sanity/balances.ts +++ b/test/sanity/balances.ts @@ -34,7 +34,7 @@ describe('Balance Tests', () => { // cold register await helpers.coldRegisterValidator(); - cluster1 = await helpers.registerValidators(4, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [ + cluster1 = await helpers.registerValidators(0, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [ GasGroup.REGISTER_VALIDATOR_NEW_STATE, ]); initNetworkFeeBalance = await ssvViews.getNetworkEarnings(); @@ -46,7 +46,7 @@ describe('Balance Tests', () => { let prevBalance: any; for (let i = 1; i <= 13; i++) { await ssvNetworkContract.connect(helpers.DB.owners[0]).removeOperator(i); - let balance = await ssvViews.getBalance(helpers.DB.owners[4].address, operatorIds, cluster); + let balance = await ssvViews.getBalance(helpers.DB.owners[0].address, operatorIds, cluster); let networkFee = await ssvViews.getNetworkFee(); if (i > 4) { expect(prevBalance - balance).to.equal(networkFee); @@ -55,39 +55,72 @@ describe('Balance Tests', () => { } }); + it.only('Check cluster balance after removing operator, progress blocks and confirm', async () => { + const operatorIds = cluster1.args.operatorIds; + const cluster = cluster1.args.cluster; + const owner = cluster1.args.owner; + + // get difference of account balance between blocks before removing operator + let balance1 = await ssvViews.getBalance(helpers.DB.owners[0].address, operatorIds, cluster); + await utils.progressBlocks(1); + let balance2 = await ssvViews.getBalance(helpers.DB.owners[0].address, operatorIds, cluster); + + await ssvNetworkContract.connect(helpers.DB.owners[0]).removeOperator(1); + + // get difference of account balance between blocks after removing operator + let balance3 = await ssvViews.getBalance(helpers.DB.owners[0].address, operatorIds, cluster); + await utils.progressBlocks(1); + let balance4 = await ssvViews.getBalance(helpers.DB.owners[0].address, operatorIds, cluster); + + // check the reducing the balance after removing operator (only 3 operators) + expect(balance1 - balance2).to.be.greaterThan(balance3 - balance4); + + // try to register a new validator in the new cluster with the same operator Ids, check revert + const newOperatorIds = operatorIds.map((id: any) => id.toNumber()); + await expect(helpers.registerValidators(1, 1, minDepositAmount, newOperatorIds)).to.be.revertedWithCustomError( + ssvNetworkContract, + 'OperatorDoesNotExist', + ); + + // try to remove the validator again and check the operator removed is skipped + await ssvNetworkContract + .connect(helpers.DB.owners[0]) + .removeValidator(helpers.DataGenerator.publicKey(1), operatorIds, cluster); + }); + it('Check cluster balance in three blocks, one after the other', async () => { await utils.progressBlocks(1); expect( - await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), + await ssvViews.getBalance(helpers.DB.owners[0].address, cluster1.args.operatorIds, cluster1.args.cluster), ).to.equal(minDepositAmount - burnPerBlock); await utils.progressBlocks(1); expect( - await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), + await ssvViews.getBalance(helpers.DB.owners[0].address, cluster1.args.operatorIds, cluster1.args.cluster), ).to.equal(minDepositAmount - burnPerBlock * 2); await utils.progressBlocks(1); expect( - await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), + await ssvViews.getBalance(helpers.DB.owners[0].address, cluster1.args.operatorIds, cluster1.args.cluster), ).to.equal(minDepositAmount - burnPerBlock * 3); }); it('Check cluster balance in two and twelve blocks, after network fee updates', async () => { await utils.progressBlocks(1); expect( - await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), + await ssvViews.getBalance(helpers.DB.owners[0].address, cluster1.args.operatorIds, cluster1.args.cluster), ).to.equal(minDepositAmount - burnPerBlock); const newBurnPerBlock = burnPerBlock + networkFee; await ssvNetworkContract.updateNetworkFee(networkFee * 2); await utils.progressBlocks(1); expect( - await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), + await ssvViews.getBalance(helpers.DB.owners[0].address, cluster1.args.operatorIds, cluster1.args.cluster), ).to.equal(minDepositAmount - burnPerBlock * 2 - newBurnPerBlock); await utils.progressBlocks(1); expect( - await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), + await ssvViews.getBalance(helpers.DB.owners[0].address, cluster1.args.operatorIds, cluster1.args.cluster), ).to.equal(minDepositAmount - burnPerBlock * 2 - newBurnPerBlock * 2); await utils.progressBlocks(10); expect( - await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), + await ssvViews.getBalance(helpers.DB.owners[0].address, cluster1.args.operatorIds, cluster1.args.cluster), ).to.equal(minDepositAmount - burnPerBlock * 2 - newBurnPerBlock * 12); }); @@ -159,21 +192,21 @@ describe('Balance Tests', () => { it('Check cluster balance with removed operator', async () => { await ssvNetworkContract.removeOperator(1); expect( - await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), + await ssvViews.getBalance(helpers.DB.owners[0].address, cluster1.args.operatorIds, cluster1.args.cluster), ).not.equals(0); }); it('Check cluster balance with not enough balance', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation + 10); expect( - await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), + await ssvViews.getBalance(helpers.DB.owners[0].address, cluster1.args.operatorIds, cluster1.args.cluster), ).to.be.equals(0); }); it('Check cluster balance in a non liquidated cluster', async () => { await utils.progressBlocks(1); expect( - await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), + await ssvViews.getBalance(helpers.DB.owners[0].address, cluster1.args.operatorIds, cluster1.args.cluster), ).to.equal(minDepositAmount - burnPerBlock); }); @@ -190,7 +223,7 @@ describe('Balance Tests', () => { await ssvViews.isLiquidated(updatedCluster.owner, updatedCluster.operatorIds, updatedCluster.cluster), ).to.equal(true); await expect( - ssvViews.getBalance(helpers.DB.owners[4].address, updatedCluster.operatorIds, updatedCluster.cluster), + ssvViews.getBalance(helpers.DB.owners[0].address, updatedCluster.operatorIds, updatedCluster.cluster), ).to.be.revertedWithCustomError(ssvViews, 'ClusterIsLiquidated'); }); @@ -207,7 +240,7 @@ describe('Balance Tests', () => { helpers.CONFIG.minimalOperatorFee * 3 + helpers.CONFIG.minimalOperatorFee, ); expect( - await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), + await ssvViews.getBalance(helpers.DB.owners[0].address, cluster1.args.operatorIds, cluster1.args.cluster), ).to.equal(minDepositAmount - burnPerBlock); expect((await ssvViews.getNetworkEarnings()) - initNetworkFeeBalance).to.equal(networkFee * 2); @@ -218,12 +251,12 @@ describe('Balance Tests', () => { await utils.progressBlocks(1); expect( - await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), + await ssvViews.getBalance(helpers.DB.owners[0].address, cluster1.args.operatorIds, cluster1.args.cluster), ).to.equal(minDepositAmount - burnPerBlock * 2 - newBurnPerBlock); expect((await ssvViews.getNetworkEarnings()) - initNetworkFeeBalance).to.equal(networkFee * 4 + newNetworkFee * 2); const minDep2 = minDepositAmount * 2; - const cluster2 = await helpers.registerValidators(4, 1, minDep2.toString(), [3, 4, 5, 6]); + const cluster2 = await helpers.registerValidators(0, 1, minDep2.toString(), [3, 4, 5, 6]); await utils.progressBlocks(2); expect(await ssvViews.getOperatorEarnings(1)).to.equal( @@ -239,10 +272,10 @@ describe('Balance Tests', () => { helpers.CONFIG.minimalOperatorFee * 6 + helpers.CONFIG.minimalOperatorFee * 5, ); expect( - await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), + await ssvViews.getBalance(helpers.DB.owners[0].address, cluster1.args.operatorIds, cluster1.args.cluster), ).to.equal(minDepositAmount - burnPerBlock * 2 - newBurnPerBlock * 5); expect( - await ssvViews.getBalance(helpers.DB.owners[4].address, cluster2.args.operatorIds, cluster2.args.cluster), + await ssvViews.getBalance(helpers.DB.owners[0].address, cluster2.args.operatorIds, cluster2.args.cluster), ).to.equal(minDep2 - newBurnPerBlock * 2); // cold cluster + cluster1 * networkFee (4) + (cold cluster + cluster1 * newNetworkFee (5 + 5)) + cluster2 * newNetworkFee (2) @@ -254,10 +287,10 @@ describe('Balance Tests', () => { await utils.progressBlocks(4); expect( - await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), + await ssvViews.getBalance(helpers.DB.owners[0].address, cluster1.args.operatorIds, cluster1.args.cluster), ).to.equal(minDepositAmount - burnPerBlock * 2 - newBurnPerBlock * 6 - burnPerBlock * 4); expect( - await ssvViews.getBalance(helpers.DB.owners[4].address, cluster2.args.operatorIds, cluster2.args.cluster), + await ssvViews.getBalance(helpers.DB.owners[0].address, cluster2.args.operatorIds, cluster2.args.cluster), ).to.equal(minDep2 - newBurnPerBlock * 3 - burnPerBlock * 4); expect(await ssvViews.getOperatorEarnings(1)).to.equal( @@ -288,22 +321,22 @@ describe('Balance Tests', () => { helpers.CONFIG.minimalOperatorFee * 4 + helpers.CONFIG.minimalOperatorFee + newFee * 2, ); expect( - await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), + await ssvViews.getBalance(helpers.DB.owners[0].address, cluster1.args.operatorIds, cluster1.args.cluster), ).to.equal(minDepositAmount - burnPerBlock - (helpers.CONFIG.minimalOperatorFee * 3 + networkFee) * 2 - newFee * 2); }); it('Check cluster balance after withdraw and deposit"', async () => { await utils.progressBlocks(1); expect( - await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), + await ssvViews.getBalance(helpers.DB.owners[0].address, cluster1.args.operatorIds, cluster1.args.cluster), ).to.equal(minDepositAmount - burnPerBlock); await helpers.DB.ssvToken - .connect(helpers.DB.owners[4]) + .connect(helpers.DB.owners[0]) .approve(helpers.DB.ssvNetwork.contract.address, minDepositAmount * 2); let validator2 = await trackGas( ssvNetworkContract - .connect(helpers.DB.owners[4]) + .connect(helpers.DB.owners[0]) .registerValidator( helpers.DataGenerator.publicKey(3), [1, 2, 3, 4], @@ -315,28 +348,28 @@ describe('Balance Tests', () => { let cluster2 = validator2.eventsByName.ValidatorAdded[0]; expect( - await ssvViews.getBalance(helpers.DB.owners[4].address, cluster2.args.operatorIds, cluster2.args.cluster), + await ssvViews.getBalance(helpers.DB.owners[0].address, cluster2.args.operatorIds, cluster2.args.cluster), ).to.equal(minDepositAmount * 3 - burnPerBlock * 3); validator2 = await trackGas( ssvNetworkContract - .connect(helpers.DB.owners[4]) + .connect(helpers.DB.owners[0]) .withdraw(cluster2.args.operatorIds, helpers.CONFIG.minimalOperatorFee, cluster2.args.cluster), ); cluster2 = validator2.eventsByName.ClusterWithdrawn[0]; expect( - await ssvViews.getBalance(helpers.DB.owners[4].address, cluster2.args.operatorIds, cluster2.args.cluster), + await ssvViews.getBalance(helpers.DB.owners[0].address, cluster2.args.operatorIds, cluster2.args.cluster), ).to.equal(minDepositAmount * 3 - burnPerBlock * 4 - burnPerBlock - helpers.CONFIG.minimalOperatorFee); await helpers.DB.ssvToken - .connect(helpers.DB.owners[4]) + .connect(helpers.DB.owners[0]) .approve(helpers.DB.ssvNetwork.contract.address, minDepositAmount); validator2 = await trackGas( ssvNetworkContract - .connect(helpers.DB.owners[4]) + .connect(helpers.DB.owners[0]) .deposit( - helpers.DB.owners[4].address, + helpers.DB.owners[0].address, cluster2.args.operatorIds, helpers.CONFIG.minimalOperatorFee, cluster2.args.cluster, @@ -346,7 +379,7 @@ describe('Balance Tests', () => { await utils.progressBlocks(2); expect( - await ssvViews.getBalance(helpers.DB.owners[4].address, cluster2.args.operatorIds, cluster2.args.cluster), + await ssvViews.getBalance(helpers.DB.owners[0].address, cluster2.args.operatorIds, cluster2.args.cluster), ).to.equal( minDepositAmount * 3 - burnPerBlock * 8 - From c5776f7e493bc89c2daaff6339897aa6f17e1944 Mon Sep 17 00:00:00 2001 From: Mohsen-T Date: Tue, 28 Nov 2023 19:45:12 +0100 Subject: [PATCH 06/38] fix: removed only --- test/sanity/balances.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/sanity/balances.ts b/test/sanity/balances.ts index ed13863e..e85e01c5 100644 --- a/test/sanity/balances.ts +++ b/test/sanity/balances.ts @@ -55,7 +55,7 @@ describe('Balance Tests', () => { } }); - it.only('Check cluster balance after removing operator, progress blocks and confirm', async () => { + it('Check cluster balance after removing operator, progress blocks and confirm', async () => { const operatorIds = cluster1.args.operatorIds; const cluster = cluster1.args.cluster; const owner = cluster1.args.owner; From 6521a99199105e6acb49821496688fe8e722902c Mon Sep 17 00:00:00 2001 From: Mohsen-T Date: Wed, 29 Nov 2023 13:31:33 +0100 Subject: [PATCH 07/38] fix: progressing --- test/sanity/balances.ts | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/test/sanity/balances.ts b/test/sanity/balances.ts index e85e01c5..efff7bf9 100644 --- a/test/sanity/balances.ts +++ b/test/sanity/balances.ts @@ -55,7 +55,7 @@ describe('Balance Tests', () => { } }); - it('Check cluster balance after removing operator, progress blocks and confirm', async () => { + it.only('Check cluster balance after removing operator, progress blocks and confirm', async () => { const operatorIds = cluster1.args.operatorIds; const cluster = cluster1.args.cluster; const owner = cluster1.args.owner; @@ -82,10 +82,21 @@ describe('Balance Tests', () => { 'OperatorDoesNotExist', ); - // try to remove the validator again and check the operator removed is skipped - await ssvNetworkContract - .connect(helpers.DB.owners[0]) - .removeValidator(helpers.DataGenerator.publicKey(1), operatorIds, cluster); + // // try to remove the validator again and check the operator removed is skipped + // await ssvNetworkContract + // .connect(helpers.DB.owners[0]) + // .removeValidator(helpers.DataGenerator.publicKey(1), operatorIds, cluster); + + // try to liquidate + await expect(ssvNetworkContract.connect(helpers.DB.owners[0]).liquidate(owner, operatorIds, cluster)).to.emit( + ssvNetworkContract, + 'ClusterLiquidated', + ); + + await expect(ssvViews.getBalance(helpers.DB.owners[0].address, operatorIds, cluster)).to.be.revertedWithCustomError( + ssvViews, + 'ClusterIsLiquidated', + ); }); it('Check cluster balance in three blocks, one after the other', async () => { From df0e0adc0ba111e42995df280900e52ba91efd9f Mon Sep 17 00:00:00 2001 From: Mohsen-T Date: Thu, 30 Nov 2023 05:27:51 +0100 Subject: [PATCH 08/38] fix: updated test case --- contracts/SSVNetworkViews.sol | 2 +- hardhat.config.ts | 61 ++++++++++++++++++----------------- test/sanity/balances.ts | 27 +++++++++------- 3 files changed, 47 insertions(+), 43 deletions(-) diff --git a/contracts/SSVNetworkViews.sol b/contracts/SSVNetworkViews.sol index 84bcfa9c..5da979a6 100644 --- a/contracts/SSVNetworkViews.sol +++ b/contracts/SSVNetworkViews.sol @@ -108,7 +108,7 @@ contract SSVNetworkViews is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVViews /*******************************/ /* DAO External View Functions */ /*******************************/ - + function getNetworkFee() external view override returns (uint256) { return ssvNetwork.getNetworkFee(); } diff --git a/hardhat.config.ts b/hardhat.config.ts index 08662e0f..7b2d5eb2 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -1,7 +1,7 @@ import 'dotenv/config'; import { HardhatUserConfig } from 'hardhat/config'; -import { NetworkUserConfig } from 'hardhat/types'; +import { NetworkUserConfig } from "hardhat/types"; import '@nomicfoundation/hardhat-toolbox'; import '@openzeppelin/hardhat-upgrades'; import 'hardhat-tracer'; @@ -14,38 +14,39 @@ import './tasks/upgrade'; type SSVNetworkConfig = NetworkUserConfig & { ssvToken: string; -}; +} + const config: HardhatUserConfig = { // Your type-safe config goes here mocha: { - timeout: 40000000000000000, + timeout: 40000000000000000 }, solidity: { compilers: [ { - version: '0.8.4', + version: "0.8.4", }, { version: '0.8.18', settings: { optimizer: { enabled: true, - runs: 10000, - }, - }, - }, + runs: 10000 + } + } + } ], }, networks: { ganache: { chainId: 1337, - url: 'http://127.0.0.1:8585', - ssvToken: process.env.SSVTOKEN_ADDRESS, // if empty, deploy SSV mock token + url: "http://127.0.0.1:8585", + ssvToken: process.env.SSVTOKEN_ADDRESS // if empty, deploy SSV mock token } as SSVNetworkConfig, hardhat: { - allowUnlimitedContractSize: true, - }, + allowUnlimitedContractSize: true + } }, etherscan: { // Your API key for Etherscan @@ -53,20 +54,20 @@ const config: HardhatUserConfig = { apiKey: process.env.ETHERSCAN_KEY, customChains: [ { - network: 'holesky', + network: "holesky", chainId: 17000, urls: { - apiURL: 'https://api-holesky.etherscan.io/api', - browserURL: 'https://holesky.etherscan.io', - }, - }, - ], + apiURL: "https://api-holesky.etherscan.io/api", + browserURL: "https://holesky.etherscan.io" + } + } + ] }, gasReporter: { - enabled: false, + enabled: true, currency: 'USD', - gasPrice: 0.3, - }, + gasPrice: 0.3 + } }; if (process.env.GOERLI_ETH_NODE_URL) { @@ -81,13 +82,13 @@ if (process.env.GOERLI_ETH_NODE_URL) { ...config.networks, goerli_development: { ...sharedConfig, - ssvToken: '0x6471F70b932390f527c6403773D082A0Db8e8A9F', + ssvToken: '0x6471F70b932390f527c6403773D082A0Db8e8A9F' } as SSVNetworkConfig, goerli_testnet: { ...sharedConfig, - ssvToken: '0x3a9f01091C446bdE031E39ea8354647AFef091E7', + ssvToken: '0x3a9f01091C446bdE031E39ea8354647AFef091E7' } as SSVNetworkConfig, - }; + } } if (process.env.HOLESKY_ETH_NODE_URL) { @@ -102,13 +103,13 @@ if (process.env.HOLESKY_ETH_NODE_URL) { ...config.networks, holesky_development: { ...sharedConfig, - ssvToken: '0x68A8DDD7a59A900E0657e9f8bbE02B70c947f25F', + ssvToken: '0x68A8DDD7a59A900E0657e9f8bbE02B70c947f25F' } as SSVNetworkConfig, holesky_testnet: { ...sharedConfig, - ssvToken: '0xad45A78180961079BFaeEe349704F411dfF947C6', + ssvToken: '0xad45A78180961079BFaeEe349704F411dfF947C6' } as SSVNetworkConfig, - }; + } } if (process.env.MAINNET_ETH_NODE_URL) { @@ -120,9 +121,9 @@ if (process.env.MAINNET_ETH_NODE_URL) { accounts: [`0x${process.env.MAINNET_OWNER_PRIVATE_KEY}`], gasPrice: +(process.env.GAS_PRICE || ''), gas: +(process.env.GAS || ''), - ssvToken: '0x9D65fF81a3c488d585bBfb0Bfe3c7707c7917f54', - } as SSVNetworkConfig, - }; + ssvToken: '0x9D65fF81a3c488d585bBfb0Bfe3c7707c7917f54' + } as SSVNetworkConfig + } } export default config; diff --git a/test/sanity/balances.ts b/test/sanity/balances.ts index efff7bf9..710c6eb2 100644 --- a/test/sanity/balances.ts +++ b/test/sanity/balances.ts @@ -55,7 +55,7 @@ describe('Balance Tests', () => { } }); - it.only('Check cluster balance after removing operator, progress blocks and confirm', async () => { + it('Check cluster balance after removing operator, progress blocks and confirm', async () => { const operatorIds = cluster1.args.operatorIds; const cluster = cluster1.args.cluster; const owner = cluster1.args.owner; @@ -82,21 +82,24 @@ describe('Balance Tests', () => { 'OperatorDoesNotExist', ); - // // try to remove the validator again and check the operator removed is skipped - // await ssvNetworkContract - // .connect(helpers.DB.owners[0]) - // .removeValidator(helpers.DataGenerator.publicKey(1), operatorIds, cluster); + // try to remove the validator again and check the operator removed is skipped + const removed = await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[0]) + .removeValidator(helpers.DataGenerator.publicKey(1), operatorIds, cluster), + ); + const cluster2 = removed.eventsByName.ValidatorRemoved[0]; // try to liquidate - await expect(ssvNetworkContract.connect(helpers.DB.owners[0]).liquidate(owner, operatorIds, cluster)).to.emit( - ssvNetworkContract, - 'ClusterLiquidated', + const liquidated = await trackGas( + ssvNetworkContract.connect(helpers.DB.owners[0]).liquidate(owner, operatorIds, cluster2.args.cluster), ); + const cluster3 = liquidated.eventsByName.ClusterLiquidated[0]; + console.log(cluster3); - await expect(ssvViews.getBalance(helpers.DB.owners[0].address, operatorIds, cluster)).to.be.revertedWithCustomError( - ssvViews, - 'ClusterIsLiquidated', - ); + await expect( + ssvViews.getBalance(helpers.DB.owners[0].address, operatorIds, cluster3.args.cluster), + ).to.be.revertedWithCustomError(ssvViews, 'ClusterIsLiquidated'); }); it('Check cluster balance in three blocks, one after the other', async () => { From d0dcb41f2f0e41e2bced39cff60b71b8eb9bd5b8 Mon Sep 17 00:00:00 2001 From: Mohsen-T Date: Thu, 30 Nov 2023 05:29:11 +0100 Subject: [PATCH 09/38] fix: removed log --- test/sanity/balances.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/test/sanity/balances.ts b/test/sanity/balances.ts index 710c6eb2..1774202a 100644 --- a/test/sanity/balances.ts +++ b/test/sanity/balances.ts @@ -95,7 +95,6 @@ describe('Balance Tests', () => { ssvNetworkContract.connect(helpers.DB.owners[0]).liquidate(owner, operatorIds, cluster2.args.cluster), ); const cluster3 = liquidated.eventsByName.ClusterLiquidated[0]; - console.log(cluster3); await expect( ssvViews.getBalance(helpers.DB.owners[0].address, operatorIds, cluster3.args.cluster), From 7564dfe344811db0ee154ac72e5deb2d0b188303 Mon Sep 17 00:00:00 2001 From: Mohsen-T <61871540+Mohsen-T@users.noreply.github.com> Date: Tue, 5 Dec 2023 10:51:44 +0000 Subject: [PATCH 10/38] [Feature] - Integration ssv-keys in ssv-network for generating keyshares (#276) * feat: updated validators & operators management using ssv-keys --- .github/workflows/slither.yml | 4 +- .gitignore | 2 +- abis/SSVNetwork.json | 4 +- hardhat.config.ts | 6 + package-lock.json | 17995 +++++++++++++++---------- package.json | 1 + test/account/deposit.ts | 101 +- test/account/withdraw.ts | 176 +- test/dao/network-fee-withdraw.ts | 51 +- test/dao/operational.ts | 139 +- test/helpers/contract-helpers.ts | 361 +- test/helpers/gas-usage.ts | 53 +- test/helpers/json/operatorKeys.json | 41 + test/helpers/json/validatorKeys.json | 22 + test/helpers/types.ts | 11 + test/liquidate/liquidate.ts | 343 +- test/liquidate/liquidated-cluster.ts | 205 +- test/liquidate/reactivate.ts | 108 +- test/operators/remove.ts | 66 +- test/sanity/balances.ts | 300 +- test/validators/others.ts | 308 +- test/validators/register.ts | 1461 +- test/validators/remove.ts | 283 +- tsconfig.json | 6 +- 24 files changed, 13433 insertions(+), 8614 deletions(-) create mode 100644 test/helpers/json/operatorKeys.json create mode 100644 test/helpers/json/validatorKeys.json create mode 100644 test/helpers/types.ts diff --git a/.github/workflows/slither.yml b/.github/workflows/slither.yml index 9940415f..2432e529 100644 --- a/.github/workflows/slither.yml +++ b/.github/workflows/slither.yml @@ -8,9 +8,9 @@ jobs: uses: actions/checkout@v3 - name: Run Slither - uses: crytic/slither-action@v0.2.0 + uses: crytic/slither-action@v0.3.0 id: slither with: - node-version: 16 + node-version: 18 fail-on: high slither-args: --exclude controlled-delegatecall \ No newline at end of file diff --git a/.gitignore b/.gitignore index a2420ca2..88003748 100644 --- a/.gitignore +++ b/.gitignore @@ -8,7 +8,7 @@ coverage coverage.json artifacts typechain-types/ -.openzeppelin/dev-*.json +.openzeppelin/*.json .DS_Store .history .dccache diff --git a/abis/SSVNetwork.json b/abis/SSVNetwork.json index 1167cb48..9a017710 100644 --- a/abis/SSVNetwork.json +++ b/abis/SSVNetwork.json @@ -842,7 +842,7 @@ "anonymous": false, "inputs": [ { - "indexed": false, + "indexed": true, "internalType": "address", "name": "owner", "type": "address" @@ -854,7 +854,7 @@ "type": "uint64[]" }, { - "indexed": true, + "indexed": false, "internalType": "bytes", "name": "publicKey", "type": "bytes" diff --git a/hardhat.config.ts b/hardhat.config.ts index d3908f89..47473be1 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -68,6 +68,12 @@ const config: HardhatUserConfig = { currency: 'USD', gasPrice: 0.3, }, + contractSizer: { + alphaSort: true, + disambiguatePaths: false, + runOnCompile: true, + strict: false, + }, abiExporter: { path: './abis', runOnCompile: true, diff --git a/package-lock.json b/package-lock.json index 50b5a065..a31de820 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33,10 +33,20 @@ "hardhat-tracer": "^1.2.1", "prompts": "^2.4.2", "simple-git": "^3.16.1", + "ssv-keys": "github:bloxapp/ssv-keys#v1.0.4", "ts-node": "^10.7.0", "typescript": "^4.6.3" } }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/@aws-crypto/sha256-js": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-1.2.2.tgz", @@ -60,11 +70,12 @@ } }, "node_modules/@aws-sdk/types": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.347.0.tgz", - "integrity": "sha512-GkCMy79mdjU9OTIe5KT58fI/6uqdf8UmMdWqVHmFJ+UpEzOci7L/uw4sOXWo7xpPzLs6cJ7s5ouGZW4GRPmHFA==", + "version": "3.465.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.465.0.tgz", + "integrity": "sha512-Clqu2eD50OOzwSftGpzJrIOGev/7VJhJpc02SeS4cqFgI9EVd+rnFKS/Ux0kcwjLQBMiPcCLtql3KAHApFHAIA==", "dev": true, "dependencies": { + "@smithy/types": "^2.5.0", "tslib": "^2.5.0" }, "engines": { @@ -72,9 +83,9 @@ } }, "node_modules/@aws-sdk/types/node_modules/tslib": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", - "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", "dev": true }, "node_modules/@aws-sdk/util-utf8-browser": { @@ -87,40 +98,112 @@ } }, "node_modules/@aws-sdk/util-utf8-browser/node_modules/tslib": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", - "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", "dev": true }, "node_modules/@babel/code-frame": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz", - "integrity": "sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", "dev": true, "dependencies": { - "@babel/highlight": "^7.22.5" + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" }, "engines": { "node": ">=6.9.0" } }, + "node_modules/@babel/code-frame/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/code-frame/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/code-frame/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", - "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.5.tgz", - "integrity": "sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.22.5", - "chalk": "^2.0.0", + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", "js-tokens": "^4.0.0" }, "engines": { @@ -262,23 +345,23 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz", - "integrity": "sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", "dev": true, "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, "node_modules/@eslint/eslintrc": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz", - "integrity": "sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.5.2", + "espree": "^9.6.0", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", @@ -294,14 +377,75 @@ } }, "node_modules/@eslint/js": { - "version": "8.43.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.43.0.tgz", - "integrity": "sha512-s2UHCoiXfxMvmfzqoN+vrQ84ahUSYde9qNO1MdxmoEhyHWsfmwOpFlwYV+ePJEVc7gFnATGUi376WowX1N7tFg==", + "version": "8.55.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.55.0.tgz", + "integrity": "sha512-qQfo2mxH5yVom1kacMtZZJFVdW+E70mqHMJvVg6WTLo+VBuQJ4TojZlfWBjK0ve5BdEeNAVxOsl/nvNMpJOaJA==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@ethereumjs/common": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-2.6.5.tgz", + "integrity": "sha512-lRyVQOeCDaIVtgfbowla32pzeDv2Obr8oR8Put5RdUBNRGr1VGPGQNGP6elWIpgK3YdpzqTOh4GyUGOureVeeA==", + "dev": true, + "dependencies": { + "crc-32": "^1.2.0", + "ethereumjs-util": "^7.1.5" + } + }, + "node_modules/@ethereumjs/rlp": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@ethereumjs/rlp/-/rlp-4.0.1.tgz", + "integrity": "sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==", + "dev": true, + "peer": true, + "bin": { + "rlp": "bin/rlp" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@ethereumjs/tx": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-3.5.2.tgz", + "integrity": "sha512-gQDNJWKrSDGu2w7w0PzVXVBNMzb7wwdDOmOqczmhNjqFxFuIbhVJDwiGEnxFNC2/b8ifcZzY7MLcluizohRzNw==", + "dev": true, + "dependencies": { + "@ethereumjs/common": "^2.6.4", + "ethereumjs-util": "^7.1.5" + } + }, + "node_modules/@ethereumjs/util": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@ethereumjs/util/-/util-8.1.0.tgz", + "integrity": "sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA==", + "dev": true, + "peer": true, + "dependencies": { + "@ethereumjs/rlp": "^4.0.1", + "ethereum-cryptography": "^2.0.0", + "micro-ftch": "^0.3.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@ethereumjs/util/node_modules/ethereum-cryptography": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.1.2.tgz", + "integrity": "sha512-Z5Ba0T0ImZ8fqXrJbpHcbpAvIswRte2wGNR/KePnu8GbbvgJ47lMxT/ZZPG6i9Jaht4azPDop4HaM00J0J59ug==", + "dev": true, + "peer": true, + "dependencies": { + "@noble/curves": "1.1.0", + "@noble/hashes": "1.3.1", + "@scure/bip32": "1.3.1", + "@scure/bip39": "1.2.1" + } + }, "node_modules/@ethersproject/abi": { "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz", @@ -1003,13 +1147,22 @@ "@ethersproject/strings": "^5.7.0" } }, + "node_modules/@fastify/busboy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.0.tgz", + "integrity": "sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA==", + "dev": true, + "engines": { + "node": ">=14" + } + }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", - "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==", + "version": "0.11.13", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", + "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", "dev": true, "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", + "@humanwhocodes/object-schema": "^2.0.1", "debug": "^4.1.1", "minimatch": "^3.0.5" }, @@ -1031,9 +1184,9 @@ } }, "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", + "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", "dev": true }, "node_modules/@jridgewell/resolve-uri": { @@ -1122,17 +1275,31 @@ "rlp": "^2.2.3" } }, + "node_modules/@noble/curves": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.1.0.tgz", + "integrity": "sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA==", + "dev": true, + "peer": true, + "dependencies": { + "@noble/hashes": "1.3.1" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@noble/hashes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.2.0.tgz", - "integrity": "sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.1.tgz", + "integrity": "sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ] + "peer": true, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } }, "node_modules/@noble/secp256k1": { "version": "1.7.1", @@ -1182,16 +1349,16 @@ } }, "node_modules/@nomicfoundation/ethereumjs-block": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-block/-/ethereumjs-block-5.0.1.tgz", - "integrity": "sha512-u1Yioemi6Ckj3xspygu/SfFvm8vZEO8/Yx5a1QLzi6nVU0jz3Pg2OmHKJ5w+D9Ogk1vhwRiqEBAqcb0GVhCyHw==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-block/-/ethereumjs-block-5.0.2.tgz", + "integrity": "sha512-hSe6CuHI4SsSiWWjHDIzWhSiAVpzMUcDRpWYzN0T9l8/Rz7xNn3elwVOJ/tAyS0LqL6vitUD78Uk7lQDXZun7Q==", "dev": true, "dependencies": { - "@nomicfoundation/ethereumjs-common": "4.0.1", - "@nomicfoundation/ethereumjs-rlp": "5.0.1", - "@nomicfoundation/ethereumjs-trie": "6.0.1", - "@nomicfoundation/ethereumjs-tx": "5.0.1", - "@nomicfoundation/ethereumjs-util": "9.0.1", + "@nomicfoundation/ethereumjs-common": "4.0.2", + "@nomicfoundation/ethereumjs-rlp": "5.0.2", + "@nomicfoundation/ethereumjs-trie": "6.0.2", + "@nomicfoundation/ethereumjs-tx": "5.0.2", + "@nomicfoundation/ethereumjs-util": "9.0.2", "ethereum-cryptography": "0.1.3", "ethers": "^5.7.1" }, @@ -1200,18 +1367,18 @@ } }, "node_modules/@nomicfoundation/ethereumjs-blockchain": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-blockchain/-/ethereumjs-blockchain-7.0.1.tgz", - "integrity": "sha512-NhzndlGg829XXbqJEYrF1VeZhAwSPgsK/OB7TVrdzft3y918hW5KNd7gIZ85sn6peDZOdjBsAXIpXZ38oBYE5A==", - "dev": true, - "dependencies": { - "@nomicfoundation/ethereumjs-block": "5.0.1", - "@nomicfoundation/ethereumjs-common": "4.0.1", - "@nomicfoundation/ethereumjs-ethash": "3.0.1", - "@nomicfoundation/ethereumjs-rlp": "5.0.1", - "@nomicfoundation/ethereumjs-trie": "6.0.1", - "@nomicfoundation/ethereumjs-tx": "5.0.1", - "@nomicfoundation/ethereumjs-util": "9.0.1", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-blockchain/-/ethereumjs-blockchain-7.0.2.tgz", + "integrity": "sha512-8UUsSXJs+MFfIIAKdh3cG16iNmWzWC/91P40sazNvrqhhdR/RtGDlFk2iFTGbBAZPs2+klZVzhRX8m2wvuvz3w==", + "dev": true, + "dependencies": { + "@nomicfoundation/ethereumjs-block": "5.0.2", + "@nomicfoundation/ethereumjs-common": "4.0.2", + "@nomicfoundation/ethereumjs-ethash": "3.0.2", + "@nomicfoundation/ethereumjs-rlp": "5.0.2", + "@nomicfoundation/ethereumjs-trie": "6.0.2", + "@nomicfoundation/ethereumjs-tx": "5.0.2", + "@nomicfoundation/ethereumjs-util": "9.0.2", "abstract-level": "^1.0.3", "debug": "^4.3.3", "ethereum-cryptography": "0.1.3", @@ -1224,24 +1391,24 @@ } }, "node_modules/@nomicfoundation/ethereumjs-common": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-4.0.1.tgz", - "integrity": "sha512-OBErlkfp54GpeiE06brBW/TTbtbuBJV5YI5Nz/aB2evTDo+KawyEzPjBlSr84z/8MFfj8wS2wxzQX1o32cev5g==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-4.0.2.tgz", + "integrity": "sha512-I2WGP3HMGsOoycSdOTSqIaES0ughQTueOsddJ36aYVpI3SN8YSusgRFLwzDJwRFVIYDKx/iJz0sQ5kBHVgdDwg==", "dev": true, "dependencies": { - "@nomicfoundation/ethereumjs-util": "9.0.1", + "@nomicfoundation/ethereumjs-util": "9.0.2", "crc-32": "^1.2.0" } }, "node_modules/@nomicfoundation/ethereumjs-ethash": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-ethash/-/ethereumjs-ethash-3.0.1.tgz", - "integrity": "sha512-KDjGIB5igzWOp8Ik5I6QiRH5DH+XgILlplsHR7TEuWANZA759G6krQ6o8bvj+tRUz08YygMQu/sGd9mJ1DYT8w==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-ethash/-/ethereumjs-ethash-3.0.2.tgz", + "integrity": "sha512-8PfoOQCcIcO9Pylq0Buijuq/O73tmMVURK0OqdjhwqcGHYC2PwhbajDh7GZ55ekB0Px197ajK3PQhpKoiI/UPg==", "dev": true, "dependencies": { - "@nomicfoundation/ethereumjs-block": "5.0.1", - "@nomicfoundation/ethereumjs-rlp": "5.0.1", - "@nomicfoundation/ethereumjs-util": "9.0.1", + "@nomicfoundation/ethereumjs-block": "5.0.2", + "@nomicfoundation/ethereumjs-rlp": "5.0.2", + "@nomicfoundation/ethereumjs-util": "9.0.2", "abstract-level": "^1.0.3", "bigint-crypto-utils": "^3.0.23", "ethereum-cryptography": "0.1.3" @@ -1251,15 +1418,15 @@ } }, "node_modules/@nomicfoundation/ethereumjs-evm": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-evm/-/ethereumjs-evm-2.0.1.tgz", - "integrity": "sha512-oL8vJcnk0Bx/onl+TgQOQ1t/534GKFaEG17fZmwtPFeH8S5soiBYPCLUrvANOl4sCp9elYxIMzIiTtMtNNN8EQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-evm/-/ethereumjs-evm-2.0.2.tgz", + "integrity": "sha512-rBLcUaUfANJxyOx9HIdMX6uXGin6lANCulIm/pjMgRqfiCRMZie3WKYxTSd8ZE/d+qT+zTedBF4+VHTdTSePmQ==", "dev": true, "dependencies": { "@ethersproject/providers": "^5.7.1", - "@nomicfoundation/ethereumjs-common": "4.0.1", - "@nomicfoundation/ethereumjs-tx": "5.0.1", - "@nomicfoundation/ethereumjs-util": "9.0.1", + "@nomicfoundation/ethereumjs-common": "4.0.2", + "@nomicfoundation/ethereumjs-tx": "5.0.2", + "@nomicfoundation/ethereumjs-util": "9.0.2", "debug": "^4.3.3", "ethereum-cryptography": "0.1.3", "mcl-wasm": "^0.7.1", @@ -1270,9 +1437,9 @@ } }, "node_modules/@nomicfoundation/ethereumjs-rlp": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-5.0.1.tgz", - "integrity": "sha512-xtxrMGa8kP4zF5ApBQBtjlSbN5E2HI8m8FYgVSYAnO6ssUoY5pVPGy2H8+xdf/bmMa22Ce8nWMH3aEW8CcqMeQ==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-5.0.2.tgz", + "integrity": "sha512-QwmemBc+MMsHJ1P1QvPl8R8p2aPvvVcKBbvHnQOKBpBztEo0omN0eaob6FeZS/e3y9NSe+mfu3nNFBHszqkjTA==", "dev": true, "bin": { "rlp": "bin/rlp" @@ -1282,13 +1449,13 @@ } }, "node_modules/@nomicfoundation/ethereumjs-statemanager": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-statemanager/-/ethereumjs-statemanager-2.0.1.tgz", - "integrity": "sha512-B5ApMOnlruVOR7gisBaYwFX+L/AP7i/2oAahatssjPIBVDF6wTX1K7Qpa39E/nzsH8iYuL3krkYeUFIdO3EMUQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-statemanager/-/ethereumjs-statemanager-2.0.2.tgz", + "integrity": "sha512-dlKy5dIXLuDubx8Z74sipciZnJTRSV/uHG48RSijhgm1V7eXYFC567xgKtsKiVZB1ViTP9iFL4B6Je0xD6X2OA==", "dev": true, "dependencies": { - "@nomicfoundation/ethereumjs-common": "4.0.1", - "@nomicfoundation/ethereumjs-rlp": "5.0.1", + "@nomicfoundation/ethereumjs-common": "4.0.2", + "@nomicfoundation/ethereumjs-rlp": "5.0.2", "debug": "^4.3.3", "ethereum-cryptography": "0.1.3", "ethers": "^5.7.1", @@ -1296,13 +1463,13 @@ } }, "node_modules/@nomicfoundation/ethereumjs-trie": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-trie/-/ethereumjs-trie-6.0.1.tgz", - "integrity": "sha512-A64It/IMpDVODzCgxDgAAla8jNjNtsoQZIzZUfIV5AY6Coi4nvn7+VReBn5itlxMiL2yaTlQr9TRWp3CSI6VoA==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-trie/-/ethereumjs-trie-6.0.2.tgz", + "integrity": "sha512-yw8vg9hBeLYk4YNg5MrSJ5H55TLOv2FSWUTROtDtTMMmDGROsAu+0tBjiNGTnKRi400M6cEzoFfa89Fc5k8NTQ==", "dev": true, "dependencies": { - "@nomicfoundation/ethereumjs-rlp": "5.0.1", - "@nomicfoundation/ethereumjs-util": "9.0.1", + "@nomicfoundation/ethereumjs-rlp": "5.0.2", + "@nomicfoundation/ethereumjs-util": "9.0.2", "@types/readable-stream": "^2.3.13", "ethereum-cryptography": "0.1.3", "readable-stream": "^3.6.0" @@ -1312,16 +1479,16 @@ } }, "node_modules/@nomicfoundation/ethereumjs-tx": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-5.0.1.tgz", - "integrity": "sha512-0HwxUF2u2hrsIM1fsasjXvlbDOq1ZHFV2dd1yGq8CA+MEYhaxZr8OTScpVkkxqMwBcc5y83FyPl0J9MZn3kY0w==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-5.0.2.tgz", + "integrity": "sha512-T+l4/MmTp7VhJeNloMkM+lPU3YMUaXdcXgTGCf8+ZFvV9NYZTRLFekRwlG6/JMmVfIfbrW+dRRJ9A6H5Q/Z64g==", "dev": true, "dependencies": { "@chainsafe/ssz": "^0.9.2", "@ethersproject/providers": "^5.7.2", - "@nomicfoundation/ethereumjs-common": "4.0.1", - "@nomicfoundation/ethereumjs-rlp": "5.0.1", - "@nomicfoundation/ethereumjs-util": "9.0.1", + "@nomicfoundation/ethereumjs-common": "4.0.2", + "@nomicfoundation/ethereumjs-rlp": "5.0.2", + "@nomicfoundation/ethereumjs-util": "9.0.2", "ethereum-cryptography": "0.1.3" }, "engines": { @@ -1329,13 +1496,13 @@ } }, "node_modules/@nomicfoundation/ethereumjs-util": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-9.0.1.tgz", - "integrity": "sha512-TwbhOWQ8QoSCFhV/DDfSmyfFIHjPjFBj957219+V3jTZYZ2rf9PmDtNOeZWAE3p3vlp8xb02XGpd0v6nTUPbsA==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-9.0.2.tgz", + "integrity": "sha512-4Wu9D3LykbSBWZo8nJCnzVIYGvGCuyiYLIJa9XXNVt1q1jUzHdB+sJvx95VGCpPkCT+IbLecW6yfzy3E1bQrwQ==", "dev": true, "dependencies": { "@chainsafe/ssz": "^0.10.0", - "@nomicfoundation/ethereumjs-rlp": "5.0.1", + "@nomicfoundation/ethereumjs-rlp": "5.0.2", "ethereum-cryptography": "0.1.3" }, "engines": { @@ -1362,20 +1529,20 @@ } }, "node_modules/@nomicfoundation/ethereumjs-vm": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-vm/-/ethereumjs-vm-7.0.1.tgz", - "integrity": "sha512-rArhyn0jPsS/D+ApFsz3yVJMQ29+pVzNZ0VJgkzAZ+7FqXSRtThl1C1prhmlVr3YNUlfpZ69Ak+RUT4g7VoOuQ==", - "dev": true, - "dependencies": { - "@nomicfoundation/ethereumjs-block": "5.0.1", - "@nomicfoundation/ethereumjs-blockchain": "7.0.1", - "@nomicfoundation/ethereumjs-common": "4.0.1", - "@nomicfoundation/ethereumjs-evm": "2.0.1", - "@nomicfoundation/ethereumjs-rlp": "5.0.1", - "@nomicfoundation/ethereumjs-statemanager": "2.0.1", - "@nomicfoundation/ethereumjs-trie": "6.0.1", - "@nomicfoundation/ethereumjs-tx": "5.0.1", - "@nomicfoundation/ethereumjs-util": "9.0.1", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-vm/-/ethereumjs-vm-7.0.2.tgz", + "integrity": "sha512-Bj3KZT64j54Tcwr7Qm/0jkeZXJMfdcAtRBedou+Hx0dPOSIgqaIr0vvLwP65TpHbak2DmAq+KJbW2KNtIoFwvA==", + "dev": true, + "dependencies": { + "@nomicfoundation/ethereumjs-block": "5.0.2", + "@nomicfoundation/ethereumjs-blockchain": "7.0.2", + "@nomicfoundation/ethereumjs-common": "4.0.2", + "@nomicfoundation/ethereumjs-evm": "2.0.2", + "@nomicfoundation/ethereumjs-rlp": "5.0.2", + "@nomicfoundation/ethereumjs-statemanager": "2.0.2", + "@nomicfoundation/ethereumjs-trie": "6.0.2", + "@nomicfoundation/ethereumjs-tx": "5.0.2", + "@nomicfoundation/ethereumjs-util": "9.0.2", "debug": "^4.3.3", "ethereum-cryptography": "0.1.3", "mcl-wasm": "^0.7.1", @@ -1406,9 +1573,9 @@ } }, "node_modules/@nomicfoundation/hardhat-network-helpers": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-network-helpers/-/hardhat-network-helpers-1.0.8.tgz", - "integrity": "sha512-MNqQbzUJZnCMIYvlniC3U+kcavz/PhhQSsY90tbEtUyMj/IQqsLwIRZa4ctjABh3Bz0KCh9OXUZ7Yk/d9hr45Q==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-network-helpers/-/hardhat-network-helpers-1.0.9.tgz", + "integrity": "sha512-OXWCv0cHpwLUO2u7bFxBna6dQtCC2Gg/aN/KtJLO7gmuuA28vgmVKYFRCDUqrbjujzgfwQ2aKyZ9Y3vSmDqS7Q==", "dev": true, "peer": true, "dependencies": { @@ -1749,26 +1916,26 @@ } }, "node_modules/@openzeppelin/contracts": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.9.2.tgz", - "integrity": "sha512-mO+y6JaqXjWeMh9glYVzVu8HYPGknAAnWyxTRhGeckOruyXQMNnlcW6w/Dx9ftLeIQk6N+ZJFuVmTwF7lEIFrg==", + "version": "4.9.3", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.9.3.tgz", + "integrity": "sha512-He3LieZ1pP2TNt5JbkPA4PNT9WC3gOTOlDcFGJW4Le4QKqwmiNJCRt44APfxMxvq7OugU/cqYuPcSBzOw38DAg==", "dev": true }, "node_modules/@openzeppelin/contracts-upgradeable": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.9.2.tgz", - "integrity": "sha512-siviV3PZV/fHfPaoIC51rf1Jb6iElkYWnNYZ0leO23/ukXuvOyoC/ahy8jqiV7g+++9Nuo3n/rk5ajSN/+d/Sg==", + "version": "4.9.3", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.9.3.tgz", + "integrity": "sha512-jjaHAVRMrE4UuZNfDwjlLGDxTHWIOwTJS2ldnc278a0gevfXfPr8hxKEVBGFBE96kl2G3VHDZhUimw/+G3TG2A==", "dev": true }, "node_modules/@openzeppelin/defender-base-client": { - "version": "1.46.0", - "resolved": "https://registry.npmjs.org/@openzeppelin/defender-base-client/-/defender-base-client-1.46.0.tgz", - "integrity": "sha512-EMnVBcfE6ZN5yMxfaxrFF3eqyGp2RQp3oSRSRP+R3yuCRJf8VCc2ArdZf1QPmQQzbq70nl8EZa03mmAqPauNlQ==", + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/@openzeppelin/defender-base-client/-/defender-base-client-1.52.0.tgz", + "integrity": "sha512-VFNu/pjVpAnFKIfuKT1cn9dRpbcO8FO8EAmVZ2XrrAsKXEWDZ3TNBtACxmj7fAu0ad/TzRkb66o5rMts7Fv7jw==", "dev": true, "dependencies": { "amazon-cognito-identity-js": "^6.0.1", "async-retry": "^1.3.3", - "axios": "^0.21.2", + "axios": "^1.4.0", "lodash": "^4.17.19", "node-fetch": "^2.6.0" } @@ -1805,6 +1972,7 @@ "version": "0.8.0", "resolved": "https://registry.npmjs.org/@openzeppelin/platform-deploy-client/-/platform-deploy-client-0.8.0.tgz", "integrity": "sha512-POx3AsnKwKSV/ZLOU/gheksj0Lq7Is1q2F3pKmcFjGZiibf+4kjGxr4eSMrT+2qgKYZQH1ZLQZ+SkbguD8fTvA==", + "deprecated": "@openzeppelin/platform-deploy-client is deprecated. Please use @openzeppelin/defender-sdk-deploy-client", "dev": true, "dependencies": { "@ethersproject/abi": "^5.6.3", @@ -1814,68 +1982,82 @@ "node-fetch": "^2.6.0" } }, + "node_modules/@openzeppelin/platform-deploy-client/node_modules/axios": { + "version": "0.21.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", + "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", + "dev": true, + "dependencies": { + "follow-redirects": "^1.14.0" + } + }, "node_modules/@openzeppelin/upgrades-core": { - "version": "1.27.1", - "resolved": "https://registry.npmjs.org/@openzeppelin/upgrades-core/-/upgrades-core-1.27.1.tgz", - "integrity": "sha512-6tLcu6jt0nYdJNr+LRicBgP3jp+//B+dixgB3KsvycSglCHNfmBNDf0ZQ3ZquDdLL0QQmKzIs1EBRVp6lNvPnQ==", + "version": "1.31.3", + "resolved": "https://registry.npmjs.org/@openzeppelin/upgrades-core/-/upgrades-core-1.31.3.tgz", + "integrity": "sha512-i7q0IuItKS4uO0clJwm4CARmt98aA9dLfKh38HFRbX+aFLGXwF0sOvB2iwr6f87ShH7d3DNuLrVgnnXUrYb7CA==", "dev": true, "dependencies": { - "cbor": "^8.0.0", + "cbor": "^9.0.0", "chalk": "^4.1.0", - "compare-versions": "^5.0.0", + "compare-versions": "^6.0.0", "debug": "^4.1.1", "ethereumjs-util": "^7.0.3", "minimist": "^1.2.7", "proper-lockfile": "^4.1.1", - "solidity-ast": "^0.4.15" + "solidity-ast": "^0.4.51" }, "bin": { "openzeppelin-upgrades-core": "dist/cli/cli.js" } }, + "node_modules/@openzeppelin/upgrades-core/node_modules/cbor": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cbor/-/cbor-9.0.1.tgz", + "integrity": "sha512-/TQOWyamDxvVIv+DY9cOLNuABkoyz8K/F3QE56539pGVYohx0+MEA1f4lChFTX79dBTBS7R1PF6ovH7G+VtBfQ==", + "dev": true, + "dependencies": { + "nofilter": "^3.1.0" + }, + "engines": { + "node": ">=16" + } + }, "node_modules/@scure/base": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.1.tgz", - "integrity": "sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.3.tgz", + "integrity": "sha512-/+SgoRjLq7Xlf0CWuLHq2LUZeL/w65kfzAPG5NH9pcmBhs+nunQTn4gvdwgMTIXnt9b2C/1SeL2XiysZEyIC9Q==", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ] + "funding": { + "url": "https://paulmillr.com/funding/" + } }, "node_modules/@scure/bip32": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.5.tgz", - "integrity": "sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.3.1.tgz", + "integrity": "sha512-osvveYtyzdEVbt3OfwwXFr4P2iVBL5u1Q3q4ONBfDY/UpOuXmOlbgwc1xECEboY8wIays8Yt6onaWMUdUbfl0A==", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], + "peer": true, "dependencies": { - "@noble/hashes": "~1.2.0", - "@noble/secp256k1": "~1.7.0", + "@noble/curves": "~1.1.0", + "@noble/hashes": "~1.3.1", "@scure/base": "~1.1.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, "node_modules/@scure/bip39": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.1.tgz", - "integrity": "sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.2.1.tgz", + "integrity": "sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg==", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], + "peer": true, "dependencies": { - "@noble/hashes": "~1.2.0", + "@noble/hashes": "~1.3.0", "@scure/base": "~1.1.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, "node_modules/@sentry/core": { @@ -1980,6 +2162,33 @@ "node": ">=6" } }, + "node_modules/@sindresorhus/is": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", + "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@smithy/types": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.6.0.tgz", + "integrity": "sha512-PgqxJq2IcdMF9iAasxcqZqqoOXBHufEfmbEUdN1pmJrJltT42b0Sc8UiYSWWzKkciIp9/mZDpzYi4qYG1qqg6g==", + "dev": true, + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/types/node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "dev": true + }, "node_modules/@solidity-parser/parser": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.14.5.tgz", @@ -1990,6 +2199,18 @@ "antlr4ts": "^0.5.0-alpha.4" } }, + "node_modules/@szmarczak/http-timer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", + "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "dev": true, + "dependencies": { + "defer-to-connect": "^1.0.1" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/@tsconfig/node10": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", @@ -2080,9 +2301,9 @@ } }, "node_modules/@typechain/hardhat/node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "dev": true, "peer": true, "engines": { @@ -2090,33 +2311,45 @@ } }, "node_modules/@types/bn.js": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.1.tgz", - "integrity": "sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g==", + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.5.tgz", + "integrity": "sha512-V46N0zwKRF5Q00AZ6hWtN0T8gGmDUaUzLWQvHFo5yThtVwK/VCenFY3wXVbOvNfajEpsTfQM4IN9k/d6gUVX3A==", "dev": true, "dependencies": { "@types/node": "*" } }, + "node_modules/@types/cacheable-request": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", + "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", + "dev": true, + "dependencies": { + "@types/http-cache-semantics": "*", + "@types/keyv": "^3.1.4", + "@types/node": "*", + "@types/responselike": "^1.0.0" + } + }, "node_modules/@types/chai": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.5.tgz", - "integrity": "sha512-mEo1sAde+UCE6b2hxn332f1g1E8WfYRu6p5SvTKr2ZKC1f7gFJXk4h5PyGP9Dt6gCaG8y8XhwnXWC6Iy2cmBng==", + "version": "4.3.11", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.11.tgz", + "integrity": "sha512-qQR1dr2rGIHYlJulmr8Ioq3De0Le9E4MJ5AiaeAETJJpndT1uUNHsGFK3L/UIu+rbkQSdj8J/w2bCsBZc/Y5fQ==", "dev": true }, "node_modules/@types/chai-as-promised": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-7.1.5.tgz", - "integrity": "sha512-jStwss93SITGBwt/niYrkf2C+/1KTeZCZl1LaeezTlqppAKeoQC7jxyqYuP72sxBGKCIbw7oHgbYssIRzT5FCQ==", + "version": "7.1.8", + "resolved": "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-7.1.8.tgz", + "integrity": "sha512-ThlRVIJhr69FLlh6IctTXFkmhtP3NpMZ2QGq69StYLyKZFp/HOp1VdKZj7RvfNWYYcJ1xlbLGLLWj1UvP5u/Gw==", "dev": true, "dependencies": { "@types/chai": "*" } }, "node_modules/@types/cli-table": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@types/cli-table/-/cli-table-0.3.1.tgz", - "integrity": "sha512-m3+6WWfSSl6zqoXy8uQQifbgqV7Gt6fsyWnHLgUWVtJQk75+OfUB+edSZ52YDj7leSiZtX7w1/E4w2x/Hb0orA==", + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@types/cli-table/-/cli-table-0.3.4.tgz", + "integrity": "sha512-GsALrTL69mlwbAw/MHF1IPTadSLZQnsxe7a80G8l4inN/iEXCOcVeT/S7aRc6hbhqzL9qZ314kHPDQnQ3ev+HA==", "dev": true }, "node_modules/@types/concat-stream": { @@ -2129,6 +2362,12 @@ "@types/node": "*" } }, + "node_modules/@types/figlet": { + "version": "1.5.8", + "resolved": "https://registry.npmjs.org/@types/figlet/-/figlet-1.5.8.tgz", + "integrity": "sha512-G22AUvy4Tl95XLE7jmUM8s8mKcoz+Hr+Xm9W90gJsppJq9f9tHvOGkrpn4gRX0q/cLtBdNkWtWCKDg2UDZoZvQ==", + "dev": true + }, "node_modules/@types/form-data": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz", @@ -2150,12 +2389,27 @@ "@types/node": "*" } }, + "node_modules/@types/http-cache-semantics": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", + "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", + "dev": true + }, "node_modules/@types/json-schema": { - "version": "7.0.12", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", - "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==", + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true }, + "node_modules/@types/keyv": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", + "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz", @@ -2182,9 +2436,9 @@ "dev": true }, "node_modules/@types/pbkdf2": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz", - "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-uRwJqmiXmh9++aSu1VNEn3iIxWOhd8AHXNSdlaLfdAAdSTY9jYVeGWnzejM3dvrkbqE3/hyQkQQ29IFATEGlew==", "dev": true, "dependencies": { "@types/node": "*" @@ -2198,9 +2452,9 @@ "peer": true }, "node_modules/@types/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", + "version": "6.9.10", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.10.tgz", + "integrity": "sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw==", "dev": true, "peer": true }, @@ -2220,33 +2474,63 @@ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, + "node_modules/@types/responselike": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz", + "integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/secp256k1": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.3.tgz", - "integrity": "sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.6.tgz", + "integrity": "sha512-hHxJU6PAEUn0TP4S/ZOzuTUvJWuZ6eIKeNKb5RBpODvSl6hp1Wrw4s7ATY50rklRCScUDpHzVA/DQdSjJ3UoYQ==", "dev": true, "dependencies": { "@types/node": "*" } }, "node_modules/@types/semver": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==", + "version": "7.5.6", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz", + "integrity": "sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==", + "dev": true + }, + "node_modules/@types/underscore": { + "version": "1.11.15", + "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.11.15.tgz", + "integrity": "sha512-HP38xE+GuWGlbSRq9WrZkousaQ7dragtZCruBVMi0oX1migFZavZ3OROKHSkNp/9ouq82zrWtZpg18jFnVN96g==", + "dev": true + }, + "node_modules/@types/yargs": { + "version": "17.0.32", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.11.tgz", - "integrity": "sha512-XxuOfTkCUiOSyBWIvHlUraLw/JT/6Io1365RO6ZuI88STKMavJZPNMU0lFcUTeQXEhHiv64CbxYxBNoDVSmghg==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", + "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.59.11", - "@typescript-eslint/type-utils": "5.59.11", - "@typescript-eslint/utils": "5.59.11", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/type-utils": "5.62.0", + "@typescript-eslint/utils": "5.62.0", "debug": "^4.3.4", - "grapheme-splitter": "^1.0.4", + "graphemer": "^1.4.0", "ignore": "^5.2.0", "natural-compare-lite": "^1.4.0", "semver": "^7.3.7", @@ -2282,9 +2566,9 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { - "version": "7.5.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.2.tgz", - "integrity": "sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -2303,15 +2587,15 @@ "dev": true }, "node_modules/@typescript-eslint/parser": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.11.tgz", - "integrity": "sha512-s9ZF3M+Nym6CAZEkJJeO2TFHHDsKAM3ecNkLuH4i4s8/RCPnF5JRip2GyviYkeEAcwGMJxkqG9h2dAsnA1nZpA==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", + "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", "dev": true, "peer": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.59.11", - "@typescript-eslint/types": "5.59.11", - "@typescript-eslint/typescript-estree": "5.59.11", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", "debug": "^4.3.4" }, "engines": { @@ -2331,13 +2615,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.11.tgz", - "integrity": "sha512-dHFOsxoLFtrIcSj5h0QoBT/89hxQONwmn3FOQ0GOQcLOOXm+MIrS8zEAhs4tWl5MraxCY3ZJpaXQQdFMc2Tu+Q==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", + "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.59.11", - "@typescript-eslint/visitor-keys": "5.59.11" + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -2348,13 +2632,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.11.tgz", - "integrity": "sha512-LZqVY8hMiVRF2a7/swmkStMYSoXMFlzL6sXV6U/2gL5cwnLWQgLEG8tjWPpaE4rMIdZ6VKWwcffPlo1jPfk43g==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz", + "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "5.59.11", - "@typescript-eslint/utils": "5.59.11", + "@typescript-eslint/typescript-estree": "5.62.0", + "@typescript-eslint/utils": "5.62.0", "debug": "^4.3.4", "tsutils": "^3.21.0" }, @@ -2375,9 +2659,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.11.tgz", - "integrity": "sha512-epoN6R6tkvBYSc+cllrz+c2sOFWkbisJZWkOE+y3xHtvYaOE6Wk6B8e114McRJwFRjGvYdJwLXQH5c9osME/AA==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", + "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -2388,13 +2672,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.11.tgz", - "integrity": "sha512-YupOpot5hJO0maupJXixi6l5ETdrITxeo5eBOeuV7RSKgYdU3G5cxO49/9WRnJq9EMrB7AuTSLH/bqOsXi7wPA==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", + "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.59.11", - "@typescript-eslint/visitor-keys": "5.59.11", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -2427,9 +2711,9 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.5.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.2.tgz", - "integrity": "sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -2448,17 +2732,17 @@ "dev": true }, "node_modules/@typescript-eslint/utils": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.11.tgz", - "integrity": "sha512-didu2rHSOMUdJThLk4aZ1Or8IcO3HzCw/ZvEjTTIfjIrcdd5cvSIwwDy2AOlE7htSNp7QIZ10fLMyRCveesMLg==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", + "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.59.11", - "@typescript-eslint/types": "5.59.11", - "@typescript-eslint/typescript-estree": "5.59.11", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", "eslint-scope": "^5.1.1", "semver": "^7.3.7" }, @@ -2486,9 +2770,9 @@ } }, "node_modules/@typescript-eslint/utils/node_modules/semver": { - "version": "7.5.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.2.tgz", - "integrity": "sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -2507,12 +2791,12 @@ "dev": true }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.11.tgz", - "integrity": "sha512-KGYniTGG3AMTuKF9QBD7EIrvufkB6O6uX3knP73xbKLMpH+QRPcgnCxjWXSHjMRuOxFLovljqQgQpR0c7GvjoA==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", + "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.59.11", + "@typescript-eslint/types": "5.62.0", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -2523,6 +2807,12 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, "node_modules/abbrev": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", @@ -2530,18 +2820,6 @@ "dev": true, "peer": true }, - "node_modules/abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "dev": true, - "dependencies": { - "event-target-shim": "^5.0.0" - }, - "engines": { - "node": ">=6.5" - } - }, "node_modules/abstract-level": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/abstract-level/-/abstract-level-1.0.3.tgz", @@ -2584,10 +2862,23 @@ "ieee754": "^1.2.1" } }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/acorn": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.9.0.tgz", - "integrity": "sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ==", + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", + "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -2606,9 +2897,9 @@ } }, "node_modules/acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.0.tgz", + "integrity": "sha512-FS7hV565M5l1R08MXqo8odwMTB02C2UqzB17RVgu9EyuYFBqJZ3/ZY97sQD5FewVu1UyDFc1yztUDrAwT0EypA==", "dev": true, "engines": { "node": ">=0.4.0" @@ -2681,9 +2972,9 @@ } }, "node_modules/amazon-cognito-identity-js": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/amazon-cognito-identity-js/-/amazon-cognito-identity-js-6.2.0.tgz", - "integrity": "sha512-9Fxrp9+MtLdsJvqOwSaE3ll+pneICeuE3pwj2yDkiyGNWuHx97b8bVLR2bOgfDmDJnY0Hq8QoeXtwdM4aaXJjg==", + "version": "6.3.7", + "resolved": "https://registry.npmjs.org/amazon-cognito-identity-js/-/amazon-cognito-identity-js-6.3.7.tgz", + "integrity": "sha512-tSjnM7KyAeOZ7UMah+oOZ6cW4Gf64FFcc7BE2l7MTcp7ekAPrXaCbpcW2xEpH1EiDS4cPcAouHzmCuc2tr72vQ==", "dev": true, "dependencies": { "@aws-crypto/sha256-js": "1.2.2", @@ -2817,7 +3108,6 @@ "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "is-array-buffer": "^3.0.1" @@ -2826,6 +3116,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true + }, "node_modules/array-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", @@ -2844,18 +3140,38 @@ "node": ">=0.10.0" } }, - "node_modules/array.prototype.reduce": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/array.prototype.reduce/-/array.prototype.reduce-1.0.5.tgz", - "integrity": "sha512-kDdugMl7id9COE8R7MHF5jWk7Dqt/fs4Pv+JXoICnYwqpjjjbUurz6w5fT5IG6brLdJhv6/VoHB0H7oyIBXd+Q==", + "node_modules/array.prototype.findlast": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.3.tgz", + "integrity": "sha512-kcBubumjciBg4JKp5KTKtI7ec7tRefPk88yjkWJwaVKYd9QfTaxcsOxoMNKd7iBr447zCfDV0z1kOF47umv42g==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0", + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz", + "integrity": "sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==", "dev": true, - "peer": true, "dependencies": { + "array-buffer-byte-length": "^1.0.0", "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "es-array-method-boxes-properly": "^1.0.0", - "is-string": "^1.0.7" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "is-array-buffer": "^3.0.2", + "is-shared-array-buffer": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -2876,17 +3192,46 @@ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", "dev": true, - "peer": true, "dependencies": { "safer-buffer": "~2.1.0" } }, + "node_modules/asn1.js": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", + "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "dev": true, + "dependencies": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/asn1.js/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/assert": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-2.1.0.tgz", + "integrity": "sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "is-nan": "^1.3.2", + "object-is": "^1.1.5", + "object.assign": "^4.1.4", + "util": "^0.12.5" + } + }, "node_modules/assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", "dev": true, - "peer": true, "engines": { "node": ">=0.8" } @@ -2920,6 +3265,12 @@ "lodash": "^4.17.14" } }, + "node_modules/async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", + "dev": true + }, "node_modules/async-retry": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz", @@ -2933,8 +3284,7 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true, - "peer": true + "dev": true }, "node_modules/at-least-node": { "version": "1.0.0", @@ -2946,12 +3296,23 @@ "node": ">= 4.0.0" } }, + "node_modules/atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true, + "bin": { + "atob": "bin/atob.js" + }, + "engines": { + "node": ">= 4.5.0" + } + }, "node_modules/available-typed-arrays": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", "dev": true, - "peer": true, "engines": { "node": ">= 0.4" }, @@ -2964,7 +3325,6 @@ "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", "dev": true, - "peer": true, "engines": { "node": "*" } @@ -2973,16 +3333,17 @@ "version": "1.12.0", "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz", "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/axios": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.2.tgz", + "integrity": "sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==", "dev": true, "dependencies": { - "follow-redirects": "^1.14.0" + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" } }, "node_modules/balanced-match": { @@ -3025,7 +3386,6 @@ "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", "dev": true, - "peer": true, "dependencies": { "tweetnacl": "^0.14.3" } @@ -3034,8 +3394,7 @@ "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/bech32": { "version": "1.1.4", @@ -3044,14 +3403,23 @@ "dev": true }, "node_modules/bigint-crypto-utils": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/bigint-crypto-utils/-/bigint-crypto-utils-3.2.2.tgz", - "integrity": "sha512-U1RbE3aX9ayCUVcIPHuPDPKcK3SFOXf93J1UK/iHlJuQB7bhagPIX06/CLpLEsDThJ7KA4Dhrnzynl+d2weTiw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/bigint-crypto-utils/-/bigint-crypto-utils-3.3.0.tgz", + "integrity": "sha512-jOTSb+drvEDxEq6OuUybOAv/xxoh3cuYRUIPyu8sSHQNKM303UQ2R1DAo45o1AkcIXw6fzbaFI1+xGGdaXs2lg==", "dev": true, "engines": { "node": ">=14.0.0" } }, + "node_modules/bignumber.js": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", + "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -3067,12 +3435,84 @@ "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==", "dev": true }, + "node_modules/bls-eth-wasm": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/bls-eth-wasm/-/bls-eth-wasm-1.1.1.tgz", + "integrity": "sha512-yaoOHCgjICZc2qTpYCvIkJ6L4N2MXBNmdhIpTZGmKZOUc3mmU941EV95qMK02apyYRSKuCydPuCN3fK4o24C1g==", + "dev": true + }, + "node_modules/bls-signatures": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/bls-signatures/-/bls-signatures-0.2.5.tgz", + "integrity": "sha512-5TzQNCtR4zWE4lM08EOMIT8l3b4h8g5LNKu50fUYP1PnupaLGSLklAcTto4lnH7VXpyhsar+74L9wNJII4E/4Q==", + "dev": true + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, "node_modules/bn.js": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", "dev": true }, + "node_modules/body-parser": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/body-parser/node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -3133,6 +3573,59 @@ "safe-buffer": "^5.0.1" } }, + "node_modules/browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "dev": true, + "dependencies": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "node_modules/browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "dependencies": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/browserify-rsa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", + "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", + "dev": true, + "dependencies": { + "bn.js": "^5.0.0", + "randombytes": "^2.0.1" + } + }, + "node_modules/browserify-sign": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.2.tgz", + "integrity": "sha512-1rudGyeYY42Dk6texmv7c4VcQ0EsvVbLwZkA+AQB7SxvXxmcD93jcHie8bzecJ+ChDlmAm2Qyu0+Ccg5uhZXCg==", + "dev": true, + "dependencies": { + "bn.js": "^5.2.1", + "browserify-rsa": "^4.1.0", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.4", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.6", + "readable-stream": "^3.6.2", + "safe-buffer": "^5.2.1" + }, + "engines": { + "node": ">= 4" + } + }, "node_modules/bs58": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", @@ -3153,6 +3646,18 @@ "safe-buffer": "^5.1.2" } }, + "node_modules/btoa": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/btoa/-/btoa-1.2.1.tgz", + "integrity": "sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g==", + "dev": true, + "bin": { + "btoa": "bin/btoa.js" + }, + "engines": { + "node": ">= 0.4.0" + } + }, "node_modules/buffer": { "version": "4.9.2", "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", @@ -3170,22 +3675,38 @@ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, + "node_modules/buffer-to-arraybuffer": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz", + "integrity": "sha512-3dthu5CYiVB1DEJp61FtApNnNndTckcqe4pFcLdvHtrpG+kcyekCJKg4MRiDcFW7A6AODnXB9U4dwQiCW5kzJQ==", + "dev": true + }, "node_modules/buffer-xor": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", "dev": true }, - "node_modules/busboy": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", - "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "node_modules/bufferutil": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.8.tgz", + "integrity": "sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==", "dev": true, + "hasInstallScript": true, "dependencies": { - "streamsearch": "^1.1.0" + "node-gyp-build": "^4.3.0" }, "engines": { - "node": ">=10.16.0" + "node": ">=6.14.2" + } + }, + "node_modules/builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha512-wxXCdllwGhI2kCC0MnvTGYTMvnVZTvqgypkiTI8Pa5tcz2i6VqsqwYGgqwXji+4RgCzms6EajE4IxiUH6HH8nQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" } }, "node_modules/bytes": { @@ -3197,14 +3718,81 @@ "node": ">= 0.8" } }, + "node_modules/cacheable-lookup": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", + "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", + "dev": true, + "engines": { + "node": ">=10.6.0" + } + }, + "node_modules/cacheable-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", + "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "dev": true, + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cacheable-request/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cacheable-request/node_modules/json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==", + "dev": true + }, + "node_modules/cacheable-request/node_modules/keyv": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", + "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.0" + } + }, + "node_modules/cacheable-request/node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", + "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", "dev": true, "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.1", + "set-function-length": "^1.1.1" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -3277,8 +3865,7 @@ "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/catering": { "version": "2.1.1", @@ -3294,6 +3881,7 @@ "resolved": "https://registry.npmjs.org/cbor/-/cbor-8.1.0.tgz", "integrity": "sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg==", "dev": true, + "peer": true, "dependencies": { "nofilter": "^3.1.0" }, @@ -3302,19 +3890,19 @@ } }, "node_modules/chai": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.7.tgz", - "integrity": "sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==", + "version": "4.3.10", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.10.tgz", + "integrity": "sha512-0UXG04VuVbruMUYbJ6JctvH0YnC/4q3/AkT18q4NaITo91CUm0liMS9VqzT9vZhVQ/1eqPanMWjBM+Juhfb/9g==", "dev": true, "peer": true, "dependencies": { "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^4.1.2", - "get-func-name": "^2.0.0", - "loupe": "^2.3.1", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", "pathval": "^1.1.1", - "type-detect": "^4.0.5" + "type-detect": "^4.0.8" }, "engines": { "node": ">=4" @@ -3365,10 +3953,13 @@ } }, "node_modules/check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", "dev": true, + "dependencies": { + "get-func-name": "^2.0.2" + }, "engines": { "node": "*" } @@ -3412,12 +4003,71 @@ "node": ">= 6" } }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, "node_modules/ci-info": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", "dev": true }, + "node_modules/cids": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/cids/-/cids-0.7.5.tgz", + "integrity": "sha512-zT7mPeghoWAu+ppn8+BS1tQ5qGmbMfB4AregnQjA/qHY3GC1m1ptI9GkWNlgeu38r7CuRdXB47uY2XgAYt6QVA==", + "deprecated": "This module has been superseded by the multiformats module", + "dev": true, + "dependencies": { + "buffer": "^5.5.0", + "class-is": "^1.1.0", + "multibase": "~0.6.0", + "multicodec": "^1.0.0", + "multihashes": "~0.4.15" + }, + "engines": { + "node": ">=4.0.0", + "npm": ">=3.0.0" + } + }, + "node_modules/cids/node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/cids/node_modules/multicodec": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-1.0.4.tgz", + "integrity": "sha512-NDd7FeS3QamVtbgfvu5h7fd1IlbaC4EQ0/pgU4zqE2vdHCmBGsUa0TiM8/TdSeG6BMPC92OOCf8F1ocE/Wkrrg==", + "deprecated": "This module has been superseded by the multiformats module", + "dev": true, + "dependencies": { + "buffer": "^5.6.0", + "varint": "^5.0.0" + } + }, "node_modules/cipher-base": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", @@ -3428,6 +4078,22 @@ "safe-buffer": "^5.0.1" } }, + "node_modules/class-is": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/class-is/-/class-is-1.1.0.tgz", + "integrity": "sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw==", + "dev": true + }, + "node_modules/class-validator": { + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/class-validator/-/class-validator-0.13.2.tgz", + "integrity": "sha512-yBUcQy07FPlGzUjoLuUfIOXzgynnQPPruyK1Ge2B74k9ROwnle1E+NxLWnUv5OLU8hA/qL5leAE9XnXq3byaBw==", + "dev": true, + "dependencies": { + "libphonenumber-js": "^1.9.43", + "validator": "^13.7.0" + } + }, "node_modules/classic-level": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/classic-level/-/classic-level-1.3.0.tgz", @@ -3510,6 +4176,18 @@ "wrap-ansi": "^7.0.0" } }, + "node_modules/clone-response": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", + "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", + "dev": true, + "dependencies": { + "mimic-response": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -3542,7 +4220,6 @@ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dev": true, - "peer": true, "dependencies": { "delayed-stream": "~1.0.0" }, @@ -3699,9 +4376,9 @@ "dev": true }, "node_modules/compare-versions": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-5.0.3.tgz", - "integrity": "sha512-4UZlZP8Z99MGEY+Ovg/uJxJuvoXuN4M6B3hKaiackiHrgzQFEe3diJi1mf1PNHbFujM7FvLrK2bpgIaImbtZ1A==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-6.1.0.tgz", + "integrity": "sha512-LNZQXhqUvqUTotpZ00qLSaify3b4VFD588aRr8MKFw4CMUr98ytzCW5wDH5qx/DEY5kCDXcbcRuCqL0szEf2tg==", "dev": true }, "node_modules/concat-map": { @@ -3759,6 +4436,38 @@ "safe-buffer": "~5.1.0" } }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-hash": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/content-hash/-/content-hash-2.5.2.tgz", + "integrity": "sha512-FvIQKy0S1JaWV10sMsA7TRx8bpU+pqPkhbsfvOJAdjRXvYxEckAwQWGwtRjiaJfh+E0DvcWUGqcdjwMGFjsSdw==", + "dev": true, + "dependencies": { + "cids": "^0.7.1", + "multicodec": "^0.5.5", + "multihashes": "^0.4.15" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/cookie": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", @@ -3768,12 +4477,36 @@ "node": ">= 0.6" } }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "dev": true + }, + "node_modules/cookiejar": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz", + "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==", + "dev": true + }, "node_modules/core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "dev": true + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", "dev": true, - "peer": true + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } }, "node_modules/cosmiconfig": { "version": "5.2.1", @@ -3859,6 +4592,22 @@ "node": ">=0.8" } }, + "node_modules/create-ecdh": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", + "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", + "dev": true, + "dependencies": { + "bn.js": "^4.1.0", + "elliptic": "^6.5.3" + } + }, + "node_modules/create-ecdh/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, "node_modules/create-hash": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", @@ -3916,12 +4665,50 @@ "node": "*" } }, + "node_modules/crypto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/crypto/-/crypto-1.0.1.tgz", + "integrity": "sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig==", + "deprecated": "This package is no longer supported. It's now a built-in Node module. If you've depended on crypto, you should switch to the one that's built-in.", + "dev": true + }, + "node_modules/crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "dependencies": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + }, + "engines": { + "node": "*" + } + }, + "node_modules/d": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "dev": true, + "dependencies": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, "node_modules/dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", "dev": true, - "peer": true, "dependencies": { "assert-plus": "^1.0.0" }, @@ -3965,6 +4752,27 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/decode-uri-component": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", + "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==", + "dev": true, + "dependencies": { + "mimic-response": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/deep-eql": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", @@ -3994,13 +4802,33 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, + "node_modules/defer-to-connect": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", + "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", + "dev": true + }, + "node_modules/define-data-property": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", + "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/define-properties": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", - "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", "dev": true, - "peer": true, "dependencies": { + "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" }, @@ -4016,7 +4844,6 @@ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "dev": true, - "peer": true, "engines": { "node": ">=0.4.0" } @@ -4060,6 +4887,26 @@ "node": ">= 0.8" } }, + "node_modules/des.js": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.1.0.tgz", + "integrity": "sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, "node_modules/detect-port": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.5.1.tgz", @@ -4084,6 +4931,23 @@ "node": ">=0.3.1" } }, + "node_modules/diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "dev": true, + "dependencies": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } + }, + "node_modules/diffie-hellman/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, "node_modules/difflib": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/difflib/-/difflib-0.2.4.tgz", @@ -4121,6 +4985,12 @@ "node": ">=6.0.0" } }, + "node_modules/dom-walk": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", + "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==", + "dev": true + }, "node_modules/dotenv": { "version": "16.3.1", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", @@ -4133,17 +5003,28 @@ "url": "https://github.com/motdotla/dotenv?sponsor=1" } }, + "node_modules/duplexer3": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.5.tgz", + "integrity": "sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==", + "dev": true + }, "node_modules/ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", "dev": true, - "peer": true, "dependencies": { "jsbn": "~0.1.0", "safer-buffer": "^2.1.0" } }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true + }, "node_modules/elliptic": { "version": "6.5.4", "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", @@ -4171,19 +5052,47 @@ "integrity": "sha512-k0/r7GrWVL32kZlGwfPNgB2Y/mMXVTq/decgLczm/j34whdaspNrZO8CnXPf1laaHxI6ptUlsnAxN+UAPw+fzg==", "dev": true }, + "node_modules/emitter-component": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/emitter-component/-/emitter-component-1.1.2.tgz", + "integrity": "sha512-QdXO3nXOzZB4pAjM0n6ZE+R9/+kPpECA/XSELIcc54NeYVnBqIk+4DFiBgK+8QbV3mdvTG6nedl7dTYgO+5wDw==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + } + }, "node_modules/enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", + "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", "dev": true, "dependencies": { - "ansi-colors": "^4.1.1" + "ansi-colors": "^4.1.1", + "strip-ansi": "^6.0.1" }, "engines": { "node": ">=8.6" @@ -4208,26 +5117,26 @@ } }, "node_modules/es-abstract": { - "version": "1.21.2", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.2.tgz", - "integrity": "sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg==", + "version": "1.22.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.3.tgz", + "integrity": "sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA==", "dev": true, - "peer": true, "dependencies": { "array-buffer-byte-length": "^1.0.0", + "arraybuffer.prototype.slice": "^1.0.2", "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", + "call-bind": "^1.0.5", "es-set-tostringtag": "^2.0.1", "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.2.0", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.2", "get-symbol-description": "^1.0.0", "globalthis": "^1.0.3", "gopd": "^1.0.1", - "has": "^1.0.3", "has-property-descriptors": "^1.0.0", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", + "hasown": "^2.0.0", "internal-slot": "^1.0.5", "is-array-buffer": "^3.0.2", "is-callable": "^1.2.7", @@ -4235,19 +5144,23 @@ "is-regex": "^1.1.4", "is-shared-array-buffer": "^1.0.2", "is-string": "^1.0.7", - "is-typed-array": "^1.1.10", + "is-typed-array": "^1.1.12", "is-weakref": "^1.0.2", - "object-inspect": "^1.12.3", + "object-inspect": "^1.13.1", "object-keys": "^1.1.1", "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.4.3", + "regexp.prototype.flags": "^1.5.1", + "safe-array-concat": "^1.0.1", "safe-regex-test": "^1.0.0", - "string.prototype.trim": "^1.2.7", - "string.prototype.trimend": "^1.0.6", - "string.prototype.trimstart": "^1.0.6", + "string.prototype.trim": "^1.2.8", + "string.prototype.trimend": "^1.0.7", + "string.prototype.trimstart": "^1.0.7", + "typed-array-buffer": "^1.0.0", + "typed-array-byte-length": "^1.0.0", + "typed-array-byte-offset": "^1.0.0", "typed-array-length": "^1.0.4", "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.9" + "which-typed-array": "^1.1.13" }, "engines": { "node": ">= 0.4" @@ -4256,45 +5169,27 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/es-abstract/node_modules/object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "node_modules/es-set-tostringtag": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz", + "integrity": "sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==", "dev": true, - "peer": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" + "get-intrinsic": "^1.2.2", + "has-tostringtag": "^1.0.0", + "hasown": "^2.0.0" }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/es-array-method-boxes-properly": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", - "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", - "dev": true, - "peer": true - }, - "node_modules/es-set-tostringtag": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", - "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", + "node_modules/es-shim-unscopables": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", + "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", "dev": true, - "peer": true, "dependencies": { - "get-intrinsic": "^1.1.3", - "has": "^1.0.3", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" + "hasown": "^2.0.0" } }, "node_modules/es-to-primitive": { @@ -4302,7 +5197,6 @@ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", "dev": true, - "peer": true, "dependencies": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", @@ -4315,6 +5209,42 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/es5-ext": { + "version": "0.10.62", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", + "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "next-tick": "^1.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", + "dev": true, + "dependencies": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/es6-symbol": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", + "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", + "dev": true, + "dependencies": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -4324,6 +5254,12 @@ "node": ">=6" } }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true + }, "node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -4425,27 +5361,28 @@ } }, "node_modules/eslint": { - "version": "8.43.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.43.0.tgz", - "integrity": "sha512-aaCpf2JqqKesMFGgmRPessmVKjcGXqdlAYLLC3THM8t5nBRZRQ+st5WM/hoJXkdioEXLLbXgclUpM0TXo5HX5Q==", + "version": "8.55.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.55.0.tgz", + "integrity": "sha512-iyUUAM0PCKj5QpwGfmCAG9XXbZCWsqP/eWAWrG/W0umvjuLRBECwSFdt+rCntju0xEH7teIABPwXpahftIaTdA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.4.0", - "@eslint/eslintrc": "^2.0.3", - "@eslint/js": "8.43.0", - "@humanwhocodes/config-array": "^0.11.10", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.55.0", + "@humanwhocodes/config-array": "^0.11.13", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.0", - "eslint-visitor-keys": "^3.4.1", - "espree": "^9.5.2", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -4455,7 +5392,6 @@ "globals": "^13.19.0", "graphemer": "^1.4.0", "ignore": "^5.2.0", - "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "is-path-inside": "^3.0.3", @@ -4465,9 +5401,8 @@ "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.1", + "optionator": "^0.9.3", "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" }, "bin": { @@ -4515,9 +5450,9 @@ } }, "node_modules/eslint-visitor-keys": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", - "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -4527,9 +5462,9 @@ } }, "node_modules/eslint/node_modules/eslint-scope": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", - "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, "dependencies": { "esrecurse": "^4.3.0", @@ -4552,12 +5487,12 @@ } }, "node_modules/espree": { - "version": "9.5.2", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz", - "integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, "dependencies": { - "acorn": "^8.8.0", + "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.4.1" }, @@ -4642,26 +5577,49 @@ "node": ">=0.10.0" } }, - "node_modules/eth-gas-reporter": { - "version": "0.2.25", - "resolved": "https://registry.npmjs.org/eth-gas-reporter/-/eth-gas-reporter-0.2.25.tgz", - "integrity": "sha512-1fRgyE4xUB8SoqLgN3eDfpDfwEfRxh2Sz1b7wzFbyQA+9TekMmvSjjoRu9SKcSVyK+vLkLIsVbJDsTWjw195OQ==", + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eth-ens-namehash": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz", + "integrity": "sha512-VWEI1+KJfz4Km//dadyvBBoBeSQ0MHTXPvr8UIXiLW6IanxvAV+DmlZAijZwAyggqGUfwQBeHf7tc9wzc1piSw==", "dev": true, - "peer": true, "dependencies": { - "@ethersproject/abi": "^5.0.0-beta.146", - "@solidity-parser/parser": "^0.14.0", - "cli-table3": "^0.5.0", - "colors": "1.4.0", - "ethereum-cryptography": "^1.0.3", - "ethers": "^4.0.40", - "fs-readdir-recursive": "^1.1.0", + "idna-uts46-hx": "^2.3.1", + "js-sha3": "^0.5.7" + } + }, + "node_modules/eth-ens-namehash/node_modules/js-sha3": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", + "integrity": "sha512-GII20kjaPX0zJ8wzkTbNDYMY7msuZcTWk8S5UOh6806Jq/wz1J8/bnr8uGU0DAUmYDjj2Mr4X1cW8v/GLYnR+g==", + "dev": true + }, + "node_modules/eth-gas-reporter": { + "version": "0.2.27", + "resolved": "https://registry.npmjs.org/eth-gas-reporter/-/eth-gas-reporter-0.2.27.tgz", + "integrity": "sha512-femhvoAM7wL0GcI8ozTdxfuBtBFJ9qsyIAsmKVjlWAHUbdnnXHt+lKzz/kmldM5lA9jLuNHGwuIxorNpLbR1Zw==", + "dev": true, + "peer": true, + "dependencies": { + "@solidity-parser/parser": "^0.14.0", + "axios": "^1.5.1", + "cli-table3": "^0.5.0", + "colors": "1.4.0", + "ethereum-cryptography": "^1.0.3", + "ethers": "^5.7.2", + "fs-readdir-recursive": "^1.1.0", "lodash": "^4.17.14", "markdown-table": "^1.1.3", - "mocha": "^7.1.1", + "mocha": "^10.2.0", "req-cwd": "^2.0.0", - "request": "^2.88.0", - "request-promise-native": "^1.0.5", "sha1": "^1.1.1", "sync-request": "^6.0.0" }, @@ -4674,114 +5632,62 @@ } } }, - "node_modules/eth-gas-reporter/node_modules/ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true, - "peer": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/eth-gas-reporter/node_modules/ansi-regex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", - "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", - "dev": true, - "peer": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/eth-gas-reporter/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "peer": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eth-gas-reporter/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "peer": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/eth-gas-reporter/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "node_modules/eth-gas-reporter/node_modules/@noble/hashes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.2.0.tgz", + "integrity": "sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==", "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], "peer": true }, - "node_modules/eth-gas-reporter/node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "peer": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/eth-gas-reporter/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "node_modules/eth-gas-reporter/node_modules/@scure/bip32": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.5.tgz", + "integrity": "sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw==", "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], "peer": true, "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" + "@noble/hashes": "~1.2.0", + "@noble/secp256k1": "~1.7.0", + "@scure/base": "~1.1.0" } }, - "node_modules/eth-gas-reporter/node_modules/chalk/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "node_modules/eth-gas-reporter/node_modules/@scure/bip39": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.1.tgz", + "integrity": "sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg==", "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], "peer": true, "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" + "@noble/hashes": "~1.2.0", + "@scure/base": "~1.1.0" } }, - "node_modules/eth-gas-reporter/node_modules/chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", + "node_modules/eth-gas-reporter/node_modules/ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", "dev": true, "peer": true, - "dependencies": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - }, "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.1.1" + "node": ">=4" } }, "node_modules/eth-gas-reporter/node_modules/cli-table3": { @@ -4801,1380 +5707,1071 @@ "colors": "^1.1.2" } }, - "node_modules/eth-gas-reporter/node_modules/cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "node_modules/eth-gas-reporter/node_modules/colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/eth-gas-reporter/node_modules/ethereum-cryptography": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.2.0.tgz", + "integrity": "sha512-6yFQC9b5ug6/17CQpCyE3k9eKBMdhyVjzUy1WkiuY/E4vj/SXDBbCw8QEIaXqf0Mf2SnY6RmpDcwlUmBSS0EJw==", "dev": true, "peer": true, "dependencies": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" + "@noble/hashes": "1.2.0", + "@noble/secp256k1": "1.7.1", + "@scure/bip32": "1.1.5", + "@scure/bip39": "1.1.1" } }, - "node_modules/eth-gas-reporter/node_modules/cliui/node_modules/ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "node_modules/eth-gas-reporter/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", "dev": true, "peer": true, "engines": { - "node": ">=6" + "node": ">=4" } }, - "node_modules/eth-gas-reporter/node_modules/cliui/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "node_modules/eth-gas-reporter/node_modules/string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "dev": true, "peer": true, "dependencies": { - "emoji-regex": "^7.0.1", "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "strip-ansi": "^4.0.0" }, "engines": { - "node": ">=6" + "node": ">=4" } }, - "node_modules/eth-gas-reporter/node_modules/cliui/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "node_modules/eth-gas-reporter/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", "dev": true, "peer": true, "dependencies": { - "ansi-regex": "^4.1.0" + "ansi-regex": "^3.0.0" }, "engines": { - "node": ">=6" + "node": ">=4" } }, - "node_modules/eth-gas-reporter/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "node_modules/eth-lib": { + "version": "0.1.29", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.1.29.tgz", + "integrity": "sha512-bfttrr3/7gG4E02HoWTDUcDDslN003OlOoBxk9virpAZQ1ja/jDgwkWB8QfJF7ojuEowrqy+lzp9VcJG7/k5bQ==", "dev": true, - "peer": true, "dependencies": { - "color-name": "1.1.3" + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "nano-json-stream-parser": "^0.1.2", + "servify": "^0.1.12", + "ws": "^3.0.0", + "xhr-request-promise": "^0.1.2" } }, - "node_modules/eth-gas-reporter/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true, - "peer": true + "node_modules/eth-lib/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true }, - "node_modules/eth-gas-reporter/node_modules/colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "node_modules/eth-lib/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/eth-lib/node_modules/ws": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", + "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", "dev": true, - "peer": true, - "engines": { - "node": ">=0.1.90" + "dependencies": { + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0", + "ultron": "~1.1.0" } }, - "node_modules/eth-gas-reporter/node_modules/debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", + "node_modules/eth2-keystore-js": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/eth2-keystore-js/-/eth2-keystore-js-1.0.8.tgz", + "integrity": "sha512-H5JLUeo7aiZs7zVAb+9gSJZZxfcx5na8zPxcgFbggNfac+atyO5H6KpvDUPJFRm/umHWM7++MdvS/q5Sbw+f9g==", "dev": true, - "peer": true, "dependencies": { - "ms": "^2.1.1" + "@types/node": "^15.12.2", + "crypto": "^1.0.1", + "ethereumjs-util": "^7.0.10", + "ethereumjs-wallet": "^1.0.1", + "husky": "^6.0.0", + "scrypt-js": "^3.0.1", + "tslint": "^6.1.3", + "tslint-config-prettier": "^1.18.0", + "typescript": "^4.3.2" } }, - "node_modules/eth-gas-reporter/node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "node_modules/eth2-keystore-js/node_modules/@types/node": { + "version": "15.14.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-15.14.9.tgz", + "integrity": "sha512-qjd88DrCxupx/kJD5yQgZdcYKZKSIGBVDIBE1/LTGcNm3d2Np/jxojkdePDdfnBHJc5W7vSMpbJ1aB7p/Py69A==", + "dev": true + }, + "node_modules/ethereum-bloom-filters": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.10.tgz", + "integrity": "sha512-rxJ5OFN3RwjQxDcFP2Z5+Q9ho4eIdEmSc2ht0fCu8Se9nbXjZ7/031uXoUYJ87KHCOdVeiUuwSnoS7hmYAGVHA==", "dev": true, - "peer": true, - "engines": { - "node": ">=0.10.0" + "dependencies": { + "js-sha3": "^0.8.0" } }, - "node_modules/eth-gas-reporter/node_modules/diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", "dev": true, - "peer": true, - "engines": { - "node": ">=0.3.1" + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" } }, - "node_modules/eth-gas-reporter/node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "node_modules/ethereumjs-abi": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz", + "integrity": "sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==", "dev": true, - "peer": true + "dependencies": { + "bn.js": "^4.11.8", + "ethereumjs-util": "^6.0.0" + } }, - "node_modules/eth-gas-reporter/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/eth-gas-reporter/node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "peer": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eth-gas-reporter/node_modules/ethereum-cryptography": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.2.0.tgz", - "integrity": "sha512-6yFQC9b5ug6/17CQpCyE3k9eKBMdhyVjzUy1WkiuY/E4vj/SXDBbCw8QEIaXqf0Mf2SnY6RmpDcwlUmBSS0EJw==", + "node_modules/ethereumjs-abi/node_modules/@types/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", "dev": true, - "peer": true, "dependencies": { - "@noble/hashes": "1.2.0", - "@noble/secp256k1": "1.7.1", - "@scure/bip32": "1.1.5", - "@scure/bip39": "1.1.1" + "@types/node": "*" } }, - "node_modules/eth-gas-reporter/node_modules/ethers": { - "version": "4.0.49", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.49.tgz", - "integrity": "sha512-kPltTvWiyu+OktYy1IStSO16i2e7cS9D9OxZ81q2UUaiNPVrm/RTcbxamCXF9VUSKzJIdJV68EAIhTEVBalRWg==", + "node_modules/ethereumjs-abi/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/ethereumjs-abi/node_modules/ethereumjs-util": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", + "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", "dev": true, - "peer": true, "dependencies": { - "aes-js": "3.0.0", - "bn.js": "^4.11.9", - "elliptic": "6.5.4", - "hash.js": "1.1.3", - "js-sha3": "0.5.7", - "scrypt-js": "2.0.4", - "setimmediate": "1.0.4", - "uuid": "2.0.1", - "xmlhttprequest": "1.8.0" + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" } }, - "node_modules/eth-gas-reporter/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "node_modules/ethereumjs-util": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", + "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", "dev": true, - "peer": true, "dependencies": { - "locate-path": "^3.0.0" + "@types/bn.js": "^5.1.0", + "bn.js": "^5.1.2", + "create-hash": "^1.1.2", + "ethereum-cryptography": "^0.1.3", + "rlp": "^2.2.4" }, "engines": { - "node": ">=6" + "node": ">=10.0.0" } }, - "node_modules/eth-gas-reporter/node_modules/flat": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz", - "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==", + "node_modules/ethereumjs-wallet": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/ethereumjs-wallet/-/ethereumjs-wallet-1.0.2.tgz", + "integrity": "sha512-CCWV4RESJgRdHIvFciVQFnCHfqyhXWchTPlkfp28Qc53ufs+doi5I/cV2+xeK9+qEo25XCWfP9MiL+WEPAZfdA==", "dev": true, - "peer": true, "dependencies": { - "is-buffer": "~2.0.3" - }, - "bin": { - "flat": "cli.js" + "aes-js": "^3.1.2", + "bs58check": "^2.1.2", + "ethereum-cryptography": "^0.1.3", + "ethereumjs-util": "^7.1.2", + "randombytes": "^2.1.0", + "scrypt-js": "^3.0.1", + "utf8": "^3.0.0", + "uuid": "^8.3.2" } }, - "node_modules/eth-gas-reporter/node_modules/fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "deprecated": "\"Please update to latest v2.3 or v2.2\"", + "node_modules/ethereumjs-wallet/node_modules/aes-js": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.1.2.tgz", + "integrity": "sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ==", + "dev": true + }, + "node_modules/ethers": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", + "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } ], - "peer": true, - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "dependencies": { + "@ethersproject/abi": "5.7.0", + "@ethersproject/abstract-provider": "5.7.0", + "@ethersproject/abstract-signer": "5.7.0", + "@ethersproject/address": "5.7.0", + "@ethersproject/base64": "5.7.0", + "@ethersproject/basex": "5.7.0", + "@ethersproject/bignumber": "5.7.0", + "@ethersproject/bytes": "5.7.0", + "@ethersproject/constants": "5.7.0", + "@ethersproject/contracts": "5.7.0", + "@ethersproject/hash": "5.7.0", + "@ethersproject/hdnode": "5.7.0", + "@ethersproject/json-wallets": "5.7.0", + "@ethersproject/keccak256": "5.7.0", + "@ethersproject/logger": "5.7.0", + "@ethersproject/networks": "5.7.1", + "@ethersproject/pbkdf2": "5.7.0", + "@ethersproject/properties": "5.7.0", + "@ethersproject/providers": "5.7.2", + "@ethersproject/random": "5.7.0", + "@ethersproject/rlp": "5.7.0", + "@ethersproject/sha2": "5.7.0", + "@ethersproject/signing-key": "5.7.0", + "@ethersproject/solidity": "5.7.0", + "@ethersproject/strings": "5.7.0", + "@ethersproject/transactions": "5.7.0", + "@ethersproject/units": "5.7.0", + "@ethersproject/wallet": "5.7.0", + "@ethersproject/web": "5.7.1", + "@ethersproject/wordlists": "5.7.0" } }, - "node_modules/eth-gas-reporter/node_modules/glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "node_modules/ethjs-unit": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", + "integrity": "sha512-/Sn9Y0oKl0uqQuvgFk/zQgR7aw1g36qX/jzSQ5lSwlO0GigPymk4eGQfeNTD03w1dPOqfz8V77Cy43jH56pagw==", "dev": true, - "peer": true, "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "bn.js": "4.11.6", + "number-to-bn": "1.7.0" }, "engines": { - "node": "*" + "node": ">=6.5.0", + "npm": ">=3" } }, - "node_modules/eth-gas-reporter/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "node_modules/ethjs-unit/node_modules/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", + "dev": true + }, + "node_modules/ethjs-util": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz", + "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==", "dev": true, - "peer": true, "dependencies": { - "is-glob": "^4.0.1" + "is-hex-prefixed": "1.0.0", + "strip-hex-prefix": "1.0.0" }, "engines": { - "node": ">= 6" + "node": ">=6.5.0", + "npm": ">=3" } }, - "node_modules/eth-gas-reporter/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "node_modules/eventemitter3": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz", + "integrity": "sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==", + "dev": true + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "dev": true, - "peer": true, "engines": { - "node": ">=4" + "node": ">=0.8.x" } }, - "node_modules/eth-gas-reporter/node_modules/hash.js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", - "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", + "node_modules/evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", "dev": true, - "peer": true, "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.0" + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" } }, - "node_modules/eth-gas-reporter/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "node_modules/express": { + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", "dev": true, - "peer": true, + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, "engines": { - "node": ">=4" + "node": ">= 0.10.0" } }, - "node_modules/eth-gas-reporter/node_modules/js-sha3": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", - "integrity": "sha512-GII20kjaPX0zJ8wzkTbNDYMY7msuZcTWk8S5UOh6806Jq/wz1J8/bnr8uGU0DAUmYDjj2Mr4X1cW8v/GLYnR+g==", - "dev": true, - "peer": true - }, - "node_modules/eth-gas-reporter/node_modules/js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "node_modules/express/node_modules/body-parser": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", "dev": true, - "peer": true, "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" } }, - "node_modules/eth-gas-reporter/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "node_modules/express/node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", "dev": true, - "peer": true, - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, "engines": { - "node": ">=6" + "node": ">= 0.6" } }, - "node_modules/eth-gas-reporter/node_modules/log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, - "peer": true, "dependencies": { - "chalk": "^2.4.2" - }, - "engines": { - "node": ">=8" + "ms": "2.0.0" } }, - "node_modules/eth-gas-reporter/node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/express/node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", "dev": true, - "peer": true, "dependencies": { - "brace-expansion": "^1.1.7" + "side-channel": "^1.0.4" }, "engines": { - "node": "*" + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eth-gas-reporter/node_modules/mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "node_modules/express/node_modules/raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", "dev": true, - "peer": true, "dependencies": { - "minimist": "^1.2.5" + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" }, - "bin": { - "mkdirp": "bin/cmd.js" + "engines": { + "node": ">= 0.8" } }, - "node_modules/eth-gas-reporter/node_modules/mocha": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", - "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", + "node_modules/ext": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", + "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", "dev": true, - "peer": true, "dependencies": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - }, - "bin": { - "_mocha": "bin/_mocha", - "mocha": "bin/mocha" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mochajs" + "type": "^2.7.2" } }, - "node_modules/eth-gas-reporter/node_modules/ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true, - "peer": true + "node_modules/ext/node_modules/type": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", + "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==", + "dev": true }, - "node_modules/eth-gas-reporter/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", "dev": true, - "peer": true, "dependencies": { - "p-try": "^2.0.0" + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" }, "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=4" } }, - "node_modules/eth-gas-reporter/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", "dev": true, - "peer": true, - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } + "engines": [ + "node >=0.6.0" + ] }, - "node_modules/eth-gas-reporter/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "node_modules/fast-base64-decode": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-base64-decode/-/fast-base64-decode-1.0.0.tgz", + "integrity": "sha512-qwaScUgUGBYeDNRnbc/KyllVU88Jk1pRHPStuF/lO7B0/RTRLj7U0lkdTAutlBblY08rwZDff6tNU9cjv6j//Q==", + "dev": true + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-diff": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, - "peer": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, "engines": { - "node": ">=4" + "node": ">=8.6.0" } }, - "node_modules/eth-gas-reporter/node_modules/readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, - "peer": true, "dependencies": { - "picomatch": "^2.0.4" + "is-glob": "^4.0.1" }, "engines": { - "node": ">= 8" + "node": ">= 6" } }, - "node_modules/eth-gas-reporter/node_modules/scrypt-js": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.4.tgz", - "integrity": "sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw==", - "dev": true, - "peer": true + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true }, - "node_modules/eth-gas-reporter/node_modules/setimmediate": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz", - "integrity": "sha512-/TjEmXQVEzdod/FFskf3o7oOAsGhHf2j1dZqRFbDzq4F3mvvxflIIi4Hd3bLQE9y/CpwqfSQam5JakI/mi3Pog==", - "dev": true, - "peer": true + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true }, - "node_modules/eth-gas-reporter/node_modules/string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "node_modules/fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", "dev": true, - "peer": true, "dependencies": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" + "reusify": "^1.0.4" + } + }, + "node_modules/figlet": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/figlet/-/figlet-1.7.0.tgz", + "integrity": "sha512-gO8l3wvqo0V7wEFLXPbkX83b7MVjRrk1oRLfYlZXol8nEpb/ON9pcKLI4qpBv5YtOTfrINtqb7b40iYY2FTWFg==", + "dev": true, + "bin": { + "figlet": "bin/index.js" }, "engines": { - "node": ">=4" + "node": ">= 0.4.0" } }, - "node_modules/eth-gas-reporter/node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "node_modules/figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==", "dev": true, - "peer": true, "dependencies": { - "ansi-regex": "^3.0.0" + "escape-string-regexp": "^1.0.5" }, "engines": { "node": ">=4" } }, - "node_modules/eth-gas-reporter/node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "node_modules/figures/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, - "peer": true, "engines": { - "node": ">=0.10.0" + "node": ">=0.8.0" } }, - "node_modules/eth-gas-reporter/node_modules/supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, - "peer": true, "dependencies": { - "has-flag": "^3.0.0" + "flat-cache": "^3.0.4" }, "engines": { - "node": ">=6" + "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/eth-gas-reporter/node_modules/uuid": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz", - "integrity": "sha512-nWg9+Oa3qD2CQzHIP4qKUqwNfzKn8P0LtFhotaCTFchsV7ZfDhAybeip/HZVeMIpZi9JgY1E3nUlwaCmZT1sEg==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "dev": true, - "peer": true - }, - "node_modules/eth-gas-reporter/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "node_modules/filename-reserved-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", + "integrity": "sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==", "dev": true, - "peer": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" + "engines": { + "node": ">=4" } }, - "node_modules/eth-gas-reporter/node_modules/wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "node_modules/filenamify": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.3.0.tgz", + "integrity": "sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==", "dev": true, - "peer": true, "dependencies": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" + "filename-reserved-regex": "^2.0.0", + "strip-outer": "^1.0.1", + "trim-repeated": "^1.0.0" }, "engines": { - "node": ">=6" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eth-gas-reporter/node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dev": true, - "peer": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/eth-gas-reporter/node_modules/wrap-ansi/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", "dev": true, - "peer": true, "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" }, "engines": { - "node": ">=6" + "node": ">= 0.8" } }, - "node_modules/eth-gas-reporter/node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, - "peer": true, "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" + "ms": "2.0.0" } }, - "node_modules/eth-gas-reporter/node_modules/y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true, - "peer": true + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true }, - "node_modules/eth-gas-reporter/node_modules/yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "node_modules/find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", "dev": true, - "peer": true, "dependencies": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" } }, - "node_modules/eth-gas-reporter/node_modules/yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "node_modules/find-replace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", + "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==", "dev": true, "peer": true, "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" + "array-back": "^3.0.1" + }, + "engines": { + "node": ">=4.0.0" } }, - "node_modules/eth-gas-reporter/node_modules/yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, - "peer": true, "dependencies": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": ">=6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eth-gas-reporter/node_modules/yargs/node_modules/ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", "dev": true, - "peer": true, - "engines": { - "node": ">=6" + "bin": { + "flat": "cli.js" } }, - "node_modules/eth-gas-reporter/node_modules/yargs/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", "dev": true, - "peer": true, "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" }, "engines": { - "node": ">=6" + "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/eth-gas-reporter/node_modules/yargs/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "node_modules/flatted": { + "version": "3.2.9", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", + "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", + "dev": true + }, + "node_modules/follow-redirects": { + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", + "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", "dev": true, - "peer": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], "engines": { - "node": ">=6" + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } } }, - "node_modules/ethereum-bloom-filters": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.10.tgz", - "integrity": "sha512-rxJ5OFN3RwjQxDcFP2Z5+Q9ho4eIdEmSc2ht0fCu8Se9nbXjZ7/031uXoUYJ87KHCOdVeiUuwSnoS7hmYAGVHA==", + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", "dev": true, - "peer": true, "dependencies": { - "js-sha3": "^0.8.0" + "is-callable": "^1.1.3" } }, - "node_modules/ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", "dev": true, - "dependencies": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" + "engines": { + "node": "*" } }, - "node_modules/ethereumjs-abi": { - "version": "0.6.8", - "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz", - "integrity": "sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==", + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", "dev": true, "dependencies": { - "bn.js": "^4.11.8", - "ethereumjs-util": "^6.0.0" + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" } }, - "node_modules/ethereumjs-abi/node_modules/@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", "dev": true, - "dependencies": { - "@types/node": "*" + "engines": { + "node": ">= 0.6" } }, - "node_modules/ethereumjs-abi/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "node_modules/fp-ts": { + "version": "1.19.3", + "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-1.19.3.tgz", + "integrity": "sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg==", "dev": true }, - "node_modules/ethereumjs-abi/node_modules/ethereumjs-util": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", - "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", "dev": true, - "dependencies": { - "@types/bn.js": "^4.11.3", - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "0.1.6", - "rlp": "^2.2.3" + "engines": { + "node": ">= 0.6" } }, - "node_modules/ethereumjs-util": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", - "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", + "node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", "dev": true, "dependencies": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" }, "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/ethers": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", - "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abi": "5.7.0", - "@ethersproject/abstract-provider": "5.7.0", - "@ethersproject/abstract-signer": "5.7.0", - "@ethersproject/address": "5.7.0", - "@ethersproject/base64": "5.7.0", - "@ethersproject/basex": "5.7.0", - "@ethersproject/bignumber": "5.7.0", - "@ethersproject/bytes": "5.7.0", - "@ethersproject/constants": "5.7.0", - "@ethersproject/contracts": "5.7.0", - "@ethersproject/hash": "5.7.0", - "@ethersproject/hdnode": "5.7.0", - "@ethersproject/json-wallets": "5.7.0", - "@ethersproject/keccak256": "5.7.0", - "@ethersproject/logger": "5.7.0", - "@ethersproject/networks": "5.7.1", - "@ethersproject/pbkdf2": "5.7.0", - "@ethersproject/properties": "5.7.0", - "@ethersproject/providers": "5.7.2", - "@ethersproject/random": "5.7.0", - "@ethersproject/rlp": "5.7.0", - "@ethersproject/sha2": "5.7.0", - "@ethersproject/signing-key": "5.7.0", - "@ethersproject/solidity": "5.7.0", - "@ethersproject/strings": "5.7.0", - "@ethersproject/transactions": "5.7.0", - "@ethersproject/units": "5.7.0", - "@ethersproject/wallet": "5.7.0", - "@ethersproject/web": "5.7.1", - "@ethersproject/wordlists": "5.7.0" + "node": ">=6 <7 || >=8" } }, - "node_modules/ethjs-unit": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", - "integrity": "sha512-/Sn9Y0oKl0uqQuvgFk/zQgR7aw1g36qX/jzSQ5lSwlO0GigPymk4eGQfeNTD03w1dPOqfz8V77Cy43jH56pagw==", + "node_modules/fs-minipass": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", + "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", "dev": true, - "peer": true, "dependencies": { - "bn.js": "4.11.6", - "number-to-bn": "1.7.0" - }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" + "minipass": "^2.6.0" } }, - "node_modules/ethjs-unit/node_modules/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", + "node_modules/fs-readdir-recursive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", + "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", "dev": true, "peer": true }, - "node_modules/ethjs-util": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz", - "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==", - "dev": true, - "dependencies": { - "is-hex-prefixed": "1.0.0", - "strip-hex-prefix": "1.0.0" - }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true }, - "node_modules/event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=6" + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "dependencies": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true, - "peer": true - }, - "node_modules/external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true, - "dependencies": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - }, - "engines": { - "node": ">=4" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", - "dev": true, - "engines": [ - "node >=0.6.0" - ], - "peer": true - }, - "node_modules/fast-base64-decode": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fast-base64-decode/-/fast-base64-decode-1.0.0.tgz", - "integrity": "sha512-qwaScUgUGBYeDNRnbc/KyllVU88Jk1pRHPStuF/lO7B0/RTRLj7U0lkdTAutlBblY08rwZDff6tNU9cjv6j//Q==", - "dev": true - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "node_modules/fast-diff": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", - "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", - "dev": true - }, - "node_modules/fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "node_modules/function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", "dev": true, "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" }, "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" + "node": ">= 0.4" }, - "engines": { - "node": ">= 6" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", "dev": true }, - "node_modules/fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", "dev": true, - "dependencies": { - "reusify": "^1.0.4" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==", + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true, - "dependencies": { - "escape-string-regexp": "^1.0.5" - }, "engines": { - "node": ">=4" + "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/figures/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "node_modules/get-func-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", "dev": true, "engines": { - "node": ">=0.8.0" + "node": "*" } }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "node_modules/get-intrinsic": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", + "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", "dev": true, "dependencies": { - "flat-cache": "^3.0.4" + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" }, - "engines": { - "node": "^10.12.0 || >=12.0.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/filename-reserved-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", - "integrity": "sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==", + "node_modules/get-port": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", + "integrity": "sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==", "dev": true, + "peer": true, "engines": { "node": ">=4" } }, - "node_modules/filenamify": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.3.0.tgz", - "integrity": "sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==", + "node_modules/get-random-values": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/get-random-values/-/get-random-values-1.2.2.tgz", + "integrity": "sha512-lMyPjQyl0cNNdDf2oR+IQ/fM3itDvpoHy45Ymo2r0L1EjazeSl13SfbKZs7KtZ/3MDCeueiaJiuOEfKqRTsSgA==", "dev": true, "dependencies": { - "filename-reserved-regex": "^2.0.0", - "strip-outer": "^1.0.1", - "trim-repeated": "^1.0.0" + "global": "^4.4.0" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "10 || 12 || >=14" } }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "node_modules/get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", "dev": true, "dependencies": { - "to-regex-range": "^5.0.1" + "pump": "^3.0.0" }, "engines": { - "node": ">=8" + "node": ">=6" } }, - "node_modules/find-cache-dir": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", - "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "node_modules/get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", "dev": true, "dependencies": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" }, "engines": { - "node": ">=8" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/find-replace": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", - "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==", + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", "dev": true, - "peer": true, "dependencies": { - "array-back": "^3.0.1" - }, - "engines": { - "node": ">=4.0.0" + "assert-plus": "^1.0.0" } }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "node_modules/gh-pages": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-3.2.3.tgz", + "integrity": "sha512-jA1PbapQ1jqzacECfjUaO9gV8uBgU6XNMV0oXLtfCX3haGLe5Atq8BxlrADhbD6/UdG9j6tZLWAkAybndOXTJg==", "dev": true, "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" + "async": "^2.6.1", + "commander": "^2.18.0", + "email-addresses": "^3.0.1", + "filenamify": "^4.3.0", + "find-cache-dir": "^3.3.1", + "fs-extra": "^8.1.0", + "globby": "^6.1.0" + }, + "bin": { + "gh-pages": "bin/gh-pages.js", + "gh-pages-clean": "bin/gh-pages-clean.js" }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "node_modules/gh-pages/node_modules/array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", "dev": true, - "bin": { - "flat": "cli.js" + "dependencies": { + "array-uniq": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "node_modules/gh-pages/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", "dev": true, "dependencies": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flatted": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", - "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", - "dev": true - }, - "node_modules/follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dev": true, - "peer": true, - "dependencies": { - "is-callable": "^1.1.3" - } - }, - "node_modules/forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", - "dev": true, - "peer": true, - "engines": { - "node": "*" - } - }, - "node_modules/form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dev": true, - "peer": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 0.12" - } - }, - "node_modules/fp-ts": { - "version": "1.19.3", - "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-1.19.3.tgz", - "integrity": "sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg==", - "dev": true - }, - "node_modules/fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/fs-readdir-recursive": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", - "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", - "dev": true, - "peer": true - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "node_modules/function.prototype.name": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", - "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", - "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0", - "functions-have-names": "^1.2.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", - "dev": true - }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true, - "peer": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", - "dev": true, - "peer": true, - "engines": { - "node": "*" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", - "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-port": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", - "integrity": "sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==", - "dev": true, - "peer": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", - "dev": true, - "peer": true, - "dependencies": { - "assert-plus": "^1.0.0" - } - }, - "node_modules/gh-pages": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-3.2.3.tgz", - "integrity": "sha512-jA1PbapQ1jqzacECfjUaO9gV8uBgU6XNMV0oXLtfCX3haGLe5Atq8BxlrADhbD6/UdG9j6tZLWAkAybndOXTJg==", - "dev": true, - "dependencies": { - "async": "^2.6.1", - "commander": "^2.18.0", - "email-addresses": "^3.0.1", - "filenamify": "^4.3.0", - "find-cache-dir": "^3.3.1", - "fs-extra": "^8.1.0", - "globby": "^6.1.0" - }, - "bin": { - "gh-pages": "bin/gh-pages.js", - "gh-pages-clean": "bin/gh-pages-clean.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/gh-pages/node_modules/array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", - "dev": true, - "dependencies": { - "array-uniq": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gh-pages/node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" + "node": ">=6 <7 || >=8" } }, "node_modules/gh-pages/node_modules/globby": { @@ -6326,6 +6923,16 @@ "node": ">=10.13.0" } }, + "node_modules/global": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", + "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", + "dev": true, + "dependencies": { + "min-document": "^2.19.0", + "process": "^0.11.10" + } + }, "node_modules/global-modules": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", @@ -6368,9 +6975,9 @@ } }, "node_modules/globals": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", - "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "version": "13.23.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", + "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -6387,7 +6994,6 @@ "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", "dev": true, - "peer": true, "dependencies": { "define-properties": "^1.1.3" }, @@ -6423,7 +7029,6 @@ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", "dev": true, - "peer": true, "dependencies": { "get-intrinsic": "^1.1.3" }, @@ -6431,16 +7036,32 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true + "node_modules/got": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", + "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "dev": true, + "dependencies": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + }, + "engines": { + "node": ">=8.6" + } }, - "node_modules/grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true }, "node_modules/graphemer": { @@ -6449,25 +7070,15 @@ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, - "node_modules/growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true, - "peer": true, - "engines": { - "node": ">=4.x" - } - }, "node_modules/handlebars": { - "version": "4.7.7", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", - "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", "dev": true, "peer": true, "dependencies": { "minimist": "^1.2.5", - "neo-async": "^2.6.0", + "neo-async": "^2.6.2", "source-map": "^0.6.1", "wordwrap": "^1.0.0" }, @@ -6496,7 +7107,6 @@ "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", "dev": true, - "peer": true, "engines": { "node": ">=4" } @@ -6507,7 +7117,6 @@ "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", "deprecated": "this library is no longer supported", "dev": true, - "peer": true, "dependencies": { "ajv": "^6.12.3", "har-schema": "^2.0.0" @@ -6517,28 +7126,27 @@ } }, "node_modules/hardhat": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.15.0.tgz", - "integrity": "sha512-cC9tM/N10YaES04zPOp7yR13iX3YibqaNmi0//Ep40Nt9ELIJx3kFpQmucur0PAIfXYpGnw5RuXHNLkxpnVHEw==", + "version": "2.19.1", + "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.19.1.tgz", + "integrity": "sha512-bsWa63g1GB78ZyMN08WLhFElLPA+J+pShuKD1BFO2+88g3l+BL3R07vj9deIi9dMbssxgE714Gof1dBEDGqnCw==", "dev": true, "dependencies": { "@ethersproject/abi": "^5.1.2", "@metamask/eth-sig-util": "^4.0.0", - "@nomicfoundation/ethereumjs-block": "5.0.1", - "@nomicfoundation/ethereumjs-blockchain": "7.0.1", - "@nomicfoundation/ethereumjs-common": "4.0.1", - "@nomicfoundation/ethereumjs-evm": "2.0.1", - "@nomicfoundation/ethereumjs-rlp": "5.0.1", - "@nomicfoundation/ethereumjs-statemanager": "2.0.1", - "@nomicfoundation/ethereumjs-trie": "6.0.1", - "@nomicfoundation/ethereumjs-tx": "5.0.1", - "@nomicfoundation/ethereumjs-util": "9.0.1", - "@nomicfoundation/ethereumjs-vm": "7.0.1", + "@nomicfoundation/ethereumjs-block": "5.0.2", + "@nomicfoundation/ethereumjs-blockchain": "7.0.2", + "@nomicfoundation/ethereumjs-common": "4.0.2", + "@nomicfoundation/ethereumjs-evm": "2.0.2", + "@nomicfoundation/ethereumjs-rlp": "5.0.2", + "@nomicfoundation/ethereumjs-statemanager": "2.0.2", + "@nomicfoundation/ethereumjs-trie": "6.0.2", + "@nomicfoundation/ethereumjs-tx": "5.0.2", + "@nomicfoundation/ethereumjs-util": "9.0.2", + "@nomicfoundation/ethereumjs-vm": "7.0.2", "@nomicfoundation/solidity-analyzer": "^0.1.0", "@sentry/node": "^5.18.1", "@types/bn.js": "^5.1.0", "@types/lru-cache": "^5.1.0", - "abort-controller": "^3.0.0", "adm-zip": "^0.4.16", "aggregate-error": "^3.0.0", "ansi-escapes": "^4.3.0", @@ -6561,7 +7169,6 @@ "mnemonist": "^0.38.0", "mocha": "^10.0.0", "p-map": "^4.0.0", - "qs": "^6.7.0", "raw-body": "^2.4.1", "resolve": "1.17.0", "semver": "^6.3.0", @@ -6576,9 +7183,6 @@ "bin": { "hardhat": "internal/cli/bootstrap.js" }, - "engines": { - "node": ">=14.0.0" - }, "peerDependencies": { "ts-node": "*", "typescript": "*" @@ -6660,6 +7264,51 @@ "hardhat": "2.x" } }, + "node_modules/hardhat/node_modules/@noble/hashes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.2.0.tgz", + "integrity": "sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/hardhat/node_modules/@scure/bip32": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.5.tgz", + "integrity": "sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "@noble/hashes": "~1.2.0", + "@noble/secp256k1": "~1.7.0", + "@scure/base": "~1.1.0" + } + }, + "node_modules/hardhat/node_modules/@scure/bip39": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.1.tgz", + "integrity": "sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "@noble/hashes": "~1.2.0", + "@scure/base": "~1.1.0" + } + }, "node_modules/hardhat/node_modules/ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -6780,15 +7429,6 @@ "node": ">=4" } }, - "node_modules/hardhat/node_modules/p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/hardhat/node_modules/path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", @@ -6810,24 +7450,11 @@ "node": ">=4" } }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, "node_modules/has-bigints": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", "dev": true, - "peer": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -6842,13 +7469,12 @@ } }, "node_modules/has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", + "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", "dev": true, - "peer": true, "dependencies": { - "get-intrinsic": "^1.1.1" + "get-intrinsic": "^1.2.2" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -6883,7 +7509,6 @@ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", "dev": true, - "peer": true, "dependencies": { "has-symbols": "^1.0.2" }, @@ -6918,6 +7543,18 @@ "minimalistic-assert": "^1.0.1" } }, + "node_modules/hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", @@ -6961,6 +7598,12 @@ "node": ">=6.0.0" } }, + "node_modules/http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", + "dev": true + }, "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -6977,6 +7620,12 @@ "node": ">= 0.8" } }, + "node_modules/http-https": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/http-https/-/http-https-1.0.0.tgz", + "integrity": "sha512-o0PWwVCSp3O0wS6FvNr6xfBCHgt0m1tvPLFOCc2iFDKTRAXhB7m8klDf7ErowFH8POa6dVdGatKU5I1YYwzUyg==", + "dev": true + }, "node_modules/http-response-object": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz", @@ -6999,7 +7648,6 @@ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", "dev": true, - "peer": true, "dependencies": { "assert-plus": "^1.0.0", "jsprim": "^1.2.2", @@ -7010,6 +7658,19 @@ "npm": ">=1.3.7" } }, + "node_modules/http2-wrapper": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", + "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", + "dev": true, + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.0.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, "node_modules/https-proxy-agent": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", @@ -7023,6 +7684,18 @@ "node": ">= 6" } }, + "node_modules/husky": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/husky/-/husky-6.0.0.tgz", + "integrity": "sha512-SQS2gDTB7tBN486QSoKPKQItZw97BMOd+Kdb6ghfpBc0yXyzrddI0oDV5MkDAbuB4X2mO3/nj60TRMcYxwzZeQ==", + "dev": true, + "bin": { + "husky": "lib/bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -7035,6 +7708,27 @@ "node": ">=0.10.0" } }, + "node_modules/idna-uts46-hx": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/idna-uts46-hx/-/idna-uts46-hx-2.3.1.tgz", + "integrity": "sha512-PWoF9Keq6laYdIRwwCdhTPl60xRqAloYNMQLiyUnG42VjT53oW07BXIRM+NK7eQjzXjAk2gUvX9caRxlnF9TAA==", + "dev": true, + "dependencies": { + "punycode": "2.1.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/idna-uts46-hx/node_modules/punycode": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz", + "integrity": "sha512-Yxz2kRwT90aPiWEMHVYnEf4+rhwF1tBmmZ4KepCP+Wkium9JxtWnUm1nqGwpiAHr/tnTSeHqr3wb++jgSkXjhA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", @@ -7056,18 +7750,18 @@ ] }, "node_modules/ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", + "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", "dev": true, "engines": { "node": ">= 4" } }, "node_modules/immutable": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.0.tgz", - "integrity": "sha512-0AOCmOip+xgJwEVTQj1EfiDDOkPmuyllDuTuEX+DDXUgapLAsBIfkg3sxCYyCEA8mQqZrrxPUGjcOQ2JS3WLkg==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.4.tgz", + "integrity": "sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==", "dev": true }, "node_modules/import-fresh": { @@ -7296,14 +7990,13 @@ } }, "node_modules/internal-slot": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", - "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.6.tgz", + "integrity": "sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg==", "dev": true, - "peer": true, "dependencies": { - "get-intrinsic": "^1.2.0", - "has": "^1.0.3", + "get-intrinsic": "^1.2.2", + "hasown": "^2.0.0", "side-channel": "^1.0.4" }, "engines": { @@ -7329,12 +8022,36 @@ "fp-ts": "^1.0.0" } }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-array-buffer": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.2.0", @@ -7355,7 +8072,6 @@ "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", "dev": true, - "peer": true, "dependencies": { "has-bigints": "^1.0.1" }, @@ -7380,7 +8096,6 @@ "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -7420,7 +8135,6 @@ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", "dev": true, - "peer": true, "engines": { "node": ">= 0.4" }, @@ -7433,7 +8147,6 @@ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", "dev": true, - "peer": true, "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -7471,6 +8184,27 @@ "node": ">=8" } }, + "node_modules/is-function": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", + "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==", + "dev": true + }, + "node_modules/is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -7493,12 +8227,27 @@ "npm": ">=3" } }, + "node_modules/is-nan": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", + "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-negative-zero": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", "dev": true, - "peer": true, "engines": { "node": ">= 0.4" }, @@ -7520,7 +8269,6 @@ "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", "dev": true, - "peer": true, "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -7554,7 +8302,6 @@ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -7571,7 +8318,6 @@ "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2" }, @@ -7584,7 +8330,6 @@ "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", "dev": true, - "peer": true, "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -7600,7 +8345,6 @@ "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", "dev": true, - "peer": true, "dependencies": { "has-symbols": "^1.0.2" }, @@ -7612,17 +8356,12 @@ } }, "node_modules/is-typed-array": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", - "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", + "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", "dev": true, - "peer": true, "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" + "which-typed-array": "^1.1.11" }, "engines": { "node": ">= 0.4" @@ -7635,8 +8374,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/is-unicode-supported": { "version": "0.1.0", @@ -7655,7 +8393,6 @@ "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2" }, @@ -7689,8 +8426,13 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", - "dev": true, - "peer": true + "dev": true + }, + "node_modules/js-base64": { + "version": "3.7.5", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.5.tgz", + "integrity": "sha512-3MEt5DTINKqfScXKfJFrRbxkrnk2AxPWGBL/ycjz4dK8iqiSJ06UxD8jh8xuh6p10TX4t2+7FsBYVxxQbMg+qA==", + "dev": true }, "node_modules/js-cookie": { "version": "2.2.1", @@ -7699,9 +8441,9 @@ "dev": true }, "node_modules/js-sdsl": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.1.tgz", - "integrity": "sha512-6Gsx8R0RucyePbWqPssR8DyfuXmLBooYN5cZFZKjHGnQuaf7pEzhtpceagJxVu4LqhYY5EYA7nko3FmeHZ1KbA==", + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.2.tgz", + "integrity": "sha512-dwXFwByc/ajSV6m5bcKAPwe4yDDF6D614pxmIi5odytzxRlwqF6nwoiCek80Ixc7Cvma5awClxrzFtxCQvcM8w==", "dev": true, "funding": { "type": "opencollective", @@ -7736,8 +8478,19 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", - "dev": true, - "peer": true + "dev": true + }, + "node_modules/jsencrypt": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/jsencrypt/-/jsencrypt-3.2.1.tgz", + "integrity": "sha512-k1sD5QV0KPn+D8uG9AdGzTQuamt82QZ3A3l6f7TRwMU6Oi2Vg0BsL+wZIQBONcraO1pc78ExMdvmBBJ8WhNYUA==", + "dev": true + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true }, "node_modules/json-parse-better-errors": { "version": "1.0.2", @@ -7749,8 +8502,7 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/json-schema-traverse": { "version": "0.4.1", @@ -7768,8 +8520,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/jsonfile": { "version": "4.0.0", @@ -7795,7 +8546,6 @@ "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", "dev": true, - "peer": true, "dependencies": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", @@ -7807,9 +8557,9 @@ } }, "node_modules/keccak": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.3.tgz", - "integrity": "sha512-JZrLIAJWuZxKbCilMpNz5Vj7Vtb4scDG3dMXLOsbzBmQGyjwE61BbW7bJkfKKCShXiQZt3T6sBgALRtmd+nZaQ==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.4.tgz", + "integrity": "sha512-3vKuW0jV8J3XNTzvfyicFR5qvxrSAGl7KIhvgOu5cmWwM7tZRj3fMbj/pfIf4be7aznbc+prBWGjywox/g2Y6Q==", "dev": true, "hasInstallScript": true, "dependencies": { @@ -7821,6 +8571,15 @@ "node": ">=10.0.0" } }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, "node_modules/kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -7841,9 +8600,9 @@ } }, "node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", "dev": true, "engines": { "node": ">=6" @@ -7925,6 +8684,12 @@ "node": ">= 0.8.0" } }, + "node_modules/libphonenumber-js": { + "version": "1.10.51", + "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.10.51.tgz", + "integrity": "sha512-vY2I+rQwrDQzoPds0JeTEpeWzbUJgqoV0O4v31PauHBb/e+1KCXKylHcDnBMgJZ9fH9mErsEbROJY3Z3JtqEmg==", + "dev": true + }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -7983,13 +8748,22 @@ } }, "node_modules/loupe": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz", - "integrity": "sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==", + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", "dev": true, "peer": true, "dependencies": { - "get-func-name": "^2.0.0" + "get-func-name": "^2.0.1" + } + }, + "node_modules/lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "dev": true, + "engines": { + "node": ">=0.10.0" } }, "node_modules/lru_map": { @@ -8055,6 +8829,15 @@ "safe-buffer": "^5.1.2" } }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/memory-level": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/memory-level/-/memory-level-1.0.0.tgz", @@ -8078,6 +8861,12 @@ "node": ">= 0.10.0" } }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", + "dev": true + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -8087,12 +8876,28 @@ "node": ">= 8" } }, - "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", "dev": true, - "dependencies": { + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micro-ftch": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/micro-ftch/-/micro-ftch-0.3.1.tgz", + "integrity": "sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg==", + "dev": true, + "peer": true + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { "braces": "^3.0.2", "picomatch": "^2.3.1" }, @@ -8100,12 +8905,42 @@ "node": ">=8.6" } }, + "node_modules/miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "dependencies": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + }, + "bin": { + "miller-rabin": "bin/miller-rabin" + } + }, + "node_modules/miller-rabin/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "dev": true, - "peer": true, "engines": { "node": ">= 0.6" } @@ -8115,7 +8950,6 @@ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "dev": true, - "peer": true, "dependencies": { "mime-db": "1.52.0" }, @@ -8132,6 +8966,24 @@ "node": ">=4" } }, + "node_modules/mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/min-document": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", + "integrity": "sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==", + "dev": true, + "dependencies": { + "dom-walk": "^0.1.0" + } + }, "node_modules/minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", @@ -8165,6 +9017,25 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "node_modules/minizlib": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", + "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "dev": true, + "dependencies": { + "minipass": "^2.9.0" + } + }, "node_modules/mkdirp": { "version": "0.5.6", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", @@ -8177,6 +9048,19 @@ "mkdirp": "bin/cmd.js" } }, + "node_modules/mkdirp-promise": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz", + "integrity": "sha512-Hepn5kb1lJPtVW84RFT40YG1OddBNTOVUZR2bzQUHc+Z03en8/3uX0+060JDhcEzyO08HmipsN9DcnFMxhIL9w==", + "deprecated": "This package is broken and no longer maintained. 'mkdirp' itself supports promises now, please switch to that.", + "dev": true, + "dependencies": { + "mkdirp": "*" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/mnemonist": { "version": "0.38.5", "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.38.5.tgz", @@ -8277,6 +9161,12 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/mock-fs": { + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-4.14.0.tgz", + "integrity": "sha512-qYvlv/exQ4+svI3UOvPUpLDF0OMX5euvUH0Ny4N5QyRyhNdgAgUrVH3iUINSzEPLvx0kbo/Bp28GJKIqvE7URw==", + "dev": true + }, "node_modules/module-error": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/module-error/-/module-error-1.0.2.tgz", @@ -8286,18 +9176,124 @@ "node": ">=10" } }, + "node_modules/moment": { + "version": "2.29.4", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", + "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "node_modules/multibase": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.6.1.tgz", + "integrity": "sha512-pFfAwyTjbbQgNc3G7D48JkJxWtoJoBMaR4xQUOuB8RnCgRqaYmWNFeJTTvrJ2w51bjLq2zTby6Rqj9TQ9elSUw==", + "deprecated": "This module has been superseded by the multiformats module", + "dev": true, + "dependencies": { + "base-x": "^3.0.8", + "buffer": "^5.5.0" + } + }, + "node_modules/multibase/node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/multicodec": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-0.5.7.tgz", + "integrity": "sha512-PscoRxm3f+88fAtELwUnZxGDkduE2HD9Q6GHUOywQLjOGT/HAdhjLDYNZ1e7VR0s0TP0EwZ16LNUTFpoBGivOA==", + "deprecated": "This module has been superseded by the multiformats module", + "dev": true, + "dependencies": { + "varint": "^5.0.0" + } + }, + "node_modules/multihashes": { + "version": "0.4.21", + "resolved": "https://registry.npmjs.org/multihashes/-/multihashes-0.4.21.tgz", + "integrity": "sha512-uVSvmeCWf36pU2nB4/1kzYZjsXD9vofZKpgudqkceYY5g2aZZXJ5r9lxuzoRLl1OAp28XljXsEJ/X/85ZsKmKw==", + "dev": true, + "dependencies": { + "buffer": "^5.5.0", + "multibase": "^0.7.0", + "varint": "^5.0.0" + } + }, + "node_modules/multihashes/node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/multihashes/node_modules/multibase": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.7.0.tgz", + "integrity": "sha512-TW8q03O0f6PNFTQDvh3xxH03c8CjGaaYrjkl9UQPG6rz53TQzzxJVCIWVjzcbN/Q5Y53Zd0IBQBMVktVgNx4Fg==", + "deprecated": "This module has been superseded by the multiformats module", + "dev": true, + "dependencies": { + "base-x": "^3.0.8", + "buffer": "^5.5.0" + } + }, "node_modules/mute-stream": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", "integrity": "sha512-r65nCZhrbXXb6dXOACihYApHw2Q6pV0M3V0PSxd74N0+D8nzAdEAITq2oAjA1jVnKI+tGvEBUpqiMh0+rW6zDQ==", "dev": true }, + "node_modules/nano-json-stream-parser": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz", + "integrity": "sha512-9MqxMH/BSJC7dnLsEMPyfN5Dvoo49IsPFYMcHw3Bcfc2kN0lpHRBSzlMSVx4HGyJ7s9B31CyBTVehWJoQ8Ctew==", + "dev": true + }, "node_modules/nanoid": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", @@ -8328,6 +9324,15 @@ "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", "dev": true }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", @@ -8335,6 +9340,12 @@ "dev": true, "peer": true }, + "node_modules/next-tick": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", + "dev": true + }, "node_modules/nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", @@ -8357,31 +9368,10 @@ "lodash": "^4.17.21" } }, - "node_modules/node-environment-flags": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", - "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", - "dev": true, - "peer": true, - "dependencies": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - } - }, - "node_modules/node-environment-flags/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "peer": true, - "bin": { - "semver": "bin/semver" - } - }, "node_modules/node-fetch": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.11.tgz", - "integrity": "sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", "dev": true, "dependencies": { "whatwg-url": "^5.0.0" @@ -8399,9 +9389,9 @@ } }, "node_modules/node-gyp-build": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz", - "integrity": "sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==", + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.7.1.tgz", + "integrity": "sha512-wTSrZ+8lsRRa3I3H8Xr65dLWSgCvY2l4AOnaeKdPA9TB/WYMPaTcrzf3rXvFoVvjKNVnu0CcWSx54qq9GKRUYg==", "dev": true, "bin": { "node-gyp-build": "bin.js", @@ -8409,6 +9399,15 @@ "node-gyp-build-test": "build-test.js" } }, + "node_modules/node-jsencrypt": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-jsencrypt/-/node-jsencrypt-1.0.0.tgz", + "integrity": "sha512-ANQ/XkOVS02R89MtfoelFxarMsLA12nlOT802VS4LVhl+JRSRZIvkLIjvKYZmIar+mENUkR9mBKUdcdiPy/7lA==", + "dev": true, + "dependencies": { + "get-random-values": "^1.2.0" + } + }, "node_modules/nofilter": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-3.1.0.tgz", @@ -8440,12 +9439,20 @@ "node": ">=0.10.0" } }, + "node_modules/normalize-url": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", + "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/number-to-bn": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", "integrity": "sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig==", "dev": true, - "peer": true, "dependencies": { "bn.js": "4.11.6", "strip-hex-prefix": "1.0.0" @@ -8459,15 +9466,13 @@ "version": "4.11.6", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", "dev": true, - "peer": true, "engines": { "node": "*" } @@ -8482,10 +9487,26 @@ } }, "node_modules/object-inspect": { - "version": "1.12.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", - "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-is": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", + "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -8495,42 +9516,23 @@ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", "dev": true, - "peer": true, "engines": { "node": ">= 0.4" } }, "node_modules/object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", "dev": true, - "peer": true, "dependencies": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" }, "engines": { "node": ">= 0.4" - } - }, - "node_modules/object.getownpropertydescriptors": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.6.tgz", - "integrity": "sha512-lq+61g26E/BgHv0ZTFgRvi7NMEPuAxLkFU7rukXjc/AlwH4Am5xXVnIXy3un1bg/JPbXHrixRkK1itUzzPiIjQ==", - "dev": true, - "peer": true, - "dependencies": { - "array.prototype.reduce": "^1.0.5", - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.21.2", - "safe-array-concat": "^1.0.0" - }, - "engines": { - "node": ">= 0.8" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -8542,6 +9544,27 @@ "integrity": "sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==", "dev": true }, + "node_modules/oboe": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/oboe/-/oboe-2.1.5.tgz", + "integrity": "sha512-zRFWiF+FoicxEs3jNI/WYUrVEgA7DeET/InK0XQuudGHRg8iIob3cNPrJTKaz4004uaA9Pbe+Dwa8iluhjLZWA==", + "dev": true, + "dependencies": { + "http-https": "^1.0.0" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -8564,17 +9587,17 @@ } }, "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", "dev": true, "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "type-check": "^0.4.0" }, "engines": { "node": ">= 0.8.0" @@ -8596,6 +9619,15 @@ "node": ">=0.10.0" } }, + "node_modules/p-cancelable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -8642,12 +9674,12 @@ } }, "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", "dev": true, "engines": { - "node": ">=6" + "node": ">=4" } }, "node_modules/parent-module": { @@ -8662,6 +9694,19 @@ "node": ">=6" } }, + "node_modules/parse-asn1": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", + "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", + "dev": true, + "dependencies": { + "asn1.js": "^5.2.0", + "browserify-aes": "^1.0.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, "node_modules/parse-cache-control": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", @@ -8669,6 +9714,12 @@ "dev": true, "peer": true }, + "node_modules/parse-headers": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.5.tgz", + "integrity": "sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA==", + "dev": true + }, "node_modules/parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", @@ -8682,6 +9733,15 @@ "node": ">=4" } }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -8730,6 +9790,12 @@ "node": ">=8" } }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", + "dev": true + }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -8769,8 +9835,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", - "dev": true, - "peer": true + "dev": true }, "node_modules/picomatch": { "version": "2.3.1", @@ -8879,6 +9944,15 @@ "node": ">=8" } }, + "node_modules/pkg-dir/node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -8888,6 +9962,15 @@ "node": ">= 0.8.0" } }, + "node_modules/prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/prettier": { "version": "1.19.1", "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", @@ -8901,6 +9984,15 @@ "node": ">=4" } }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "dev": true, + "engines": { + "node": ">= 0.6.0" + } + }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -8929,11 +10021,11 @@ }, "node_modules/prompts": { "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "resolved": "git+ssh://git@github.com/meshin-blox/prompts.git#a22bdac044f6b32ba67adb4eacc2e58322512a2d", "dev": true, + "license": "MIT", "dependencies": { - "kleur": "^3.0.3", + "kleur": "^4.0.1", "sisteransi": "^1.0.5" }, "engines": { @@ -8960,17 +10052,65 @@ "node": ">= 4" } }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true + }, "node_modules/psl": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", + "dev": true + }, + "node_modules/public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", "dev": true, - "peer": true + "dependencies": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/public-encrypt/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } }, "node_modules/punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, "engines": { "node": ">=6" @@ -8981,6 +10121,7 @@ "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", "dev": true, + "peer": true, "dependencies": { "side-channel": "^1.0.4" }, @@ -8991,6 +10132,20 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/query-string": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", + "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", + "dev": true, + "dependencies": { + "decode-uri-component": "^0.2.0", + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -9011,6 +10166,18 @@ } ] }, + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -9020,6 +10187,25 @@ "safe-buffer": "^5.1.0" } }, + "node_modules/randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, + "dependencies": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/raw-body": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", @@ -9098,15 +10284,14 @@ } }, "node_modules/regexp.prototype.flags": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz", - "integrity": "sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz", + "integrity": "sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", - "functions-have-names": "^1.2.3" + "set-function-name": "^2.0.0" }, "engines": { "node": ">= 0.4" @@ -9166,7 +10351,6 @@ "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", "dev": true, - "peer": true, "dependencies": { "aws-sign2": "~0.7.0", "aws4": "^1.8.0", @@ -9193,39 +10377,18 @@ "node": ">= 6" } }, - "node_modules/request-promise-core": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", - "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", - "dev": true, - "peer": true, - "dependencies": { - "lodash": "^4.17.19" - }, - "engines": { - "node": ">=0.10.0" - }, - "peerDependencies": { - "request": "^2.34" - } - }, - "node_modules/request-promise-native": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz", - "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==", - "deprecated": "request-promise-native has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142", + "node_modules/request/node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", "dev": true, - "peer": true, "dependencies": { - "request-promise-core": "1.1.4", - "stealthy-require": "^1.1.1", - "tough-cookie": "^2.3.3" + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" }, "engines": { - "node": ">=0.12.0" - }, - "peerDependencies": { - "request": "^2.34" + "node": ">= 0.12" } }, "node_modules/request/node_modules/qs": { @@ -9233,7 +10396,6 @@ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", "dev": true, - "peer": true, "engines": { "node": ">=0.6" } @@ -9244,7 +10406,6 @@ "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", "dev": true, - "peer": true, "bin": { "uuid": "bin/uuid" } @@ -9267,13 +10428,6 @@ "node": ">=0.10.0" } }, - "node_modules/require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true, - "peer": true - }, "node_modules/resolve": { "version": "1.17.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", @@ -9286,6 +10440,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "dev": true + }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -9295,6 +10455,15 @@ "node": ">=4" } }, + "node_modules/responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==", + "dev": true, + "dependencies": { + "lowercase-keys": "^1.0.0" + } + }, "node_modules/restore-cursor": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", @@ -9438,14 +10607,13 @@ } }, "node_modules/safe-array-concat": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.0.tgz", - "integrity": "sha512-9dVEFruWIsnie89yym+xWTAYASdpw3CJV7Li/6zBewGf9z2i1j31rP6jnY0pHEO4QZh6N0K11bFjWmdR8UGdPQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.1.tgz", + "integrity": "sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.0", + "get-intrinsic": "^1.2.1", "has-symbols": "^1.0.3", "isarray": "^2.0.5" }, @@ -9460,8 +10628,7 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/safe-buffer": { "version": "5.2.1", @@ -9488,7 +10655,6 @@ "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.1.3", @@ -9657,14 +10823,59 @@ } }, "node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "bin": { "semver": "bin/semver.js" } }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, "node_modules/serialize-javascript": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", @@ -9674,12 +10885,65 @@ "randombytes": "^2.1.0" } }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "node_modules/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", "dev": true, - "peer": true + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/servify": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/servify/-/servify-0.1.12.tgz", + "integrity": "sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw==", + "dev": true, + "dependencies": { + "body-parser": "^1.16.0", + "cors": "^2.8.1", + "express": "^4.14.0", + "request": "^2.79.0", + "xhr": "^2.3.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/set-function-length": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", + "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.1", + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz", + "integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==", + "dev": true, + "dependencies": { + "define-data-property": "^1.0.1", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } }, "node_modules/setimmediate": { "version": "1.0.5", @@ -9779,10 +11043,41 @@ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/simple-get": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.2.tgz", + "integrity": "sha512-Ijd/rV5o+mSBBs4F/x9oDPtTx9Zb6X9brmnXvMW4J7IR15ngi9q5xxqWBKU744jTZiaXtxaPL7uHG6vtN8kUkw==", + "dev": true, + "dependencies": { + "decompress-response": "^3.3.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, "node_modules/simple-git": { - "version": "3.19.0", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.19.0.tgz", - "integrity": "sha512-hyH2p9Ptxjf/xPuL7HfXbpYt9gKhC1yWDh3KYIAYJJePAKV7AEjLN4xhp7lozOdNiaJ9jlVvAbBymVlcS2jRiA==", + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.21.0.tgz", + "integrity": "sha512-oTzw9248AF5bDTMk9MrxsRzEzivMlY+DWH0yWS4VYpMhNLhDWnN06pCtaUyPnqv/FpsdeNmRqmZugMABHRPdDA==", "dev": true, "dependencies": { "@kwsites/file-exists": "^1.1.1", @@ -9891,9 +11186,9 @@ } }, "node_modules/solc/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true, "bin": { "semver": "bin/semver" @@ -10028,9 +11323,9 @@ } }, "node_modules/solhint/node_modules/cross-spawn/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true, "bin": { "semver": "bin/semver" @@ -10124,9 +11419,9 @@ } }, "node_modules/solhint/node_modules/eslint/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true, "bin": { "semver": "bin/semver" @@ -10443,20 +11738,23 @@ } }, "node_modules/solidity-ast": { - "version": "0.4.49", - "resolved": "https://registry.npmjs.org/solidity-ast/-/solidity-ast-0.4.49.tgz", - "integrity": "sha512-Pr5sCAj1SFqzwFZw1HPKSq0PehlQNdM8GwKyAVYh2DOn7/cCK8LUKD1HeHnKtTgBW7hi9h4nnnan7hpAg5RhWQ==", - "dev": true + "version": "0.4.55", + "resolved": "https://registry.npmjs.org/solidity-ast/-/solidity-ast-0.4.55.tgz", + "integrity": "sha512-qeEU/r/K+V5lrAw8iswf2/yfWAnSGs3WKPHI+zAFKFjX0dIBVXEU/swQ8eJQYHf6PJWUZFO2uWV4V1wEOkeQbA==", + "dev": true, + "dependencies": { + "array.prototype.findlast": "^1.2.2" + } }, "node_modules/solidity-coverage": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.8.2.tgz", - "integrity": "sha512-cv2bWb7lOXPE9/SSleDO6czkFiMHgP4NXPj+iW9W7iEKLBk7Cj0AGBiNmGX3V1totl9wjPrT0gHmABZKZt65rQ==", + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.8.5.tgz", + "integrity": "sha512-6C6N6OV2O8FQA0FWA95FdzVH+L16HU94iFgg5wAFZ29UpLFkgNI/DRR2HotG1bC0F4gAc/OMs2BJI44Q/DYlKQ==", "dev": true, "peer": true, "dependencies": { "@ethersproject/abi": "^5.0.9", - "@solidity-parser/parser": "^0.14.1", + "@solidity-parser/parser": "^0.16.0", "chalk": "^2.4.2", "death": "^1.1.0", "detect-port": "^1.3.0", @@ -10467,7 +11765,7 @@ "globby": "^10.0.1", "jsonschema": "^1.2.4", "lodash": "^4.17.15", - "mocha": "7.1.2", + "mocha": "10.2.0", "node-emoji": "^1.10.0", "pify": "^4.0.1", "recursive-readdir": "^2.2.2", @@ -10483,24 +11781,14 @@ "hardhat": "^2.11.0" } }, - "node_modules/solidity-coverage/node_modules/ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true, - "peer": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/solidity-coverage/node_modules/ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "node_modules/solidity-coverage/node_modules/@solidity-parser/parser": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.16.2.tgz", + "integrity": "sha512-PI9NfoA3P8XK2VBkK5oIfRgKDsicwDZfkVq9ZTBCQYGOP1N2owgY2dyLGyU5/J/hQs8KRk55kdmvTLjy3Mu3vg==", "dev": true, "peer": true, - "engines": { - "node": ">=6" + "dependencies": { + "antlr4ts": "^0.5.0-alpha.4" } }, "node_modules/solidity-coverage/node_modules/ansi-styles": { @@ -10516,26 +11804,6 @@ "node": ">=4" } }, - "node_modules/solidity-coverage/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "peer": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/solidity-coverage/node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "peer": true, - "engines": { - "node": ">=6" - } - }, "node_modules/solidity-coverage/node_modules/chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -10551,48 +11819,14 @@ "node": ">=4" } }, - "node_modules/solidity-coverage/node_modules/chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", + "node_modules/solidity-coverage/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, "peer": true, "dependencies": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.1.1" - } - }, - "node_modules/solidity-coverage/node_modules/cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "peer": true, - "dependencies": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "node_modules/solidity-coverage/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "peer": true, - "dependencies": { - "color-name": "1.1.3" + "color-name": "1.1.3" } }, "node_modules/solidity-coverage/node_modules/color-name": { @@ -10602,44 +11836,6 @@ "dev": true, "peer": true }, - "node_modules/solidity-coverage/node_modules/debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", - "dev": true, - "peer": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/solidity-coverage/node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/solidity-coverage/node_modules/diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/solidity-coverage/node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true, - "peer": true - }, "node_modules/solidity-coverage/node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", @@ -10650,46 +11846,6 @@ "node": ">=0.8.0" } }, - "node_modules/solidity-coverage/node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "peer": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/solidity-coverage/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "peer": true, - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/solidity-coverage/node_modules/flat": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz", - "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==", - "dev": true, - "peer": true, - "dependencies": { - "is-buffer": "~2.0.3" - }, - "bin": { - "flat": "cli.js" - } - }, "node_modules/solidity-coverage/node_modules/fs-extra": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", @@ -10705,53 +11861,6 @@ "node": ">=6 <7 || >=8" } }, - "node_modules/solidity-coverage/node_modules/fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "deprecated": "\"Please update to latest v2.3 or v2.2\"", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "peer": true, - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/solidity-coverage/node_modules/glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "peer": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - } - }, - "node_modules/solidity-coverage/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "peer": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/solidity-coverage/node_modules/globby": { "version": "10.0.2", "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", @@ -10782,220 +11891,211 @@ "node": ">=4" } }, - "node_modules/solidity-coverage/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "node_modules/solidity-coverage/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, "peer": true, + "dependencies": { + "yallist": "^4.0.0" + }, "engines": { - "node": ">=4" + "node": ">=10" } }, - "node_modules/solidity-coverage/node_modules/js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "node_modules/solidity-coverage/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "peer": true, "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "lru-cache": "^6.0.0" }, "bin": { - "js-yaml": "bin/js-yaml.js" + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, - "node_modules/solidity-coverage/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "node_modules/solidity-coverage/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "peer": true, "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" + "has-flag": "^3.0.0" }, "engines": { - "node": ">=6" + "node": ">=4" } }, - "node_modules/solidity-coverage/node_modules/log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", + "node_modules/solidity-coverage/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "peer": true + }, + "node_modules/source-map": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", + "integrity": "sha512-CBdZ2oa/BHhS4xj5DlhjWNHcan57/5YuvfdLf17iVmIpd9KRm+DFLmC6nBNj+6Ua7Kt3TmOjDpQT1aTYOQtoUA==", "dev": true, + "optional": true, "peer": true, "dependencies": { - "chalk": "^2.4.2" + "amdefine": ">=0.0.4" }, "engines": { - "node": ">=8" + "node": ">=0.8.0" } }, - "node_modules/solidity-coverage/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "dev": true, - "peer": true, "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" } }, - "node_modules/solidity-coverage/node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, - "peer": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, "engines": { - "node": "*" + "node": ">=0.10.0" } }, - "node_modules/solidity-coverage/node_modules/mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "node_modules/sshpk": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", + "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", "dev": true, - "peer": true, "dependencies": { - "minimist": "^1.2.5" + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" }, "bin": { - "mkdirp": "bin/cmd.js" + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/solidity-coverage/node_modules/mocha": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.1.2.tgz", - "integrity": "sha512-o96kdRKMKI3E8U0bjnfqW4QMk12MwZ4mhdBTf+B5a1q9+aq2HRnj+3ZdJu0B/ZhJeK78MgYuv6L8d/rA5AeBJA==", + "node_modules/sshpk/node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", + "dev": true + }, + "node_modules/ssv-keys": { + "version": "1.0.4", + "resolved": "git+ssh://git@github.com/bloxapp/ssv-keys.git#cc9e5cdd4696a0e855fc4642c2868abd62d5141a", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" + "@types/figlet": "^1.5.4", + "@types/underscore": "^1.11.4", + "@types/yargs": "^17.0.12", + "argparse": "^2.0.1", + "assert": "^2.0.0", + "atob": "^2.1.2", + "bls-eth-wasm": "^1.0.4", + "bls-signatures": "^0.2.5", + "btoa": "^1.2.1", + "class-validator": "^0.13.2", + "colors": "^1.4.0", + "crypto": "^1.0.1", + "eth2-keystore-js": "^1.0.8", + "ethereumjs-util": "^7.1.5", + "ethereumjs-wallet": "^1.0.1", + "ethers": "^5.7.2", + "events": "^3.3.0", + "figlet": "^1.5.2", + "js-base64": "^3.7.2", + "jsencrypt": "3.2.1", + "minimist": "^1.2.6", + "moment": "^2.29.3", + "node-jsencrypt": "^1.0.0", + "prompts": "https://github.com/meshin-blox/prompts.git", + "scrypt-js": "^3.0.1", + "semver": "^7.5.1", + "stream": "^0.0.2", + "underscore": "^1.13.4", + "web3": "1.7.3", + "yargs": "^17.5.1" }, "bin": { - "_mocha": "bin/_mocha", - "mocha": "bin/mocha" + "ssv-keys": "dist/tsc/src/cli.js" }, "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mochajs" + "node": ">=12" } }, - "node_modules/solidity-coverage/node_modules/mocha/node_modules/supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", + "node_modules/ssv-keys/node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, - "peer": true, "dependencies": { - "has-flag": "^3.0.0" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" }, "engines": { - "node": ">=6" + "node": ">=12" } }, - "node_modules/solidity-coverage/node_modules/ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "node_modules/ssv-keys/node_modules/colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", "dev": true, - "peer": true + "engines": { + "node": ">=0.1.90" + } }, - "node_modules/solidity-coverage/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "node_modules/ssv-keys/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, - "peer": true, "dependencies": { - "p-try": "^2.0.0" + "yallist": "^4.0.0" }, "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=10" } }, - "node_modules/solidity-coverage/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "node_modules/ssv-keys/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, - "peer": true, "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/solidity-coverage/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true, - "peer": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/solidity-coverage/node_modules/readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", - "dev": true, - "peer": true, - "dependencies": { - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/solidity-coverage/node_modules/semver": { - "version": "7.5.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.2.tgz", - "integrity": "sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==", - "dev": true, - "peer": true, - "dependencies": { - "lru-cache": "^6.0.0" + "lru-cache": "^6.0.0" }, "bin": { "semver": "bin/semver.js" @@ -11004,216 +12104,39 @@ "node": ">=10" } }, - "node_modules/solidity-coverage/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "peer": true, - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/solidity-coverage/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "peer": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/solidity-coverage/node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/solidity-coverage/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "peer": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/solidity-coverage/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "peer": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/solidity-coverage/node_modules/wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "peer": true, - "dependencies": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/solidity-coverage/node_modules/y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true, - "peer": true - }, - "node_modules/solidity-coverage/node_modules/yallist": { + "node_modules/ssv-keys/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true, - "peer": true + "dev": true }, - "node_modules/solidity-coverage/node_modules/yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "node_modules/ssv-keys/node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, - "peer": true, "dependencies": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - } - }, - "node_modules/solidity-coverage/node_modules/yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "peer": true, - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "node_modules/solidity-coverage/node_modules/yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "dev": true, - "peer": true, - "dependencies": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/source-map": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", - "integrity": "sha512-CBdZ2oa/BHhS4xj5DlhjWNHcan57/5YuvfdLf17iVmIpd9KRm+DFLmC6nBNj+6Ua7Kt3TmOjDpQT1aTYOQtoUA==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "amdefine": ">=0.0.4" + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" }, "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/source-map-support/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" + "node": ">=12" } }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true - }, - "node_modules/sshpk": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", - "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", + "node_modules/ssv-keys/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true, - "peer": true, - "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" - }, "engines": { - "node": ">=0.10.0" + "node": ">=12" } }, - "node_modules/sshpk/node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", - "dev": true, - "peer": true - }, "node_modules/stacktrace-parser": { "version": "0.1.10", "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz", @@ -11244,23 +12167,22 @@ "node": ">= 0.8" } }, - "node_modules/stealthy-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", - "integrity": "sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g==", + "node_modules/stream": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stream/-/stream-0.0.2.tgz", + "integrity": "sha512-gCq3NDI2P35B2n6t76YJuOp7d6cN/C7Rt0577l91wllh0sY9ZBuw9KaSGqH/b0hzn3CWWJbpbW0W0WvQ1H/Q7g==", "dev": true, - "peer": true, - "engines": { - "node": ">=0.10.0" + "dependencies": { + "emitter-component": "^1.1.1" } }, - "node_modules/streamsearch": { + "node_modules/strict-uri-encode": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", - "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", + "integrity": "sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==", "dev": true, "engines": { - "node": ">=10.0.0" + "node": ">=0.10.0" } }, "node_modules/string_decoder": { @@ -11294,15 +12216,14 @@ } }, "node_modules/string.prototype.trim": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz", - "integrity": "sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", + "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" }, "engines": { "node": ">= 0.4" @@ -11312,30 +12233,28 @@ } }, "node_modules/string.prototype.trimend": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", - "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", + "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/string.prototype.trimstart": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", - "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", + "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -11411,56 +12330,270 @@ "node": ">=8" } }, - "node_modules/sync-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz", - "integrity": "sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==", + "node_modules/swarm-js": { + "version": "0.1.42", + "resolved": "https://registry.npmjs.org/swarm-js/-/swarm-js-0.1.42.tgz", + "integrity": "sha512-BV7c/dVlA3R6ya1lMlSSNPLYrntt0LUq4YMgy3iwpCIc6rZnS5W2wUoctarZ5pXlpKtxDDf9hNziEkcfrxdhqQ==", "dev": true, - "peer": true, "dependencies": { - "http-response-object": "^3.0.1", - "sync-rpc": "^1.2.1", - "then-request": "^6.0.0" - }, - "engines": { - "node": ">=8.0.0" + "bluebird": "^3.5.0", + "buffer": "^5.0.5", + "eth-lib": "^0.1.26", + "fs-extra": "^4.0.2", + "got": "^11.8.5", + "mime-types": "^2.1.16", + "mkdirp-promise": "^5.0.1", + "mock-fs": "^4.1.0", + "setimmediate": "^1.0.5", + "tar": "^4.0.2", + "xhr-request": "^1.0.1" } }, - "node_modules/sync-rpc": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.6.tgz", - "integrity": "sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==", + "node_modules/swarm-js/node_modules/@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", "dev": true, - "peer": true, - "dependencies": { - "get-port": "^3.1.0" + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" } }, - "node_modules/table": { - "version": "6.8.1", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", - "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", + "node_modules/swarm-js/node_modules/@szmarczak/http-timer": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", "dev": true, - "peer": true, "dependencies": { - "ajv": "^8.0.1", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" + "defer-to-connect": "^2.0.0" }, "engines": { - "node": ">=10.0.0" + "node": ">=10" } }, - "node_modules/table-layout": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-1.0.2.tgz", - "integrity": "sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A==", + "node_modules/swarm-js/node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", "dev": true, - "peer": true, - "dependencies": { - "array-back": "^4.0.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/swarm-js/node_modules/cacheable-request": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", + "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", + "dev": true, + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/swarm-js/node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dev": true, + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/swarm-js/node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/swarm-js/node_modules/fs-extra": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", + "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "node_modules/swarm-js/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/swarm-js/node_modules/got": { + "version": "11.8.6", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", + "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", + "dev": true, + "dependencies": { + "@sindresorhus/is": "^4.0.0", + "@szmarczak/http-timer": "^4.0.5", + "@types/cacheable-request": "^6.0.1", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^5.0.3", + "cacheable-request": "^7.0.2", + "decompress-response": "^6.0.0", + "http2-wrapper": "^1.0.0-beta.5.2", + "lowercase-keys": "^2.0.0", + "p-cancelable": "^2.0.0", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=10.19.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "node_modules/swarm-js/node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/swarm-js/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/swarm-js/node_modules/normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/swarm-js/node_modules/p-cancelable": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/swarm-js/node_modules/responselike": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", + "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", + "dev": true, + "dependencies": { + "lowercase-keys": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/sync-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz", + "integrity": "sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==", + "dev": true, + "peer": true, + "dependencies": { + "http-response-object": "^3.0.1", + "sync-rpc": "^1.2.1", + "then-request": "^6.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/sync-rpc": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.6.tgz", + "integrity": "sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==", + "dev": true, + "peer": true, + "dependencies": { + "get-port": "^3.1.0" + } + }, + "node_modules/table": { + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", + "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", + "dev": true, + "peer": true, + "dependencies": { + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/table-layout": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-1.0.2.tgz", + "integrity": "sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A==", + "dev": true, + "peer": true, + "dependencies": { + "array-back": "^4.0.1", "deep-extend": "~0.6.0", "typical": "^5.2.0", "wordwrapjs": "^4.0.0" @@ -11513,6 +12646,24 @@ "dev": true, "peer": true }, + "node_modules/tar": { + "version": "4.4.19", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.19.tgz", + "integrity": "sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==", + "dev": true, + "dependencies": { + "chownr": "^1.1.4", + "fs-minipass": "^1.2.7", + "minipass": "^2.9.0", + "minizlib": "^1.3.3", + "mkdirp": "^0.5.5", + "safe-buffer": "^5.2.1", + "yallist": "^3.1.1" + }, + "engines": { + "node": ">=4.5" + } + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -11549,12 +12700,36 @@ "dev": true, "peer": true }, + "node_modules/then-request/node_modules/form-data": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", + "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "dev": true, + "peer": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, "node_modules/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", "dev": true }, + "node_modules/timed-out": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", + "integrity": "sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -11567,6 +12742,15 @@ "node": ">=0.6.0" } }, + "node_modules/to-readable-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", + "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -11593,7 +12777,6 @@ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", "dev": true, - "peer": true, "dependencies": { "psl": "^1.1.28", "punycode": "^2.1.1" @@ -11713,76 +12896,260 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, - "node_modules/tsort": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/tsort/-/tsort-0.0.1.tgz", - "integrity": "sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw==", - "dev": true - }, - "node_modules/tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "node_modules/tslint": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz", + "integrity": "sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg==", + "deprecated": "TSLint has been deprecated in favor of ESLint. Please see https://github.com/palantir/tslint/issues/4534 for more information.", "dev": true, "dependencies": { - "tslib": "^1.8.1" + "@babel/code-frame": "^7.0.0", + "builtin-modules": "^1.1.1", + "chalk": "^2.3.0", + "commander": "^2.12.1", + "diff": "^4.0.1", + "glob": "^7.1.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.3", + "resolve": "^1.3.2", + "semver": "^5.3.0", + "tslib": "^1.13.0", + "tsutils": "^2.29.0" + }, + "bin": { + "tslint": "bin/tslint" }, "engines": { - "node": ">= 6" + "node": ">=4.8.0" }, "peerDependencies": { - "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + "typescript": ">=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >=3.0.0-dev || >= 3.1.0-dev || >= 3.2.0-dev || >= 4.0.0-dev" } }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "node_modules/tslint-config-prettier": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/tslint-config-prettier/-/tslint-config-prettier-1.18.0.tgz", + "integrity": "sha512-xPw9PgNPLG3iKRxmK7DWr+Ea/SzrvfHtjFt5LBl61gk2UBG/DB9kCXRjv+xyIU1rUtnayLeMUVJBcMX8Z17nDg==", "dev": true, - "peer": true, - "dependencies": { - "safe-buffer": "^5.0.1" + "bin": { + "tslint-config-prettier-check": "bin/check.js" }, "engines": { - "node": "*" + "node": ">=4.0.0" } }, - "node_modules/tweetnacl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==", - "dev": true - }, - "node_modules/tweetnacl-util": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", - "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==", - "dev": true - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "node_modules/tslint/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "dependencies": { - "prelude-ls": "^1.2.1" + "color-convert": "^1.9.0" }, "engines": { - "node": ">= 0.8.0" + "node": ">=4" } }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "node_modules/tslint/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, - "peer": true, - "engines": { - "node": ">=4" + "dependencies": { + "sprintf-js": "~1.0.2" } }, - "node_modules/type-fest": { - "version": "0.20.2", + "node_modules/tslint/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tslint/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/tslint/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/tslint/node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/tslint/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/tslint/node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tslint/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/tslint/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/tslint/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/tslint/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tslint/node_modules/tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "peerDependencies": { + "typescript": ">=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >= 3.0.0-dev || >= 3.1.0-dev" + } + }, + "node_modules/tsort": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/tsort/-/tsort-0.0.1.tgz", + "integrity": "sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw==", + "dev": true + }, + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==", + "dev": true + }, + "node_modules/tweetnacl-util": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", + "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==", + "dev": true + }, + "node_modules/type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", + "dev": true + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, @@ -11793,10 +13160,23 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/typechain": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/typechain/-/typechain-8.2.0.tgz", - "integrity": "sha512-tZqhqjxJ9xAS/Lh32jccTjMkpx7sTdUVVHAy5Bf0TIer5QFNYXotiX74oCvoVYjyxUKDK3MXHtMFzMyD3kE+jg==", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/typechain/-/typechain-8.3.2.tgz", + "integrity": "sha512-x/sQYr5w9K7yv3es7jo4KTX05CLxOf7TRWwoHlrjRh8H82G64g+k7VuWPJlgMo6qrjfCulOdfBjiaDtmhFYD/Q==", "dev": true, "peer": true, "dependencies": { @@ -11868,12 +13248,62 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, + "node_modules/typed-array-buffer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", + "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", + "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", + "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/typed-array-length": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "for-each": "^0.3.3", @@ -11890,6 +13320,15 @@ "dev": true, "peer": true }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, "node_modules/typescript": { "version": "4.9.5", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", @@ -11927,12 +13366,17 @@ "node": ">=0.8.0" } }, + "node_modules/ultron": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", + "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==", + "dev": true + }, "node_modules/unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "has-bigints": "^1.0.2", @@ -11943,13 +13387,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/underscore": { + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", + "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==", + "dev": true + }, "node_modules/undici": { - "version": "5.22.1", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.22.1.tgz", - "integrity": "sha512-Ji2IJhFXZY0x/0tVBXeQwgPlLWw13GVzpsWPQ3rV50IFMMof2I55PZZxtm4P6iNq+L5znYN9nSTAq0ZyE6lSJw==", + "version": "5.28.2", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.2.tgz", + "integrity": "sha512-wh1pHJHnUeQV5Xa8/kyQhO7WFa8M34l026L5P/+2TYiakvGy5Rdc8jWZVyG7ieht/0WgJLEd3kcU5gKx+6GC8w==", "dev": true, "dependencies": { - "busboy": "^1.6.0" + "@fastify/busboy": "^2.0.0" }, "engines": { "node": ">=14.0" @@ -11988,12 +13438,55 @@ "punycode": "^2.1.0" } }, + "node_modules/url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ==", + "dev": true, + "dependencies": { + "prepend-http": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/url-set-query": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/url-set-query/-/url-set-query-1.0.0.tgz", + "integrity": "sha512-3AChu4NiXquPfeckE5R5cGdiHCMWJx1dwCWOmWIL4KHAziJNOFIYJlpGFeKDvwLPHovZRCxK3cYlwzqI9Vp+Gg==", + "dev": true + }, + "node_modules/utf-8-validate": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz", + "integrity": "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, "node_modules/utf8": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==", + "dev": true + }, + "node_modules/util": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", + "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", "dev": true, - "peer": true + "dependencies": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "which-typed-array": "^1.1.2" + } }, "node_modules/util-deprecate": { "version": "1.0.2", @@ -12001,7 +13494,16 @@ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "dev": true }, - "node_modules/uuid": { + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", @@ -12016,6 +13518,30 @@ "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", "dev": true }, + "node_modules/validator": { + "version": "13.11.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz", + "integrity": "sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/varint": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz", + "integrity": "sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow==", + "dev": true + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", @@ -12024,2939 +13550,4231 @@ "engines": [ "node >=0.6.0" ], - "peer": true, "dependencies": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", "extsprintf": "^1.2.0" } }, - "node_modules/web3-utils": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.10.0.tgz", - "integrity": "sha512-kSaCM0uMcZTNUSmn5vMEhlo02RObGNRRCkdX0V9UTAU0+lrvn0HSaudyCo6CQzuXUsnuY2ERJGCGPfeWmv19Rg==", + "node_modules/web3": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3/-/web3-1.7.3.tgz", + "integrity": "sha512-UgBvQnKIXncGYzsiGacaiHtm0xzQ/JtGqcSO/ddzQHYxnNuwI72j1Pb4gskztLYihizV9qPNQYHMSCiBlStI9A==", "dev": true, - "peer": true, + "hasInstallScript": true, "dependencies": { - "bn.js": "^5.2.1", - "ethereum-bloom-filters": "^1.0.6", - "ethereumjs-util": "^7.1.0", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" + "web3-bzz": "1.7.3", + "web3-core": "1.7.3", + "web3-eth": "1.7.3", + "web3-eth-personal": "1.7.3", + "web3-net": "1.7.3", + "web3-shh": "1.7.3", + "web3-utils": "1.7.3" }, "engines": { "node": ">=8.0.0" } }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "dev": true - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "node_modules/web3-bzz": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.7.3.tgz", + "integrity": "sha512-y2i2IW0MfSqFc1JBhBSQ59Ts9xE30hhxSmLS13jLKWzie24/An5dnoGarp2rFAy20tevJu1zJVPYrEl14jiL5w==", "dev": true, + "hasInstallScript": true, "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" + "@types/node": "^12.12.6", + "got": "9.6.0", + "swarm-js": "^0.1.40" + }, + "engines": { + "node": ">=8.0.0" } }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "node_modules/web3-bzz/node_modules/@types/node": { + "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", + "dev": true + }, + "node_modules/web3-core": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.7.3.tgz", + "integrity": "sha512-4RNxueGyevD1XSjdHE57vz/YWRHybpcd3wfQS33fgMyHZBVLFDNwhn+4dX4BeofVlK/9/cmPAokLfBUStZMLdw==", "dev": true, "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" + "@types/bn.js": "^4.11.5", + "@types/node": "^12.12.6", + "bignumber.js": "^9.0.0", + "web3-core-helpers": "1.7.3", + "web3-core-method": "1.7.3", + "web3-core-requestmanager": "1.7.3", + "web3-utils": "1.7.3" }, "engines": { - "node": ">= 8" + "node": ">=8.0.0" } }, - "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "node_modules/web3-core-helpers": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.3.tgz", + "integrity": "sha512-qS2t6UKLhRV/6C7OFHtMeoHphkcA+CKUr2vfpxy4hubs3+Nj28K9pgiqFuvZiXmtEEwIAE2A28GBOC3RdcSuFg==", "dev": true, - "peer": true, "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" + "web3-eth-iban": "1.7.3", + "web3-utils": "1.7.3" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=8.0.0" } }, - "node_modules/which-module": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", - "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", - "dev": true, - "peer": true + "node_modules/web3-core-helpers/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true }, - "node_modules/which-typed-array": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", - "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", + "node_modules/web3-core-helpers/node_modules/web3-utils": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.3.tgz", + "integrity": "sha512-g6nQgvb/bUpVUIxJE+ezVN+rYwYmlFyMvMIRSuqpi1dk6ApDD00YNArrk7sPcZnjvxOJ76813Xs2vIN2rgh4lg==", "dev": true, - "peer": true, "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.10" + "bn.js": "^4.11.9", + "ethereum-bloom-filters": "^1.0.6", + "ethereumjs-util": "^7.1.0", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=8.0.0" } }, - "node_modules/wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "node_modules/web3-core-method": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.7.3.tgz", + "integrity": "sha512-SeF8YL/NVFbj/ddwLhJeS0io8y7wXaPYA2AVT0h2C2ESYkpvOtQmyw2Bc3aXxBmBErKcbOJjE2ABOKdUmLSmMA==", "dev": true, - "peer": true, "dependencies": { - "string-width": "^1.0.2 || 2" + "@ethersproject/transactions": "^5.0.0-beta.135", + "web3-core-helpers": "1.7.3", + "web3-core-promievent": "1.7.3", + "web3-core-subscriptions": "1.7.3", + "web3-utils": "1.7.3" + }, + "engines": { + "node": ">=8.0.0" } }, - "node_modules/wide-align/node_modules/ansi-regex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", - "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "node_modules/web3-core-method/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/web3-core-method/node_modules/web3-utils": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.3.tgz", + "integrity": "sha512-g6nQgvb/bUpVUIxJE+ezVN+rYwYmlFyMvMIRSuqpi1dk6ApDD00YNArrk7sPcZnjvxOJ76813Xs2vIN2rgh4lg==", "dev": true, - "peer": true, + "dependencies": { + "bn.js": "^4.11.9", + "ethereum-bloom-filters": "^1.0.6", + "ethereumjs-util": "^7.1.0", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, "engines": { - "node": ">=4" + "node": ">=8.0.0" } }, - "node_modules/wide-align/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "node_modules/web3-core-promievent": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.7.3.tgz", + "integrity": "sha512-+mcfNJLP8h2JqcL/UdMGdRVfTdm+bsoLzAFtLpazE4u9kU7yJUgMMAqnK59fKD3Zpke3DjaUJKwz1TyiGM5wig==", "dev": true, - "peer": true, + "dependencies": { + "eventemitter3": "4.0.4" + }, "engines": { - "node": ">=4" + "node": ">=8.0.0" } }, - "node_modules/wide-align/node_modules/string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "node_modules/web3-core-requestmanager": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.7.3.tgz", + "integrity": "sha512-bC+jeOjPbagZi2IuL1J5d44f3zfPcgX+GWYUpE9vicNkPUxFBWRG+olhMo7L+BIcD57cTmukDlnz+1xBULAjFg==", "dev": true, - "peer": true, "dependencies": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" + "util": "^0.12.0", + "web3-core-helpers": "1.7.3", + "web3-providers-http": "1.7.3", + "web3-providers-ipc": "1.7.3", + "web3-providers-ws": "1.7.3" }, "engines": { - "node": ">=4" + "node": ">=8.0.0" } }, - "node_modules/wide-align/node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "node_modules/web3-core-subscriptions": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.7.3.tgz", + "integrity": "sha512-/i1ZCLW3SDxEs5mu7HW8KL4Vq7x4/fDXY+yf/vPoDljlpvcLEOnI8y9r7om+0kYwvuTlM6DUHHafvW0221TyRQ==", "dev": true, - "peer": true, "dependencies": { - "ansi-regex": "^3.0.0" + "eventemitter3": "4.0.4", + "web3-core-helpers": "1.7.3" }, "engines": { - "node": ">=4" + "node": ">=8.0.0" } }, - "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "node_modules/web3-core/node_modules/@types/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", "dev": true, - "engines": { - "node": ">=0.10.0" + "dependencies": { + "@types/node": "*" } }, - "node_modules/wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "node_modules/web3-core/node_modules/@types/node": { + "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", + "dev": true + }, + "node_modules/web3-core/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/web3-core/node_modules/web3-utils": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.3.tgz", + "integrity": "sha512-g6nQgvb/bUpVUIxJE+ezVN+rYwYmlFyMvMIRSuqpi1dk6ApDD00YNArrk7sPcZnjvxOJ76813Xs2vIN2rgh4lg==", "dev": true, - "peer": true + "dependencies": { + "bn.js": "^4.11.9", + "ethereum-bloom-filters": "^1.0.6", + "ethereumjs-util": "^7.1.0", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } }, - "node_modules/wordwrapjs": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-4.0.1.tgz", - "integrity": "sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA==", + "node_modules/web3-eth": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.7.3.tgz", + "integrity": "sha512-BCIRMPwaMlTCbswXyGT6jj9chCh9RirbDFkPtvqozfQ73HGW7kP78TXXf9+Xdo1GjutQfxi/fQ9yPdxtDJEpDA==", "dev": true, - "peer": true, "dependencies": { - "reduce-flatten": "^2.0.0", - "typical": "^5.2.0" + "web3-core": "1.7.3", + "web3-core-helpers": "1.7.3", + "web3-core-method": "1.7.3", + "web3-core-subscriptions": "1.7.3", + "web3-eth-abi": "1.7.3", + "web3-eth-accounts": "1.7.3", + "web3-eth-contract": "1.7.3", + "web3-eth-ens": "1.7.3", + "web3-eth-iban": "1.7.3", + "web3-eth-personal": "1.7.3", + "web3-net": "1.7.3", + "web3-utils": "1.7.3" }, "engines": { "node": ">=8.0.0" } }, - "node_modules/wordwrapjs/node_modules/typical": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", - "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", + "node_modules/web3-eth-abi": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.7.3.tgz", + "integrity": "sha512-ZlD8DrJro0ocnbZViZpAoMX44x5aYAb73u2tMq557rMmpiluZNnhcCYF/NnVMy6UIkn7SF/qEA45GXA1ne6Tnw==", "dev": true, - "peer": true, + "dependencies": { + "@ethersproject/abi": "5.0.7", + "web3-utils": "1.7.3" + }, "engines": { - "node": ">=8" + "node": ">=8.0.0" } }, - "node_modules/workerpool": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", - "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", + "node_modules/web3-eth-abi/node_modules/@ethersproject/abi": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.7.tgz", + "integrity": "sha512-Cqktk+hSIckwP/W8O47Eef60VwmoSC/L3lY0+dIBhQPCNn9E4V7rwmm2aFrNRRDJfFlGuZ1khkQUOc3oBX+niw==", + "dev": true, + "dependencies": { + "@ethersproject/address": "^5.0.4", + "@ethersproject/bignumber": "^5.0.7", + "@ethersproject/bytes": "^5.0.4", + "@ethersproject/constants": "^5.0.4", + "@ethersproject/hash": "^5.0.4", + "@ethersproject/keccak256": "^5.0.3", + "@ethersproject/logger": "^5.0.5", + "@ethersproject/properties": "^5.0.3", + "@ethersproject/strings": "^5.0.4" + } + }, + "node_modules/web3-eth-abi/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", "dev": true }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "node_modules/web3-eth-abi/node_modules/web3-utils": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.3.tgz", + "integrity": "sha512-g6nQgvb/bUpVUIxJE+ezVN+rYwYmlFyMvMIRSuqpi1dk6ApDD00YNArrk7sPcZnjvxOJ76813Xs2vIN2rgh4lg==", "dev": true, "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "bn.js": "^4.11.9", + "ethereum-bloom-filters": "^1.0.6", + "ethereumjs-util": "^7.1.0", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" }, "engines": { - "node": ">=10" + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-accounts": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.7.3.tgz", + "integrity": "sha512-aDaWjW1oJeh0LeSGRVyEBiTe/UD2/cMY4dD6pQYa8dOhwgMtNQjxIQ7kacBBXe7ZKhjbIFZDhvXN4mjXZ82R2Q==", + "dev": true, + "dependencies": { + "@ethereumjs/common": "^2.5.0", + "@ethereumjs/tx": "^3.3.2", + "crypto-browserify": "3.12.0", + "eth-lib": "0.2.8", + "ethereumjs-util": "^7.0.10", + "scrypt-js": "^3.0.1", + "uuid": "3.3.2", + "web3-core": "1.7.3", + "web3-core-helpers": "1.7.3", + "web3-core-method": "1.7.3", + "web3-utils": "1.7.3" }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "engines": { + "node": ">=8.0.0" } }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "node_modules/web3-eth-accounts/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", "dev": true }, - "node_modules/write": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", + "node_modules/web3-eth-accounts/node_modules/eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", "dev": true, "dependencies": { - "mkdirp": "^0.5.1" - }, - "engines": { - "node": ">=4" + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" } }, - "node_modules/ws": { - "version": "7.4.6", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", - "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "node_modules/web3-eth-accounts/node_modules/uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", "dev": true, - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } + "bin": { + "uuid": "bin/uuid" } }, - "node_modules/xmlhttprequest": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", - "integrity": "sha512-58Im/U0mlVBLM38NdZjHyhuMtCqa61469k2YP/AaPbvCoV9aQGUpbJBj1QRm2ytRiVQBD/fsw7L2bJGDVQswBA==", + "node_modules/web3-eth-accounts/node_modules/web3-utils": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.3.tgz", + "integrity": "sha512-g6nQgvb/bUpVUIxJE+ezVN+rYwYmlFyMvMIRSuqpi1dk6ApDD00YNArrk7sPcZnjvxOJ76813Xs2vIN2rgh4lg==", "dev": true, - "peer": true, + "dependencies": { + "bn.js": "^4.11.9", + "ethereum-bloom-filters": "^1.0.6", + "ethereumjs-util": "^7.1.0", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, "engines": { - "node": ">=0.4.0" + "node": ">=8.0.0" } }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "node_modules/web3-eth-contract": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.7.3.tgz", + "integrity": "sha512-7mjkLxCNMWlQrlfM/MmNnlKRHwFk5XrZcbndoMt3KejcqDP6dPHi2PZLutEcw07n/Sk8OMpSamyF3QiGfmyRxw==", "dev": true, + "dependencies": { + "@types/bn.js": "^4.11.5", + "web3-core": "1.7.3", + "web3-core-helpers": "1.7.3", + "web3-core-method": "1.7.3", + "web3-core-promievent": "1.7.3", + "web3-core-subscriptions": "1.7.3", + "web3-eth-abi": "1.7.3", + "web3-utils": "1.7.3" + }, "engines": { - "node": ">=10" + "node": ">=8.0.0" } }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "node_modules/web3-eth-contract/node_modules/@types/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/web3-eth-contract/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", "dev": true }, - "node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "node_modules/web3-eth-contract/node_modules/web3-utils": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.3.tgz", + "integrity": "sha512-g6nQgvb/bUpVUIxJE+ezVN+rYwYmlFyMvMIRSuqpi1dk6ApDD00YNArrk7sPcZnjvxOJ76813Xs2vIN2rgh4lg==", "dev": true, "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" + "bn.js": "^4.11.9", + "ethereum-bloom-filters": "^1.0.6", + "ethereumjs-util": "^7.1.0", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" }, "engines": { - "node": ">=10" + "node": ">=8.0.0" } }, - "node_modules/yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "node_modules/web3-eth-ens": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.7.3.tgz", + "integrity": "sha512-q7+hFGHIc0mBI3LwgRVcLCQmp6GItsWgUtEZ5bjwdjOnJdbjYddm7PO9RDcTDQ6LIr7hqYaY4WTRnDHZ6BEt5Q==", "dev": true, + "dependencies": { + "content-hash": "^2.5.2", + "eth-ens-namehash": "2.0.8", + "web3-core": "1.7.3", + "web3-core-helpers": "1.7.3", + "web3-core-promievent": "1.7.3", + "web3-eth-abi": "1.7.3", + "web3-eth-contract": "1.7.3", + "web3-utils": "1.7.3" + }, "engines": { - "node": ">=10" + "node": ">=8.0.0" } }, - "node_modules/yargs-unparser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", - "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "node_modules/web3-eth-ens/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/web3-eth-ens/node_modules/web3-utils": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.3.tgz", + "integrity": "sha512-g6nQgvb/bUpVUIxJE+ezVN+rYwYmlFyMvMIRSuqpi1dk6ApDD00YNArrk7sPcZnjvxOJ76813Xs2vIN2rgh4lg==", "dev": true, "dependencies": { - "camelcase": "^6.0.0", - "decamelize": "^4.0.0", - "flat": "^5.0.2", - "is-plain-obj": "^2.1.0" + "bn.js": "^4.11.9", + "ethereum-bloom-filters": "^1.0.6", + "ethereumjs-util": "^7.1.0", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" }, "engines": { - "node": ">=10" + "node": ">=8.0.0" } }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "node_modules/web3-eth-iban": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.3.tgz", + "integrity": "sha512-1GPVWgajwhh7g53mmYDD1YxcftQniIixMiRfOqlnA1w0mFGrTbCoPeVaSQ3XtSf+rYehNJIZAUeDBnONVjXXmg==", "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "web3-utils": "1.7.3" + }, "engines": { - "node": ">=6" + "node": ">=8.0.0" } }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "node_modules/web3-eth-iban/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/web3-eth-iban/node_modules/web3-utils": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.3.tgz", + "integrity": "sha512-g6nQgvb/bUpVUIxJE+ezVN+rYwYmlFyMvMIRSuqpi1dk6ApDD00YNArrk7sPcZnjvxOJ76813Xs2vIN2rgh4lg==", "dev": true, - "engines": { - "node": ">=10" + "dependencies": { + "bn.js": "^4.11.9", + "ethereum-bloom-filters": "^1.0.6", + "ethereumjs-util": "^7.1.0", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">=8.0.0" } - } - }, - "dependencies": { - "@aws-crypto/sha256-js": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-1.2.2.tgz", - "integrity": "sha512-Nr1QJIbW/afYYGzYvrF70LtaHrIRtd4TNAglX8BvlfxJLZ45SAmueIKYl5tWoNBPzp65ymXGFK0Bb1vZUpuc9g==", + }, + "node_modules/web3-eth-personal": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.7.3.tgz", + "integrity": "sha512-iTLz2OYzEsJj2qGE4iXC1Gw+KZN924fTAl0ESBFs2VmRhvVaM7GFqZz/wx7/XESl3GVxGxlRje3gNK0oGIoYYQ==", "dev": true, - "requires": { - "@aws-crypto/util": "^1.2.2", - "@aws-sdk/types": "^3.1.0", - "tslib": "^1.11.1" + "dependencies": { + "@types/node": "^12.12.6", + "web3-core": "1.7.3", + "web3-core-helpers": "1.7.3", + "web3-core-method": "1.7.3", + "web3-net": "1.7.3", + "web3-utils": "1.7.3" + }, + "engines": { + "node": ">=8.0.0" } }, - "@aws-crypto/util": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-1.2.2.tgz", - "integrity": "sha512-H8PjG5WJ4wz0UXAFXeJjWCW1vkvIJ3qUUD+rGRwJ2/hj+xT58Qle2MTql/2MGzkU+1JLAFuR6aJpLAjHwhmwwg==", + "node_modules/web3-eth-personal/node_modules/@types/node": { + "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", + "dev": true + }, + "node_modules/web3-eth-personal/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/web3-eth-personal/node_modules/web3-utils": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.3.tgz", + "integrity": "sha512-g6nQgvb/bUpVUIxJE+ezVN+rYwYmlFyMvMIRSuqpi1dk6ApDD00YNArrk7sPcZnjvxOJ76813Xs2vIN2rgh4lg==", "dev": true, - "requires": { - "@aws-sdk/types": "^3.1.0", - "@aws-sdk/util-utf8-browser": "^3.0.0", - "tslib": "^1.11.1" + "dependencies": { + "bn.js": "^4.11.9", + "ethereum-bloom-filters": "^1.0.6", + "ethereumjs-util": "^7.1.0", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" } }, - "@aws-sdk/types": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.347.0.tgz", - "integrity": "sha512-GkCMy79mdjU9OTIe5KT58fI/6uqdf8UmMdWqVHmFJ+UpEzOci7L/uw4sOXWo7xpPzLs6cJ7s5ouGZW4GRPmHFA==", + "node_modules/web3-eth/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/web3-eth/node_modules/web3-utils": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.3.tgz", + "integrity": "sha512-g6nQgvb/bUpVUIxJE+ezVN+rYwYmlFyMvMIRSuqpi1dk6ApDD00YNArrk7sPcZnjvxOJ76813Xs2vIN2rgh4lg==", "dev": true, - "requires": { - "tslib": "^2.5.0" - }, "dependencies": { - "tslib": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", - "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==", - "dev": true - } + "bn.js": "^4.11.9", + "ethereum-bloom-filters": "^1.0.6", + "ethereumjs-util": "^7.1.0", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" } }, - "@aws-sdk/util-utf8-browser": { - "version": "3.259.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.259.0.tgz", - "integrity": "sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw==", + "node_modules/web3-net": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.7.3.tgz", + "integrity": "sha512-zAByK0Qrr71k9XW0Adtn+EOuhS9bt77vhBO6epAeQ2/VKl8rCGLAwrl3GbeEl7kWa8s/su72cjI5OetG7cYR0g==", "dev": true, - "requires": { - "tslib": "^2.3.1" + "dependencies": { + "web3-core": "1.7.3", + "web3-core-method": "1.7.3", + "web3-utils": "1.7.3" }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-net/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/web3-net/node_modules/web3-utils": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.3.tgz", + "integrity": "sha512-g6nQgvb/bUpVUIxJE+ezVN+rYwYmlFyMvMIRSuqpi1dk6ApDD00YNArrk7sPcZnjvxOJ76813Xs2vIN2rgh4lg==", + "dev": true, "dependencies": { - "tslib": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", - "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==", - "dev": true - } + "bn.js": "^4.11.9", + "ethereum-bloom-filters": "^1.0.6", + "ethereumjs-util": "^7.1.0", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" } }, - "@babel/code-frame": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz", - "integrity": "sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==", + "node_modules/web3-providers-http": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.7.3.tgz", + "integrity": "sha512-TQJfMsDQ5Uq9zGMYlu7azx1L7EvxW+Llks3MaWn3cazzr5tnrDbGh6V17x6LN4t8tFDHWx0rYKr3mDPqyTjOZw==", "dev": true, - "requires": { - "@babel/highlight": "^7.22.5" + "dependencies": { + "web3-core-helpers": "1.7.3", + "xhr2-cookies": "1.1.0" + }, + "engines": { + "node": ">=8.0.0" } }, - "@babel/helper-validator-identifier": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", - "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", - "dev": true + "node_modules/web3-providers-ipc": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.7.3.tgz", + "integrity": "sha512-Z4EGdLKzz6I1Bw+VcSyqVN4EJiT2uAro48Am1eRvxUi4vktGoZtge1ixiyfrRIVb6nPe7KnTFl30eQBtMqS0zA==", + "dev": true, + "dependencies": { + "oboe": "2.1.5", + "web3-core-helpers": "1.7.3" + }, + "engines": { + "node": ">=8.0.0" + } }, - "@babel/highlight": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.5.tgz", - "integrity": "sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==", + "node_modules/web3-providers-ws": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.7.3.tgz", + "integrity": "sha512-PpykGbkkkKtxPgv7U4ny4UhnkqSZDfLgBEvFTXuXLAngbX/qdgfYkhIuz3MiGplfL7Yh93SQw3xDjImXmn2Rgw==", "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.22.5", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" + "dependencies": { + "eventemitter3": "4.0.4", + "web3-core-helpers": "1.7.3", + "websocket": "^1.0.32" }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-shh": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.7.3.tgz", + "integrity": "sha512-bQTSKkyG7GkuULdZInJ0osHjnmkHij9tAySibpev1XjYdjLiQnd0J9YGF4HjvxoG3glNROpuCyTaRLrsLwaZuw==", + "dev": true, + "hasInstallScript": true, "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } + "web3-core": "1.7.3", + "web3-core-method": "1.7.3", + "web3-core-subscriptions": "1.7.3", + "web3-net": "1.7.3" + }, + "engines": { + "node": ">=8.0.0" } }, - "@chainsafe/as-sha256": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@chainsafe/as-sha256/-/as-sha256-0.3.1.tgz", - "integrity": "sha512-hldFFYuf49ed7DAakWVXSJODuq3pzJEguD8tQ7h+sGkM18vja+OFoJI9krnGmgzyuZC2ETX0NOIcCTy31v2Mtg==", - "dev": true - }, - "@chainsafe/persistent-merkle-tree": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@chainsafe/persistent-merkle-tree/-/persistent-merkle-tree-0.4.2.tgz", - "integrity": "sha512-lLO3ihKPngXLTus/L7WHKaw9PnNJWizlOF1H9NNzHP6Xvh82vzg9F2bzkXhYIFshMZ2gTCEz8tq6STe7r5NDfQ==", + "node_modules/web3-utils": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.10.3.tgz", + "integrity": "sha512-OqcUrEE16fDBbGoQtZXWdavsPzbGIDc5v3VrRTZ0XrIpefC/viZ1ZU9bGEemazyS0catk/3rkOOxpzTfY+XsyQ==", "dev": true, - "requires": { - "@chainsafe/as-sha256": "^0.3.1" + "peer": true, + "dependencies": { + "@ethereumjs/util": "^8.1.0", + "bn.js": "^5.2.1", + "ethereum-bloom-filters": "^1.0.6", + "ethereum-cryptography": "^2.1.2", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" } }, - "@chainsafe/ssz": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/@chainsafe/ssz/-/ssz-0.9.4.tgz", - "integrity": "sha512-77Qtg2N1ayqs4Bg/wvnWfg5Bta7iy7IRh8XqXh7oNMeP2HBbBwx8m6yTpA8p0EHItWPEBkgZd5S5/LSlp3GXuQ==", + "node_modules/web3-utils/node_modules/ethereum-cryptography": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.1.2.tgz", + "integrity": "sha512-Z5Ba0T0ImZ8fqXrJbpHcbpAvIswRte2wGNR/KePnu8GbbvgJ47lMxT/ZZPG6i9Jaht4azPDop4HaM00J0J59ug==", "dev": true, - "requires": { - "@chainsafe/as-sha256": "^0.3.1", - "@chainsafe/persistent-merkle-tree": "^0.4.2", - "case": "^1.6.3" + "peer": true, + "dependencies": { + "@noble/curves": "1.1.0", + "@noble/hashes": "1.3.1", + "@scure/bip32": "1.3.1", + "@scure/bip39": "1.2.1" } }, - "@colors/colors": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", - "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", - "dev": true, - "optional": true + "node_modules/web3/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true }, - "@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "node_modules/web3/node_modules/web3-utils": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.3.tgz", + "integrity": "sha512-g6nQgvb/bUpVUIxJE+ezVN+rYwYmlFyMvMIRSuqpi1dk6ApDD00YNArrk7sPcZnjvxOJ76813Xs2vIN2rgh4lg==", "dev": true, - "requires": { - "@jridgewell/trace-mapping": "0.3.9" + "dependencies": { + "bn.js": "^4.11.9", + "ethereum-bloom-filters": "^1.0.6", + "ethereumjs-util": "^7.1.0", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" } }, - "@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true + }, + "node_modules/websocket": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.34.tgz", + "integrity": "sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ==", "dev": true, - "requires": { - "eslint-visitor-keys": "^3.3.0" + "dependencies": { + "bufferutil": "^4.0.1", + "debug": "^2.2.0", + "es5-ext": "^0.10.50", + "typedarray-to-buffer": "^3.1.5", + "utf-8-validate": "^5.0.2", + "yaeti": "^0.0.6" + }, + "engines": { + "node": ">=4.0.0" } }, - "@eslint-community/regexpp": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz", - "integrity": "sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==", - "dev": true - }, - "@eslint/eslintrc": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz", - "integrity": "sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==", + "node_modules/websocket/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, - "requires": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.5.2", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" + "dependencies": { + "ms": "2.0.0" } }, - "@eslint/js": { - "version": "8.43.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.43.0.tgz", - "integrity": "sha512-s2UHCoiXfxMvmfzqoN+vrQ84ahUSYde9qNO1MdxmoEhyHWsfmwOpFlwYV+ePJEVc7gFnATGUi376WowX1N7tFg==", + "node_modules/websocket/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true }, - "@ethersproject/abi": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz", - "integrity": "sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==", + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", "dev": true, - "requires": { - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" } }, - "@ethersproject/abstract-provider": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz", - "integrity": "sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==", + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, - "requires": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/networks": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/web": "^5.7.0" + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" } }, - "@ethersproject/abstract-signer": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz", - "integrity": "sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==", + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", "dev": true, - "requires": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0" + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "@ethersproject/address": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz", - "integrity": "sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==", + "node_modules/which-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz", + "integrity": "sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==", "dev": true, - "requires": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/rlp": "^5.7.0" + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.4", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "@ethersproject/base64": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.7.0.tgz", - "integrity": "sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==", + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, - "requires": { - "@ethersproject/bytes": "^5.7.0" + "engines": { + "node": ">=0.10.0" } }, - "@ethersproject/basex": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.7.0.tgz", - "integrity": "sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/properties": "^5.7.0" - } - }, - "@ethersproject/bignumber": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.7.0.tgz", - "integrity": "sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==", + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", "dev": true, - "requires": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "bn.js": "^5.2.1" - } + "peer": true }, - "@ethersproject/bytes": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz", - "integrity": "sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==", + "node_modules/wordwrapjs": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-4.0.1.tgz", + "integrity": "sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA==", "dev": true, - "requires": { - "@ethersproject/logger": "^5.7.0" + "peer": true, + "dependencies": { + "reduce-flatten": "^2.0.0", + "typical": "^5.2.0" + }, + "engines": { + "node": ">=8.0.0" } }, - "@ethersproject/constants": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.7.0.tgz", - "integrity": "sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==", + "node_modules/wordwrapjs/node_modules/typical": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", + "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", "dev": true, - "requires": { - "@ethersproject/bignumber": "^5.7.0" + "peer": true, + "engines": { + "node": ">=8" } }, - "@ethersproject/contracts": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.7.0.tgz", - "integrity": "sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg==", - "dev": true, - "requires": { - "@ethersproject/abi": "^5.7.0", - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/transactions": "^5.7.0" - } + "node_modules/workerpool": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", + "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", + "dev": true }, - "@ethersproject/hash": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz", - "integrity": "sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==", + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, - "requires": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/base64": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "@ethersproject/hdnode": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.7.0.tgz", - "integrity": "sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==", + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/write": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", "dev": true, - "requires": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/basex": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/pbkdf2": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/wordlists": "^5.7.0" + "dependencies": { + "mkdirp": "^0.5.1" + }, + "engines": { + "node": ">=4" } }, - "@ethersproject/json-wallets": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz", - "integrity": "sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g==", + "node_modules/ws": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", "dev": true, - "requires": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hdnode": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/pbkdf2": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "aes-js": "3.0.0", - "scrypt-js": "3.0.1" + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } } }, - "@ethersproject/keccak256": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.7.0.tgz", - "integrity": "sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==", + "node_modules/xhr": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.6.0.tgz", + "integrity": "sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==", "dev": true, - "requires": { - "@ethersproject/bytes": "^5.7.0", - "js-sha3": "0.8.0" + "dependencies": { + "global": "~4.4.0", + "is-function": "^1.0.1", + "parse-headers": "^2.0.0", + "xtend": "^4.0.0" } }, - "@ethersproject/logger": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.7.0.tgz", - "integrity": "sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==", - "dev": true - }, - "@ethersproject/networks": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.1.tgz", - "integrity": "sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==", + "node_modules/xhr-request": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/xhr-request/-/xhr-request-1.1.0.tgz", + "integrity": "sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA==", "dev": true, - "requires": { - "@ethersproject/logger": "^5.7.0" + "dependencies": { + "buffer-to-arraybuffer": "^0.0.5", + "object-assign": "^4.1.1", + "query-string": "^5.0.1", + "simple-get": "^2.7.0", + "timed-out": "^4.0.1", + "url-set-query": "^1.0.0", + "xhr": "^2.0.4" } }, - "@ethersproject/pbkdf2": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz", - "integrity": "sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw==", + "node_modules/xhr-request-promise": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/xhr-request-promise/-/xhr-request-promise-0.1.3.tgz", + "integrity": "sha512-YUBytBsuwgitWtdRzXDDkWAXzhdGB8bYm0sSzMPZT7Z2MBjMSTHFsyCT1yCRATY+XC69DUrQraRAEgcoCRaIPg==", "dev": true, - "requires": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/sha2": "^5.7.0" + "dependencies": { + "xhr-request": "^1.1.0" } }, - "@ethersproject/properties": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.7.0.tgz", - "integrity": "sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==", + "node_modules/xhr2-cookies": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz", + "integrity": "sha512-hjXUA6q+jl/bd8ADHcVfFsSPIf+tyLIjuO9TwJC9WI6JP2zKcS7C+p56I9kCLLsaCiNT035iYvEUUzdEFj/8+g==", "dev": true, - "requires": { - "@ethersproject/logger": "^5.7.0" + "dependencies": { + "cookiejar": "^2.1.1" } }, - "@ethersproject/providers": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.2.tgz", - "integrity": "sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg==", + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", "dev": true, - "requires": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/base64": "^5.7.0", - "@ethersproject/basex": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/networks": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/rlp": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/web": "^5.7.0", - "bech32": "1.1.4", - "ws": "7.4.6" + "engines": { + "node": ">=0.4" } }, - "@ethersproject/random": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.7.0.tgz", - "integrity": "sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ==", + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true, - "requires": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0" + "engines": { + "node": ">=10" } }, - "@ethersproject/rlp": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.7.0.tgz", - "integrity": "sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==", + "node_modules/yaeti": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz", + "integrity": "sha512-MvQa//+KcZCUkBTIC9blM+CU9J2GzuTytsOUwf2lidtvkx/6gnEp1QvJv34t9vdjhFmha/mUiNDbN0D0mJWdug==", "dev": true, - "requires": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0" + "engines": { + "node": ">=0.10.32" } }, - "@ethersproject/sha2": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.7.0.tgz", - "integrity": "sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "hash.js": "1.1.7" - } - }, - "@ethersproject/signing-key": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.7.0.tgz", - "integrity": "sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "bn.js": "^5.2.1", - "elliptic": "6.5.4", - "hash.js": "1.1.7" - } - }, - "@ethersproject/solidity": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.7.0.tgz", - "integrity": "sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA==", - "dev": true, - "requires": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true }, - "@ethersproject/strings": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.7.0.tgz", - "integrity": "sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==", + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, - "requires": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0" + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" } }, - "@ethersproject/transactions": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.7.0.tgz", - "integrity": "sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==", + "node_modules/yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", "dev": true, - "requires": { - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/rlp": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0" + "engines": { + "node": ">=10" } }, - "@ethersproject/units": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.7.0.tgz", - "integrity": "sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg==", + "node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", "dev": true, - "requires": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0" + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" } }, - "@ethersproject/wallet": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.7.0.tgz", - "integrity": "sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA==", + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "dev": true, - "requires": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/hdnode": "^5.7.0", - "@ethersproject/json-wallets": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/wordlists": "^5.7.0" + "engines": { + "node": ">=6" } }, - "@ethersproject/web": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.1.tgz", - "integrity": "sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==", + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, - "requires": { - "@ethersproject/base64": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } + } + }, + "dependencies": { + "@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true }, - "@ethersproject/wordlists": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.7.0.tgz", - "integrity": "sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA==", + "@aws-crypto/sha256-js": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-1.2.2.tgz", + "integrity": "sha512-Nr1QJIbW/afYYGzYvrF70LtaHrIRtd4TNAglX8BvlfxJLZ45SAmueIKYl5tWoNBPzp65ymXGFK0Bb1vZUpuc9g==", "dev": true, "requires": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" + "@aws-crypto/util": "^1.2.2", + "@aws-sdk/types": "^3.1.0", + "tslib": "^1.11.1" } }, - "@humanwhocodes/config-array": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", - "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==", + "@aws-crypto/util": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-1.2.2.tgz", + "integrity": "sha512-H8PjG5WJ4wz0UXAFXeJjWCW1vkvIJ3qUUD+rGRwJ2/hj+xT58Qle2MTql/2MGzkU+1JLAFuR6aJpLAjHwhmwwg==", "dev": true, "requires": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.5" + "@aws-sdk/types": "^3.1.0", + "@aws-sdk/util-utf8-browser": "^3.0.0", + "tslib": "^1.11.1" } }, - "@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true - }, - "@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true - }, - "@jridgewell/resolve-uri": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", - "dev": true - }, - "@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true - }, - "@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "@aws-sdk/types": { + "version": "3.465.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.465.0.tgz", + "integrity": "sha512-Clqu2eD50OOzwSftGpzJrIOGev/7VJhJpc02SeS4cqFgI9EVd+rnFKS/Ux0kcwjLQBMiPcCLtql3KAHApFHAIA==", "dev": true, "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@smithy/types": "^2.5.0", + "tslib": "^2.5.0" + }, + "dependencies": { + "tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "dev": true + } } }, - "@kwsites/file-exists": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz", - "integrity": "sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==", + "@aws-sdk/util-utf8-browser": { + "version": "3.259.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.259.0.tgz", + "integrity": "sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw==", "dev": true, "requires": { - "debug": "^4.1.1" + "tslib": "^2.3.1" + }, + "dependencies": { + "tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "dev": true + } } }, - "@kwsites/promise-deferred": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz", - "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==", - "dev": true - }, - "@metamask/eth-sig-util": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz", - "integrity": "sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ==", + "@babel/code-frame": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", "dev": true, "requires": { - "ethereumjs-abi": "^0.6.8", - "ethereumjs-util": "^6.2.1", - "ethjs-util": "^0.1.6", - "tweetnacl": "^1.0.3", - "tweetnacl-util": "^0.15.1" + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" }, "dependencies": { - "@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { - "@types/node": "*" + "color-convert": "^1.9.0" } }, - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, - "ethereumjs-util": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", - "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { - "@types/bn.js": "^4.11.3", - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "0.1.6", - "rlp": "^2.2.3" + "has-flag": "^3.0.0" } } } }, - "@noble/hashes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.2.0.tgz", - "integrity": "sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==", - "dev": true - }, - "@noble/secp256k1": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-1.7.1.tgz", - "integrity": "sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw==", + "@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "dev": true }, - "@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "@babel/highlight": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", "dev": true, "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } } }, - "@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "@chainsafe/as-sha256": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@chainsafe/as-sha256/-/as-sha256-0.3.1.tgz", + "integrity": "sha512-hldFFYuf49ed7DAakWVXSJODuq3pzJEguD8tQ7h+sGkM18vja+OFoJI9krnGmgzyuZC2ETX0NOIcCTy31v2Mtg==", "dev": true }, - "@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "@chainsafe/persistent-merkle-tree": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@chainsafe/persistent-merkle-tree/-/persistent-merkle-tree-0.4.2.tgz", + "integrity": "sha512-lLO3ihKPngXLTus/L7WHKaw9PnNJWizlOF1H9NNzHP6Xvh82vzg9F2bzkXhYIFshMZ2gTCEz8tq6STe7r5NDfQ==", "dev": true, "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" + "@chainsafe/as-sha256": "^0.3.1" } }, - "@nomicfoundation/ethereumjs-block": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-block/-/ethereumjs-block-5.0.1.tgz", - "integrity": "sha512-u1Yioemi6Ckj3xspygu/SfFvm8vZEO8/Yx5a1QLzi6nVU0jz3Pg2OmHKJ5w+D9Ogk1vhwRiqEBAqcb0GVhCyHw==", + "@chainsafe/ssz": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/@chainsafe/ssz/-/ssz-0.9.4.tgz", + "integrity": "sha512-77Qtg2N1ayqs4Bg/wvnWfg5Bta7iy7IRh8XqXh7oNMeP2HBbBwx8m6yTpA8p0EHItWPEBkgZd5S5/LSlp3GXuQ==", "dev": true, "requires": { - "@nomicfoundation/ethereumjs-common": "4.0.1", - "@nomicfoundation/ethereumjs-rlp": "5.0.1", - "@nomicfoundation/ethereumjs-trie": "6.0.1", - "@nomicfoundation/ethereumjs-tx": "5.0.1", - "@nomicfoundation/ethereumjs-util": "9.0.1", - "ethereum-cryptography": "0.1.3", - "ethers": "^5.7.1" + "@chainsafe/as-sha256": "^0.3.1", + "@chainsafe/persistent-merkle-tree": "^0.4.2", + "case": "^1.6.3" } }, - "@nomicfoundation/ethereumjs-blockchain": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-blockchain/-/ethereumjs-blockchain-7.0.1.tgz", - "integrity": "sha512-NhzndlGg829XXbqJEYrF1VeZhAwSPgsK/OB7TVrdzft3y918hW5KNd7gIZ85sn6peDZOdjBsAXIpXZ38oBYE5A==", + "@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", "dev": true, - "requires": { - "@nomicfoundation/ethereumjs-block": "5.0.1", - "@nomicfoundation/ethereumjs-common": "4.0.1", - "@nomicfoundation/ethereumjs-ethash": "3.0.1", - "@nomicfoundation/ethereumjs-rlp": "5.0.1", - "@nomicfoundation/ethereumjs-trie": "6.0.1", - "@nomicfoundation/ethereumjs-tx": "5.0.1", - "@nomicfoundation/ethereumjs-util": "9.0.1", - "abstract-level": "^1.0.3", - "debug": "^4.3.3", - "ethereum-cryptography": "0.1.3", - "level": "^8.0.0", - "lru-cache": "^5.1.1", - "memory-level": "^1.0.0" - } + "optional": true }, - "@nomicfoundation/ethereumjs-common": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-4.0.1.tgz", - "integrity": "sha512-OBErlkfp54GpeiE06brBW/TTbtbuBJV5YI5Nz/aB2evTDo+KawyEzPjBlSr84z/8MFfj8wS2wxzQX1o32cev5g==", + "@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", "dev": true, "requires": { - "@nomicfoundation/ethereumjs-util": "9.0.1", - "crc-32": "^1.2.0" + "@jridgewell/trace-mapping": "0.3.9" } }, - "@nomicfoundation/ethereumjs-ethash": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-ethash/-/ethereumjs-ethash-3.0.1.tgz", - "integrity": "sha512-KDjGIB5igzWOp8Ik5I6QiRH5DH+XgILlplsHR7TEuWANZA759G6krQ6o8bvj+tRUz08YygMQu/sGd9mJ1DYT8w==", + "@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", "dev": true, "requires": { - "@nomicfoundation/ethereumjs-block": "5.0.1", - "@nomicfoundation/ethereumjs-rlp": "5.0.1", - "@nomicfoundation/ethereumjs-util": "9.0.1", - "abstract-level": "^1.0.3", - "bigint-crypto-utils": "^3.0.23", - "ethereum-cryptography": "0.1.3" + "eslint-visitor-keys": "^3.3.0" } }, - "@nomicfoundation/ethereumjs-evm": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-evm/-/ethereumjs-evm-2.0.1.tgz", - "integrity": "sha512-oL8vJcnk0Bx/onl+TgQOQ1t/534GKFaEG17fZmwtPFeH8S5soiBYPCLUrvANOl4sCp9elYxIMzIiTtMtNNN8EQ==", + "@eslint-community/regexpp": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "dev": true + }, + "@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, "requires": { - "@ethersproject/providers": "^5.7.1", - "@nomicfoundation/ethereumjs-common": "4.0.1", - "@nomicfoundation/ethereumjs-tx": "5.0.1", - "@nomicfoundation/ethereumjs-util": "9.0.1", - "debug": "^4.3.3", - "ethereum-cryptography": "0.1.3", - "mcl-wasm": "^0.7.1", - "rustbn.js": "~0.2.0" + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" } }, - "@nomicfoundation/ethereumjs-rlp": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-5.0.1.tgz", - "integrity": "sha512-xtxrMGa8kP4zF5ApBQBtjlSbN5E2HI8m8FYgVSYAnO6ssUoY5pVPGy2H8+xdf/bmMa22Ce8nWMH3aEW8CcqMeQ==", + "@eslint/js": { + "version": "8.55.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.55.0.tgz", + "integrity": "sha512-qQfo2mxH5yVom1kacMtZZJFVdW+E70mqHMJvVg6WTLo+VBuQJ4TojZlfWBjK0ve5BdEeNAVxOsl/nvNMpJOaJA==", "dev": true }, - "@nomicfoundation/ethereumjs-statemanager": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-statemanager/-/ethereumjs-statemanager-2.0.1.tgz", - "integrity": "sha512-B5ApMOnlruVOR7gisBaYwFX+L/AP7i/2oAahatssjPIBVDF6wTX1K7Qpa39E/nzsH8iYuL3krkYeUFIdO3EMUQ==", + "@ethereumjs/common": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-2.6.5.tgz", + "integrity": "sha512-lRyVQOeCDaIVtgfbowla32pzeDv2Obr8oR8Put5RdUBNRGr1VGPGQNGP6elWIpgK3YdpzqTOh4GyUGOureVeeA==", "dev": true, "requires": { - "@nomicfoundation/ethereumjs-common": "4.0.1", - "@nomicfoundation/ethereumjs-rlp": "5.0.1", - "debug": "^4.3.3", - "ethereum-cryptography": "0.1.3", - "ethers": "^5.7.1", - "js-sdsl": "^4.1.4" + "crc-32": "^1.2.0", + "ethereumjs-util": "^7.1.5" } }, - "@nomicfoundation/ethereumjs-trie": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-trie/-/ethereumjs-trie-6.0.1.tgz", - "integrity": "sha512-A64It/IMpDVODzCgxDgAAla8jNjNtsoQZIzZUfIV5AY6Coi4nvn7+VReBn5itlxMiL2yaTlQr9TRWp3CSI6VoA==", + "@ethereumjs/rlp": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@ethereumjs/rlp/-/rlp-4.0.1.tgz", + "integrity": "sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==", "dev": true, - "requires": { - "@nomicfoundation/ethereumjs-rlp": "5.0.1", - "@nomicfoundation/ethereumjs-util": "9.0.1", - "@types/readable-stream": "^2.3.13", - "ethereum-cryptography": "0.1.3", - "readable-stream": "^3.6.0" - } + "peer": true }, - "@nomicfoundation/ethereumjs-tx": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-5.0.1.tgz", - "integrity": "sha512-0HwxUF2u2hrsIM1fsasjXvlbDOq1ZHFV2dd1yGq8CA+MEYhaxZr8OTScpVkkxqMwBcc5y83FyPl0J9MZn3kY0w==", + "@ethereumjs/tx": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-3.5.2.tgz", + "integrity": "sha512-gQDNJWKrSDGu2w7w0PzVXVBNMzb7wwdDOmOqczmhNjqFxFuIbhVJDwiGEnxFNC2/b8ifcZzY7MLcluizohRzNw==", "dev": true, "requires": { - "@chainsafe/ssz": "^0.9.2", - "@ethersproject/providers": "^5.7.2", - "@nomicfoundation/ethereumjs-common": "4.0.1", - "@nomicfoundation/ethereumjs-rlp": "5.0.1", - "@nomicfoundation/ethereumjs-util": "9.0.1", - "ethereum-cryptography": "0.1.3" + "@ethereumjs/common": "^2.6.4", + "ethereumjs-util": "^7.1.5" } }, - "@nomicfoundation/ethereumjs-util": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-9.0.1.tgz", - "integrity": "sha512-TwbhOWQ8QoSCFhV/DDfSmyfFIHjPjFBj957219+V3jTZYZ2rf9PmDtNOeZWAE3p3vlp8xb02XGpd0v6nTUPbsA==", + "@ethereumjs/util": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@ethereumjs/util/-/util-8.1.0.tgz", + "integrity": "sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA==", "dev": true, + "peer": true, "requires": { - "@chainsafe/ssz": "^0.10.0", - "@nomicfoundation/ethereumjs-rlp": "5.0.1", - "ethereum-cryptography": "0.1.3" + "@ethereumjs/rlp": "^4.0.1", + "ethereum-cryptography": "^2.0.0", + "micro-ftch": "^0.3.1" }, "dependencies": { - "@chainsafe/persistent-merkle-tree": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@chainsafe/persistent-merkle-tree/-/persistent-merkle-tree-0.5.0.tgz", - "integrity": "sha512-l0V1b5clxA3iwQLXP40zYjyZYospQLZXzBVIhhr9kDg/1qHZfzzHw0jj4VPBijfYCArZDlPkRi1wZaV2POKeuw==", + "ethereum-cryptography": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.1.2.tgz", + "integrity": "sha512-Z5Ba0T0ImZ8fqXrJbpHcbpAvIswRte2wGNR/KePnu8GbbvgJ47lMxT/ZZPG6i9Jaht4azPDop4HaM00J0J59ug==", "dev": true, + "peer": true, "requires": { - "@chainsafe/as-sha256": "^0.3.1" - } - }, - "@chainsafe/ssz": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/@chainsafe/ssz/-/ssz-0.10.2.tgz", - "integrity": "sha512-/NL3Lh8K+0q7A3LsiFq09YXS9fPE+ead2rr7vM2QK8PLzrNsw3uqrif9bpRX5UxgeRjM+vYi+boCM3+GM4ovXg==", - "dev": true, - "requires": { - "@chainsafe/as-sha256": "^0.3.1", - "@chainsafe/persistent-merkle-tree": "^0.5.0" + "@noble/curves": "1.1.0", + "@noble/hashes": "1.3.1", + "@scure/bip32": "1.3.1", + "@scure/bip39": "1.2.1" } } } }, - "@nomicfoundation/ethereumjs-vm": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-vm/-/ethereumjs-vm-7.0.1.tgz", - "integrity": "sha512-rArhyn0jPsS/D+ApFsz3yVJMQ29+pVzNZ0VJgkzAZ+7FqXSRtThl1C1prhmlVr3YNUlfpZ69Ak+RUT4g7VoOuQ==", - "dev": true, - "requires": { - "@nomicfoundation/ethereumjs-block": "5.0.1", - "@nomicfoundation/ethereumjs-blockchain": "7.0.1", - "@nomicfoundation/ethereumjs-common": "4.0.1", - "@nomicfoundation/ethereumjs-evm": "2.0.1", - "@nomicfoundation/ethereumjs-rlp": "5.0.1", - "@nomicfoundation/ethereumjs-statemanager": "2.0.1", - "@nomicfoundation/ethereumjs-trie": "6.0.1", - "@nomicfoundation/ethereumjs-tx": "5.0.1", - "@nomicfoundation/ethereumjs-util": "9.0.1", - "debug": "^4.3.3", - "ethereum-cryptography": "0.1.3", - "mcl-wasm": "^0.7.1", - "rustbn.js": "~0.2.0" - } - }, - "@nomicfoundation/hardhat-chai-matchers": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-chai-matchers/-/hardhat-chai-matchers-1.0.6.tgz", - "integrity": "sha512-f5ZMNmabZeZegEfuxn/0kW+mm7+yV7VNDxLpMOMGXWFJ2l/Ct3QShujzDRF9cOkK9Ui/hbDeOWGZqyQALDXVCQ==", + "@ethersproject/abi": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz", + "integrity": "sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==", "dev": true, - "peer": true, "requires": { - "@ethersproject/abi": "^5.1.2", - "@types/chai-as-promised": "^7.1.3", - "chai-as-promised": "^7.1.1", - "deep-eql": "^4.0.1", - "ordinal": "^1.0.3" + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" } }, - "@nomicfoundation/hardhat-network-helpers": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-network-helpers/-/hardhat-network-helpers-1.0.8.tgz", - "integrity": "sha512-MNqQbzUJZnCMIYvlniC3U+kcavz/PhhQSsY90tbEtUyMj/IQqsLwIRZa4ctjABh3Bz0KCh9OXUZ7Yk/d9hr45Q==", + "@ethersproject/abstract-provider": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz", + "integrity": "sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==", "dev": true, - "peer": true, "requires": { - "ethereumjs-util": "^7.1.4" + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/networks": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/web": "^5.7.0" } }, - "@nomicfoundation/hardhat-toolbox": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-toolbox/-/hardhat-toolbox-2.0.2.tgz", - "integrity": "sha512-vnN1AzxbvpSx9pfdRHbUzTRIXpMLPXnUlkW855VaDk6N1pwRaQ2gNzEmFAABk4lWf11E00PKwFd/q27HuwYrYg==", + "@ethersproject/abstract-signer": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz", + "integrity": "sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==", "dev": true, - "requires": {} + "requires": { + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0" + } }, - "@nomicfoundation/solidity-analyzer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.1.tgz", - "integrity": "sha512-1LMtXj1puAxyFusBgUIy5pZk3073cNXYnXUpuNKFghHbIit/xZgbk0AokpUADbNm3gyD6bFWl3LRFh3dhVdREg==", + "@ethersproject/address": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz", + "integrity": "sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==", "dev": true, "requires": { - "@nomicfoundation/solidity-analyzer-darwin-arm64": "0.1.1", - "@nomicfoundation/solidity-analyzer-darwin-x64": "0.1.1", - "@nomicfoundation/solidity-analyzer-freebsd-x64": "0.1.1", - "@nomicfoundation/solidity-analyzer-linux-arm64-gnu": "0.1.1", - "@nomicfoundation/solidity-analyzer-linux-arm64-musl": "0.1.1", - "@nomicfoundation/solidity-analyzer-linux-x64-gnu": "0.1.1", - "@nomicfoundation/solidity-analyzer-linux-x64-musl": "0.1.1", - "@nomicfoundation/solidity-analyzer-win32-arm64-msvc": "0.1.1", - "@nomicfoundation/solidity-analyzer-win32-ia32-msvc": "0.1.1", - "@nomicfoundation/solidity-analyzer-win32-x64-msvc": "0.1.1" + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/rlp": "^5.7.0" } }, - "@nomicfoundation/solidity-analyzer-darwin-arm64": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.1.tgz", - "integrity": "sha512-KcTodaQw8ivDZyF+D76FokN/HdpgGpfjc/gFCImdLUyqB6eSWVaZPazMbeAjmfhx3R0zm/NYVzxwAokFKgrc0w==", + "@ethersproject/base64": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.7.0.tgz", + "integrity": "sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==", "dev": true, - "optional": true + "requires": { + "@ethersproject/bytes": "^5.7.0" + } }, - "@nomicfoundation/solidity-analyzer-darwin-x64": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-x64/-/solidity-analyzer-darwin-x64-0.1.1.tgz", - "integrity": "sha512-XhQG4BaJE6cIbjAVtzGOGbK3sn1BO9W29uhk9J8y8fZF1DYz0Doj8QDMfpMu+A6TjPDs61lbsmeYodIDnfveSA==", + "@ethersproject/basex": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.7.0.tgz", + "integrity": "sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw==", "dev": true, - "optional": true + "requires": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/properties": "^5.7.0" + } }, - "@nomicfoundation/solidity-analyzer-freebsd-x64": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-freebsd-x64/-/solidity-analyzer-freebsd-x64-0.1.1.tgz", - "integrity": "sha512-GHF1VKRdHW3G8CndkwdaeLkVBi5A9u2jwtlS7SLhBc8b5U/GcoL39Q+1CSO3hYqePNP+eV5YI7Zgm0ea6kMHoA==", + "@ethersproject/bignumber": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.7.0.tgz", + "integrity": "sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==", "dev": true, - "optional": true + "requires": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "bn.js": "^5.2.1" + } }, - "@nomicfoundation/solidity-analyzer-linux-arm64-gnu": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-gnu/-/solidity-analyzer-linux-arm64-gnu-0.1.1.tgz", - "integrity": "sha512-g4Cv2fO37ZsUENQ2vwPnZc2zRenHyAxHcyBjKcjaSmmkKrFr64yvzeNO8S3GBFCo90rfochLs99wFVGT/0owpg==", + "@ethersproject/bytes": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz", + "integrity": "sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==", "dev": true, - "optional": true + "requires": { + "@ethersproject/logger": "^5.7.0" + } }, - "@nomicfoundation/solidity-analyzer-linux-arm64-musl": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-musl/-/solidity-analyzer-linux-arm64-musl-0.1.1.tgz", - "integrity": "sha512-WJ3CE5Oek25OGE3WwzK7oaopY8xMw9Lhb0mlYuJl/maZVo+WtP36XoQTb7bW/i8aAdHW5Z+BqrHMux23pvxG3w==", + "@ethersproject/constants": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.7.0.tgz", + "integrity": "sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==", "dev": true, - "optional": true + "requires": { + "@ethersproject/bignumber": "^5.7.0" + } }, - "@nomicfoundation/solidity-analyzer-linux-x64-gnu": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-gnu/-/solidity-analyzer-linux-x64-gnu-0.1.1.tgz", - "integrity": "sha512-5WN7leSr5fkUBBjE4f3wKENUy9HQStu7HmWqbtknfXkkil+eNWiBV275IOlpXku7v3uLsXTOKpnnGHJYI2qsdA==", + "@ethersproject/contracts": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.7.0.tgz", + "integrity": "sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg==", "dev": true, - "optional": true + "requires": { + "@ethersproject/abi": "^5.7.0", + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/transactions": "^5.7.0" + } }, - "@nomicfoundation/solidity-analyzer-linux-x64-musl": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-musl/-/solidity-analyzer-linux-x64-musl-0.1.1.tgz", - "integrity": "sha512-KdYMkJOq0SYPQMmErv/63CwGwMm5XHenEna9X9aB8mQmhDBrYrlAOSsIPgFCUSL0hjxE3xHP65/EPXR/InD2+w==", + "@ethersproject/hash": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz", + "integrity": "sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==", "dev": true, - "optional": true + "requires": { + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/base64": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } }, - "@nomicfoundation/solidity-analyzer-win32-arm64-msvc": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-arm64-msvc/-/solidity-analyzer-win32-arm64-msvc-0.1.1.tgz", - "integrity": "sha512-VFZASBfl4qiBYwW5xeY20exWhmv6ww9sWu/krWSesv3q5hA0o1JuzmPHR4LPN6SUZj5vcqci0O6JOL8BPw+APg==", + "@ethersproject/hdnode": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.7.0.tgz", + "integrity": "sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==", "dev": true, - "optional": true + "requires": { + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/basex": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/pbkdf2": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/wordlists": "^5.7.0" + } }, - "@nomicfoundation/solidity-analyzer-win32-ia32-msvc": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-ia32-msvc/-/solidity-analyzer-win32-ia32-msvc-0.1.1.tgz", - "integrity": "sha512-JnFkYuyCSA70j6Si6cS1A9Gh1aHTEb8kOTBApp/c7NRTFGNMH8eaInKlyuuiIbvYFhlXW4LicqyYuWNNq9hkpQ==", + "@ethersproject/json-wallets": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz", + "integrity": "sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g==", "dev": true, - "optional": true + "requires": { + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hdnode": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/pbkdf2": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "aes-js": "3.0.0", + "scrypt-js": "3.0.1" + } }, - "@nomicfoundation/solidity-analyzer-win32-x64-msvc": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-x64-msvc/-/solidity-analyzer-win32-x64-msvc-0.1.1.tgz", - "integrity": "sha512-HrVJr6+WjIXGnw3Q9u6KQcbZCtk0caVWhCdFADySvRyUxJ8PnzlaP+MhwNE8oyT8OZ6ejHBRrrgjSqDCFXGirw==", + "@ethersproject/keccak256": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.7.0.tgz", + "integrity": "sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==", "dev": true, - "optional": true + "requires": { + "@ethersproject/bytes": "^5.7.0", + "js-sha3": "0.8.0" + } }, - "@nomiclabs/hardhat-ethers": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.2.3.tgz", - "integrity": "sha512-YhzPdzb612X591FOe68q+qXVXGG2ANZRvDo0RRUtimev85rCrAlv/TLMEZw5c+kq9AbzocLTVX/h2jVIFPL9Xg==", - "dev": true, - "requires": {} + "@ethersproject/logger": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.7.0.tgz", + "integrity": "sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==", + "dev": true }, - "@nomiclabs/hardhat-etherscan": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-3.1.7.tgz", - "integrity": "sha512-tZ3TvSgpvsQ6B6OGmo1/Au6u8BrAkvs1mIC/eURA3xgIfznUZBhmpne8hv7BXUzw9xNL3fXdpOYgOQlVMTcoHQ==", + "@ethersproject/networks": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.1.tgz", + "integrity": "sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==", "dev": true, - "peer": true, "requires": { - "@ethersproject/abi": "^5.1.2", - "@ethersproject/address": "^5.0.2", - "cbor": "^8.1.0", - "chalk": "^2.4.2", - "debug": "^4.1.1", - "fs-extra": "^7.0.1", - "lodash": "^4.17.11", - "semver": "^6.3.0", - "table": "^6.8.0", - "undici": "^5.14.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "peer": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "peer": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "peer": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true, - "peer": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "peer": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "peer": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "peer": true, - "requires": { - "has-flag": "^3.0.0" - } - } + "@ethersproject/logger": "^5.7.0" } }, - "@nomiclabs/hardhat-solhint": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-solhint/-/hardhat-solhint-2.0.1.tgz", - "integrity": "sha512-SrTLufY21t78KLpJL5fS6gHIsCwVv0yWsHp1aQOPL1qwRWpe0Mnh5wb2YzBHd3Dbr/KzUYys+j2ui0PsSVU9pg==", + "@ethersproject/pbkdf2": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz", + "integrity": "sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw==", "dev": true, "requires": { - "solhint": "^2.0.0" + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/sha2": "^5.7.0" } }, - "@openzeppelin/contracts": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.9.2.tgz", - "integrity": "sha512-mO+y6JaqXjWeMh9glYVzVu8HYPGknAAnWyxTRhGeckOruyXQMNnlcW6w/Dx9ftLeIQk6N+ZJFuVmTwF7lEIFrg==", - "dev": true - }, - "@openzeppelin/contracts-upgradeable": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.9.2.tgz", - "integrity": "sha512-siviV3PZV/fHfPaoIC51rf1Jb6iElkYWnNYZ0leO23/ukXuvOyoC/ahy8jqiV7g+++9Nuo3n/rk5ajSN/+d/Sg==", - "dev": true - }, - "@openzeppelin/defender-base-client": { - "version": "1.46.0", - "resolved": "https://registry.npmjs.org/@openzeppelin/defender-base-client/-/defender-base-client-1.46.0.tgz", - "integrity": "sha512-EMnVBcfE6ZN5yMxfaxrFF3eqyGp2RQp3oSRSRP+R3yuCRJf8VCc2ArdZf1QPmQQzbq70nl8EZa03mmAqPauNlQ==", + "@ethersproject/properties": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.7.0.tgz", + "integrity": "sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==", "dev": true, "requires": { - "amazon-cognito-identity-js": "^6.0.1", - "async-retry": "^1.3.3", - "axios": "^0.21.2", - "lodash": "^4.17.19", - "node-fetch": "^2.6.0" + "@ethersproject/logger": "^5.7.0" } }, - "@openzeppelin/hardhat-upgrades": { - "version": "1.28.0", - "resolved": "https://registry.npmjs.org/@openzeppelin/hardhat-upgrades/-/hardhat-upgrades-1.28.0.tgz", - "integrity": "sha512-7sb/Jf+X+uIufOBnmHR0FJVWuxEs2lpxjJnLNN6eCJCP8nD0v+Ot5lTOW2Qb/GFnh+fLvJtEkhkowz4ZQ57+zQ==", + "@ethersproject/providers": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.2.tgz", + "integrity": "sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg==", "dev": true, "requires": { - "@openzeppelin/defender-base-client": "^1.46.0", - "@openzeppelin/platform-deploy-client": "^0.8.0", - "@openzeppelin/upgrades-core": "^1.27.0", - "chalk": "^4.1.0", - "debug": "^4.1.1", - "proper-lockfile": "^4.1.1" + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/base64": "^5.7.0", + "@ethersproject/basex": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/networks": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/rlp": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/web": "^5.7.0", + "bech32": "1.1.4", + "ws": "7.4.6" } }, - "@openzeppelin/platform-deploy-client": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@openzeppelin/platform-deploy-client/-/platform-deploy-client-0.8.0.tgz", - "integrity": "sha512-POx3AsnKwKSV/ZLOU/gheksj0Lq7Is1q2F3pKmcFjGZiibf+4kjGxr4eSMrT+2qgKYZQH1ZLQZ+SkbguD8fTvA==", + "@ethersproject/random": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.7.0.tgz", + "integrity": "sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ==", "dev": true, "requires": { - "@ethersproject/abi": "^5.6.3", - "@openzeppelin/defender-base-client": "^1.46.0", - "axios": "^0.21.2", - "lodash": "^4.17.19", - "node-fetch": "^2.6.0" + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0" } }, - "@openzeppelin/upgrades-core": { - "version": "1.27.1", - "resolved": "https://registry.npmjs.org/@openzeppelin/upgrades-core/-/upgrades-core-1.27.1.tgz", - "integrity": "sha512-6tLcu6jt0nYdJNr+LRicBgP3jp+//B+dixgB3KsvycSglCHNfmBNDf0ZQ3ZquDdLL0QQmKzIs1EBRVp6lNvPnQ==", + "@ethersproject/rlp": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.7.0.tgz", + "integrity": "sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==", "dev": true, "requires": { - "cbor": "^8.0.0", - "chalk": "^4.1.0", - "compare-versions": "^5.0.0", - "debug": "^4.1.1", - "ethereumjs-util": "^7.0.3", - "minimist": "^1.2.7", - "proper-lockfile": "^4.1.1", - "solidity-ast": "^0.4.15" + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0" } }, - "@scure/base": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.1.tgz", - "integrity": "sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==", - "dev": true - }, - "@scure/bip32": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.5.tgz", - "integrity": "sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw==", + "@ethersproject/sha2": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.7.0.tgz", + "integrity": "sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw==", "dev": true, "requires": { - "@noble/hashes": "~1.2.0", - "@noble/secp256k1": "~1.7.0", - "@scure/base": "~1.1.0" + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "hash.js": "1.1.7" } }, - "@scure/bip39": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.1.tgz", - "integrity": "sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg==", + "@ethersproject/signing-key": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.7.0.tgz", + "integrity": "sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==", "dev": true, "requires": { - "@noble/hashes": "~1.2.0", - "@scure/base": "~1.1.0" + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "bn.js": "^5.2.1", + "elliptic": "6.5.4", + "hash.js": "1.1.7" } }, - "@sentry/core": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-5.30.0.tgz", - "integrity": "sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg==", + "@ethersproject/solidity": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.7.0.tgz", + "integrity": "sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA==", "dev": true, "requires": { - "@sentry/hub": "5.30.0", - "@sentry/minimal": "5.30.0", - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "tslib": "^1.9.3" + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/strings": "^5.7.0" } }, - "@sentry/hub": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-5.30.0.tgz", - "integrity": "sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ==", + "@ethersproject/strings": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.7.0.tgz", + "integrity": "sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==", "dev": true, "requires": { - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "tslib": "^1.9.3" + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0" } }, - "@sentry/minimal": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.30.0.tgz", - "integrity": "sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw==", + "@ethersproject/transactions": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.7.0.tgz", + "integrity": "sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==", "dev": true, "requires": { - "@sentry/hub": "5.30.0", - "@sentry/types": "5.30.0", - "tslib": "^1.9.3" + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/rlp": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0" } }, - "@sentry/node": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/node/-/node-5.30.0.tgz", - "integrity": "sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg==", + "@ethersproject/units": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.7.0.tgz", + "integrity": "sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg==", "dev": true, "requires": { - "@sentry/core": "5.30.0", - "@sentry/hub": "5.30.0", - "@sentry/tracing": "5.30.0", - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "cookie": "^0.4.1", - "https-proxy-agent": "^5.0.0", - "lru_map": "^0.3.3", - "tslib": "^1.9.3" + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0" } }, - "@sentry/tracing": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-5.30.0.tgz", - "integrity": "sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw==", + "@ethersproject/wallet": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.7.0.tgz", + "integrity": "sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA==", "dev": true, "requires": { - "@sentry/hub": "5.30.0", - "@sentry/minimal": "5.30.0", - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "tslib": "^1.9.3" + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/hdnode": "^5.7.0", + "@ethersproject/json-wallets": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/wordlists": "^5.7.0" } }, - "@sentry/types": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-5.30.0.tgz", - "integrity": "sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw==", - "dev": true + "@ethersproject/web": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.1.tgz", + "integrity": "sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==", + "dev": true, + "requires": { + "@ethersproject/base64": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } }, - "@sentry/utils": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-5.30.0.tgz", - "integrity": "sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww==", + "@ethersproject/wordlists": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.7.0.tgz", + "integrity": "sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA==", "dev": true, "requires": { - "@sentry/types": "5.30.0", - "tslib": "^1.9.3" + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" } }, - "@solidity-parser/parser": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.14.5.tgz", - "integrity": "sha512-6dKnHZn7fg/iQATVEzqyUOyEidbn05q7YA2mQ9hC0MMXhhV3/JrsxmFSYZAcr7j1yUP700LLhTruvJ3MiQmjJg==", + "@fastify/busboy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.0.tgz", + "integrity": "sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA==", + "dev": true + }, + "@humanwhocodes/config-array": { + "version": "0.11.13", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", + "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", "dev": true, - "peer": true, "requires": { - "antlr4ts": "^0.5.0-alpha.4" + "@humanwhocodes/object-schema": "^2.0.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" } }, - "@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true }, - "@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "@humanwhocodes/object-schema": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", + "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", "dev": true }, - "@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", "dev": true }, - "@tsconfig/node16": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", "dev": true }, - "@typechain/ethers-v5": { - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/@typechain/ethers-v5/-/ethers-v5-10.2.1.tgz", - "integrity": "sha512-n3tQmCZjRE6IU4h6lqUGiQ1j866n5MTCBJreNEHHVWXa2u9GJTaeYyU1/k+1qLutkyw+sS6VAN+AbeiTqsxd/A==", + "@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", "dev": true, - "peer": true, "requires": { - "lodash": "^4.17.15", - "ts-essentials": "^7.0.1" + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" } }, - "@typechain/hardhat": { - "version": "6.1.6", - "resolved": "https://registry.npmjs.org/@typechain/hardhat/-/hardhat-6.1.6.tgz", - "integrity": "sha512-BiVnegSs+ZHVymyidtK472syodx1sXYlYJJixZfRstHVGYTi8V1O7QG4nsjyb0PC/LORcq7sfBUcHto1y6UgJA==", + "@kwsites/file-exists": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz", + "integrity": "sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==", "dev": true, - "peer": true, "requires": { - "fs-extra": "^9.1.0" + "debug": "^4.1.1" + } + }, + "@kwsites/promise-deferred": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz", + "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==", + "dev": true + }, + "@metamask/eth-sig-util": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz", + "integrity": "sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ==", + "dev": true, + "requires": { + "ethereumjs-abi": "^0.6.8", + "ethereumjs-util": "^6.2.1", + "ethjs-util": "^0.1.6", + "tweetnacl": "^1.0.3", + "tweetnacl-util": "^0.15.1" }, "dependencies": { - "fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "@types/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", "dev": true, - "peer": true, "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" + "@types/node": "*" } }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "ethereumjs-util": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", + "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", "dev": true, - "peer": true, "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" } - }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true, - "peer": true } } }, - "@types/bn.js": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.1.tgz", - "integrity": "sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g==", + "@noble/curves": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.1.0.tgz", + "integrity": "sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA==", "dev": true, + "peer": true, "requires": { - "@types/node": "*" + "@noble/hashes": "1.3.1" } }, - "@types/chai": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.5.tgz", - "integrity": "sha512-mEo1sAde+UCE6b2hxn332f1g1E8WfYRu6p5SvTKr2ZKC1f7gFJXk4h5PyGP9Dt6gCaG8y8XhwnXWC6Iy2cmBng==", + "@noble/hashes": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.1.tgz", + "integrity": "sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==", + "dev": true, + "peer": true + }, + "@noble/secp256k1": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-1.7.1.tgz", + "integrity": "sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw==", "dev": true }, - "@types/chai-as-promised": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-7.1.5.tgz", - "integrity": "sha512-jStwss93SITGBwt/niYrkf2C+/1KTeZCZl1LaeezTlqppAKeoQC7jxyqYuP72sxBGKCIbw7oHgbYssIRzT5FCQ==", + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, "requires": { - "@types/chai": "*" + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" } }, - "@types/cli-table": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@types/cli-table/-/cli-table-0.3.1.tgz", - "integrity": "sha512-m3+6WWfSSl6zqoXy8uQQifbgqV7Gt6fsyWnHLgUWVtJQk75+OfUB+edSZ52YDj7leSiZtX7w1/E4w2x/Hb0orA==", + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true }, - "@types/concat-stream": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.1.tgz", - "integrity": "sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==", + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, - "peer": true, "requires": { - "@types/node": "*" + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" } }, - "@types/form-data": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz", - "integrity": "sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==", + "@nomicfoundation/ethereumjs-block": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-block/-/ethereumjs-block-5.0.2.tgz", + "integrity": "sha512-hSe6CuHI4SsSiWWjHDIzWhSiAVpzMUcDRpWYzN0T9l8/Rz7xNn3elwVOJ/tAyS0LqL6vitUD78Uk7lQDXZun7Q==", "dev": true, - "peer": true, "requires": { - "@types/node": "*" + "@nomicfoundation/ethereumjs-common": "4.0.2", + "@nomicfoundation/ethereumjs-rlp": "5.0.2", + "@nomicfoundation/ethereumjs-trie": "6.0.2", + "@nomicfoundation/ethereumjs-tx": "5.0.2", + "@nomicfoundation/ethereumjs-util": "9.0.2", + "ethereum-cryptography": "0.1.3", + "ethers": "^5.7.1" } }, - "@types/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", + "@nomicfoundation/ethereumjs-blockchain": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-blockchain/-/ethereumjs-blockchain-7.0.2.tgz", + "integrity": "sha512-8UUsSXJs+MFfIIAKdh3cG16iNmWzWC/91P40sazNvrqhhdR/RtGDlFk2iFTGbBAZPs2+klZVzhRX8m2wvuvz3w==", + "dev": true, + "requires": { + "@nomicfoundation/ethereumjs-block": "5.0.2", + "@nomicfoundation/ethereumjs-common": "4.0.2", + "@nomicfoundation/ethereumjs-ethash": "3.0.2", + "@nomicfoundation/ethereumjs-rlp": "5.0.2", + "@nomicfoundation/ethereumjs-trie": "6.0.2", + "@nomicfoundation/ethereumjs-tx": "5.0.2", + "@nomicfoundation/ethereumjs-util": "9.0.2", + "abstract-level": "^1.0.3", + "debug": "^4.3.3", + "ethereum-cryptography": "0.1.3", + "level": "^8.0.0", + "lru-cache": "^5.1.1", + "memory-level": "^1.0.0" + } + }, + "@nomicfoundation/ethereumjs-common": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-4.0.2.tgz", + "integrity": "sha512-I2WGP3HMGsOoycSdOTSqIaES0ughQTueOsddJ36aYVpI3SN8YSusgRFLwzDJwRFVIYDKx/iJz0sQ5kBHVgdDwg==", "dev": true, - "peer": true, "requires": { - "@types/minimatch": "*", - "@types/node": "*" + "@nomicfoundation/ethereumjs-util": "9.0.2", + "crc-32": "^1.2.0" } }, - "@types/json-schema": { - "version": "7.0.12", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", - "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==", - "dev": true - }, - "@types/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==", - "dev": true - }, - "@types/minimatch": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", - "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", + "@nomicfoundation/ethereumjs-ethash": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-ethash/-/ethereumjs-ethash-3.0.2.tgz", + "integrity": "sha512-8PfoOQCcIcO9Pylq0Buijuq/O73tmMVURK0OqdjhwqcGHYC2PwhbajDh7GZ55ekB0Px197ajK3PQhpKoiI/UPg==", "dev": true, - "peer": true - }, - "@types/mocha": { - "version": "9.1.1", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.1.tgz", - "integrity": "sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw==", - "dev": true - }, - "@types/node": { - "version": "17.0.45", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", - "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==", - "dev": true + "requires": { + "@nomicfoundation/ethereumjs-block": "5.0.2", + "@nomicfoundation/ethereumjs-rlp": "5.0.2", + "@nomicfoundation/ethereumjs-util": "9.0.2", + "abstract-level": "^1.0.3", + "bigint-crypto-utils": "^3.0.23", + "ethereum-cryptography": "0.1.3" + } }, - "@types/pbkdf2": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz", - "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==", + "@nomicfoundation/ethereumjs-evm": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-evm/-/ethereumjs-evm-2.0.2.tgz", + "integrity": "sha512-rBLcUaUfANJxyOx9HIdMX6uXGin6lANCulIm/pjMgRqfiCRMZie3WKYxTSd8ZE/d+qT+zTedBF4+VHTdTSePmQ==", "dev": true, "requires": { - "@types/node": "*" + "@ethersproject/providers": "^5.7.1", + "@nomicfoundation/ethereumjs-common": "4.0.2", + "@nomicfoundation/ethereumjs-tx": "5.0.2", + "@nomicfoundation/ethereumjs-util": "9.0.2", + "debug": "^4.3.3", + "ethereum-cryptography": "0.1.3", + "mcl-wasm": "^0.7.1", + "rustbn.js": "~0.2.0" } }, - "@types/prettier": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.3.tgz", - "integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==", - "dev": true, - "peer": true + "@nomicfoundation/ethereumjs-rlp": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-5.0.2.tgz", + "integrity": "sha512-QwmemBc+MMsHJ1P1QvPl8R8p2aPvvVcKBbvHnQOKBpBztEo0omN0eaob6FeZS/e3y9NSe+mfu3nNFBHszqkjTA==", + "dev": true }, - "@types/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", + "@nomicfoundation/ethereumjs-statemanager": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-statemanager/-/ethereumjs-statemanager-2.0.2.tgz", + "integrity": "sha512-dlKy5dIXLuDubx8Z74sipciZnJTRSV/uHG48RSijhgm1V7eXYFC567xgKtsKiVZB1ViTP9iFL4B6Je0xD6X2OA==", "dev": true, - "peer": true + "requires": { + "@nomicfoundation/ethereumjs-common": "4.0.2", + "@nomicfoundation/ethereumjs-rlp": "5.0.2", + "debug": "^4.3.3", + "ethereum-cryptography": "0.1.3", + "ethers": "^5.7.1", + "js-sdsl": "^4.1.4" + } }, - "@types/readable-stream": { - "version": "2.3.15", - "resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-2.3.15.tgz", - "integrity": "sha512-oM5JSKQCcICF1wvGgmecmHldZ48OZamtMxcGGVICOJA8o8cahXC1zEVAif8iwoc5j8etxFaRFnf095+CDsuoFQ==", + "@nomicfoundation/ethereumjs-trie": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-trie/-/ethereumjs-trie-6.0.2.tgz", + "integrity": "sha512-yw8vg9hBeLYk4YNg5MrSJ5H55TLOv2FSWUTROtDtTMMmDGROsAu+0tBjiNGTnKRi400M6cEzoFfa89Fc5k8NTQ==", "dev": true, "requires": { - "@types/node": "*", - "safe-buffer": "~5.1.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - } + "@nomicfoundation/ethereumjs-rlp": "5.0.2", + "@nomicfoundation/ethereumjs-util": "9.0.2", + "@types/readable-stream": "^2.3.13", + "ethereum-cryptography": "0.1.3", + "readable-stream": "^3.6.0" } }, - "@types/secp256k1": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.3.tgz", - "integrity": "sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==", + "@nomicfoundation/ethereumjs-tx": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-5.0.2.tgz", + "integrity": "sha512-T+l4/MmTp7VhJeNloMkM+lPU3YMUaXdcXgTGCf8+ZFvV9NYZTRLFekRwlG6/JMmVfIfbrW+dRRJ9A6H5Q/Z64g==", "dev": true, "requires": { - "@types/node": "*" + "@chainsafe/ssz": "^0.9.2", + "@ethersproject/providers": "^5.7.2", + "@nomicfoundation/ethereumjs-common": "4.0.2", + "@nomicfoundation/ethereumjs-rlp": "5.0.2", + "@nomicfoundation/ethereumjs-util": "9.0.2", + "ethereum-cryptography": "0.1.3" } }, - "@types/semver": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==", - "dev": true - }, - "@typescript-eslint/eslint-plugin": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.11.tgz", - "integrity": "sha512-XxuOfTkCUiOSyBWIvHlUraLw/JT/6Io1365RO6ZuI88STKMavJZPNMU0lFcUTeQXEhHiv64CbxYxBNoDVSmghg==", + "@nomicfoundation/ethereumjs-util": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-9.0.2.tgz", + "integrity": "sha512-4Wu9D3LykbSBWZo8nJCnzVIYGvGCuyiYLIJa9XXNVt1q1jUzHdB+sJvx95VGCpPkCT+IbLecW6yfzy3E1bQrwQ==", "dev": true, "requires": { - "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.59.11", - "@typescript-eslint/type-utils": "5.59.11", - "@typescript-eslint/utils": "5.59.11", - "debug": "^4.3.4", - "grapheme-splitter": "^1.0.4", - "ignore": "^5.2.0", - "natural-compare-lite": "^1.4.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" + "@chainsafe/ssz": "^0.10.0", + "@nomicfoundation/ethereumjs-rlp": "5.0.2", + "ethereum-cryptography": "0.1.3" }, "dependencies": { - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "@chainsafe/persistent-merkle-tree": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@chainsafe/persistent-merkle-tree/-/persistent-merkle-tree-0.5.0.tgz", + "integrity": "sha512-l0V1b5clxA3iwQLXP40zYjyZYospQLZXzBVIhhr9kDg/1qHZfzzHw0jj4VPBijfYCArZDlPkRi1wZaV2POKeuw==", "dev": true, "requires": { - "yallist": "^4.0.0" + "@chainsafe/as-sha256": "^0.3.1" } }, - "semver": { - "version": "7.5.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.2.tgz", - "integrity": "sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==", + "@chainsafe/ssz": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/@chainsafe/ssz/-/ssz-0.10.2.tgz", + "integrity": "sha512-/NL3Lh8K+0q7A3LsiFq09YXS9fPE+ead2rr7vM2QK8PLzrNsw3uqrif9bpRX5UxgeRjM+vYi+boCM3+GM4ovXg==", "dev": true, "requires": { - "lru-cache": "^6.0.0" + "@chainsafe/as-sha256": "^0.3.1", + "@chainsafe/persistent-merkle-tree": "^0.5.0" } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true } } }, - "@typescript-eslint/parser": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.11.tgz", - "integrity": "sha512-s9ZF3M+Nym6CAZEkJJeO2TFHHDsKAM3ecNkLuH4i4s8/RCPnF5JRip2GyviYkeEAcwGMJxkqG9h2dAsnA1nZpA==", - "dev": true, - "peer": true, - "requires": { - "@typescript-eslint/scope-manager": "5.59.11", - "@typescript-eslint/types": "5.59.11", - "@typescript-eslint/typescript-estree": "5.59.11", - "debug": "^4.3.4" + "@nomicfoundation/ethereumjs-vm": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-vm/-/ethereumjs-vm-7.0.2.tgz", + "integrity": "sha512-Bj3KZT64j54Tcwr7Qm/0jkeZXJMfdcAtRBedou+Hx0dPOSIgqaIr0vvLwP65TpHbak2DmAq+KJbW2KNtIoFwvA==", + "dev": true, + "requires": { + "@nomicfoundation/ethereumjs-block": "5.0.2", + "@nomicfoundation/ethereumjs-blockchain": "7.0.2", + "@nomicfoundation/ethereumjs-common": "4.0.2", + "@nomicfoundation/ethereumjs-evm": "2.0.2", + "@nomicfoundation/ethereumjs-rlp": "5.0.2", + "@nomicfoundation/ethereumjs-statemanager": "2.0.2", + "@nomicfoundation/ethereumjs-trie": "6.0.2", + "@nomicfoundation/ethereumjs-tx": "5.0.2", + "@nomicfoundation/ethereumjs-util": "9.0.2", + "debug": "^4.3.3", + "ethereum-cryptography": "0.1.3", + "mcl-wasm": "^0.7.1", + "rustbn.js": "~0.2.0" } }, - "@typescript-eslint/scope-manager": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.11.tgz", - "integrity": "sha512-dHFOsxoLFtrIcSj5h0QoBT/89hxQONwmn3FOQ0GOQcLOOXm+MIrS8zEAhs4tWl5MraxCY3ZJpaXQQdFMc2Tu+Q==", + "@nomicfoundation/hardhat-chai-matchers": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-chai-matchers/-/hardhat-chai-matchers-1.0.6.tgz", + "integrity": "sha512-f5ZMNmabZeZegEfuxn/0kW+mm7+yV7VNDxLpMOMGXWFJ2l/Ct3QShujzDRF9cOkK9Ui/hbDeOWGZqyQALDXVCQ==", "dev": true, + "peer": true, "requires": { - "@typescript-eslint/types": "5.59.11", - "@typescript-eslint/visitor-keys": "5.59.11" + "@ethersproject/abi": "^5.1.2", + "@types/chai-as-promised": "^7.1.3", + "chai-as-promised": "^7.1.1", + "deep-eql": "^4.0.1", + "ordinal": "^1.0.3" } }, - "@typescript-eslint/type-utils": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.11.tgz", - "integrity": "sha512-LZqVY8hMiVRF2a7/swmkStMYSoXMFlzL6sXV6U/2gL5cwnLWQgLEG8tjWPpaE4rMIdZ6VKWwcffPlo1jPfk43g==", + "@nomicfoundation/hardhat-network-helpers": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-network-helpers/-/hardhat-network-helpers-1.0.9.tgz", + "integrity": "sha512-OXWCv0cHpwLUO2u7bFxBna6dQtCC2Gg/aN/KtJLO7gmuuA28vgmVKYFRCDUqrbjujzgfwQ2aKyZ9Y3vSmDqS7Q==", "dev": true, + "peer": true, "requires": { - "@typescript-eslint/typescript-estree": "5.59.11", - "@typescript-eslint/utils": "5.59.11", - "debug": "^4.3.4", - "tsutils": "^3.21.0" + "ethereumjs-util": "^7.1.4" } }, - "@typescript-eslint/types": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.11.tgz", - "integrity": "sha512-epoN6R6tkvBYSc+cllrz+c2sOFWkbisJZWkOE+y3xHtvYaOE6Wk6B8e114McRJwFRjGvYdJwLXQH5c9osME/AA==", - "dev": true + "@nomicfoundation/hardhat-toolbox": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-toolbox/-/hardhat-toolbox-2.0.2.tgz", + "integrity": "sha512-vnN1AzxbvpSx9pfdRHbUzTRIXpMLPXnUlkW855VaDk6N1pwRaQ2gNzEmFAABk4lWf11E00PKwFd/q27HuwYrYg==", + "dev": true, + "requires": {} }, - "@typescript-eslint/typescript-estree": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.11.tgz", - "integrity": "sha512-YupOpot5hJO0maupJXixi6l5ETdrITxeo5eBOeuV7RSKgYdU3G5cxO49/9WRnJq9EMrB7AuTSLH/bqOsXi7wPA==", + "@nomicfoundation/solidity-analyzer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.1.tgz", + "integrity": "sha512-1LMtXj1puAxyFusBgUIy5pZk3073cNXYnXUpuNKFghHbIit/xZgbk0AokpUADbNm3gyD6bFWl3LRFh3dhVdREg==", "dev": true, "requires": { - "@typescript-eslint/types": "5.59.11", - "@typescript-eslint/visitor-keys": "5.59.11", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "dependencies": { - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "semver": { - "version": "7.5.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.2.tgz", - "integrity": "sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } + "@nomicfoundation/solidity-analyzer-darwin-arm64": "0.1.1", + "@nomicfoundation/solidity-analyzer-darwin-x64": "0.1.1", + "@nomicfoundation/solidity-analyzer-freebsd-x64": "0.1.1", + "@nomicfoundation/solidity-analyzer-linux-arm64-gnu": "0.1.1", + "@nomicfoundation/solidity-analyzer-linux-arm64-musl": "0.1.1", + "@nomicfoundation/solidity-analyzer-linux-x64-gnu": "0.1.1", + "@nomicfoundation/solidity-analyzer-linux-x64-musl": "0.1.1", + "@nomicfoundation/solidity-analyzer-win32-arm64-msvc": "0.1.1", + "@nomicfoundation/solidity-analyzer-win32-ia32-msvc": "0.1.1", + "@nomicfoundation/solidity-analyzer-win32-x64-msvc": "0.1.1" } }, - "@typescript-eslint/utils": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.11.tgz", - "integrity": "sha512-didu2rHSOMUdJThLk4aZ1Or8IcO3HzCw/ZvEjTTIfjIrcdd5cvSIwwDy2AOlE7htSNp7QIZ10fLMyRCveesMLg==", + "@nomicfoundation/solidity-analyzer-darwin-arm64": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.1.tgz", + "integrity": "sha512-KcTodaQw8ivDZyF+D76FokN/HdpgGpfjc/gFCImdLUyqB6eSWVaZPazMbeAjmfhx3R0zm/NYVzxwAokFKgrc0w==", "dev": true, - "requires": { - "@eslint-community/eslint-utils": "^4.2.0", - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.59.11", - "@typescript-eslint/types": "5.59.11", - "@typescript-eslint/typescript-estree": "5.59.11", - "eslint-scope": "^5.1.1", - "semver": "^7.3.7" + "optional": true + }, + "@nomicfoundation/solidity-analyzer-darwin-x64": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-x64/-/solidity-analyzer-darwin-x64-0.1.1.tgz", + "integrity": "sha512-XhQG4BaJE6cIbjAVtzGOGbK3sn1BO9W29uhk9J8y8fZF1DYz0Doj8QDMfpMu+A6TjPDs61lbsmeYodIDnfveSA==", + "dev": true, + "optional": true + }, + "@nomicfoundation/solidity-analyzer-freebsd-x64": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-freebsd-x64/-/solidity-analyzer-freebsd-x64-0.1.1.tgz", + "integrity": "sha512-GHF1VKRdHW3G8CndkwdaeLkVBi5A9u2jwtlS7SLhBc8b5U/GcoL39Q+1CSO3hYqePNP+eV5YI7Zgm0ea6kMHoA==", + "dev": true, + "optional": true + }, + "@nomicfoundation/solidity-analyzer-linux-arm64-gnu": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-gnu/-/solidity-analyzer-linux-arm64-gnu-0.1.1.tgz", + "integrity": "sha512-g4Cv2fO37ZsUENQ2vwPnZc2zRenHyAxHcyBjKcjaSmmkKrFr64yvzeNO8S3GBFCo90rfochLs99wFVGT/0owpg==", + "dev": true, + "optional": true + }, + "@nomicfoundation/solidity-analyzer-linux-arm64-musl": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-musl/-/solidity-analyzer-linux-arm64-musl-0.1.1.tgz", + "integrity": "sha512-WJ3CE5Oek25OGE3WwzK7oaopY8xMw9Lhb0mlYuJl/maZVo+WtP36XoQTb7bW/i8aAdHW5Z+BqrHMux23pvxG3w==", + "dev": true, + "optional": true + }, + "@nomicfoundation/solidity-analyzer-linux-x64-gnu": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-gnu/-/solidity-analyzer-linux-x64-gnu-0.1.1.tgz", + "integrity": "sha512-5WN7leSr5fkUBBjE4f3wKENUy9HQStu7HmWqbtknfXkkil+eNWiBV275IOlpXku7v3uLsXTOKpnnGHJYI2qsdA==", + "dev": true, + "optional": true + }, + "@nomicfoundation/solidity-analyzer-linux-x64-musl": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-musl/-/solidity-analyzer-linux-x64-musl-0.1.1.tgz", + "integrity": "sha512-KdYMkJOq0SYPQMmErv/63CwGwMm5XHenEna9X9aB8mQmhDBrYrlAOSsIPgFCUSL0hjxE3xHP65/EPXR/InD2+w==", + "dev": true, + "optional": true + }, + "@nomicfoundation/solidity-analyzer-win32-arm64-msvc": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-arm64-msvc/-/solidity-analyzer-win32-arm64-msvc-0.1.1.tgz", + "integrity": "sha512-VFZASBfl4qiBYwW5xeY20exWhmv6ww9sWu/krWSesv3q5hA0o1JuzmPHR4LPN6SUZj5vcqci0O6JOL8BPw+APg==", + "dev": true, + "optional": true + }, + "@nomicfoundation/solidity-analyzer-win32-ia32-msvc": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-ia32-msvc/-/solidity-analyzer-win32-ia32-msvc-0.1.1.tgz", + "integrity": "sha512-JnFkYuyCSA70j6Si6cS1A9Gh1aHTEb8kOTBApp/c7NRTFGNMH8eaInKlyuuiIbvYFhlXW4LicqyYuWNNq9hkpQ==", + "dev": true, + "optional": true + }, + "@nomicfoundation/solidity-analyzer-win32-x64-msvc": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-x64-msvc/-/solidity-analyzer-win32-x64-msvc-0.1.1.tgz", + "integrity": "sha512-HrVJr6+WjIXGnw3Q9u6KQcbZCtk0caVWhCdFADySvRyUxJ8PnzlaP+MhwNE8oyT8OZ6ejHBRrrgjSqDCFXGirw==", + "dev": true, + "optional": true + }, + "@nomiclabs/hardhat-ethers": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.2.3.tgz", + "integrity": "sha512-YhzPdzb612X591FOe68q+qXVXGG2ANZRvDo0RRUtimev85rCrAlv/TLMEZw5c+kq9AbzocLTVX/h2jVIFPL9Xg==", + "dev": true, + "requires": {} + }, + "@nomiclabs/hardhat-etherscan": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-3.1.7.tgz", + "integrity": "sha512-tZ3TvSgpvsQ6B6OGmo1/Au6u8BrAkvs1mIC/eURA3xgIfznUZBhmpne8hv7BXUzw9xNL3fXdpOYgOQlVMTcoHQ==", + "dev": true, + "peer": true, + "requires": { + "@ethersproject/abi": "^5.1.2", + "@ethersproject/address": "^5.0.2", + "cbor": "^8.1.0", + "chalk": "^2.4.2", + "debug": "^4.1.1", + "fs-extra": "^7.0.1", + "lodash": "^4.17.11", + "semver": "^6.3.0", + "table": "^6.8.0", + "undici": "^5.14.0" }, "dependencies": { - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, + "peer": true, "requires": { - "yallist": "^4.0.0" + "color-convert": "^1.9.0" } }, - "semver": { - "version": "7.5.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.2.tgz", - "integrity": "sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==", + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, + "peer": true, "requires": { - "lru-cache": "^6.0.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "peer": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true, + "peer": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "peer": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "peer": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "peer": true, + "requires": { + "has-flag": "^3.0.0" + } } } }, - "@typescript-eslint/visitor-keys": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.11.tgz", - "integrity": "sha512-KGYniTGG3AMTuKF9QBD7EIrvufkB6O6uX3knP73xbKLMpH+QRPcgnCxjWXSHjMRuOxFLovljqQgQpR0c7GvjoA==", + "@nomiclabs/hardhat-solhint": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-solhint/-/hardhat-solhint-2.0.1.tgz", + "integrity": "sha512-SrTLufY21t78KLpJL5fS6gHIsCwVv0yWsHp1aQOPL1qwRWpe0Mnh5wb2YzBHd3Dbr/KzUYys+j2ui0PsSVU9pg==", "dev": true, "requires": { - "@typescript-eslint/types": "5.59.11", - "eslint-visitor-keys": "^3.3.0" + "solhint": "^2.0.0" } }, - "abbrev": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", - "integrity": "sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q==", + "@openzeppelin/contracts": { + "version": "4.9.3", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.9.3.tgz", + "integrity": "sha512-He3LieZ1pP2TNt5JbkPA4PNT9WC3gOTOlDcFGJW4Le4QKqwmiNJCRt44APfxMxvq7OugU/cqYuPcSBzOw38DAg==", + "dev": true + }, + "@openzeppelin/contracts-upgradeable": { + "version": "4.9.3", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.9.3.tgz", + "integrity": "sha512-jjaHAVRMrE4UuZNfDwjlLGDxTHWIOwTJS2ldnc278a0gevfXfPr8hxKEVBGFBE96kl2G3VHDZhUimw/+G3TG2A==", + "dev": true + }, + "@openzeppelin/defender-base-client": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/@openzeppelin/defender-base-client/-/defender-base-client-1.52.0.tgz", + "integrity": "sha512-VFNu/pjVpAnFKIfuKT1cn9dRpbcO8FO8EAmVZ2XrrAsKXEWDZ3TNBtACxmj7fAu0ad/TzRkb66o5rMts7Fv7jw==", "dev": true, - "peer": true + "requires": { + "amazon-cognito-identity-js": "^6.0.1", + "async-retry": "^1.3.3", + "axios": "^1.4.0", + "lodash": "^4.17.19", + "node-fetch": "^2.6.0" + } }, - "abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "@openzeppelin/hardhat-upgrades": { + "version": "1.28.0", + "resolved": "https://registry.npmjs.org/@openzeppelin/hardhat-upgrades/-/hardhat-upgrades-1.28.0.tgz", + "integrity": "sha512-7sb/Jf+X+uIufOBnmHR0FJVWuxEs2lpxjJnLNN6eCJCP8nD0v+Ot5lTOW2Qb/GFnh+fLvJtEkhkowz4ZQ57+zQ==", "dev": true, "requires": { - "event-target-shim": "^5.0.0" + "@openzeppelin/defender-base-client": "^1.46.0", + "@openzeppelin/platform-deploy-client": "^0.8.0", + "@openzeppelin/upgrades-core": "^1.27.0", + "chalk": "^4.1.0", + "debug": "^4.1.1", + "proper-lockfile": "^4.1.1" } }, - "abstract-level": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/abstract-level/-/abstract-level-1.0.3.tgz", - "integrity": "sha512-t6jv+xHy+VYwc4xqZMn2Pa9DjcdzvzZmQGRjTFc8spIbRGHgBrEKbPq+rYXc7CCo0lxgYvSgKVg9qZAhpVQSjA==", + "@openzeppelin/platform-deploy-client": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@openzeppelin/platform-deploy-client/-/platform-deploy-client-0.8.0.tgz", + "integrity": "sha512-POx3AsnKwKSV/ZLOU/gheksj0Lq7Is1q2F3pKmcFjGZiibf+4kjGxr4eSMrT+2qgKYZQH1ZLQZ+SkbguD8fTvA==", "dev": true, "requires": { - "buffer": "^6.0.3", - "catering": "^2.1.0", - "is-buffer": "^2.0.5", - "level-supports": "^4.0.0", - "level-transcoder": "^1.0.1", - "module-error": "^1.0.1", - "queue-microtask": "^1.2.3" + "@ethersproject/abi": "^5.6.3", + "@openzeppelin/defender-base-client": "^1.46.0", + "axios": "^0.21.2", + "lodash": "^4.17.19", + "node-fetch": "^2.6.0" }, "dependencies": { - "buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "axios": { + "version": "0.21.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", + "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", "dev": true, "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" + "follow-redirects": "^1.14.0" } } } }, - "acorn": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.9.0.tgz", - "integrity": "sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ==", - "dev": true - }, - "acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "@openzeppelin/upgrades-core": { + "version": "1.31.3", + "resolved": "https://registry.npmjs.org/@openzeppelin/upgrades-core/-/upgrades-core-1.31.3.tgz", + "integrity": "sha512-i7q0IuItKS4uO0clJwm4CARmt98aA9dLfKh38HFRbX+aFLGXwF0sOvB2iwr6f87ShH7d3DNuLrVgnnXUrYb7CA==", "dev": true, - "requires": {} + "requires": { + "cbor": "^9.0.0", + "chalk": "^4.1.0", + "compare-versions": "^6.0.0", + "debug": "^4.1.1", + "ethereumjs-util": "^7.0.3", + "minimist": "^1.2.7", + "proper-lockfile": "^4.1.1", + "solidity-ast": "^0.4.51" + }, + "dependencies": { + "cbor": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cbor/-/cbor-9.0.1.tgz", + "integrity": "sha512-/TQOWyamDxvVIv+DY9cOLNuABkoyz8K/F3QE56539pGVYohx0+MEA1f4lChFTX79dBTBS7R1PF6ovH7G+VtBfQ==", + "dev": true, + "requires": { + "nofilter": "^3.1.0" + } + } + } }, - "acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "@scure/base": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.3.tgz", + "integrity": "sha512-/+SgoRjLq7Xlf0CWuLHq2LUZeL/w65kfzAPG5NH9pcmBhs+nunQTn4gvdwgMTIXnt9b2C/1SeL2XiysZEyIC9Q==", "dev": true }, - "address": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/address/-/address-1.2.2.tgz", - "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==", + "@scure/bip32": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.3.1.tgz", + "integrity": "sha512-osvveYtyzdEVbt3OfwwXFr4P2iVBL5u1Q3q4ONBfDY/UpOuXmOlbgwc1xECEboY8wIays8Yt6onaWMUdUbfl0A==", "dev": true, - "peer": true + "peer": true, + "requires": { + "@noble/curves": "~1.1.0", + "@noble/hashes": "~1.3.1", + "@scure/base": "~1.1.0" + } }, - "adm-zip": { - "version": "0.4.16", - "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz", - "integrity": "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==", - "dev": true + "@scure/bip39": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.2.1.tgz", + "integrity": "sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg==", + "dev": true, + "peer": true, + "requires": { + "@noble/hashes": "~1.3.0", + "@scure/base": "~1.1.0" + } }, - "aes-js": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", - "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==", - "dev": true + "@sentry/core": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-5.30.0.tgz", + "integrity": "sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg==", + "dev": true, + "requires": { + "@sentry/hub": "5.30.0", + "@sentry/minimal": "5.30.0", + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "tslib": "^1.9.3" + } }, - "agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "@sentry/hub": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-5.30.0.tgz", + "integrity": "sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ==", "dev": true, "requires": { - "debug": "4" + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "tslib": "^1.9.3" } }, - "aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "@sentry/minimal": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.30.0.tgz", + "integrity": "sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw==", "dev": true, "requires": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" + "@sentry/hub": "5.30.0", + "@sentry/types": "5.30.0", + "tslib": "^1.9.3" } }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "@sentry/node": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/node/-/node-5.30.0.tgz", + "integrity": "sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg==", "dev": true, "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "@sentry/core": "5.30.0", + "@sentry/hub": "5.30.0", + "@sentry/tracing": "5.30.0", + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "cookie": "^0.4.1", + "https-proxy-agent": "^5.0.0", + "lru_map": "^0.3.3", + "tslib": "^1.9.3" } }, - "amazon-cognito-identity-js": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/amazon-cognito-identity-js/-/amazon-cognito-identity-js-6.2.0.tgz", - "integrity": "sha512-9Fxrp9+MtLdsJvqOwSaE3ll+pneICeuE3pwj2yDkiyGNWuHx97b8bVLR2bOgfDmDJnY0Hq8QoeXtwdM4aaXJjg==", + "@sentry/tracing": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-5.30.0.tgz", + "integrity": "sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw==", "dev": true, "requires": { - "@aws-crypto/sha256-js": "1.2.2", - "buffer": "4.9.2", - "fast-base64-decode": "^1.0.0", - "isomorphic-unfetch": "^3.0.0", - "js-cookie": "^2.2.1" + "@sentry/hub": "5.30.0", + "@sentry/minimal": "5.30.0", + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "tslib": "^1.9.3" } }, - "amdefine": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==", + "@sentry/types": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-5.30.0.tgz", + "integrity": "sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw==", + "dev": true + }, + "@sentry/utils": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-5.30.0.tgz", + "integrity": "sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww==", "dev": true, - "optional": true, - "peer": true + "requires": { + "@sentry/types": "5.30.0", + "tslib": "^1.9.3" + } }, - "ansi-colors": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", - "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "@sindresorhus/is": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", + "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", "dev": true }, - "ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "@smithy/types": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.6.0.tgz", + "integrity": "sha512-PgqxJq2IcdMF9iAasxcqZqqoOXBHufEfmbEUdN1pmJrJltT42b0Sc8UiYSWWzKkciIp9/mZDpzYi4qYG1qqg6g==", "dev": true, "requires": { - "type-fest": "^0.21.3" + "tslib": "^2.5.0" }, "dependencies": { - "type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", "dev": true } } }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "@solidity-parser/parser": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.14.5.tgz", + "integrity": "sha512-6dKnHZn7fg/iQATVEzqyUOyEidbn05q7YA2mQ9hC0MMXhhV3/JrsxmFSYZAcr7j1yUP700LLhTruvJ3MiQmjJg==", "dev": true, + "peer": true, "requires": { - "color-convert": "^2.0.1" + "antlr4ts": "^0.5.0-alpha.4" } }, - "antlr4": { - "version": "4.7.1", - "resolved": "https://registry.npmjs.org/antlr4/-/antlr4-4.7.1.tgz", - "integrity": "sha512-haHyTW7Y9joE5MVs37P2lNYfU2RWBLfcRDD8OWldcdZm5TiCE91B5Xl1oWSwiDUSd4rlExpt2pu1fksYQjRBYQ==", - "dev": true - }, - "antlr4ts": { - "version": "0.5.0-alpha.4", - "resolved": "https://registry.npmjs.org/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz", - "integrity": "sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ==", - "dev": true, - "peer": true - }, - "anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "@szmarczak/http-timer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", + "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", "dev": true, "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" + "defer-to-connect": "^1.0.1" } }, - "arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", "dev": true }, - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", "dev": true }, - "array-back": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", - "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", - "dev": true, - "peer": true - }, - "array-buffer-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", - "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", - "dev": true, - "peer": true, - "requires": { - "call-bind": "^1.0.2", - "is-array-buffer": "^3.0.1" - } - }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", "dev": true }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", + "@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", "dev": true }, - "array.prototype.reduce": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/array.prototype.reduce/-/array.prototype.reduce-1.0.5.tgz", - "integrity": "sha512-kDdugMl7id9COE8R7MHF5jWk7Dqt/fs4Pv+JXoICnYwqpjjjbUurz6w5fT5IG6brLdJhv6/VoHB0H7oyIBXd+Q==", + "@typechain/ethers-v5": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/@typechain/ethers-v5/-/ethers-v5-10.2.1.tgz", + "integrity": "sha512-n3tQmCZjRE6IU4h6lqUGiQ1j866n5MTCBJreNEHHVWXa2u9GJTaeYyU1/k+1qLutkyw+sS6VAN+AbeiTqsxd/A==", "dev": true, "peer": true, "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "es-array-method-boxes-properly": "^1.0.0", - "is-string": "^1.0.7" + "lodash": "^4.17.15", + "ts-essentials": "^7.0.1" } }, - "asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", - "dev": true, - "peer": true - }, - "asn1": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", - "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "@typechain/hardhat": { + "version": "6.1.6", + "resolved": "https://registry.npmjs.org/@typechain/hardhat/-/hardhat-6.1.6.tgz", + "integrity": "sha512-BiVnegSs+ZHVymyidtK472syodx1sXYlYJJixZfRstHVGYTi8V1O7QG4nsjyb0PC/LORcq7sfBUcHto1y6UgJA==", "dev": true, "peer": true, "requires": { - "safer-buffer": "~2.1.0" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "dev": true, - "peer": true - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true, - "peer": true - }, - "astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true, - "peer": true + "fs-extra": "^9.1.0" + }, + "dependencies": { + "fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "peer": true, + "requires": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "peer": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "peer": true + } + } }, - "async": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", - "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "@types/bn.js": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.5.tgz", + "integrity": "sha512-V46N0zwKRF5Q00AZ6hWtN0T8gGmDUaUzLWQvHFo5yThtVwK/VCenFY3wXVbOvNfajEpsTfQM4IN9k/d6gUVX3A==", "dev": true, "requires": { - "lodash": "^4.17.14" + "@types/node": "*" } }, - "async-retry": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz", - "integrity": "sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==", + "@types/cacheable-request": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", + "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", "dev": true, "requires": { - "retry": "0.13.1" + "@types/http-cache-semantics": "*", + "@types/keyv": "^3.1.4", + "@types/node": "*", + "@types/responselike": "^1.0.0" } }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true, - "peer": true - }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "dev": true, - "peer": true - }, - "available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", - "dev": true, - "peer": true + "@types/chai": { + "version": "4.3.11", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.11.tgz", + "integrity": "sha512-qQR1dr2rGIHYlJulmr8Ioq3De0Le9E4MJ5AiaeAETJJpndT1uUNHsGFK3L/UIu+rbkQSdj8J/w2bCsBZc/Y5fQ==", + "dev": true }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", + "@types/chai-as-promised": { + "version": "7.1.8", + "resolved": "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-7.1.8.tgz", + "integrity": "sha512-ThlRVIJhr69FLlh6IctTXFkmhtP3NpMZ2QGq69StYLyKZFp/HOp1VdKZj7RvfNWYYcJ1xlbLGLLWj1UvP5u/Gw==", "dev": true, - "peer": true + "requires": { + "@types/chai": "*" + } }, - "aws4": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz", - "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==", - "dev": true, - "peer": true + "@types/cli-table": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@types/cli-table/-/cli-table-0.3.4.tgz", + "integrity": "sha512-GsALrTL69mlwbAw/MHF1IPTadSLZQnsxe7a80G8l4inN/iEXCOcVeT/S7aRc6hbhqzL9qZ314kHPDQnQ3ev+HA==", + "dev": true }, - "axios": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", + "@types/concat-stream": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.1.tgz", + "integrity": "sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==", "dev": true, + "peer": true, "requires": { - "follow-redirects": "^1.14.0" + "@types/node": "*" } }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "@types/figlet": { + "version": "1.5.8", + "resolved": "https://registry.npmjs.org/@types/figlet/-/figlet-1.5.8.tgz", + "integrity": "sha512-G22AUvy4Tl95XLE7jmUM8s8mKcoz+Hr+Xm9W90gJsppJq9f9tHvOGkrpn4gRX0q/cLtBdNkWtWCKDg2UDZoZvQ==", "dev": true }, - "base-x": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", - "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", + "@types/form-data": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz", + "integrity": "sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==", "dev": true, + "peer": true, "requires": { - "safe-buffer": "^5.0.1" + "@types/node": "*" } }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "@types/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", "dev": true, "peer": true, "requires": { - "tweetnacl": "^0.14.3" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", - "dev": true, - "peer": true - } + "@types/minimatch": "*", + "@types/node": "*" } }, - "bech32": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", - "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==", + "@types/http-cache-semantics": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", + "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", "dev": true }, - "bigint-crypto-utils": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/bigint-crypto-utils/-/bigint-crypto-utils-3.2.2.tgz", - "integrity": "sha512-U1RbE3aX9ayCUVcIPHuPDPKcK3SFOXf93J1UK/iHlJuQB7bhagPIX06/CLpLEsDThJ7KA4Dhrnzynl+d2weTiw==", + "@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true }, - "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "@types/keyv": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", + "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==", "dev": true }, - "blakejs": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", - "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==", + "@types/minimatch": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", + "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", + "dev": true, + "peer": true + }, + "@types/mocha": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.1.tgz", + "integrity": "sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw==", "dev": true }, - "bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", + "@types/node": { + "version": "17.0.45", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", + "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==", "dev": true }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "@types/pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-uRwJqmiXmh9++aSu1VNEn3iIxWOhd8AHXNSdlaLfdAAdSTY9jYVeGWnzejM3dvrkbqE3/hyQkQQ29IFATEGlew==", "dev": true, "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "@types/node": "*" } }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "@types/prettier": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.3.tgz", + "integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==", + "dev": true, + "peer": true + }, + "@types/qs": { + "version": "6.9.10", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.10.tgz", + "integrity": "sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw==", + "dev": true, + "peer": true + }, + "@types/readable-stream": { + "version": "2.3.15", + "resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-2.3.15.tgz", + "integrity": "sha512-oM5JSKQCcICF1wvGgmecmHldZ48OZamtMxcGGVICOJA8o8cahXC1zEVAif8iwoc5j8etxFaRFnf095+CDsuoFQ==", "dev": true, "requires": { - "fill-range": "^7.0.1" + "@types/node": "*", + "safe-buffer": "~5.1.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } } }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", - "dev": true + "@types/responselike": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz", + "integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==", + "dev": true, + "requires": { + "@types/node": "*" + } }, - "browser-level": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browser-level/-/browser-level-1.0.1.tgz", - "integrity": "sha512-XECYKJ+Dbzw0lbydyQuJzwNXtOpbMSq737qxJN11sIRTErOMShvDpbzTlgju7orJKvx4epULolZAuJGLzCmWRQ==", + "@types/secp256k1": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.6.tgz", + "integrity": "sha512-hHxJU6PAEUn0TP4S/ZOzuTUvJWuZ6eIKeNKb5RBpODvSl6hp1Wrw4s7ATY50rklRCScUDpHzVA/DQdSjJ3UoYQ==", "dev": true, "requires": { - "abstract-level": "^1.0.2", - "catering": "^2.1.1", - "module-error": "^1.0.2", - "run-parallel-limit": "^1.1.0" + "@types/node": "*" } }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "@types/semver": { + "version": "7.5.6", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz", + "integrity": "sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==", "dev": true }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "@types/underscore": { + "version": "1.11.15", + "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.11.15.tgz", + "integrity": "sha512-HP38xE+GuWGlbSRq9WrZkousaQ7dragtZCruBVMi0oX1migFZavZ3OROKHSkNp/9ouq82zrWtZpg18jFnVN96g==", + "dev": true + }, + "@types/yargs": { + "version": "17.0.32", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", "dev": true, "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "@types/yargs-parser": "*" } }, - "bs58": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", - "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "dev": true + }, + "@typescript-eslint/eslint-plugin": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", + "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==", "dev": true, "requires": { - "base-x": "^3.0.2" + "@eslint-community/regexpp": "^4.4.0", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/type-utils": "5.62.0", + "@typescript-eslint/utils": "5.62.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "natural-compare-lite": "^1.4.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } } }, - "bs58check": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", - "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", + "@typescript-eslint/parser": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", + "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", "dev": true, + "peer": true, "requires": { - "bs58": "^4.0.0", - "create-hash": "^1.1.0", - "safe-buffer": "^5.1.2" + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", + "debug": "^4.3.4" } }, - "buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "@typescript-eslint/scope-manager": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", + "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", "dev": true, "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0" } }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", - "dev": true - }, - "busboy": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", - "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "@typescript-eslint/type-utils": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz", + "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==", "dev": true, "requires": { - "streamsearch": "^1.1.0" + "@typescript-eslint/typescript-estree": "5.62.0", + "@typescript-eslint/utils": "5.62.0", + "debug": "^4.3.4", + "tsutils": "^3.21.0" } }, - "bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "@typescript-eslint/types": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", + "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", "dev": true }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "@typescript-eslint/typescript-estree": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", + "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", "dev": true, "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } } }, - "caller-callsite": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", - "integrity": "sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ==", + "@typescript-eslint/utils": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", + "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", "dev": true, "requires": { - "callsites": "^2.0.0" + "@eslint-community/eslint-utils": "^4.2.0", + "@types/json-schema": "^7.0.9", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", + "eslint-scope": "^5.1.1", + "semver": "^7.3.7" }, "dependencies": { - "callsites": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", - "integrity": "sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ==", + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true } } }, - "caller-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", - "integrity": "sha512-MCL3sf6nCSXOwCTzvPKhN18TU7AHTvdtam8DAogxcrJ8Rjfbbg7Lgng64H9Iy+vUV6VGFClN/TyxBkAebLRR4A==", + "@typescript-eslint/visitor-keys": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", + "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", "dev": true, "requires": { - "caller-callsite": "^2.0.0" + "@typescript-eslint/types": "5.62.0", + "eslint-visitor-keys": "^3.3.0" } }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, - "camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true - }, - "case": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/case/-/case-1.6.3.tgz", - "integrity": "sha512-mzDSXIPaFwVDvZAHqZ9VlbyF4yyXRuX6IvB06WvPYkqJVO24kX1PPhv9bfpKNFZyxYFmmgo03HUiD8iklmJYRQ==", + "@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", "dev": true }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", + "abbrev": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", + "integrity": "sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q==", "dev": true, "peer": true }, - "catering": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/catering/-/catering-2.1.1.tgz", - "integrity": "sha512-K7Qy8O9p76sL3/3m7/zLKbRkyOlSZAgzEaLhyj2mXS8PsCud2Eo4hAb8aLtZqHh0QGqLcb9dlJSu6lHRVENm1w==", - "dev": true - }, - "cbor": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/cbor/-/cbor-8.1.0.tgz", - "integrity": "sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg==", + "abstract-level": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/abstract-level/-/abstract-level-1.0.3.tgz", + "integrity": "sha512-t6jv+xHy+VYwc4xqZMn2Pa9DjcdzvzZmQGRjTFc8spIbRGHgBrEKbPq+rYXc7CCo0lxgYvSgKVg9qZAhpVQSjA==", "dev": true, "requires": { - "nofilter": "^3.1.0" + "buffer": "^6.0.3", + "catering": "^2.1.0", + "is-buffer": "^2.0.5", + "level-supports": "^4.0.0", + "level-transcoder": "^1.0.1", + "module-error": "^1.0.1", + "queue-microtask": "^1.2.3" + }, + "dependencies": { + "buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + } } }, - "chai": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.7.tgz", - "integrity": "sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==", + "accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", "dev": true, - "peer": true, "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^4.1.2", - "get-func-name": "^2.0.0", - "loupe": "^2.3.1", - "pathval": "^1.1.1", - "type-detect": "^4.0.5" + "mime-types": "~2.1.34", + "negotiator": "0.6.3" } }, - "chai-as-promised": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.1.tgz", - "integrity": "sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA==", - "dev": true, - "requires": { - "check-error": "^1.0.2" - } + "acorn": { + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", + "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", + "dev": true }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } + "requires": {} }, - "chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "acorn-walk": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.0.tgz", + "integrity": "sha512-FS7hV565M5l1R08MXqo8odwMTB02C2UqzB17RVgu9EyuYFBqJZ3/ZY97sQD5FewVu1UyDFc1yztUDrAwT0EypA==", "dev": true }, - "charenc": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", - "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", + "address": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/address/-/address-1.2.2.tgz", + "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==", "dev": true, "peer": true }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", - "dev": true + "adm-zip": { + "version": "0.4.16", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz", + "integrity": "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==", + "dev": true }, - "chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "aes-js": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", + "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==", + "dev": true + }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "dev": true, "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "dependencies": { - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - } + "debug": "4" } }, - "ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", "dev": true, "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" } }, - "classic-level": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/classic-level/-/classic-level-1.3.0.tgz", - "integrity": "sha512-iwFAJQYtqRTRM0F6L8h4JCt00ZSGdOyqh7yVrhhjrOpFhmBjNlRUey64MCiyo6UmQHMJ+No3c81nujPv+n9yrg==", + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "requires": { - "abstract-level": "^1.0.2", - "catering": "^2.1.0", - "module-error": "^1.0.1", - "napi-macros": "^2.2.2", - "node-gyp-build": "^4.3.0" + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" } }, - "clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true - }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==", + "amazon-cognito-identity-js": { + "version": "6.3.7", + "resolved": "https://registry.npmjs.org/amazon-cognito-identity-js/-/amazon-cognito-identity-js-6.3.7.tgz", + "integrity": "sha512-tSjnM7KyAeOZ7UMah+oOZ6cW4Gf64FFcc7BE2l7MTcp7ekAPrXaCbpcW2xEpH1EiDS4cPcAouHzmCuc2tr72vQ==", "dev": true, "requires": { - "restore-cursor": "^2.0.0" + "@aws-crypto/sha256-js": "1.2.2", + "buffer": "4.9.2", + "fast-base64-decode": "^1.0.0", + "isomorphic-unfetch": "^3.0.0", + "js-cookie": "^2.2.1" } }, - "cli-table": { - "version": "0.3.11", - "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.11.tgz", - "integrity": "sha512-IqLQi4lO0nIB4tcdTpN4LCB9FI3uqrJZK7RC515EnhZ6qBaglkIgICb1wjeAqpdoOabm1+SuQtkXIPdYC93jhQ==", + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==", + "dev": true, + "optional": true, + "peer": true + }, + "ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true + }, + "ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "dev": true, "requires": { - "colors": "1.0.3" + "type-fest": "^0.21.3" + }, + "dependencies": { + "type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true + } } }, - "cli-table3": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz", - "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==", + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@colors/colors": "1.5.0", - "string-width": "^4.2.0" + "color-convert": "^2.0.1" } }, - "cli-width": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", - "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", + "antlr4": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/antlr4/-/antlr4-4.7.1.tgz", + "integrity": "sha512-haHyTW7Y9joE5MVs37P2lNYfU2RWBLfcRDD8OWldcdZm5TiCE91B5Xl1oWSwiDUSd4rlExpt2pu1fksYQjRBYQ==", "dev": true }, - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "antlr4ts": { + "version": "0.5.0-alpha.4", + "resolved": "https://registry.npmjs.org/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz", + "integrity": "sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ==", + "dev": true, + "peer": true + }, + "anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" } }, - "color-convert": { + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "argparse": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "array-back": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", + "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", + "dev": true, + "peer": true + }, + "array-buffer-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", + "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", "dev": true, "requires": { - "color-name": "~1.1.4" + "call-bind": "^1.0.2", + "is-array-buffer": "^3.0.1" } }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", "dev": true }, - "colors": { + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, + "array-uniq": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", - "integrity": "sha512-pFGrxThWcWQ2MsAz6RtgeWe4NK2kUE1WfsrvvlctdII745EW9I0yflqhe7++M5LEc7bV2c/9/5zc8sFcpL0Drw==", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", "dev": true }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "array.prototype.findlast": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.3.tgz", + "integrity": "sha512-kcBubumjciBg4JKp5KTKtI7ec7tRefPk88yjkWJwaVKYd9QfTaxcsOxoMNKd7iBr447zCfDV0z1kOF47umv42g==", "dev": true, - "peer": true, "requires": { - "delayed-stream": "~1.0.0" + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0", + "get-intrinsic": "^1.2.1" } }, - "command-exists": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz", - "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==", - "dev": true - }, - "command-line-args": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.2.1.tgz", - "integrity": "sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==", + "arraybuffer.prototype.slice": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz", + "integrity": "sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==", "dev": true, - "peer": true, "requires": { - "array-back": "^3.1.0", - "find-replace": "^3.0.0", - "lodash.camelcase": "^4.3.0", - "typical": "^4.0.0" + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "is-array-buffer": "^3.0.2", + "is-shared-array-buffer": "^1.0.2" } }, - "command-line-usage": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-6.1.3.tgz", - "integrity": "sha512-sH5ZSPr+7UStsloltmDh7Ce5fb8XPlHyoPzTpyyMuYCtervL65+ubVZ6Q61cFtFl62UyJlc8/JwERRbAFPUqgw==", + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", "dev": true, - "peer": true, - "requires": { - "array-back": "^4.0.2", - "chalk": "^2.4.2", - "table-layout": "^1.0.2", - "typical": "^5.2.0" + "peer": true + }, + "asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "dev": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "asn1.js": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", + "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + } + } + }, + "assert": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-2.1.0.tgz", + "integrity": "sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "is-nan": "^1.3.2", + "object-is": "^1.1.5", + "object.assign": "^4.1.4", + "util": "^0.12.5" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "dev": true + }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, + "peer": true + }, + "astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "peer": true + }, + "async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "dev": true, + "requires": { + "lodash": "^4.17.14" + } + }, + "async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", + "dev": true + }, + "async-retry": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz", + "integrity": "sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==", + "dev": true, + "requires": { + "retry": "0.13.1" + } + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true + }, + "at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true, + "peer": true + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true + }, + "available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "dev": true + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", + "dev": true + }, + "aws4": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz", + "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==", + "dev": true + }, + "axios": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.2.tgz", + "integrity": "sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==", + "dev": true, + "requires": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "base-x": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", + "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "dev": true, + "requires": { + "tweetnacl": "^0.14.3" + }, + "dependencies": { + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", + "dev": true + } + } + }, + "bech32": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", + "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==", + "dev": true + }, + "bigint-crypto-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/bigint-crypto-utils/-/bigint-crypto-utils-3.3.0.tgz", + "integrity": "sha512-jOTSb+drvEDxEq6OuUybOAv/xxoh3cuYRUIPyu8sSHQNKM303UQ2R1DAo45o1AkcIXw6fzbaFI1+xGGdaXs2lg==", + "dev": true + }, + "bignumber.js": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", + "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", + "dev": true + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, + "blakejs": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", + "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==", + "dev": true + }, + "bls-eth-wasm": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/bls-eth-wasm/-/bls-eth-wasm-1.1.1.tgz", + "integrity": "sha512-yaoOHCgjICZc2qTpYCvIkJ6L4N2MXBNmdhIpTZGmKZOUc3mmU941EV95qMK02apyYRSKuCydPuCN3fK4o24C1g==", + "dev": true + }, + "bls-signatures": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/bls-signatures/-/bls-signatures-0.2.5.tgz", + "integrity": "sha512-5TzQNCtR4zWE4lM08EOMIT8l3b4h8g5LNKu50fUYP1PnupaLGSLklAcTto4lnH7VXpyhsar+74L9wNJII4E/4Q==", + "dev": true + }, + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", + "dev": true + }, + "body-parser": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "dev": true, + "requires": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dev": true, + "requires": { + "side-channel": "^1.0.4" + } + } + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", + "dev": true + }, + "browser-level": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browser-level/-/browser-level-1.0.1.tgz", + "integrity": "sha512-XECYKJ+Dbzw0lbydyQuJzwNXtOpbMSq737qxJN11sIRTErOMShvDpbzTlgju7orJKvx4epULolZAuJGLzCmWRQ==", + "dev": true, + "requires": { + "abstract-level": "^1.0.2", + "catering": "^2.1.1", + "module-error": "^1.0.2", + "run-parallel-limit": "^1.1.0" + } + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, + "requires": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "dev": true, + "requires": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "browserify-rsa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", + "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", + "dev": true, + "requires": { + "bn.js": "^5.0.0", + "randombytes": "^2.0.1" + } + }, + "browserify-sign": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.2.tgz", + "integrity": "sha512-1rudGyeYY42Dk6texmv7c4VcQ0EsvVbLwZkA+AQB7SxvXxmcD93jcHie8bzecJ+ChDlmAm2Qyu0+Ccg5uhZXCg==", + "dev": true, + "requires": { + "bn.js": "^5.2.1", + "browserify-rsa": "^4.1.0", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.4", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.6", + "readable-stream": "^3.6.2", + "safe-buffer": "^5.2.1" + } + }, + "bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "dev": true, + "requires": { + "base-x": "^3.0.2" + } + }, + "bs58check": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", + "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", + "dev": true, + "requires": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, + "btoa": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/btoa/-/btoa-1.2.1.tgz", + "integrity": "sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g==", + "dev": true + }, + "buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "buffer-to-arraybuffer": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz", + "integrity": "sha512-3dthu5CYiVB1DEJp61FtApNnNndTckcqe4pFcLdvHtrpG+kcyekCJKg4MRiDcFW7A6AODnXB9U4dwQiCW5kzJQ==", + "dev": true + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", + "dev": true + }, + "bufferutil": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.8.tgz", + "integrity": "sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==", + "dev": true, + "requires": { + "node-gyp-build": "^4.3.0" + } + }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha512-wxXCdllwGhI2kCC0MnvTGYTMvnVZTvqgypkiTI8Pa5tcz2i6VqsqwYGgqwXji+4RgCzms6EajE4IxiUH6HH8nQ==", + "dev": true + }, + "bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true + }, + "cacheable-lookup": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", + "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", + "dev": true + }, + "cacheable-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", + "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "dev": true, + "requires": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "dependencies": { + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==", + "dev": true + }, + "keyv": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", + "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "dev": true, + "requires": { + "json-buffer": "3.0.0" + } + }, + "lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true + } + } + }, + "call-bind": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", + "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", + "dev": true, + "requires": { + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.1", + "set-function-length": "^1.1.1" + } + }, + "caller-callsite": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", + "integrity": "sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ==", + "dev": true, + "requires": { + "callsites": "^2.0.0" + }, + "dependencies": { + "callsites": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ==", + "dev": true + } + } + }, + "caller-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", + "integrity": "sha512-MCL3sf6nCSXOwCTzvPKhN18TU7AHTvdtam8DAogxcrJ8Rjfbbg7Lgng64H9Iy+vUV6VGFClN/TyxBkAebLRR4A==", + "dev": true, + "requires": { + "caller-callsite": "^2.0.0" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true + }, + "case": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/case/-/case-1.6.3.tgz", + "integrity": "sha512-mzDSXIPaFwVDvZAHqZ9VlbyF4yyXRuX6IvB06WvPYkqJVO24kX1PPhv9bfpKNFZyxYFmmgo03HUiD8iklmJYRQ==", + "dev": true + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", + "dev": true + }, + "catering": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/catering/-/catering-2.1.1.tgz", + "integrity": "sha512-K7Qy8O9p76sL3/3m7/zLKbRkyOlSZAgzEaLhyj2mXS8PsCud2Eo4hAb8aLtZqHh0QGqLcb9dlJSu6lHRVENm1w==", + "dev": true + }, + "cbor": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/cbor/-/cbor-8.1.0.tgz", + "integrity": "sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg==", + "dev": true, + "peer": true, + "requires": { + "nofilter": "^3.1.0" + } + }, + "chai": { + "version": "4.3.10", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.10.tgz", + "integrity": "sha512-0UXG04VuVbruMUYbJ6JctvH0YnC/4q3/AkT18q4NaITo91CUm0liMS9VqzT9vZhVQ/1eqPanMWjBM+Juhfb/9g==", + "dev": true, + "peer": true, + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", + "pathval": "^1.1.1", + "type-detect": "^4.0.8" + } + }, + "chai-as-promised": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.1.tgz", + "integrity": "sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA==", + "dev": true, + "requires": { + "check-error": "^1.0.2" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "charenc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", + "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", + "dev": true, + "peer": true + }, + "check-error": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "dev": true, + "requires": { + "get-func-name": "^2.0.2" + } + }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "dependencies": { + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + } + } + }, + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "cids": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/cids/-/cids-0.7.5.tgz", + "integrity": "sha512-zT7mPeghoWAu+ppn8+BS1tQ5qGmbMfB4AregnQjA/qHY3GC1m1ptI9GkWNlgeu38r7CuRdXB47uY2XgAYt6QVA==", + "dev": true, + "requires": { + "buffer": "^5.5.0", + "class-is": "^1.1.0", + "multibase": "~0.6.0", + "multicodec": "^1.0.0", + "multihashes": "~0.4.15" + }, + "dependencies": { + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "multicodec": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-1.0.4.tgz", + "integrity": "sha512-NDd7FeS3QamVtbgfvu5h7fd1IlbaC4EQ0/pgU4zqE2vdHCmBGsUa0TiM8/TdSeG6BMPC92OOCf8F1ocE/Wkrrg==", + "dev": true, + "requires": { + "buffer": "^5.6.0", + "varint": "^5.0.0" + } + } + } + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "class-is": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/class-is/-/class-is-1.1.0.tgz", + "integrity": "sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw==", + "dev": true + }, + "class-validator": { + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/class-validator/-/class-validator-0.13.2.tgz", + "integrity": "sha512-yBUcQy07FPlGzUjoLuUfIOXzgynnQPPruyK1Ge2B74k9ROwnle1E+NxLWnUv5OLU8hA/qL5leAE9XnXq3byaBw==", + "dev": true, + "requires": { + "libphonenumber-js": "^1.9.43", + "validator": "^13.7.0" + } + }, + "classic-level": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/classic-level/-/classic-level-1.3.0.tgz", + "integrity": "sha512-iwFAJQYtqRTRM0F6L8h4JCt00ZSGdOyqh7yVrhhjrOpFhmBjNlRUey64MCiyo6UmQHMJ+No3c81nujPv+n9yrg==", + "dev": true, + "requires": { + "abstract-level": "^1.0.2", + "catering": "^2.1.0", + "module-error": "^1.0.1", + "napi-macros": "^2.2.2", + "node-gyp-build": "^4.3.0" + } + }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==", + "dev": true, + "requires": { + "restore-cursor": "^2.0.0" + } + }, + "cli-table": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.11.tgz", + "integrity": "sha512-IqLQi4lO0nIB4tcdTpN4LCB9FI3uqrJZK7RC515EnhZ6qBaglkIgICb1wjeAqpdoOabm1+SuQtkXIPdYC93jhQ==", + "dev": true, + "requires": { + "colors": "1.0.3" + } + }, + "cli-table3": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz", + "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==", + "dev": true, + "requires": { + "@colors/colors": "1.5.0", + "string-width": "^4.2.0" + } + }, + "cli-width": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", + "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", + "dev": true + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "clone-response": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", + "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "colors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", + "integrity": "sha512-pFGrxThWcWQ2MsAz6RtgeWe4NK2kUE1WfsrvvlctdII745EW9I0yflqhe7++M5LEc7bV2c/9/5zc8sFcpL0Drw==", + "dev": true + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "command-exists": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz", + "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==", + "dev": true + }, + "command-line-args": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.2.1.tgz", + "integrity": "sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==", + "dev": true, + "peer": true, + "requires": { + "array-back": "^3.1.0", + "find-replace": "^3.0.0", + "lodash.camelcase": "^4.3.0", + "typical": "^4.0.0" + } + }, + "command-line-usage": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-6.1.3.tgz", + "integrity": "sha512-sH5ZSPr+7UStsloltmDh7Ce5fb8XPlHyoPzTpyyMuYCtervL65+ubVZ6Q61cFtFl62UyJlc8/JwERRbAFPUqgw==", + "dev": true, + "peer": true, + "requires": { + "array-back": "^4.0.2", + "chalk": "^2.4.2", + "table-layout": "^1.0.2", + "typical": "^5.2.0" }, "dependencies": { "ansi-styles": { @@ -15051,9 +17869,9 @@ "dev": true }, "compare-versions": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-5.0.3.tgz", - "integrity": "sha512-4UZlZP8Z99MGEY+Ovg/uJxJuvoXuN4M6B3hKaiackiHrgzQFEe3diJi1mf1PNHbFujM7FvLrK2bpgIaImbtZ1A==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-6.1.0.tgz", + "integrity": "sha512-LNZQXhqUvqUTotpZ00qLSaify3b4VFD588aRr8MKFw4CMUr98ytzCW5wDH5qx/DEY5kCDXcbcRuCqL0szEf2tg==", "dev": true }, "concat-map": { @@ -15110,18 +17928,65 @@ } } }, + "content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "requires": { + "safe-buffer": "5.2.1" + } + }, + "content-hash": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/content-hash/-/content-hash-2.5.2.tgz", + "integrity": "sha512-FvIQKy0S1JaWV10sMsA7TRx8bpU+pqPkhbsfvOJAdjRXvYxEckAwQWGwtRjiaJfh+E0DvcWUGqcdjwMGFjsSdw==", + "dev": true, + "requires": { + "cids": "^0.7.1", + "multicodec": "^0.5.5", + "multihashes": "^0.4.15" + } + }, + "content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "dev": true + }, "cookie": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", "dev": true }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "dev": true + }, + "cookiejar": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz", + "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==", + "dev": true + }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "dev": true + }, + "cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", "dev": true, - "peer": true + "requires": { + "object-assign": "^4", + "vary": "^1" + } }, "cosmiconfig": { "version": "5.2.1", @@ -15184,6 +18049,24 @@ "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", "dev": true }, + "create-ecdh": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", + "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "elliptic": "^6.5.3" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + } + } + }, "create-hash": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", @@ -15235,12 +18118,46 @@ "dev": true, "peer": true }, + "crypto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/crypto/-/crypto-1.0.1.tgz", + "integrity": "sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig==", + "dev": true + }, + "crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "requires": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + } + }, + "d": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "dev": true, + "requires": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, "dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", "dev": true, - "peer": true, "requires": { "assert-plus": "^1.0.0" } @@ -15267,6 +18184,21 @@ "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", "dev": true }, + "decode-uri-component": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", + "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", + "dev": true + }, + "decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, "deep-eql": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", @@ -15290,13 +18222,30 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, + "defer-to-connect": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", + "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", + "dev": true + }, + "define-data-property": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", + "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "dev": true, + "requires": { + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + } + }, "define-properties": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", - "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", "dev": true, - "peer": true, "requires": { + "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" } @@ -15305,8 +18254,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true, - "peer": true + "dev": true }, "delete-empty": { "version": "3.0.0", @@ -15337,6 +18285,22 @@ "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", "dev": true }, + "des.js": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.1.0.tgz", + "integrity": "sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true + }, "detect-port": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.5.1.tgz", @@ -15354,6 +18318,25 @@ "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", "dev": true }, + "diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + } + } + }, "difflib": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/difflib/-/difflib-0.2.4.tgz", @@ -15382,23 +18365,40 @@ "esutils": "^2.0.2" } }, + "dom-walk": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", + "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==", + "dev": true + }, "dotenv": { "version": "16.3.1", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==", "dev": true }, + "duplexer3": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.5.tgz", + "integrity": "sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==", + "dev": true + }, "ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", "dev": true, - "peer": true, "requires": { "jsbn": "~0.1.0", "safer-buffer": "^2.1.0" } }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true + }, "elliptic": { "version": "6.5.4", "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", @@ -15428,858 +18428,532 @@ "integrity": "sha512-k0/r7GrWVL32kZlGwfPNgB2Y/mMXVTq/decgLczm/j34whdaspNrZO8CnXPf1laaHxI6ptUlsnAxN+UAPw+fzg==", "dev": true }, + "emitter-component": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/emitter-component/-/emitter-component-1.1.2.tgz", + "integrity": "sha512-QdXO3nXOzZB4pAjM0n6ZE+R9/+kPpECA/XSELIcc54NeYVnBqIk+4DFiBgK+8QbV3mdvTG6nedl7dTYgO+5wDw==", + "dev": true + }, "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, - "enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "requires": { - "ansi-colors": "^4.1.1" - } - }, - "env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "dev": true - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es-abstract": { - "version": "1.21.2", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.2.tgz", - "integrity": "sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg==", - "dev": true, - "peer": true, - "requires": { - "array-buffer-byte-length": "^1.0.0", - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-set-tostringtag": "^2.0.1", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.2.0", - "get-symbol-description": "^1.0.0", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", - "has": "^1.0.3", - "has-property-descriptors": "^1.0.0", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.5", - "is-array-buffer": "^3.0.2", - "is-callable": "^1.2.7", - "is-negative-zero": "^2.0.2", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.10", - "is-weakref": "^1.0.2", - "object-inspect": "^1.12.3", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.4.3", - "safe-regex-test": "^1.0.0", - "string.prototype.trim": "^1.2.7", - "string.prototype.trimend": "^1.0.6", - "string.prototype.trimstart": "^1.0.6", - "typed-array-length": "^1.0.4", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.9" - }, - "dependencies": { - "object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", - "dev": true, - "peer": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - } - } - } - }, - "es-array-method-boxes-properly": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", - "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", - "dev": true, - "peer": true - }, - "es-set-tostringtag": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", - "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", - "dev": true, - "peer": true, - "requires": { - "get-intrinsic": "^1.1.3", - "has": "^1.0.3", - "has-tostringtag": "^1.0.0" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "peer": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", "dev": true }, - "escodegen": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", - "integrity": "sha512-yhi5S+mNTOuRvyW4gWlg5W1byMaQGWWSYHXsuFZ7GBo7tpyOwi2EdzMP/QWxh9hwkD2m+wDVHJsxhRIj+v/b/A==", - "dev": true, - "peer": true, - "requires": { - "esprima": "^2.7.1", - "estraverse": "^1.9.1", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.2.0" - }, - "dependencies": { - "estraverse": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", - "integrity": "sha512-25w1fMXQrGdoquWnScXZGckOv+Wes+JDnuN/+7ex3SauFRS72r2lFDec0EKPt2YD1wUJ/IrfEex+9yp4hfSOJA==", - "dev": true, - "peer": true - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "dev": true, - "peer": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, - "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "peer": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - } - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", - "dev": true, - "peer": true - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", - "dev": true, - "peer": true, - "requires": { - "prelude-ls": "~1.1.2" - } - } - } - }, - "eslint": { - "version": "8.43.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.43.0.tgz", - "integrity": "sha512-aaCpf2JqqKesMFGgmRPessmVKjcGXqdlAYLLC3THM8t5nBRZRQ+st5WM/hoJXkdioEXLLbXgclUpM0TXo5HX5Q==", - "dev": true, - "requires": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.4.0", - "@eslint/eslintrc": "^2.0.3", - "@eslint/js": "8.43.0", - "@humanwhocodes/config-array": "^0.11.10", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.0", - "eslint-visitor-keys": "^3.4.1", - "espree": "^9.5.2", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0" - }, - "dependencies": { - "eslint-scope": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", - "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - } - }, - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - } - } - }, - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", "dev": true, "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" + "once": "^1.4.0" } }, - "eslint-utils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", - "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", + "enquirer": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", + "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", "dev": true, "requires": { - "eslint-visitor-keys": "^1.1.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - } + "ansi-colors": "^4.1.1", + "strip-ansi": "^6.0.1" } }, - "eslint-visitor-keys": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", - "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", + "env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", "dev": true }, - "espree": { - "version": "9.5.2", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz", - "integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==", + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, "requires": { - "acorn": "^8.8.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" + "is-arrayish": "^0.2.1" } }, - "esprima": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha512-OarPfz0lFCiW4/AV2Oy1Rp9qu0iusTKqykwTspGCZtPxmF81JR4MmIebvF1F9+UOKth2ZubLQ4XGGaU+hSn99A==", + "es-abstract": { + "version": "1.22.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.3.tgz", + "integrity": "sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA==", "dev": true, - "peer": true + "requires": { + "array-buffer-byte-length": "^1.0.0", + "arraybuffer.prototype.slice": "^1.0.2", + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.5", + "es-set-tostringtag": "^2.0.1", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.2", + "get-symbol-description": "^1.0.0", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0", + "internal-slot": "^1.0.5", + "is-array-buffer": "^3.0.2", + "is-callable": "^1.2.7", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.12", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.1", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.1", + "safe-array-concat": "^1.0.1", + "safe-regex-test": "^1.0.0", + "string.prototype.trim": "^1.2.8", + "string.prototype.trimend": "^1.0.7", + "string.prototype.trimstart": "^1.0.7", + "typed-array-buffer": "^1.0.0", + "typed-array-byte-length": "^1.0.0", + "typed-array-byte-offset": "^1.0.0", + "typed-array-length": "^1.0.4", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.13" + } }, - "esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "es-set-tostringtag": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz", + "integrity": "sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==", "dev": true, "requires": { - "estraverse": "^5.1.0" - }, - "dependencies": { - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - } + "get-intrinsic": "^1.2.2", + "has-tostringtag": "^1.0.0", + "hasown": "^2.0.0" } }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "es-shim-unscopables": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", + "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", "dev": true, "requires": { - "estraverse": "^5.2.0" - }, - "dependencies": { - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - } + "hasown": "^2.0.0" } }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } }, - "esutils": { + "es5-ext": { + "version": "0.10.62", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", + "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", + "dev": true, + "requires": { + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "next-tick": "^1.1.0" + } + }, + "es6-iterator": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } }, - "eth-gas-reporter": { - "version": "0.2.25", - "resolved": "https://registry.npmjs.org/eth-gas-reporter/-/eth-gas-reporter-0.2.25.tgz", - "integrity": "sha512-1fRgyE4xUB8SoqLgN3eDfpDfwEfRxh2Sz1b7wzFbyQA+9TekMmvSjjoRu9SKcSVyK+vLkLIsVbJDsTWjw195OQ==", + "es6-symbol": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", + "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", "dev": true, - "peer": true, "requires": { - "@ethersproject/abi": "^5.0.0-beta.146", - "@solidity-parser/parser": "^0.14.0", - "cli-table3": "^0.5.0", - "colors": "1.4.0", - "ethereum-cryptography": "^1.0.3", - "ethers": "^4.0.40", - "fs-readdir-recursive": "^1.1.0", - "lodash": "^4.17.14", - "markdown-table": "^1.1.3", - "mocha": "^7.1.1", - "req-cwd": "^2.0.0", - "request": "^2.88.0", - "request-promise-native": "^1.0.5", - "sha1": "^1.1.1", - "sync-request": "^6.0.0" - }, - "dependencies": { - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true, - "peer": true - }, - "ansi-regex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", - "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", - "dev": true, - "peer": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "peer": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "peer": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true, - "peer": true - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "peer": true - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "peer": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "peer": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", - "dev": true, - "peer": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - } - }, - "cli-table3": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.5.1.tgz", - "integrity": "sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==", - "dev": true, - "peer": true, - "requires": { - "colors": "^1.1.2", - "object-assign": "^4.1.0", - "string-width": "^2.1.1" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "peer": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "dev": true, - "peer": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "peer": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "peer": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "color-convert": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "escodegen": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", + "integrity": "sha512-yhi5S+mNTOuRvyW4gWlg5W1byMaQGWWSYHXsuFZ7GBo7tpyOwi2EdzMP/QWxh9hwkD2m+wDVHJsxhRIj+v/b/A==", + "dev": true, + "peer": true, + "requires": { + "esprima": "^2.7.1", + "estraverse": "^1.9.1", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.2.0" + }, + "dependencies": { + "estraverse": { "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "peer": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true, - "peer": true - }, - "colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "dev": true, - "peer": true - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "peer": true, - "requires": { - "ms": "^2.1.1" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true, - "peer": true - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true, - "peer": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true, - "peer": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "peer": true - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", + "integrity": "sha512-25w1fMXQrGdoquWnScXZGckOv+Wes+JDnuN/+7ex3SauFRS72r2lFDec0EKPt2YD1wUJ/IrfEex+9yp4hfSOJA==", "dev": true, "peer": true }, - "ethereum-cryptography": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.2.0.tgz", - "integrity": "sha512-6yFQC9b5ug6/17CQpCyE3k9eKBMdhyVjzUy1WkiuY/E4vj/SXDBbCw8QEIaXqf0Mf2SnY6RmpDcwlUmBSS0EJw==", - "dev": true, - "peer": true, - "requires": { - "@noble/hashes": "1.2.0", - "@noble/secp256k1": "1.7.1", - "@scure/bip32": "1.1.5", - "@scure/bip39": "1.1.1" - } - }, - "ethers": { - "version": "4.0.49", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.49.tgz", - "integrity": "sha512-kPltTvWiyu+OktYy1IStSO16i2e7cS9D9OxZ81q2UUaiNPVrm/RTcbxamCXF9VUSKzJIdJV68EAIhTEVBalRWg==", - "dev": true, - "peer": true, - "requires": { - "aes-js": "3.0.0", - "bn.js": "^4.11.9", - "elliptic": "6.5.4", - "hash.js": "1.1.3", - "js-sha3": "0.5.7", - "scrypt-js": "2.0.4", - "setimmediate": "1.0.4", - "uuid": "2.0.1", - "xmlhttprequest": "1.8.0" - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", "dev": true, "peer": true, "requires": { - "locate-path": "^3.0.0" + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" } }, - "flat": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz", - "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==", + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", "dev": true, "peer": true, "requires": { - "is-buffer": "~2.0.3" + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" } }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", "dev": true, - "optional": true, "peer": true }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "peer": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", "dev": true, "peer": true, "requires": { - "is-glob": "^4.0.1" + "prelude-ls": "~1.1.2" } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "peer": true - }, - "hash.js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", - "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", + } + } + }, + "eslint": { + "version": "8.55.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.55.0.tgz", + "integrity": "sha512-iyUUAM0PCKj5QpwGfmCAG9XXbZCWsqP/eWAWrG/W0umvjuLRBECwSFdt+rCntju0xEH7teIABPwXpahftIaTdA==", + "dev": true, + "requires": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.55.0", + "@humanwhocodes/config-array": "^0.11.13", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "dependencies": { + "eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, - "peer": true, "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.0" + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" } }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "dev": true, - "peer": true - }, + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + } + } + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", + "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } + } + }, + "eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true + }, + "espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "requires": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + } + }, + "esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha512-OarPfz0lFCiW4/AV2Oy1Rp9qu0iusTKqykwTspGCZtPxmF81JR4MmIebvF1F9+UOKth2ZubLQ4XGGaU+hSn99A==", + "dev": true, + "peer": true + }, + "esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + } + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + } + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true + }, + "eth-ens-namehash": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz", + "integrity": "sha512-VWEI1+KJfz4Km//dadyvBBoBeSQ0MHTXPvr8UIXiLW6IanxvAV+DmlZAijZwAyggqGUfwQBeHf7tc9wzc1piSw==", + "dev": true, + "requires": { + "idna-uts46-hx": "^2.3.1", + "js-sha3": "^0.5.7" + }, + "dependencies": { "js-sha3": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", "integrity": "sha512-GII20kjaPX0zJ8wzkTbNDYMY7msuZcTWk8S5UOh6806Jq/wz1J8/bnr8uGU0DAUmYDjj2Mr4X1cW8v/GLYnR+g==", + "dev": true + } + } + }, + "eth-gas-reporter": { + "version": "0.2.27", + "resolved": "https://registry.npmjs.org/eth-gas-reporter/-/eth-gas-reporter-0.2.27.tgz", + "integrity": "sha512-femhvoAM7wL0GcI8ozTdxfuBtBFJ9qsyIAsmKVjlWAHUbdnnXHt+lKzz/kmldM5lA9jLuNHGwuIxorNpLbR1Zw==", + "dev": true, + "peer": true, + "requires": { + "@solidity-parser/parser": "^0.14.0", + "axios": "^1.5.1", + "cli-table3": "^0.5.0", + "colors": "1.4.0", + "ethereum-cryptography": "^1.0.3", + "ethers": "^5.7.2", + "fs-readdir-recursive": "^1.1.0", + "lodash": "^4.17.14", + "markdown-table": "^1.1.3", + "mocha": "^10.2.0", + "req-cwd": "^2.0.0", + "sha1": "^1.1.1", + "sync-request": "^6.0.0" + }, + "dependencies": { + "@noble/hashes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.2.0.tgz", + "integrity": "sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==", "dev": true, "peer": true }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, - "peer": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "peer": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "dev": true, - "peer": true, - "requires": { - "chalk": "^2.4.2" - } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "peer": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "@scure/bip32": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.5.tgz", + "integrity": "sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw==", "dev": true, "peer": true, "requires": { - "minimist": "^1.2.5" + "@noble/hashes": "~1.2.0", + "@noble/secp256k1": "~1.7.0", + "@scure/base": "~1.1.0" } }, - "mocha": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", - "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", + "@scure/bip39": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.1.tgz", + "integrity": "sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg==", "dev": true, "peer": true, "requires": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" + "@noble/hashes": "~1.2.0", + "@scure/base": "~1.1.0" } }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", "dev": true, "peer": true }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "peer": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "cli-table3": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.5.1.tgz", + "integrity": "sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==", "dev": true, "peer": true, "requires": { - "p-limit": "^2.0.0" + "colors": "^1.1.2", + "object-assign": "^4.1.0", + "string-width": "^2.1.1" } }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", "dev": true, "peer": true }, - "readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", + "ethereum-cryptography": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.2.0.tgz", + "integrity": "sha512-6yFQC9b5ug6/17CQpCyE3k9eKBMdhyVjzUy1WkiuY/E4vj/SXDBbCw8QEIaXqf0Mf2SnY6RmpDcwlUmBSS0EJw==", "dev": true, "peer": true, "requires": { - "picomatch": "^2.0.4" + "@noble/hashes": "1.2.0", + "@noble/secp256k1": "1.7.1", + "@scure/bip32": "1.1.5", + "@scure/bip39": "1.1.1" } }, - "scrypt-js": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.4.tgz", - "integrity": "sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw==", - "dev": true, - "peer": true - }, - "setimmediate": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz", - "integrity": "sha512-/TjEmXQVEzdod/FFskf3o7oOAsGhHf2j1dZqRFbDzq4F3mvvxflIIi4Hd3bLQE9y/CpwqfSQam5JakI/mi3Pog==", + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", "dev": true, "peer": true }, @@ -16303,172 +18977,78 @@ "requires": { "ansi-regex": "^3.0.0" } + } + } + }, + "eth-lib": { + "version": "0.1.29", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.1.29.tgz", + "integrity": "sha512-bfttrr3/7gG4E02HoWTDUcDDslN003OlOoBxk9virpAZQ1ja/jDgwkWB8QfJF7ojuEowrqy+lzp9VcJG7/k5bQ==", + "dev": true, + "requires": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "nano-json-stream-parser": "^0.1.2", + "servify": "^0.1.12", + "ws": "^3.0.0", + "xhr-request-promise": "^0.1.2" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "dev": true, - "peer": true - }, - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "dev": true, - "peer": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "uuid": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz", - "integrity": "sha512-nWg9+Oa3qD2CQzHIP4qKUqwNfzKn8P0LtFhotaCTFchsV7ZfDhAybeip/HZVeMIpZi9JgY1E3nUlwaCmZT1sEg==", - "dev": true, - "peer": true - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "peer": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "peer": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "dev": true, - "peer": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "peer": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "peer": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true, - "peer": true - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "peer": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "dev": true, - "peer": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "peer": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "peer": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "peer": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", + "ws": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", + "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", "dev": true, - "peer": true, "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0", + "ultron": "~1.1.0" } } } }, + "eth2-keystore-js": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/eth2-keystore-js/-/eth2-keystore-js-1.0.8.tgz", + "integrity": "sha512-H5JLUeo7aiZs7zVAb+9gSJZZxfcx5na8zPxcgFbggNfac+atyO5H6KpvDUPJFRm/umHWM7++MdvS/q5Sbw+f9g==", + "dev": true, + "requires": { + "@types/node": "^15.12.2", + "crypto": "^1.0.1", + "ethereumjs-util": "^7.0.10", + "ethereumjs-wallet": "^1.0.1", + "husky": "^6.0.0", + "scrypt-js": "^3.0.1", + "tslint": "^6.1.3", + "tslint-config-prettier": "^1.18.0", + "typescript": "^4.3.2" + }, + "dependencies": { + "@types/node": { + "version": "15.14.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-15.14.9.tgz", + "integrity": "sha512-qjd88DrCxupx/kJD5yQgZdcYKZKSIGBVDIBE1/LTGcNm3d2Np/jxojkdePDdfnBHJc5W7vSMpbJ1aB7p/Py69A==", + "dev": true + } + } + }, "ethereum-bloom-filters": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.10.tgz", "integrity": "sha512-rxJ5OFN3RwjQxDcFP2Z5+Q9ho4eIdEmSc2ht0fCu8Se9nbXjZ7/031uXoUYJ87KHCOdVeiUuwSnoS7hmYAGVHA==", "dev": true, - "peer": true, "requires": { "js-sha3": "^0.8.0" } @@ -16551,6 +19131,30 @@ "rlp": "^2.2.4" } }, + "ethereumjs-wallet": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/ethereumjs-wallet/-/ethereumjs-wallet-1.0.2.tgz", + "integrity": "sha512-CCWV4RESJgRdHIvFciVQFnCHfqyhXWchTPlkfp28Qc53ufs+doi5I/cV2+xeK9+qEo25XCWfP9MiL+WEPAZfdA==", + "dev": true, + "requires": { + "aes-js": "^3.1.2", + "bs58check": "^2.1.2", + "ethereum-cryptography": "^0.1.3", + "ethereumjs-util": "^7.1.2", + "randombytes": "^2.1.0", + "scrypt-js": "^3.0.1", + "utf8": "^3.0.0", + "uuid": "^8.3.2" + }, + "dependencies": { + "aes-js": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.1.2.tgz", + "integrity": "sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ==", + "dev": true + } + } + }, "ethers": { "version": "5.7.2", "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", @@ -16594,7 +19198,6 @@ "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", "integrity": "sha512-/Sn9Y0oKl0uqQuvgFk/zQgR7aw1g36qX/jzSQ5lSwlO0GigPymk4eGQfeNTD03w1dPOqfz8V77Cy43jH56pagw==", "dev": true, - "peer": true, "requires": { "bn.js": "4.11.6", "number-to-bn": "1.7.0" @@ -16604,8 +19207,7 @@ "version": "4.11.6", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", - "dev": true, - "peer": true + "dev": true } } }, @@ -16619,10 +19221,16 @@ "strip-hex-prefix": "1.0.0" } }, - "event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "eventemitter3": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz", + "integrity": "sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==", + "dev": true + }, + "events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "dev": true }, "evp_bytestokey": { @@ -16635,12 +19243,131 @@ "safe-buffer": "^5.1.1" } }, + "express": { + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "dev": true, + "requires": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "body-parser": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "dev": true, + "requires": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + } + }, + "cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "dev": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dev": true, + "requires": { + "side-channel": "^1.0.4" + } + }, + "raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "dev": true, + "requires": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + } + } + }, + "ext": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", + "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", + "dev": true, + "requires": { + "type": "^2.7.2" + }, + "dependencies": { + "type": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", + "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==", + "dev": true + } + } + }, "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true, - "peer": true + "dev": true }, "external-editor": { "version": "3.1.0", @@ -16657,8 +19384,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", - "dev": true, - "peer": true + "dev": true }, "fast-base64-decode": { "version": "1.0.0", @@ -16679,9 +19405,9 @@ "dev": true }, "fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", @@ -16723,6 +19449,12 @@ "reusify": "^1.0.4" } }, + "figlet": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/figlet/-/figlet-1.7.0.tgz", + "integrity": "sha512-gO8l3wvqo0V7wEFLXPbkX83b7MVjRrk1oRLfYlZXol8nEpb/ON9pcKLI4qpBv5YtOTfrINtqb7b40iYY2FTWFg==", + "dev": true + }, "figures": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", @@ -16775,6 +19507,38 @@ "to-regex-range": "^5.0.1" } }, + "finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dev": true, + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + } + } + }, "find-cache-dir": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", @@ -16813,25 +19577,26 @@ "dev": true }, "flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", "dev": true, "requires": { - "flatted": "^3.1.0", + "flatted": "^3.2.9", + "keyv": "^4.5.3", "rimraf": "^3.0.2" } }, "flatted": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", - "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", + "version": "3.2.9", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", + "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", "dev": true }, "follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", + "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", "dev": true }, "for-each": { @@ -16839,7 +19604,6 @@ "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", "dev": true, - "peer": true, "requires": { "is-callable": "^1.1.3" } @@ -16848,27 +19612,37 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", - "dev": true, - "peer": true + "dev": true }, "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", "dev": true, - "peer": true, "requires": { "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", + "combined-stream": "^1.0.8", "mime-types": "^2.1.12" } }, + "forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true + }, "fp-ts": { "version": "1.19.3", "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-1.19.3.tgz", "integrity": "sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg==", "dev": true }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true + }, "fs-extra": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", @@ -16880,6 +19654,15 @@ "universalify": "^0.1.0" } }, + "fs-minipass": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", + "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "dev": true, + "requires": { + "minipass": "^2.6.0" + } + }, "fs-readdir-recursive": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", @@ -16894,29 +19677,28 @@ "dev": true }, "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "optional": true }, "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true }, "function.prototype.name": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", - "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", "dev": true, - "peer": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0", - "functions-have-names": "^1.2.2" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" } }, "functional-red-black-tree": { @@ -16929,8 +19711,7 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true, - "peer": true + "dev": true }, "get-caller-file": { "version": "2.0.5", @@ -16939,22 +19720,21 @@ "dev": true }, "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", - "dev": true, - "peer": true + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "dev": true }, "get-intrinsic": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", - "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", + "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", "dev": true, "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", + "function-bind": "^1.1.2", "has-proto": "^1.0.1", - "has-symbols": "^1.0.3" + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" } }, "get-port": { @@ -16964,12 +19744,29 @@ "dev": true, "peer": true }, + "get-random-values": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/get-random-values/-/get-random-values-1.2.2.tgz", + "integrity": "sha512-lMyPjQyl0cNNdDf2oR+IQ/fM3itDvpoHy45Ymo2r0L1EjazeSl13SfbKZs7KtZ/3MDCeueiaJiuOEfKqRTsSgA==", + "dev": true, + "requires": { + "global": "^4.4.0" + } + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, "get-symbol-description": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", "dev": true, - "peer": true, "requires": { "call-bind": "^1.0.2", "get-intrinsic": "^1.1.1" @@ -16980,7 +19777,6 @@ "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", "dev": true, - "peer": true, "requires": { "assert-plus": "^1.0.0" } @@ -17140,6 +19936,16 @@ "is-glob": "^4.0.3" } }, + "global": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", + "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", + "dev": true, + "requires": { + "min-document": "^2.19.0", + "process": "^0.11.10" + } + }, "global-modules": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", @@ -17175,9 +19981,9 @@ } }, "globals": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", - "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "version": "13.23.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", + "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -17188,7 +19994,6 @@ "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", "dev": true, - "peer": true, "requires": { "define-properties": "^1.1.3" } @@ -17212,45 +20017,50 @@ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", "dev": true, - "peer": true, "requires": { "get-intrinsic": "^1.1.3" } }, + "got": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", + "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "dev": true, + "requires": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + } + }, "graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true }, - "grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", - "dev": true - }, "graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true, - "peer": true - }, "handlebars": { - "version": "4.7.7", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", - "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", "dev": true, "peer": true, "requires": { "minimist": "^1.2.5", - "neo-async": "^2.6.0", + "neo-async": "^2.6.2", "source-map": "^0.6.1", "uglify-js": "^3.1.4", "wordwrap": "^1.0.0" @@ -17269,43 +20079,40 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", - "dev": true, - "peer": true + "dev": true }, "har-validator": { "version": "5.1.5", "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", "dev": true, - "peer": true, "requires": { "ajv": "^6.12.3", "har-schema": "^2.0.0" } }, "hardhat": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.15.0.tgz", - "integrity": "sha512-cC9tM/N10YaES04zPOp7yR13iX3YibqaNmi0//Ep40Nt9ELIJx3kFpQmucur0PAIfXYpGnw5RuXHNLkxpnVHEw==", + "version": "2.19.1", + "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.19.1.tgz", + "integrity": "sha512-bsWa63g1GB78ZyMN08WLhFElLPA+J+pShuKD1BFO2+88g3l+BL3R07vj9deIi9dMbssxgE714Gof1dBEDGqnCw==", "dev": true, "requires": { "@ethersproject/abi": "^5.1.2", "@metamask/eth-sig-util": "^4.0.0", - "@nomicfoundation/ethereumjs-block": "5.0.1", - "@nomicfoundation/ethereumjs-blockchain": "7.0.1", - "@nomicfoundation/ethereumjs-common": "4.0.1", - "@nomicfoundation/ethereumjs-evm": "2.0.1", - "@nomicfoundation/ethereumjs-rlp": "5.0.1", - "@nomicfoundation/ethereumjs-statemanager": "2.0.1", - "@nomicfoundation/ethereumjs-trie": "6.0.1", - "@nomicfoundation/ethereumjs-tx": "5.0.1", - "@nomicfoundation/ethereumjs-util": "9.0.1", - "@nomicfoundation/ethereumjs-vm": "7.0.1", + "@nomicfoundation/ethereumjs-block": "5.0.2", + "@nomicfoundation/ethereumjs-blockchain": "7.0.2", + "@nomicfoundation/ethereumjs-common": "4.0.2", + "@nomicfoundation/ethereumjs-evm": "2.0.2", + "@nomicfoundation/ethereumjs-rlp": "5.0.2", + "@nomicfoundation/ethereumjs-statemanager": "2.0.2", + "@nomicfoundation/ethereumjs-trie": "6.0.2", + "@nomicfoundation/ethereumjs-tx": "5.0.2", + "@nomicfoundation/ethereumjs-util": "9.0.2", + "@nomicfoundation/ethereumjs-vm": "7.0.2", "@nomicfoundation/solidity-analyzer": "^0.1.0", "@sentry/node": "^5.18.1", "@types/bn.js": "^5.1.0", "@types/lru-cache": "^5.1.0", - "abort-controller": "^3.0.0", "adm-zip": "^0.4.16", "aggregate-error": "^3.0.0", "ansi-escapes": "^4.3.0", @@ -17328,7 +20135,6 @@ "mnemonist": "^0.38.0", "mocha": "^10.0.0", "p-map": "^4.0.0", - "qs": "^6.7.0", "raw-body": "^2.4.1", "resolve": "1.17.0", "semver": "^6.3.0", @@ -17341,6 +20147,33 @@ "ws": "^7.4.6" }, "dependencies": { + "@noble/hashes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.2.0.tgz", + "integrity": "sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==", + "dev": true + }, + "@scure/bip32": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.5.tgz", + "integrity": "sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw==", + "dev": true, + "requires": { + "@noble/hashes": "~1.2.0", + "@noble/secp256k1": "~1.7.0", + "@scure/base": "~1.1.0" + } + }, + "@scure/bip39": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.1.tgz", + "integrity": "sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg==", + "dev": true, + "requires": { + "@noble/hashes": "~1.2.0", + "@scure/base": "~1.1.0" + } + }, "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -17437,12 +20270,6 @@ "p-limit": "^1.1.0" } }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", - "dev": true - }, "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", @@ -17509,21 +20336,11 @@ "ethers": "^5.6.1" } }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, "has-bigints": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "dev": true, - "peer": true + "dev": true }, "has-flag": { "version": "4.0.0", @@ -17532,13 +20349,12 @@ "dev": true }, "has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", + "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", "dev": true, - "peer": true, "requires": { - "get-intrinsic": "^1.1.1" + "get-intrinsic": "^1.2.2" } }, "has-proto": { @@ -17558,7 +20374,6 @@ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", "dev": true, - "peer": true, "requires": { "has-symbols": "^1.0.2" } @@ -17584,6 +20399,15 @@ "minimalistic-assert": "^1.0.1" } }, + "hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "dev": true, + "requires": { + "function-bind": "^1.1.2" + } + }, "he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", @@ -17621,6 +20445,12 @@ "parse-cache-control": "^1.0.1" } }, + "http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", + "dev": true + }, "http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -17634,6 +20464,12 @@ "toidentifier": "1.0.1" } }, + "http-https": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/http-https/-/http-https-1.0.0.tgz", + "integrity": "sha512-o0PWwVCSp3O0wS6FvNr6xfBCHgt0m1tvPLFOCc2iFDKTRAXhB7m8klDf7ErowFH8POa6dVdGatKU5I1YYwzUyg==", + "dev": true + }, "http-response-object": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz", @@ -17658,13 +20494,22 @@ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", "dev": true, - "peer": true, "requires": { "assert-plus": "^1.0.0", "jsprim": "^1.2.2", "sshpk": "^1.7.0" } }, + "http2-wrapper": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", + "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", + "dev": true, + "requires": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.0.0" + } + }, "https-proxy-agent": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", @@ -17675,6 +20520,12 @@ "debug": "4" } }, + "husky": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/husky/-/husky-6.0.0.tgz", + "integrity": "sha512-SQS2gDTB7tBN486QSoKPKQItZw97BMOd+Kdb6ghfpBc0yXyzrddI0oDV5MkDAbuB4X2mO3/nj60TRMcYxwzZeQ==", + "dev": true + }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -17684,6 +20535,23 @@ "safer-buffer": ">= 2.1.2 < 3" } }, + "idna-uts46-hx": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/idna-uts46-hx/-/idna-uts46-hx-2.3.1.tgz", + "integrity": "sha512-PWoF9Keq6laYdIRwwCdhTPl60xRqAloYNMQLiyUnG42VjT53oW07BXIRM+NK7eQjzXjAk2gUvX9caRxlnF9TAA==", + "dev": true, + "requires": { + "punycode": "2.1.0" + }, + "dependencies": { + "punycode": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz", + "integrity": "sha512-Yxz2kRwT90aPiWEMHVYnEf4+rhwF1tBmmZ4KepCP+Wkium9JxtWnUm1nqGwpiAHr/tnTSeHqr3wb++jgSkXjhA==", + "dev": true + } + } + }, "ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", @@ -17691,15 +20559,15 @@ "dev": true }, "ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", + "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", "dev": true }, "immutable": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.0.tgz", - "integrity": "sha512-0AOCmOip+xgJwEVTQj1EfiDDOkPmuyllDuTuEX+DDXUgapLAsBIfkg3sxCYyCEA8mQqZrrxPUGjcOQ2JS3WLkg==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.4.tgz", + "integrity": "sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==", "dev": true }, "import-fresh": { @@ -17881,14 +20749,13 @@ } }, "internal-slot": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", - "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.6.tgz", + "integrity": "sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg==", "dev": true, - "peer": true, "requires": { - "get-intrinsic": "^1.2.0", - "has": "^1.0.3", + "get-intrinsic": "^1.2.2", + "hasown": "^2.0.0", "side-channel": "^1.0.4" } }, @@ -17908,12 +20775,27 @@ "fp-ts": "^1.0.0" } }, + "ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true + }, + "is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, "is-array-buffer": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", "dev": true, - "peer": true, "requires": { "call-bind": "^1.0.2", "get-intrinsic": "^1.2.0", @@ -17931,7 +20813,6 @@ "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", "dev": true, - "peer": true, "requires": { "has-bigints": "^1.0.1" } @@ -17950,7 +20831,6 @@ "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", "dev": true, - "peer": true, "requires": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -17966,15 +20846,13 @@ "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "dev": true, - "peer": true + "dev": true }, "is-date-object": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", "dev": true, - "peer": true, "requires": { "has-tostringtag": "^1.0.0" } @@ -17997,6 +20875,21 @@ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, + "is-function": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", + "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==", + "dev": true + }, + "is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, "is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -18012,12 +20905,21 @@ "integrity": "sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==", "dev": true }, + "is-nan": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", + "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + } + }, "is-negative-zero": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", - "dev": true, - "peer": true + "dev": true }, "is-number": { "version": "7.0.0", @@ -18030,7 +20932,6 @@ "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", "dev": true, - "peer": true, "requires": { "has-tostringtag": "^1.0.0" } @@ -18052,7 +20953,6 @@ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", "dev": true, - "peer": true, "requires": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -18063,7 +20963,6 @@ "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", "dev": true, - "peer": true, "requires": { "call-bind": "^1.0.2" } @@ -18073,7 +20972,6 @@ "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", "dev": true, - "peer": true, "requires": { "has-tostringtag": "^1.0.0" } @@ -18083,31 +20981,24 @@ "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", "dev": true, - "peer": true, "requires": { "has-symbols": "^1.0.2" } }, "is-typed-array": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", - "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", + "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", "dev": true, - "peer": true, "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" + "which-typed-array": "^1.1.11" } }, "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true, - "peer": true + "dev": true }, "is-unicode-supported": { "version": "0.1.0", @@ -18120,7 +21011,6 @@ "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", "dev": true, - "peer": true, "requires": { "call-bind": "^1.0.2" } @@ -18151,8 +21041,13 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", - "dev": true, - "peer": true + "dev": true + }, + "js-base64": { + "version": "3.7.5", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.5.tgz", + "integrity": "sha512-3MEt5DTINKqfScXKfJFrRbxkrnk2AxPWGBL/ycjz4dK8iqiSJ06UxD8jh8xuh6p10TX4t2+7FsBYVxxQbMg+qA==", + "dev": true }, "js-cookie": { "version": "2.2.1", @@ -18161,9 +21056,9 @@ "dev": true }, "js-sdsl": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.1.tgz", - "integrity": "sha512-6Gsx8R0RucyePbWqPssR8DyfuXmLBooYN5cZFZKjHGnQuaf7pEzhtpceagJxVu4LqhYY5EYA7nko3FmeHZ1KbA==", + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.2.tgz", + "integrity": "sha512-dwXFwByc/ajSV6m5bcKAPwe4yDDF6D614pxmIi5odytzxRlwqF6nwoiCek80Ixc7Cvma5awClxrzFtxCQvcM8w==", "dev": true }, "js-sha3": { @@ -18191,8 +21086,19 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", - "dev": true, - "peer": true + "dev": true + }, + "jsencrypt": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/jsencrypt/-/jsencrypt-3.2.1.tgz", + "integrity": "sha512-k1sD5QV0KPn+D8uG9AdGzTQuamt82QZ3A3l6f7TRwMU6Oi2Vg0BsL+wZIQBONcraO1pc78ExMdvmBBJ8WhNYUA==", + "dev": true + }, + "json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true }, "json-parse-better-errors": { "version": "1.0.2", @@ -18204,8 +21110,7 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", - "dev": true, - "peer": true + "dev": true }, "json-schema-traverse": { "version": "0.4.1", @@ -18223,8 +21128,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true, - "peer": true + "dev": true }, "jsonfile": { "version": "4.0.0", @@ -18247,7 +21151,6 @@ "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", "dev": true, - "peer": true, "requires": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", @@ -18256,9 +21159,9 @@ } }, "keccak": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.3.tgz", - "integrity": "sha512-JZrLIAJWuZxKbCilMpNz5Vj7Vtb4scDG3dMXLOsbzBmQGyjwE61BbW7bJkfKKCShXiQZt3T6sBgALRtmd+nZaQ==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.4.tgz", + "integrity": "sha512-3vKuW0jV8J3XNTzvfyicFR5qvxrSAGl7KIhvgOu5cmWwM7tZRj3fMbj/pfIf4be7aznbc+prBWGjywox/g2Y6Q==", "dev": true, "requires": { "node-addon-api": "^2.0.0", @@ -18266,6 +21169,15 @@ "readable-stream": "^3.6.0" } }, + "keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "requires": { + "json-buffer": "3.0.1" + } + }, "kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -18283,9 +21195,9 @@ } }, "kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", "dev": true }, "level": { @@ -18336,6 +21248,12 @@ "type-check": "~0.4.0" } }, + "libphonenumber-js": { + "version": "1.10.51", + "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.10.51.tgz", + "integrity": "sha512-vY2I+rQwrDQzoPds0JeTEpeWzbUJgqoV0O4v31PauHBb/e+1KCXKylHcDnBMgJZ9fH9mErsEbROJY3Z3JtqEmg==", + "dev": true + }, "locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -18382,15 +21300,21 @@ } }, "loupe": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz", - "integrity": "sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==", + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", "dev": true, "peer": true, "requires": { - "get-func-name": "^2.0.0" + "get-func-name": "^2.0.1" } }, + "lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "dev": true + }, "lru_map": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz", @@ -18445,6 +21369,12 @@ "safe-buffer": "^5.1.2" } }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true + }, "memory-level": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/memory-level/-/memory-level-1.0.0.tgz", @@ -18462,12 +21392,31 @@ "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", "dev": true }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", + "dev": true + }, "merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true + }, + "micro-ftch": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/micro-ftch/-/micro-ftch-0.3.1.tgz", + "integrity": "sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg==", + "dev": true, + "peer": true + }, "micromatch": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", @@ -18478,19 +21427,41 @@ "picomatch": "^2.3.1" } }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + } + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true + }, "mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, - "peer": true + "dev": true }, "mime-types": { "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "dev": true, - "peer": true, "requires": { "mime-db": "1.52.0" } @@ -18501,6 +21472,21 @@ "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", "dev": true }, + "mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true + }, + "min-document": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", + "integrity": "sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==", + "dev": true, + "requires": { + "dom-walk": "^0.1.0" + } + }, "minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", @@ -18528,6 +21514,25 @@ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "dev": true }, + "minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", + "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "dev": true, + "requires": { + "minipass": "^2.9.0" + } + }, "mkdirp": { "version": "0.5.6", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", @@ -18537,6 +21542,15 @@ "minimist": "^1.2.6" } }, + "mkdirp-promise": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz", + "integrity": "sha512-Hepn5kb1lJPtVW84RFT40YG1OddBNTOVUZR2bzQUHc+Z03en8/3uX0+060JDhcEzyO08HmipsN9DcnFMxhIL9w==", + "dev": true, + "requires": { + "mkdirp": "*" + } + }, "mnemonist": { "version": "0.38.5", "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.38.5.tgz", @@ -18616,24 +21630,106 @@ } } }, + "mock-fs": { + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-4.14.0.tgz", + "integrity": "sha512-qYvlv/exQ4+svI3UOvPUpLDF0OMX5euvUH0Ny4N5QyRyhNdgAgUrVH3iUINSzEPLvx0kbo/Bp28GJKIqvE7URw==", + "dev": true + }, "module-error": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/module-error/-/module-error-1.0.2.tgz", "integrity": "sha512-0yuvsqSCv8LbaOKhnsQ/T5JhyFlCYLPXK3U2sgV10zoKQwzs/MyfuQUOZQ1V/6OCOJsK/TRgNVrPuPDqtdMFtA==", "dev": true }, + "moment": { + "version": "2.29.4", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", + "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==", + "dev": true + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "multibase": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.6.1.tgz", + "integrity": "sha512-pFfAwyTjbbQgNc3G7D48JkJxWtoJoBMaR4xQUOuB8RnCgRqaYmWNFeJTTvrJ2w51bjLq2zTby6Rqj9TQ9elSUw==", + "dev": true, + "requires": { + "base-x": "^3.0.8", + "buffer": "^5.5.0" + }, + "dependencies": { + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + } + } + }, + "multicodec": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-0.5.7.tgz", + "integrity": "sha512-PscoRxm3f+88fAtELwUnZxGDkduE2HD9Q6GHUOywQLjOGT/HAdhjLDYNZ1e7VR0s0TP0EwZ16LNUTFpoBGivOA==", + "dev": true, + "requires": { + "varint": "^5.0.0" + } + }, + "multihashes": { + "version": "0.4.21", + "resolved": "https://registry.npmjs.org/multihashes/-/multihashes-0.4.21.tgz", + "integrity": "sha512-uVSvmeCWf36pU2nB4/1kzYZjsXD9vofZKpgudqkceYY5g2aZZXJ5r9lxuzoRLl1OAp28XljXsEJ/X/85ZsKmKw==", + "dev": true, + "requires": { + "buffer": "^5.5.0", + "multibase": "^0.7.0", + "varint": "^5.0.0" + }, + "dependencies": { + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "multibase": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.7.0.tgz", + "integrity": "sha512-TW8q03O0f6PNFTQDvh3xxH03c8CjGaaYrjkl9UQPG6rz53TQzzxJVCIWVjzcbN/Q5Y53Zd0IBQBMVktVgNx4Fg==", + "dev": true, + "requires": { + "base-x": "^3.0.8", + "buffer": "^5.5.0" + } + } + } + }, "mute-stream": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", "integrity": "sha512-r65nCZhrbXXb6dXOACihYApHw2Q6pV0M3V0PSxd74N0+D8nzAdEAITq2oAjA1jVnKI+tGvEBUpqiMh0+rW6zDQ==", "dev": true }, + "nano-json-stream-parser": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz", + "integrity": "sha512-9MqxMH/BSJC7dnLsEMPyfN5Dvoo49IsPFYMcHw3Bcfc2kN0lpHRBSzlMSVx4HGyJ7s9B31CyBTVehWJoQ8Ctew==", + "dev": true + }, "nanoid": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", @@ -18658,6 +21754,12 @@ "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", "dev": true }, + "negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true + }, "neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", @@ -18665,6 +21767,12 @@ "dev": true, "peer": true }, + "next-tick": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", + "dev": true + }, "nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", @@ -18687,41 +21795,30 @@ "lodash": "^4.17.21" } }, - "node-environment-flags": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", - "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", - "dev": true, - "peer": true, - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "peer": true - } - } - }, "node-fetch": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.11.tgz", - "integrity": "sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", "dev": true, "requires": { "whatwg-url": "^5.0.0" } }, "node-gyp-build": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz", - "integrity": "sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==", + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.7.1.tgz", + "integrity": "sha512-wTSrZ+8lsRRa3I3H8Xr65dLWSgCvY2l4AOnaeKdPA9TB/WYMPaTcrzf3rXvFoVvjKNVnu0CcWSx54qq9GKRUYg==", "dev": true }, + "node-jsencrypt": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-jsencrypt/-/node-jsencrypt-1.0.0.tgz", + "integrity": "sha512-ANQ/XkOVS02R89MtfoelFxarMsLA12nlOT802VS4LVhl+JRSRZIvkLIjvKYZmIar+mENUkR9mBKUdcdiPy/7lA==", + "dev": true, + "requires": { + "get-random-values": "^1.2.0" + } + }, "nofilter": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-3.1.0.tgz", @@ -18744,12 +21841,17 @@ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true }, + "normalize-url": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", + "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", + "dev": true + }, "number-to-bn": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", "integrity": "sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig==", "dev": true, - "peer": true, "requires": { "bn.js": "4.11.6", "strip-hex-prefix": "1.0.0" @@ -18759,8 +21861,7 @@ "version": "4.11.6", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", - "dev": true, - "peer": true + "dev": true } } }, @@ -18768,8 +21869,7 @@ "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true, - "peer": true + "dev": true }, "object-assign": { "version": "4.1.1", @@ -18778,43 +21878,37 @@ "dev": true }, "object-inspect": { - "version": "1.12.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", - "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", "dev": true }, + "object-is": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", + "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, "object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, - "peer": true + "dev": true }, "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "peer": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.6.tgz", - "integrity": "sha512-lq+61g26E/BgHv0ZTFgRvi7NMEPuAxLkFU7rukXjc/AlwH4Am5xXVnIXy3un1bg/JPbXHrixRkK1itUzzPiIjQ==", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", "dev": true, - "peer": true, "requires": { - "array.prototype.reduce": "^1.0.5", - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.21.2", - "safe-array-concat": "^1.0.0" + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" } }, "obliterator": { @@ -18823,6 +21917,24 @@ "integrity": "sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==", "dev": true }, + "oboe": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/oboe/-/oboe-2.1.5.tgz", + "integrity": "sha512-zRFWiF+FoicxEs3jNI/WYUrVEgA7DeET/InK0XQuudGHRg8iIob3cNPrJTKaz4004uaA9Pbe+Dwa8iluhjLZWA==", + "dev": true, + "requires": { + "http-https": "^1.0.0" + } + }, + "on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "requires": { + "ee-first": "1.1.1" + } + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -18842,17 +21954,17 @@ } }, "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", "dev": true, "requires": { + "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "type-check": "^0.4.0" } }, "ordinal": { @@ -18868,6 +21980,12 @@ "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", "dev": true }, + "p-cancelable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", + "dev": true + }, "p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -18896,9 +22014,9 @@ } }, "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", "dev": true }, "parent-module": { @@ -18907,7 +22025,20 @@ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, "requires": { - "callsites": "^3.0.0" + "callsites": "^3.0.0" + } + }, + "parse-asn1": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", + "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", + "dev": true, + "requires": { + "asn1.js": "^5.2.0", + "browserify-aes": "^1.0.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" } }, "parse-cache-control": { @@ -18917,6 +22048,12 @@ "dev": true, "peer": true }, + "parse-headers": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.5.tgz", + "integrity": "sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA==", + "dev": true + }, "parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", @@ -18927,6 +22064,12 @@ "json-parse-better-errors": "^1.0.1" } }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true + }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -18963,6 +22106,12 @@ "integrity": "sha512-wZ3AeiRBRlNwkdUxvBANh0+esnt38DLffHDujZyRHkqkaKHTglnY2EP5UX3b8rdeiSutgO4y9NEJwXezNP5vHg==", "dev": true }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", + "dev": true + }, "path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -18993,8 +22142,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", - "dev": true, - "peer": true + "dev": true }, "picomatch": { "version": "2.3.1", @@ -19069,6 +22217,12 @@ "requires": { "p-limit": "^2.2.0" } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true } } }, @@ -19078,6 +22232,12 @@ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true }, + "prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==", + "dev": true + }, "prettier": { "version": "1.19.1", "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", @@ -19085,6 +22245,12 @@ "dev": true, "optional": true }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "dev": true + }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -19109,12 +22275,11 @@ } }, "prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "version": "git+ssh://git@github.com/meshin-blox/prompts.git#a22bdac044f6b32ba67adb4eacc2e58322512a2d", "dev": true, + "from": "prompts@^2.4.2", "requires": { - "kleur": "^3.0.3", + "kleur": "^4.0.1", "sisteransi": "^1.0.5" } }, @@ -19137,17 +22302,64 @@ } } }, + "proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "requires": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + } + }, + "proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true + }, "psl": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", + "dev": true + }, + "public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", "dev": true, - "peer": true + "requires": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + } + } + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } }, "punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true }, "qs": { @@ -19155,16 +22367,34 @@ "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", "dev": true, + "peer": true, "requires": { "side-channel": "^1.0.4" } }, + "query-string": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", + "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", + "dev": true, + "requires": { + "decode-uri-component": "^0.2.0", + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" + } + }, "queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true }, + "quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true + }, "randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -19174,6 +22404,22 @@ "safe-buffer": "^5.1.0" } }, + "randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, + "requires": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true + }, "raw-body": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", @@ -19234,15 +22480,14 @@ "peer": true }, "regexp.prototype.flags": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz", - "integrity": "sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz", + "integrity": "sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==", "dev": true, - "peer": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", - "functions-have-names": "^1.2.3" + "set-function-name": "^2.0.0" } }, "regexpp": { @@ -19285,7 +22530,6 @@ "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", "dev": true, - "peer": true, "requires": { "aws-sign2": "~0.7.0", "aws4": "^1.8.0", @@ -19309,44 +22553,31 @@ "uuid": "^3.3.2" }, "dependencies": { + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, "qs": { "version": "6.5.3", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", - "dev": true, - "peer": true + "dev": true }, "uuid": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true, - "peer": true + "dev": true } } }, - "request-promise-core": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", - "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", - "dev": true, - "peer": true, - "requires": { - "lodash": "^4.17.19" - } - }, - "request-promise-native": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz", - "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==", - "dev": true, - "peer": true, - "requires": { - "request-promise-core": "1.1.4", - "stealthy-require": "^1.1.1", - "tough-cookie": "^2.3.3" - } - }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -19359,13 +22590,6 @@ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true, - "peer": true - }, "resolve": { "version": "1.17.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", @@ -19375,12 +22599,27 @@ "path-parse": "^1.0.6" } }, + "resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "dev": true + }, "resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, + "responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==", + "dev": true, + "requires": { + "lowercase-keys": "^1.0.0" + } + }, "restore-cursor": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", @@ -19471,14 +22710,13 @@ } }, "safe-array-concat": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.0.tgz", - "integrity": "sha512-9dVEFruWIsnie89yym+xWTAYASdpw3CJV7Li/6zBewGf9z2i1j31rP6jnY0pHEO4QZh6N0K11bFjWmdR8UGdPQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.1.tgz", + "integrity": "sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==", "dev": true, - "peer": true, "requires": { "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.0", + "get-intrinsic": "^1.2.1", "has-symbols": "^1.0.3", "isarray": "^2.0.5" }, @@ -19487,8 +22725,7 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true, - "peer": true + "dev": true } } }, @@ -19503,7 +22740,6 @@ "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", "dev": true, - "peer": true, "requires": { "call-bind": "^1.0.2", "get-intrinsic": "^1.1.3", @@ -19644,11 +22880,57 @@ } }, "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true }, + "send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dev": true, + "requires": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + } + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + } + } + }, "serialize-javascript": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", @@ -19658,12 +22940,53 @@ "randombytes": "^2.1.0" } }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", "dev": true, - "peer": true + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + } + }, + "servify": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/servify/-/servify-0.1.12.tgz", + "integrity": "sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw==", + "dev": true, + "requires": { + "body-parser": "^1.16.0", + "cors": "^2.8.1", + "express": "^4.14.0", + "request": "^2.79.0", + "xhr": "^2.3.3" + } + }, + "set-function-length": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", + "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", + "dev": true, + "requires": { + "define-data-property": "^1.1.1", + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + } + }, + "set-function-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz", + "integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==", + "dev": true, + "requires": { + "define-data-property": "^1.0.1", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.0" + } }, "setimmediate": { "version": "1.0.5", @@ -19742,10 +23065,27 @@ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, + "simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "dev": true + }, + "simple-get": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.2.tgz", + "integrity": "sha512-Ijd/rV5o+mSBBs4F/x9oDPtTx9Zb6X9brmnXvMW4J7IR15ngi9q5xxqWBKU744jTZiaXtxaPL7uHG6vtN8kUkw==", + "dev": true, + "requires": { + "decompress-response": "^3.3.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, "simple-git": { - "version": "3.19.0", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.19.0.tgz", - "integrity": "sha512-hyH2p9Ptxjf/xPuL7HfXbpYt9gKhC1yWDh3KYIAYJJePAKV7AEjLN4xhp7lozOdNiaJ9jlVvAbBymVlcS2jRiA==", + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.21.0.tgz", + "integrity": "sha512-oTzw9248AF5bDTMk9MrxsRzEzivMlY+DWH0yWS4VYpMhNLhDWnN06pCtaUyPnqv/FpsdeNmRqmZugMABHRPdDA==", "dev": true, "requires": { "@kwsites/file-exists": "^1.1.1", @@ -19832,9 +23172,9 @@ } }, "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true } } @@ -19942,9 +23282,9 @@ }, "dependencies": { "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true } } @@ -20006,9 +23346,9 @@ }, "dependencies": { "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true } } @@ -20262,20 +23602,23 @@ } }, "solidity-ast": { - "version": "0.4.49", - "resolved": "https://registry.npmjs.org/solidity-ast/-/solidity-ast-0.4.49.tgz", - "integrity": "sha512-Pr5sCAj1SFqzwFZw1HPKSq0PehlQNdM8GwKyAVYh2DOn7/cCK8LUKD1HeHnKtTgBW7hi9h4nnnan7hpAg5RhWQ==", - "dev": true + "version": "0.4.55", + "resolved": "https://registry.npmjs.org/solidity-ast/-/solidity-ast-0.4.55.tgz", + "integrity": "sha512-qeEU/r/K+V5lrAw8iswf2/yfWAnSGs3WKPHI+zAFKFjX0dIBVXEU/swQ8eJQYHf6PJWUZFO2uWV4V1wEOkeQbA==", + "dev": true, + "requires": { + "array.prototype.findlast": "^1.2.2" + } }, "solidity-coverage": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.8.2.tgz", - "integrity": "sha512-cv2bWb7lOXPE9/SSleDO6czkFiMHgP4NXPj+iW9W7iEKLBk7Cj0AGBiNmGX3V1totl9wjPrT0gHmABZKZt65rQ==", + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.8.5.tgz", + "integrity": "sha512-6C6N6OV2O8FQA0FWA95FdzVH+L16HU94iFgg5wAFZ29UpLFkgNI/DRR2HotG1bC0F4gAc/OMs2BJI44Q/DYlKQ==", "dev": true, "peer": true, "requires": { "@ethersproject/abi": "^5.0.9", - "@solidity-parser/parser": "^0.14.1", + "@solidity-parser/parser": "^0.16.0", "chalk": "^2.4.2", "death": "^1.1.0", "detect-port": "^1.3.0", @@ -20286,7 +23629,7 @@ "globby": "^10.0.1", "jsonschema": "^1.2.4", "lodash": "^4.17.15", - "mocha": "7.1.2", + "mocha": "10.2.0", "node-emoji": "^1.10.0", "pify": "^4.0.1", "recursive-readdir": "^2.2.2", @@ -20296,19 +23639,15 @@ "web3-utils": "^1.3.6" }, "dependencies": { - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true, - "peer": true - }, - "ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "@solidity-parser/parser": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.16.2.tgz", + "integrity": "sha512-PI9NfoA3P8XK2VBkK5oIfRgKDsicwDZfkVq9ZTBCQYGOP1N2owgY2dyLGyU5/J/hQs8KRk55kdmvTLjy3Mu3vg==", "dev": true, - "peer": true + "peer": true, + "requires": { + "antlr4ts": "^0.5.0-alpha.4" + } }, "ansi-styles": { "version": "3.2.1", @@ -20320,1204 +23659,1982 @@ "color-convert": "^1.9.0" } }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "peer": true, "requires": { - "sprintf-js": "~1.0.2" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "peer": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true, + "peer": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "peer": true + }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "peer": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "globby": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", + "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", + "dev": true, + "peer": true, + "requires": { + "@types/glob": "^7.1.1", + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.0.3", + "glob": "^7.1.3", + "ignore": "^5.1.1", + "merge2": "^1.2.3", + "slash": "^3.0.0" } }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, "peer": true }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, "peer": true, "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "yallist": "^4.0.0" } }, - "chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", + "semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "peer": true, "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" + "lru-cache": "^6.0.0" } }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "peer": true, "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" + "has-flag": "^3.0.0" } }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "peer": true + } + } + }, + "source-map": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", + "integrity": "sha512-CBdZ2oa/BHhS4xj5DlhjWNHcan57/5YuvfdLf17iVmIpd9KRm+DFLmC6nBNj+6Ua7Kt3TmOjDpQT1aTYOQtoUA==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "amdefine": ">=0.0.4" + } + }, + "source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "sshpk": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", + "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", + "dev": true, + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "dependencies": { + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", + "dev": true + } + } + }, + "ssv-keys": { + "version": "git+ssh://git@github.com/bloxapp/ssv-keys.git#cc9e5cdd4696a0e855fc4642c2868abd62d5141a", + "dev": true, + "from": "ssv-keys@github:bloxapp/ssv-keys#v1.0.4", + "requires": { + "@types/figlet": "^1.5.4", + "@types/underscore": "^1.11.4", + "@types/yargs": "^17.0.12", + "argparse": "^2.0.1", + "assert": "^2.0.0", + "atob": "^2.1.2", + "bls-eth-wasm": "^1.0.4", + "bls-signatures": "^0.2.5", + "btoa": "^1.2.1", + "class-validator": "^0.13.2", + "colors": "^1.4.0", + "crypto": "^1.0.1", + "eth2-keystore-js": "^1.0.8", + "ethereumjs-util": "^7.1.5", + "ethereumjs-wallet": "^1.0.1", + "ethers": "^5.7.2", + "events": "^3.3.0", + "figlet": "^1.5.2", + "js-base64": "^3.7.2", + "jsencrypt": "3.2.1", + "minimist": "^1.2.6", + "moment": "^2.29.3", + "node-jsencrypt": "^1.0.0", + "prompts": "https://github.com/meshin-blox/prompts.git", + "scrypt-js": "^3.0.1", + "semver": "^7.5.1", + "stream": "^0.0.2", + "underscore": "^1.13.4", + "web3": "1.7.3", + "yargs": "^17.5.1" + }, + "dependencies": { + "cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, - "peer": true, "requires": { - "color-name": "1.1.3" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" } }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true, - "peer": true + "colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, - "peer": true, "requires": { - "ms": "^2.1.1" + "yallist": "^4.0.0" } }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, - "peer": true + "requires": { + "lru-cache": "^6.0.0" + } }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true, - "peer": true + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, - "peer": true + "requires": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + } }, + "yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true + } + } + }, + "stacktrace-parser": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz", + "integrity": "sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==", + "dev": true, + "requires": { + "type-fest": "^0.7.1" + }, + "dependencies": { + "type-fest": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz", + "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==", + "dev": true + } + } + }, + "statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true + }, + "stream": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stream/-/stream-0.0.2.tgz", + "integrity": "sha512-gCq3NDI2P35B2n6t76YJuOp7d6cN/C7Rt0577l91wllh0sY9ZBuw9KaSGqH/b0hzn3CWWJbpbW0W0WvQ1H/Q7g==", + "dev": true, + "requires": { + "emitter-component": "^1.1.1" + } + }, + "strict-uri-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", + "integrity": "sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==", + "dev": true + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "string-format": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/string-format/-/string-format-2.0.0.tgz", + "integrity": "sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA==", + "dev": true, + "peer": true + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "string.prototype.trim": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", + "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + } + }, + "string.prototype.trimend": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", + "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + } + }, + "string.prototype.trimstart": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", + "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-hex-prefix": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", + "integrity": "sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==", + "dev": true, + "requires": { + "is-hex-prefixed": "1.0.0" + } + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "strip-outer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", + "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.2" + }, + "dependencies": { "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "peer": true + "dev": true + } + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "swarm-js": { + "version": "0.1.42", + "resolved": "https://registry.npmjs.org/swarm-js/-/swarm-js-0.1.42.tgz", + "integrity": "sha512-BV7c/dVlA3R6ya1lMlSSNPLYrntt0LUq4YMgy3iwpCIc6rZnS5W2wUoctarZ5pXlpKtxDDf9hNziEkcfrxdhqQ==", + "dev": true, + "requires": { + "bluebird": "^3.5.0", + "buffer": "^5.0.5", + "eth-lib": "^0.1.26", + "fs-extra": "^4.0.2", + "got": "^11.8.5", + "mime-types": "^2.1.16", + "mkdirp-promise": "^5.0.1", + "mock-fs": "^4.1.0", + "setimmediate": "^1.0.5", + "tar": "^4.0.2", + "xhr-request": "^1.0.1" + }, + "dependencies": { + "@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "dev": true }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "@szmarczak/http-timer": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", "dev": true, - "peer": true + "requires": { + "defer-to-connect": "^2.0.0" + } }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", "dev": true, - "peer": true, "requires": { - "locate-path": "^3.0.0" + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" } }, - "flat": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz", - "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==", + "cacheable-request": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", + "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", "dev": true, - "peer": true, "requires": { - "is-buffer": "~2.0.3" + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" } }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", "dev": true, - "peer": true, "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" + "mimic-response": "^3.1.0" } }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true, - "peer": true + "defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "dev": true }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "fs-extra": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", + "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", "dev": true, - "peer": true, "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" } }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, - "peer": true, "requires": { - "is-glob": "^4.0.1" + "pump": "^3.0.0" } }, - "globby": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", - "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", + "got": { + "version": "11.8.6", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", + "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", "dev": true, - "peer": true, "requires": { - "@types/glob": "^7.1.1", - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.0.3", - "glob": "^7.1.3", - "ignore": "^5.1.1", - "merge2": "^1.2.3", - "slash": "^3.0.0" + "@sindresorhus/is": "^4.0.0", + "@szmarczak/http-timer": "^4.0.5", + "@types/cacheable-request": "^6.0.1", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^5.0.3", + "cacheable-request": "^7.0.2", + "decompress-response": "^6.0.0", + "http2-wrapper": "^1.0.0-beta.5.2", + "lowercase-keys": "^2.0.0", + "p-cancelable": "^2.0.0", + "responselike": "^2.0.0" } }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "peer": true - }, - "is-fullwidth-code-point": { + "lowercase-keys": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "dev": true, - "peer": true + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, - "peer": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } + "mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "peer": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } + "normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "dev": true }, - "log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "dev": true, - "peer": true, - "requires": { - "chalk": "^2.4.2" - } + "p-cancelable": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "dev": true }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "responselike": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", + "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", "dev": true, - "peer": true, "requires": { - "yallist": "^4.0.0" + "lowercase-keys": "^2.0.0" } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + } + } + }, + "sync-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz", + "integrity": "sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==", + "dev": true, + "peer": true, + "requires": { + "http-response-object": "^3.0.1", + "sync-rpc": "^1.2.1", + "then-request": "^6.0.0" + } + }, + "sync-rpc": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.6.tgz", + "integrity": "sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==", + "dev": true, + "peer": true, + "requires": { + "get-port": "^3.1.0" + } + }, + "table": { + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", + "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", + "dev": true, + "peer": true, + "requires": { + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "dependencies": { + "ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dev": true, "peer": true, "requires": { - "brace-expansion": "^1.1.7" + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" } }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true, - "peer": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "mocha": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.1.2.tgz", - "integrity": "sha512-o96kdRKMKI3E8U0bjnfqW4QMk12MwZ4mhdBTf+B5a1q9+aq2HRnj+3ZdJu0B/ZhJeK78MgYuv6L8d/rA5AeBJA==", + "peer": true + } + } + }, + "table-layout": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-1.0.2.tgz", + "integrity": "sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A==", + "dev": true, + "peer": true, + "requires": { + "array-back": "^4.0.1", + "deep-extend": "~0.6.0", + "typical": "^5.2.0", + "wordwrapjs": "^4.0.0" + }, + "dependencies": { + "array-back": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz", + "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==", "dev": true, - "peer": true, - "requires": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - }, - "dependencies": { - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "dev": true, - "peer": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } + "peer": true }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "typical": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", + "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", + "dev": true, + "peer": true + } + } + }, + "tar": { + "version": "4.4.19", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.19.tgz", + "integrity": "sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==", + "dev": true, + "requires": { + "chownr": "^1.1.4", + "fs-minipass": "^1.2.7", + "minipass": "^2.9.0", + "minizlib": "^1.3.3", + "mkdirp": "^0.5.5", + "safe-buffer": "^5.2.1", + "yallist": "^3.1.1" + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "then-request": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/then-request/-/then-request-6.0.2.tgz", + "integrity": "sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==", + "dev": true, + "peer": true, + "requires": { + "@types/concat-stream": "^1.6.0", + "@types/form-data": "0.0.33", + "@types/node": "^8.0.0", + "@types/qs": "^6.2.31", + "caseless": "~0.12.0", + "concat-stream": "^1.6.0", + "form-data": "^2.2.0", + "http-basic": "^8.1.1", + "http-response-object": "^3.0.1", + "promise": "^8.0.0", + "qs": "^6.4.0" + }, + "dependencies": { + "@types/node": { + "version": "8.10.66", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz", + "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==", "dev": true, "peer": true }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "peer": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "form-data": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", + "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", "dev": true, "peer": true, "requires": { - "p-limit": "^2.0.0" + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true, - "peer": true - }, - "readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", + } + } + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true + }, + "timed-out": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", + "integrity": "sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==", + "dev": true + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + }, + "to-readable-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", + "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", + "dev": true + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true + }, + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true + }, + "trim-repeated": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", + "integrity": "sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.2" + }, + "dependencies": { + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true + } + } + }, + "ts-command-line-args": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/ts-command-line-args/-/ts-command-line-args-2.5.1.tgz", + "integrity": "sha512-H69ZwTw3rFHb5WYpQya40YAX2/w7Ut75uUECbgBIsLmM+BNuYnxsltfyyLMxy6sEeKxgijLTnQtLd0nKd6+IYw==", + "dev": true, + "peer": true, + "requires": { + "chalk": "^4.1.0", + "command-line-args": "^5.1.1", + "command-line-usage": "^6.1.0", + "string-format": "^2.0.0" + } + }, + "ts-essentials": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-7.0.3.tgz", + "integrity": "sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ==", + "dev": true, + "peer": true, + "requires": {} + }, + "ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "dev": true, + "requires": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "dependencies": { + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + } + } + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "tslint": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz", + "integrity": "sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "builtin-modules": "^1.1.1", + "chalk": "^2.3.0", + "commander": "^2.12.1", + "diff": "^4.0.1", + "glob": "^7.1.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.3", + "resolve": "^1.3.2", + "semver": "^5.3.0", + "tslib": "^1.13.0", + "tsutils": "^2.29.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, - "peer": true, "requires": { - "picomatch": "^2.0.4" + "color-convert": "^1.9.0" } }, - "semver": { - "version": "7.5.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.2.tgz", - "integrity": "sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==", + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, - "peer": true, "requires": { - "lru-cache": "^6.0.0" + "sprintf-js": "~1.0.2" } }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, - "peer": true, "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, - "peer": true, "requires": { - "ansi-regex": "^4.1.0" + "color-name": "1.1.3" } }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "dev": true, - "peer": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "peer": true, - "requires": { - "has-flag": "^3.0.0" - } + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "peer": true, - "requires": { - "isexe": "^2.0.0" - } + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "peer": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - } + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true }, - "y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true, - "peer": true + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true, - "peer": true + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, - "peer": true, "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" + "argparse": "^1.0.7", + "esprima": "^4.0.0" } }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, - "peer": true, "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" + "has-flag": "^3.0.0" } }, - "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", + "tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", "dev": true, - "peer": true, "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" + "tslib": "^1.8.1" } } } }, - "source-map": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", - "integrity": "sha512-CBdZ2oa/BHhS4xj5DlhjWNHcan57/5YuvfdLf17iVmIpd9KRm+DFLmC6nBNj+6Ua7Kt3TmOjDpQT1aTYOQtoUA==", + "tslint-config-prettier": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/tslint-config-prettier/-/tslint-config-prettier-1.18.0.tgz", + "integrity": "sha512-xPw9PgNPLG3iKRxmK7DWr+Ea/SzrvfHtjFt5LBl61gk2UBG/DB9kCXRjv+xyIU1rUtnayLeMUVJBcMX8Z17nDg==", + "dev": true + }, + "tsort": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/tsort/-/tsort-0.0.1.tgz", + "integrity": "sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw==", + "dev": true + }, + "tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", "dev": true, - "optional": true, - "peer": true, "requires": { - "amdefine": ">=0.0.4" + "tslib": "^1.8.1" } }, - "source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", "dev": true, "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } + "safe-buffer": "^5.0.1" } }, - "sprintf-js": { + "tweetnacl": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==", "dev": true }, - "sshpk": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", - "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", + "tweetnacl-util": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", + "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==", + "dev": true + }, + "type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", + "dev": true + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "peer": true + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "typechain": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/typechain/-/typechain-8.3.2.tgz", + "integrity": "sha512-x/sQYr5w9K7yv3es7jo4KTX05CLxOf7TRWwoHlrjRh8H82G64g+k7VuWPJlgMo6qrjfCulOdfBjiaDtmhFYD/Q==", "dev": true, "peer": true, "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" + "@types/prettier": "^2.1.1", + "debug": "^4.3.1", + "fs-extra": "^7.0.0", + "glob": "7.1.7", + "js-sha3": "^0.8.0", + "lodash": "^4.17.15", + "mkdirp": "^1.0.4", + "prettier": "^2.3.1", + "ts-command-line-args": "^2.2.0", + "ts-essentials": "^7.0.1" }, "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", + "glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "dev": true, + "peer": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "peer": true + }, + "prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", "dev": true, "peer": true } } }, - "stacktrace-parser": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz", - "integrity": "sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==", + "typed-array-buffer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", + "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==", "dev": true, "requires": { - "type-fest": "^0.7.1" - }, - "dependencies": { - "type-fest": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz", - "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==", - "dev": true - } + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1", + "is-typed-array": "^1.1.10" } }, - "statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true - }, - "stealthy-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", - "integrity": "sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g==", + "typed-array-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", + "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", "dev": true, - "peer": true + "requires": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + } }, - "streamsearch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", - "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", - "dev": true + "typed-array-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", + "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", + "dev": true, + "requires": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + } }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "typed-array-length": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", + "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", "dev": true, "requires": { - "safe-buffer": "~5.2.0" + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "is-typed-array": "^1.1.9" } }, - "string-format": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/string-format/-/string-format-2.0.0.tgz", - "integrity": "sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA==", + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", "dev": true, "peer": true }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", "dev": true, "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "is-typedarray": "^1.0.0" } }, - "string.prototype.trim": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz", - "integrity": "sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==", + "typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "dev": true + }, + "typical": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", + "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==", + "dev": true, + "peer": true + }, + "uglify-js": { + "version": "3.17.4", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", + "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", + "dev": true, + "optional": true, + "peer": true + }, + "ultron": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", + "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==", + "dev": true + }, + "unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", "dev": true, - "peer": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" } }, - "string.prototype.trimend": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", - "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", + "underscore": { + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", + "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==", + "dev": true + }, + "undici": { + "version": "5.28.2", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.2.tgz", + "integrity": "sha512-wh1pHJHnUeQV5Xa8/kyQhO7WFa8M34l026L5P/+2TYiakvGy5Rdc8jWZVyG7ieht/0WgJLEd3kcU5gKx+6GC8w==", "dev": true, - "peer": true, "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "@fastify/busboy": "^2.0.0" } }, - "string.prototype.trimstart": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", - "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", + "unfetch": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/unfetch/-/unfetch-4.2.0.tgz", + "integrity": "sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA==", + "dev": true + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, - "peer": true, "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "punycode": "^2.1.0" } }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ==", "dev": true, "requires": { - "ansi-regex": "^5.0.1" + "prepend-http": "^2.0.0" } }, - "strip-hex-prefix": { + "url-set-query": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", - "integrity": "sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==", + "resolved": "https://registry.npmjs.org/url-set-query/-/url-set-query-1.0.0.tgz", + "integrity": "sha512-3AChu4NiXquPfeckE5R5cGdiHCMWJx1dwCWOmWIL4KHAziJNOFIYJlpGFeKDvwLPHovZRCxK3cYlwzqI9Vp+Gg==", + "dev": true + }, + "utf-8-validate": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz", + "integrity": "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==", "dev": true, "requires": { - "is-hex-prefixed": "1.0.0" + "node-gyp-build": "^4.3.0" } }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "utf8": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", + "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==", "dev": true }, - "strip-outer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", - "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", + "util": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", + "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", "dev": true, "requires": { - "escape-string-regexp": "^1.0.2" - }, - "dependencies": { - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - } + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "which-typed-array": "^1.1.2" } }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "dev": true + }, + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true + }, + "v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, + "validator": { + "version": "13.11.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz", + "integrity": "sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==", + "dev": true + }, + "varint": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz", + "integrity": "sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow==", + "dev": true + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", "dev": true, "requires": { - "has-flag": "^4.0.0" + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" } }, - "sync-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz", - "integrity": "sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==", + "web3": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3/-/web3-1.7.3.tgz", + "integrity": "sha512-UgBvQnKIXncGYzsiGacaiHtm0xzQ/JtGqcSO/ddzQHYxnNuwI72j1Pb4gskztLYihizV9qPNQYHMSCiBlStI9A==", "dev": true, - "peer": true, "requires": { - "http-response-object": "^3.0.1", - "sync-rpc": "^1.2.1", - "then-request": "^6.0.0" + "web3-bzz": "1.7.3", + "web3-core": "1.7.3", + "web3-eth": "1.7.3", + "web3-eth-personal": "1.7.3", + "web3-net": "1.7.3", + "web3-shh": "1.7.3", + "web3-utils": "1.7.3" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "web3-utils": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.3.tgz", + "integrity": "sha512-g6nQgvb/bUpVUIxJE+ezVN+rYwYmlFyMvMIRSuqpi1dk6ApDD00YNArrk7sPcZnjvxOJ76813Xs2vIN2rgh4lg==", + "dev": true, + "requires": { + "bn.js": "^4.11.9", + "ethereum-bloom-filters": "^1.0.6", + "ethereumjs-util": "^7.1.0", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + } + } } }, - "sync-rpc": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.6.tgz", - "integrity": "sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==", + "web3-bzz": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.7.3.tgz", + "integrity": "sha512-y2i2IW0MfSqFc1JBhBSQ59Ts9xE30hhxSmLS13jLKWzie24/An5dnoGarp2rFAy20tevJu1zJVPYrEl14jiL5w==", "dev": true, - "peer": true, "requires": { - "get-port": "^3.1.0" + "@types/node": "^12.12.6", + "got": "9.6.0", + "swarm-js": "^0.1.40" + }, + "dependencies": { + "@types/node": { + "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", + "dev": true + } } }, - "table": { - "version": "6.8.1", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", - "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", + "web3-core": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.7.3.tgz", + "integrity": "sha512-4RNxueGyevD1XSjdHE57vz/YWRHybpcd3wfQS33fgMyHZBVLFDNwhn+4dX4BeofVlK/9/cmPAokLfBUStZMLdw==", "dev": true, - "peer": true, "requires": { - "ajv": "^8.0.1", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" + "@types/bn.js": "^4.11.5", + "@types/node": "^12.12.6", + "bignumber.js": "^9.0.0", + "web3-core-helpers": "1.7.3", + "web3-core-method": "1.7.3", + "web3-core-requestmanager": "1.7.3", + "web3-utils": "1.7.3" }, "dependencies": { - "ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "@types/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", "dev": true, - "peer": true, "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "@types/node": "*" } }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "@types/node": { + "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", + "dev": true + }, + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "web3-utils": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.3.tgz", + "integrity": "sha512-g6nQgvb/bUpVUIxJE+ezVN+rYwYmlFyMvMIRSuqpi1dk6ApDD00YNArrk7sPcZnjvxOJ76813Xs2vIN2rgh4lg==", "dev": true, - "peer": true + "requires": { + "bn.js": "^4.11.9", + "ethereum-bloom-filters": "^1.0.6", + "ethereumjs-util": "^7.1.0", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + } } } }, - "table-layout": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-1.0.2.tgz", - "integrity": "sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A==", + "web3-core-helpers": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.3.tgz", + "integrity": "sha512-qS2t6UKLhRV/6C7OFHtMeoHphkcA+CKUr2vfpxy4hubs3+Nj28K9pgiqFuvZiXmtEEwIAE2A28GBOC3RdcSuFg==", "dev": true, - "peer": true, "requires": { - "array-back": "^4.0.1", - "deep-extend": "~0.6.0", - "typical": "^5.2.0", - "wordwrapjs": "^4.0.0" + "web3-eth-iban": "1.7.3", + "web3-utils": "1.7.3" }, "dependencies": { - "array-back": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz", - "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==", - "dev": true, - "peer": true + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true }, - "typical": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", - "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", + "web3-utils": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.3.tgz", + "integrity": "sha512-g6nQgvb/bUpVUIxJE+ezVN+rYwYmlFyMvMIRSuqpi1dk6ApDD00YNArrk7sPcZnjvxOJ76813Xs2vIN2rgh4lg==", "dev": true, - "peer": true + "requires": { + "bn.js": "^4.11.9", + "ethereum-bloom-filters": "^1.0.6", + "ethereumjs-util": "^7.1.0", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + } } - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, - "then-request": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/then-request/-/then-request-6.0.2.tgz", - "integrity": "sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==", - "dev": true, - "peer": true, - "requires": { - "@types/concat-stream": "^1.6.0", - "@types/form-data": "0.0.33", - "@types/node": "^8.0.0", - "@types/qs": "^6.2.31", - "caseless": "~0.12.0", - "concat-stream": "^1.6.0", - "form-data": "^2.2.0", - "http-basic": "^8.1.1", - "http-response-object": "^3.0.1", - "promise": "^8.0.0", - "qs": "^6.4.0" + } + }, + "web3-core-method": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.7.3.tgz", + "integrity": "sha512-SeF8YL/NVFbj/ddwLhJeS0io8y7wXaPYA2AVT0h2C2ESYkpvOtQmyw2Bc3aXxBmBErKcbOJjE2ABOKdUmLSmMA==", + "dev": true, + "requires": { + "@ethersproject/transactions": "^5.0.0-beta.135", + "web3-core-helpers": "1.7.3", + "web3-core-promievent": "1.7.3", + "web3-core-subscriptions": "1.7.3", + "web3-utils": "1.7.3" }, "dependencies": { - "@types/node": { - "version": "8.10.66", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz", - "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==", + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "web3-utils": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.3.tgz", + "integrity": "sha512-g6nQgvb/bUpVUIxJE+ezVN+rYwYmlFyMvMIRSuqpi1dk6ApDD00YNArrk7sPcZnjvxOJ76813Xs2vIN2rgh4lg==", "dev": true, - "peer": true + "requires": { + "bn.js": "^4.11.9", + "ethereum-bloom-filters": "^1.0.6", + "ethereumjs-util": "^7.1.0", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + } } } }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true - }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "web3-core-promievent": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.7.3.tgz", + "integrity": "sha512-+mcfNJLP8h2JqcL/UdMGdRVfTdm+bsoLzAFtLpazE4u9kU7yJUgMMAqnK59fKD3Zpke3DjaUJKwz1TyiGM5wig==", "dev": true, "requires": { - "os-tmpdir": "~1.0.2" + "eventemitter3": "4.0.4" } }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "web3-core-requestmanager": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.7.3.tgz", + "integrity": "sha512-bC+jeOjPbagZi2IuL1J5d44f3zfPcgX+GWYUpE9vicNkPUxFBWRG+olhMo7L+BIcD57cTmukDlnz+1xBULAjFg==", "dev": true, "requires": { - "is-number": "^7.0.0" + "util": "^0.12.0", + "web3-core-helpers": "1.7.3", + "web3-providers-http": "1.7.3", + "web3-providers-ipc": "1.7.3", + "web3-providers-ws": "1.7.3" } }, - "toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "dev": true - }, - "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "web3-core-subscriptions": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.7.3.tgz", + "integrity": "sha512-/i1ZCLW3SDxEs5mu7HW8KL4Vq7x4/fDXY+yf/vPoDljlpvcLEOnI8y9r7om+0kYwvuTlM6DUHHafvW0221TyRQ==", "dev": true, - "peer": true, "requires": { - "psl": "^1.1.28", - "punycode": "^2.1.1" + "eventemitter3": "4.0.4", + "web3-core-helpers": "1.7.3" } }, - "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "dev": true - }, - "trim-repeated": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", - "integrity": "sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==", + "web3-eth": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.7.3.tgz", + "integrity": "sha512-BCIRMPwaMlTCbswXyGT6jj9chCh9RirbDFkPtvqozfQ73HGW7kP78TXXf9+Xdo1GjutQfxi/fQ9yPdxtDJEpDA==", "dev": true, "requires": { - "escape-string-regexp": "^1.0.2" + "web3-core": "1.7.3", + "web3-core-helpers": "1.7.3", + "web3-core-method": "1.7.3", + "web3-core-subscriptions": "1.7.3", + "web3-eth-abi": "1.7.3", + "web3-eth-accounts": "1.7.3", + "web3-eth-contract": "1.7.3", + "web3-eth-ens": "1.7.3", + "web3-eth-iban": "1.7.3", + "web3-eth-personal": "1.7.3", + "web3-net": "1.7.3", + "web3-utils": "1.7.3" }, "dependencies": { - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", "dev": true + }, + "web3-utils": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.3.tgz", + "integrity": "sha512-g6nQgvb/bUpVUIxJE+ezVN+rYwYmlFyMvMIRSuqpi1dk6ApDD00YNArrk7sPcZnjvxOJ76813Xs2vIN2rgh4lg==", + "dev": true, + "requires": { + "bn.js": "^4.11.9", + "ethereum-bloom-filters": "^1.0.6", + "ethereumjs-util": "^7.1.0", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + } } } }, - "ts-command-line-args": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/ts-command-line-args/-/ts-command-line-args-2.5.1.tgz", - "integrity": "sha512-H69ZwTw3rFHb5WYpQya40YAX2/w7Ut75uUECbgBIsLmM+BNuYnxsltfyyLMxy6sEeKxgijLTnQtLd0nKd6+IYw==", - "dev": true, - "peer": true, - "requires": { - "chalk": "^4.1.0", - "command-line-args": "^5.1.1", - "command-line-usage": "^6.1.0", - "string-format": "^2.0.0" - } - }, - "ts-essentials": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-7.0.3.tgz", - "integrity": "sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ==", - "dev": true, - "peer": true, - "requires": {} - }, - "ts-node": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "web3-eth-abi": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.7.3.tgz", + "integrity": "sha512-ZlD8DrJro0ocnbZViZpAoMX44x5aYAb73u2tMq557rMmpiluZNnhcCYF/NnVMy6UIkn7SF/qEA45GXA1ne6Tnw==", "dev": true, "requires": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" + "@ethersproject/abi": "5.0.7", + "web3-utils": "1.7.3" }, "dependencies": { - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "@ethersproject/abi": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.7.tgz", + "integrity": "sha512-Cqktk+hSIckwP/W8O47Eef60VwmoSC/L3lY0+dIBhQPCNn9E4V7rwmm2aFrNRRDJfFlGuZ1khkQUOc3oBX+niw==", + "dev": true, + "requires": { + "@ethersproject/address": "^5.0.4", + "@ethersproject/bignumber": "^5.0.7", + "@ethersproject/bytes": "^5.0.4", + "@ethersproject/constants": "^5.0.4", + "@ethersproject/hash": "^5.0.4", + "@ethersproject/keccak256": "^5.0.3", + "@ethersproject/logger": "^5.0.5", + "@ethersproject/properties": "^5.0.3", + "@ethersproject/strings": "^5.0.4" + } + }, + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", "dev": true + }, + "web3-utils": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.3.tgz", + "integrity": "sha512-g6nQgvb/bUpVUIxJE+ezVN+rYwYmlFyMvMIRSuqpi1dk6ApDD00YNArrk7sPcZnjvxOJ76813Xs2vIN2rgh4lg==", + "dev": true, + "requires": { + "bn.js": "^4.11.9", + "ethereum-bloom-filters": "^1.0.6", + "ethereumjs-util": "^7.1.0", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + } } } }, - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "tsort": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/tsort/-/tsort-0.0.1.tgz", - "integrity": "sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw==", - "dev": true - }, - "tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "web3-eth-accounts": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.7.3.tgz", + "integrity": "sha512-aDaWjW1oJeh0LeSGRVyEBiTe/UD2/cMY4dD6pQYa8dOhwgMtNQjxIQ7kacBBXe7ZKhjbIFZDhvXN4mjXZ82R2Q==", "dev": true, "requires": { - "tslib": "^1.8.1" + "@ethereumjs/common": "^2.5.0", + "@ethereumjs/tx": "^3.3.2", + "crypto-browserify": "3.12.0", + "eth-lib": "0.2.8", + "ethereumjs-util": "^7.0.10", + "scrypt-js": "^3.0.1", + "uuid": "3.3.2", + "web3-core": "1.7.3", + "web3-core-helpers": "1.7.3", + "web3-core-method": "1.7.3", + "web3-utils": "1.7.3" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "requires": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "dev": true + }, + "web3-utils": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.3.tgz", + "integrity": "sha512-g6nQgvb/bUpVUIxJE+ezVN+rYwYmlFyMvMIRSuqpi1dk6ApDD00YNArrk7sPcZnjvxOJ76813Xs2vIN2rgh4lg==", + "dev": true, + "requires": { + "bn.js": "^4.11.9", + "ethereum-bloom-filters": "^1.0.6", + "ethereumjs-util": "^7.1.0", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + } + } } }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "web3-eth-contract": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.7.3.tgz", + "integrity": "sha512-7mjkLxCNMWlQrlfM/MmNnlKRHwFk5XrZcbndoMt3KejcqDP6dPHi2PZLutEcw07n/Sk8OMpSamyF3QiGfmyRxw==", "dev": true, - "peer": true, "requires": { - "safe-buffer": "^5.0.1" + "@types/bn.js": "^4.11.5", + "web3-core": "1.7.3", + "web3-core-helpers": "1.7.3", + "web3-core-method": "1.7.3", + "web3-core-promievent": "1.7.3", + "web3-core-subscriptions": "1.7.3", + "web3-eth-abi": "1.7.3", + "web3-utils": "1.7.3" + }, + "dependencies": { + "@types/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "web3-utils": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.3.tgz", + "integrity": "sha512-g6nQgvb/bUpVUIxJE+ezVN+rYwYmlFyMvMIRSuqpi1dk6ApDD00YNArrk7sPcZnjvxOJ76813Xs2vIN2rgh4lg==", + "dev": true, + "requires": { + "bn.js": "^4.11.9", + "ethereum-bloom-filters": "^1.0.6", + "ethereumjs-util": "^7.1.0", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + } + } } }, - "tweetnacl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==", - "dev": true - }, - "tweetnacl-util": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", - "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==", - "dev": true - }, - "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "web3-eth-ens": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.7.3.tgz", + "integrity": "sha512-q7+hFGHIc0mBI3LwgRVcLCQmp6GItsWgUtEZ5bjwdjOnJdbjYddm7PO9RDcTDQ6LIr7hqYaY4WTRnDHZ6BEt5Q==", "dev": true, "requires": { - "prelude-ls": "^1.2.1" + "content-hash": "^2.5.2", + "eth-ens-namehash": "2.0.8", + "web3-core": "1.7.3", + "web3-core-helpers": "1.7.3", + "web3-core-promievent": "1.7.3", + "web3-eth-abi": "1.7.3", + "web3-eth-contract": "1.7.3", + "web3-utils": "1.7.3" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "web3-utils": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.3.tgz", + "integrity": "sha512-g6nQgvb/bUpVUIxJE+ezVN+rYwYmlFyMvMIRSuqpi1dk6ApDD00YNArrk7sPcZnjvxOJ76813Xs2vIN2rgh4lg==", + "dev": true, + "requires": { + "bn.js": "^4.11.9", + "ethereum-bloom-filters": "^1.0.6", + "ethereumjs-util": "^7.1.0", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + } + } } }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, - "peer": true - }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true - }, - "typechain": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/typechain/-/typechain-8.2.0.tgz", - "integrity": "sha512-tZqhqjxJ9xAS/Lh32jccTjMkpx7sTdUVVHAy5Bf0TIer5QFNYXotiX74oCvoVYjyxUKDK3MXHtMFzMyD3kE+jg==", + "web3-eth-iban": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.3.tgz", + "integrity": "sha512-1GPVWgajwhh7g53mmYDD1YxcftQniIixMiRfOqlnA1w0mFGrTbCoPeVaSQ3XtSf+rYehNJIZAUeDBnONVjXXmg==", "dev": true, - "peer": true, "requires": { - "@types/prettier": "^2.1.1", - "debug": "^4.3.1", - "fs-extra": "^7.0.0", - "glob": "7.1.7", - "js-sha3": "^0.8.0", - "lodash": "^4.17.15", - "mkdirp": "^1.0.4", - "prettier": "^2.3.1", - "ts-command-line-args": "^2.2.0", - "ts-essentials": "^7.0.1" + "bn.js": "^4.11.9", + "web3-utils": "1.7.3" }, "dependencies": { - "glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "web3-utils": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.3.tgz", + "integrity": "sha512-g6nQgvb/bUpVUIxJE+ezVN+rYwYmlFyMvMIRSuqpi1dk6ApDD00YNArrk7sPcZnjvxOJ76813Xs2vIN2rgh4lg==", "dev": true, - "peer": true, "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "bn.js": "^4.11.9", + "ethereum-bloom-filters": "^1.0.6", + "ethereumjs-util": "^7.1.0", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" } + } + } + }, + "web3-eth-personal": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.7.3.tgz", + "integrity": "sha512-iTLz2OYzEsJj2qGE4iXC1Gw+KZN924fTAl0ESBFs2VmRhvVaM7GFqZz/wx7/XESl3GVxGxlRje3gNK0oGIoYYQ==", + "dev": true, + "requires": { + "@types/node": "^12.12.6", + "web3-core": "1.7.3", + "web3-core-helpers": "1.7.3", + "web3-core-method": "1.7.3", + "web3-net": "1.7.3", + "web3-utils": "1.7.3" + }, + "dependencies": { + "@types/node": { + "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", + "dev": true }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, - "peer": true + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true }, - "prettier": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", - "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "web3-utils": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.3.tgz", + "integrity": "sha512-g6nQgvb/bUpVUIxJE+ezVN+rYwYmlFyMvMIRSuqpi1dk6ApDD00YNArrk7sPcZnjvxOJ76813Xs2vIN2rgh4lg==", "dev": true, - "peer": true + "requires": { + "bn.js": "^4.11.9", + "ethereum-bloom-filters": "^1.0.6", + "ethereumjs-util": "^7.1.0", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + } } } }, - "typed-array-length": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", - "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", + "web3-net": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.7.3.tgz", + "integrity": "sha512-zAByK0Qrr71k9XW0Adtn+EOuhS9bt77vhBO6epAeQ2/VKl8rCGLAwrl3GbeEl7kWa8s/su72cjI5OetG7cYR0g==", "dev": true, - "peer": true, "requires": { - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "is-typed-array": "^1.1.9" + "web3-core": "1.7.3", + "web3-core-method": "1.7.3", + "web3-utils": "1.7.3" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "web3-utils": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.3.tgz", + "integrity": "sha512-g6nQgvb/bUpVUIxJE+ezVN+rYwYmlFyMvMIRSuqpi1dk6ApDD00YNArrk7sPcZnjvxOJ76813Xs2vIN2rgh4lg==", + "dev": true, + "requires": { + "bn.js": "^4.11.9", + "ethereum-bloom-filters": "^1.0.6", + "ethereumjs-util": "^7.1.0", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + } + } } }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", - "dev": true, - "peer": true - }, - "typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", - "dev": true - }, - "typical": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", - "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==", - "dev": true, - "peer": true - }, - "uglify-js": { - "version": "3.17.4", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", - "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", - "dev": true, - "optional": true, - "peer": true - }, - "unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "web3-providers-http": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.7.3.tgz", + "integrity": "sha512-TQJfMsDQ5Uq9zGMYlu7azx1L7EvxW+Llks3MaWn3cazzr5tnrDbGh6V17x6LN4t8tFDHWx0rYKr3mDPqyTjOZw==", "dev": true, - "peer": true, "requires": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" + "web3-core-helpers": "1.7.3", + "xhr2-cookies": "1.1.0" } }, - "undici": { - "version": "5.22.1", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.22.1.tgz", - "integrity": "sha512-Ji2IJhFXZY0x/0tVBXeQwgPlLWw13GVzpsWPQ3rV50IFMMof2I55PZZxtm4P6iNq+L5znYN9nSTAq0ZyE6lSJw==", + "web3-providers-ipc": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.7.3.tgz", + "integrity": "sha512-Z4EGdLKzz6I1Bw+VcSyqVN4EJiT2uAro48Am1eRvxUi4vktGoZtge1ixiyfrRIVb6nPe7KnTFl30eQBtMqS0zA==", "dev": true, "requires": { - "busboy": "^1.6.0" + "oboe": "2.1.5", + "web3-core-helpers": "1.7.3" } }, - "unfetch": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/unfetch/-/unfetch-4.2.0.tgz", - "integrity": "sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA==", - "dev": true - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "dev": true - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "web3-providers-ws": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.7.3.tgz", + "integrity": "sha512-PpykGbkkkKtxPgv7U4ny4UhnkqSZDfLgBEvFTXuXLAngbX/qdgfYkhIuz3MiGplfL7Yh93SQw3xDjImXmn2Rgw==", "dev": true, "requires": { - "punycode": "^2.1.0" + "eventemitter3": "4.0.4", + "web3-core-helpers": "1.7.3", + "websocket": "^1.0.32" } }, - "utf8": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", - "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==", - "dev": true, - "peer": true - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true - }, - "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true - }, - "v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "web3-shh": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.7.3.tgz", + "integrity": "sha512-bQTSKkyG7GkuULdZInJ0osHjnmkHij9tAySibpev1XjYdjLiQnd0J9YGF4HjvxoG3glNROpuCyTaRLrsLwaZuw==", "dev": true, - "peer": true, "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" + "web3-core": "1.7.3", + "web3-core-method": "1.7.3", + "web3-core-subscriptions": "1.7.3", + "web3-net": "1.7.3" } }, "web3-utils": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.10.0.tgz", - "integrity": "sha512-kSaCM0uMcZTNUSmn5vMEhlo02RObGNRRCkdX0V9UTAU0+lrvn0HSaudyCo6CQzuXUsnuY2ERJGCGPfeWmv19Rg==", + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.10.3.tgz", + "integrity": "sha512-OqcUrEE16fDBbGoQtZXWdavsPzbGIDc5v3VrRTZ0XrIpefC/viZ1ZU9bGEemazyS0catk/3rkOOxpzTfY+XsyQ==", "dev": true, "peer": true, "requires": { + "@ethereumjs/util": "^8.1.0", "bn.js": "^5.2.1", "ethereum-bloom-filters": "^1.0.6", - "ethereumjs-util": "^7.1.0", + "ethereum-cryptography": "^2.1.2", "ethjs-unit": "0.1.6", "number-to-bn": "1.7.0", "randombytes": "^2.1.0", "utf8": "3.0.0" + }, + "dependencies": { + "ethereum-cryptography": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.1.2.tgz", + "integrity": "sha512-Z5Ba0T0ImZ8fqXrJbpHcbpAvIswRte2wGNR/KePnu8GbbvgJ47lMxT/ZZPG6i9Jaht4azPDop4HaM00J0J59ug==", + "dev": true, + "peer": true, + "requires": { + "@noble/curves": "1.1.0", + "@noble/hashes": "1.3.1", + "@scure/bip32": "1.3.1", + "@scure/bip39": "1.2.1" + } + } } }, "webidl-conversions": { @@ -21526,6 +25643,37 @@ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", "dev": true }, + "websocket": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.34.tgz", + "integrity": "sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ==", + "dev": true, + "requires": { + "bufferutil": "^4.0.1", + "debug": "^2.2.0", + "es5-ext": "^0.10.50", + "typedarray-to-buffer": "^3.1.5", + "utf-8-validate": "^5.0.2", + "yaeti": "^0.0.6" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + } + } + }, "whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", @@ -21550,7 +25698,6 @@ "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", "dev": true, - "peer": true, "requires": { "is-bigint": "^1.0.1", "is-boolean-object": "^1.1.0", @@ -21559,79 +25706,23 @@ "is-symbol": "^1.0.3" } }, - "which-module": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", - "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", - "dev": true, - "peer": true - }, "which-typed-array": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", - "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz", + "integrity": "sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==", "dev": true, - "peer": true, "requires": { "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", + "call-bind": "^1.0.4", "for-each": "^0.3.3", "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.10" - } - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "peer": true, - "requires": { - "string-width": "^1.0.2 || 2" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", - "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", - "dev": true, - "peer": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "dev": true, - "peer": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "peer": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", - "dev": true, - "peer": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } + "has-tostringtag": "^1.0.0" } }, "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true }, "wordwrap": { @@ -21700,12 +25791,56 @@ "dev": true, "requires": {} }, - "xmlhttprequest": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", - "integrity": "sha512-58Im/U0mlVBLM38NdZjHyhuMtCqa61469k2YP/AaPbvCoV9aQGUpbJBj1QRm2ytRiVQBD/fsw7L2bJGDVQswBA==", + "xhr": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.6.0.tgz", + "integrity": "sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==", "dev": true, - "peer": true + "requires": { + "global": "~4.4.0", + "is-function": "^1.0.1", + "parse-headers": "^2.0.0", + "xtend": "^4.0.0" + } + }, + "xhr-request": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/xhr-request/-/xhr-request-1.1.0.tgz", + "integrity": "sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA==", + "dev": true, + "requires": { + "buffer-to-arraybuffer": "^0.0.5", + "object-assign": "^4.1.1", + "query-string": "^5.0.1", + "simple-get": "^2.7.0", + "timed-out": "^4.0.1", + "url-set-query": "^1.0.0", + "xhr": "^2.0.4" + } + }, + "xhr-request-promise": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/xhr-request-promise/-/xhr-request-promise-0.1.3.tgz", + "integrity": "sha512-YUBytBsuwgitWtdRzXDDkWAXzhdGB8bYm0sSzMPZT7Z2MBjMSTHFsyCT1yCRATY+XC69DUrQraRAEgcoCRaIPg==", + "dev": true, + "requires": { + "xhr-request": "^1.1.0" + } + }, + "xhr2-cookies": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz", + "integrity": "sha512-hjXUA6q+jl/bd8ADHcVfFsSPIf+tyLIjuO9TwJC9WI6JP2zKcS7C+p56I9kCLLsaCiNT035iYvEUUzdEFj/8+g==", + "dev": true, + "requires": { + "cookiejar": "^2.1.1" + } + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true }, "y18n": { "version": "5.0.8", @@ -21713,6 +25848,12 @@ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true }, + "yaeti": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz", + "integrity": "sha512-MvQa//+KcZCUkBTIC9blM+CU9J2GzuTytsOUwf2lidtvkx/6gnEp1QvJv34t9vdjhFmha/mUiNDbN0D0mJWdug==", + "dev": true + }, "yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", diff --git a/package.json b/package.json index 979bf9e6..dbc0163d 100644 --- a/package.json +++ b/package.json @@ -61,6 +61,7 @@ "hardhat-abi-exporter": "^2.10.1", "prompts": "^2.4.2", "simple-git": "^3.16.1", + "ssv-keys": "github:bloxapp/ssv-keys#v1.0.4", "ts-node": "^10.7.0", "typescript": "^4.6.3" } diff --git a/test/account/deposit.ts b/test/account/deposit.ts index 2ba6b7d3..cf7cf0b4 100644 --- a/test/account/deposit.ts +++ b/test/account/deposit.ts @@ -10,7 +10,7 @@ let ssvNetworkContract: any, ssvViews: any, cluster1: any, minDepositAmount: any describe('Deposit Tests', () => { beforeEach(async () => { // Initialize contract - const metadata = (await helpers.initializeContract()); + const metadata = await helpers.initializeContract(); ssvNetworkContract = metadata.contract; ssvViews = metadata.ssvViews; @@ -24,78 +24,89 @@ describe('Deposit Tests', () => { await helpers.coldRegisterValidator(); // Register validators - cluster1 = await helpers.registerValidators(4, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + cluster1 = await helpers.registerValidators( + 4, + minDepositAmount, + [1], + [1, 2, 3, 4], + helpers.getClusterForValidator(0, 0, 0, 0, true), + [GasGroup.REGISTER_VALIDATOR_NEW_STATE], + ); }); it('Deposit to a non liquidated cluster I own emits "ClusterDeposited"', async () => { - expect(await ssvViews.isLiquidated(cluster1.args.owner, cluster1.args.operatorIds, cluster1.args.cluster)).to.equal(false); + expect(await ssvViews.isLiquidated(cluster1.args.owner, cluster1.args.operatorIds, cluster1.args.cluster)).to.equal( + false, + ); await helpers.DB.ssvToken.connect(helpers.DB.owners[4]).approve(ssvNetworkContract.address, minDepositAmount); - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).deposit( - helpers.DB.owners[4].address, - cluster1.args.operatorIds, - minDepositAmount, - cluster1.args.cluster)).to.emit(ssvNetworkContract, 'ClusterDeposited'); + await expect( + ssvNetworkContract + .connect(helpers.DB.owners[4]) + .deposit(helpers.DB.owners[4].address, cluster1.args.operatorIds, minDepositAmount, cluster1.args.cluster), + ).to.emit(ssvNetworkContract, 'ClusterDeposited'); }); it('Deposit to a cluster I own gas limits', async () => { await helpers.DB.ssvToken.connect(helpers.DB.owners[4]).approve(ssvNetworkContract.address, minDepositAmount); - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).deposit( - helpers.DB.owners[4].address, - cluster1.args.operatorIds, - minDepositAmount, - cluster1.args.cluster), [GasGroup.DEPOSIT]); + await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[4]) + .deposit(helpers.DB.owners[4].address, cluster1.args.operatorIds, minDepositAmount, cluster1.args.cluster), + [GasGroup.DEPOSIT], + ); }); it('Deposit to a cluster I do not own emits "ClusterDeposited"', async () => { await helpers.DB.ssvToken.connect(helpers.DB.owners[0]).approve(ssvNetworkContract.address, minDepositAmount); - await expect(ssvNetworkContract.connect(helpers.DB.owners[0]).deposit( - helpers.DB.owners[4].address, - cluster1.args.operatorIds, - minDepositAmount, - cluster1.args.cluster)).to.emit(ssvNetworkContract, 'ClusterDeposited'); + await expect( + ssvNetworkContract + .connect(helpers.DB.owners[0]) + .deposit(helpers.DB.owners[4].address, cluster1.args.operatorIds, minDepositAmount, cluster1.args.cluster), + ).to.emit(ssvNetworkContract, 'ClusterDeposited'); }); it('Deposit to a cluster I do not own gas limits', async () => { await helpers.DB.ssvToken.connect(helpers.DB.owners[0]).approve(ssvNetworkContract.address, minDepositAmount); - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[0]).deposit( - helpers.DB.owners[4].address, - cluster1.args.operatorIds, - minDepositAmount, - cluster1.args.cluster), [GasGroup.DEPOSIT]); + await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[0]) + .deposit(helpers.DB.owners[4].address, cluster1.args.operatorIds, minDepositAmount, cluster1.args.cluster), + [GasGroup.DEPOSIT], + ); }); it('Deposit to a cluster I do own with a cluster that does not exist reverts "ClusterDoesNotExists"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).deposit( - helpers.DB.owners[1].address, - cluster1.args.operatorIds, - minDepositAmount, - cluster1.args.cluster)).to.be.revertedWithCustomError(ssvNetworkContract, 'ClusterDoesNotExists'); + await expect( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .deposit(helpers.DB.owners[1].address, cluster1.args.operatorIds, minDepositAmount, cluster1.args.cluster), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'ClusterDoesNotExists'); }); it('Deposit to a cluster I do not own with a cluster that does not exist reverts "ClusterDoesNotExists"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).deposit( - helpers.DB.owners[1].address, - [1, 2, 4, 5], - minDepositAmount, - cluster1.args.cluster)).to.be.revertedWithCustomError(ssvNetworkContract, 'ClusterDoesNotExists'); + await expect( + ssvNetworkContract + .connect(helpers.DB.owners[4]) + .deposit(helpers.DB.owners[1].address, [1, 2, 4, 5], minDepositAmount, cluster1.args.cluster), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'ClusterDoesNotExists'); }); it('Deposit to a liquidated cluster emits "ClusterDeposited"', async () => { await progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - const liquidatedCluster = await trackGas(ssvNetworkContract.liquidate( - cluster1.args.owner, - cluster1.args.operatorIds, - cluster1.args.cluster - )); + const liquidatedCluster = await trackGas( + ssvNetworkContract.liquidate(cluster1.args.owner, cluster1.args.operatorIds, cluster1.args.cluster), + ); const updatedCluster = liquidatedCluster.eventsByName.ClusterLiquidated[0].args; - expect(await ssvViews.isLiquidated(cluster1.args.owner, cluster1.args.operatorIds, updatedCluster.cluster)).to.equal(true); + expect( + await ssvViews.isLiquidated(cluster1.args.owner, cluster1.args.operatorIds, updatedCluster.cluster), + ).to.equal(true); await helpers.DB.ssvToken.connect(helpers.DB.owners[4]).approve(ssvNetworkContract.address, minDepositAmount); - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).deposit( - helpers.DB.owners[4].address, - cluster1.args.operatorIds, - minDepositAmount, - updatedCluster.cluster)).to.emit(ssvNetworkContract, 'ClusterDeposited'); + await expect( + ssvNetworkContract + .connect(helpers.DB.owners[4]) + .deposit(helpers.DB.owners[4].address, cluster1.args.operatorIds, minDepositAmount, updatedCluster.cluster), + ).to.emit(ssvNetworkContract, 'ClusterDeposited'); }); -}); \ No newline at end of file +}); diff --git a/test/account/withdraw.ts b/test/account/withdraw.ts index 10ad1a7f..30ab62ca 100644 --- a/test/account/withdraw.ts +++ b/test/account/withdraw.ts @@ -10,7 +10,7 @@ let ssvNetworkContract: any, ssvViews: any, ssvToken: any, cluster1: any, minDep describe('Withdraw Tests', () => { beforeEach(async () => { // Initialize contract - const metadata = (await helpers.initializeContract()); + const metadata = await helpers.initializeContract(); ssvNetworkContract = metadata.contract; ssvNetworkContract = metadata.contract; ssvViews = metadata.ssvViews; @@ -20,122 +20,196 @@ describe('Withdraw Tests', () => { await helpers.registerOperators(0, 14, helpers.CONFIG.minimalOperatorFee); minDepositAmount = (helpers.CONFIG.minimalBlocksBeforeLiquidation + 10) * helpers.CONFIG.minimalOperatorFee * 4; - // Register validators + // cold register await helpers.coldRegisterValidator(); - await ssvToken.connect(helpers.DB.owners[4]).approve(ssvNetworkContract.address, minDepositAmount); - const register = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).registerValidator( - helpers.DataGenerator.publicKey(1), - [1, 2, 3, 4], - helpers.DataGenerator.shares(4), + // Register validators + const cluster = await helpers.registerValidators( + 4, minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true - } - ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); - cluster1 = register.eventsByName.ValidatorAdded[0].args; + [1], + [1, 2, 3, 4], + helpers.getClusterForValidator(0, 0, 0, 0, true), + [GasGroup.REGISTER_VALIDATOR_NEW_STATE], + ); + + cluster1 = cluster.args; }); it('Withdraw from cluster emits "ClusterWithdrawn"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).withdraw(cluster1.operatorIds, helpers.CONFIG.minimalOperatorFee, cluster1.cluster)).to.emit(ssvNetworkContract, 'ClusterWithdrawn'); + await expect( + ssvNetworkContract + .connect(helpers.DB.owners[4]) + .withdraw(cluster1.operatorIds, helpers.CONFIG.minimalOperatorFee, cluster1.cluster), + ).to.emit(ssvNetworkContract, 'ClusterWithdrawn'); }); it('Withdraw from cluster gas limits', async () => { - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).withdraw(cluster1.operatorIds, helpers.CONFIG.minimalOperatorFee, cluster1.cluster), [GasGroup.WITHDRAW_CLUSTER_BALANCE]); + await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[4]) + .withdraw(cluster1.operatorIds, helpers.CONFIG.minimalOperatorFee, cluster1.cluster), + [GasGroup.WITHDRAW_CLUSTER_BALANCE], + ); }); it('Withdraw from operator balance emits "OperatorWithdrawn"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[0]).withdrawOperatorEarnings(1, helpers.CONFIG.minimalOperatorFee)).to.emit(ssvNetworkContract, 'OperatorWithdrawn'); + await expect( + ssvNetworkContract.connect(helpers.DB.owners[0]).withdrawOperatorEarnings(1, helpers.CONFIG.minimalOperatorFee), + ).to.emit(ssvNetworkContract, 'OperatorWithdrawn'); }); it('Withdraw from operator balance gas limits', async () => { - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[0]).withdrawOperatorEarnings(1, helpers.CONFIG.minimalOperatorFee), [GasGroup.WITHDRAW_OPERATOR_BALANCE]); + await trackGas( + ssvNetworkContract.connect(helpers.DB.owners[0]).withdrawOperatorEarnings(1, helpers.CONFIG.minimalOperatorFee), + [GasGroup.WITHDRAW_OPERATOR_BALANCE], + ); }); it('Withdraw the total operator balance emits "OperatorWithdrawn"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[0]).withdrawAllOperatorEarnings(1)).to.emit(ssvNetworkContract, 'OperatorWithdrawn'); + await expect(ssvNetworkContract.connect(helpers.DB.owners[0]).withdrawAllOperatorEarnings(1)).to.emit( + ssvNetworkContract, + 'OperatorWithdrawn', + ); }); it('Withdraw the total operator balance gas limits', async () => { - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[0]).withdrawAllOperatorEarnings(1), [GasGroup.WITHDRAW_OPERATOR_BALANCE]); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[0]).withdrawAllOperatorEarnings(1), [ + GasGroup.WITHDRAW_OPERATOR_BALANCE, + ]); }); it('Withdraw from a cluster that has a removed operator emits "ClusterWithdrawn"', async () => { await ssvNetworkContract.removeOperator(1); - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).withdraw(cluster1.operatorIds, helpers.CONFIG.minimalOperatorFee, cluster1.cluster)).to.emit(ssvNetworkContract, 'ClusterWithdrawn'); + await expect( + ssvNetworkContract + .connect(helpers.DB.owners[4]) + .withdraw(cluster1.operatorIds, helpers.CONFIG.minimalOperatorFee, cluster1.cluster), + ).to.emit(ssvNetworkContract, 'ClusterWithdrawn'); }); it('Withdraw more than the cluster balance reverts "InsufficientBalance"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).withdraw(cluster1.operatorIds, minDepositAmount, cluster1.cluster)).to.be.revertedWithCustomError(ssvNetworkContract, 'InsufficientBalance'); + await expect( + ssvNetworkContract + .connect(helpers.DB.owners[4]) + .withdraw(cluster1.operatorIds, minDepositAmount, cluster1.cluster), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'InsufficientBalance'); }); it('Sequentially withdraw more than the cluster balance reverts "InsufficientBalance"', async () => { const burnPerBlock = helpers.CONFIG.minimalOperatorFee * 4; - cluster1 = await helpers.deposit(1, cluster1.owner, cluster1.operatorIds, (minDepositAmount * 2).toString(), cluster1.cluster); - expect(await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.operatorIds, cluster1.cluster)).to.be.equals(minDepositAmount * 3 - (burnPerBlock * 2)); + cluster1 = await helpers.deposit( + 1, + cluster1.owner, + cluster1.operatorIds, + (minDepositAmount * 2).toString(), + cluster1.cluster, + ); + expect( + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.operatorIds, cluster1.cluster), + ).to.be.equals(minDepositAmount * 3 - burnPerBlock * 2); cluster1 = await helpers.withdraw(4, cluster1.operatorIds, minDepositAmount, cluster1.cluster); - expect(await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.operatorIds, cluster1.cluster)).to.be.equals(minDepositAmount * 2 - (burnPerBlock * 3)); + expect( + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.operatorIds, cluster1.cluster), + ).to.be.equals(minDepositAmount * 2 - burnPerBlock * 3); cluster1 = await helpers.withdraw(4, cluster1.operatorIds, minDepositAmount, cluster1.cluster); - expect(await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.operatorIds, cluster1.cluster)).to.be.equals(minDepositAmount - (burnPerBlock * 4)); + expect( + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.operatorIds, cluster1.cluster), + ).to.be.equals(minDepositAmount - burnPerBlock * 4); - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).withdraw(cluster1.operatorIds, minDepositAmount, cluster1.cluster)).to.be.revertedWithCustomError(ssvNetworkContract, 'InsufficientBalance'); + await expect( + ssvNetworkContract + .connect(helpers.DB.owners[4]) + .withdraw(cluster1.operatorIds, minDepositAmount, cluster1.cluster), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'InsufficientBalance'); }); it('Withdraw from a liquidatable cluster reverts "InsufficientBalance" (liquidation threshold)', async () => { await utils.progressBlocks(20); - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).withdraw(cluster1.operatorIds, 4000000000, cluster1.cluster)).to.be.revertedWithCustomError(ssvNetworkContract, 'InsufficientBalance'); + await expect( + ssvNetworkContract.connect(helpers.DB.owners[4]).withdraw(cluster1.operatorIds, 4000000000, cluster1.cluster), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'InsufficientBalance'); }); it('Withdraw from a liquidatable cluster reverts "InsufficientBalance" (liquidation collateral)', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation - 10); - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).withdraw(cluster1.operatorIds, 7500000000, cluster1.cluster)).to.be.revertedWithCustomError(ssvNetworkContract, 'InsufficientBalance'); + await expect( + ssvNetworkContract.connect(helpers.DB.owners[4]).withdraw(cluster1.operatorIds, 7500000000, cluster1.cluster), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'InsufficientBalance'); }); it('Withdraw from a liquidatable cluster after liquidation period reverts "InsufficientBalance"', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation + 10); - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).withdraw(cluster1.operatorIds, helpers.CONFIG.minimalOperatorFee, cluster1.cluster)).to.be.revertedWithCustomError(ssvNetworkContract, 'InsufficientBalance'); + await expect( + ssvNetworkContract + .connect(helpers.DB.owners[4]) + .withdraw(cluster1.operatorIds, helpers.CONFIG.minimalOperatorFee, cluster1.cluster), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'InsufficientBalance'); }); it('Withdraw balance from an operator I do not own reverts "CallerNotOwner"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[2]).withdrawOperatorEarnings(1, minDepositAmount)).to.be.revertedWithCustomError(ssvNetworkContract, 'CallerNotOwner'); + await expect( + ssvNetworkContract.connect(helpers.DB.owners[2]).withdrawOperatorEarnings(1, minDepositAmount), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'CallerNotOwner'); }); it('Withdraw more than the operator balance reverts "InsufficientBalance"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[0]).withdrawOperatorEarnings(1, minDepositAmount - )).to.be.revertedWithCustomError(ssvNetworkContract, 'InsufficientBalance'); + await expect( + ssvNetworkContract.connect(helpers.DB.owners[0]).withdrawOperatorEarnings(1, minDepositAmount), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'InsufficientBalance'); }); it('Sequentially withdraw more than the operator balance reverts "InsufficientBalance"', async () => { - await ssvNetworkContract.connect(helpers.DB.owners[0]).withdrawOperatorEarnings(1, helpers.CONFIG.minimalOperatorFee * 3); - expect(await ssvViews.getOperatorEarnings(1)).to.be.equals(helpers.CONFIG.minimalOperatorFee * 4 - helpers.CONFIG.minimalOperatorFee * 3); - - await ssvNetworkContract.connect(helpers.DB.owners[0]).withdrawOperatorEarnings(1, helpers.CONFIG.minimalOperatorFee * 3); - expect(await ssvViews.getOperatorEarnings(1)).to.be.equals(helpers.CONFIG.minimalOperatorFee * 6 - helpers.CONFIG.minimalOperatorFee * 6); - - await expect(ssvNetworkContract.connect(helpers.DB.owners[0]).withdrawOperatorEarnings(1, helpers.CONFIG.minimalOperatorFee * 3 - )).to.be.revertedWithCustomError(ssvNetworkContract, 'InsufficientBalance'); + await ssvNetworkContract + .connect(helpers.DB.owners[0]) + .withdrawOperatorEarnings(1, helpers.CONFIG.minimalOperatorFee * 3); + expect(await ssvViews.getOperatorEarnings(1)).to.be.equals( + helpers.CONFIG.minimalOperatorFee * 4 - helpers.CONFIG.minimalOperatorFee * 3, + ); + + await ssvNetworkContract + .connect(helpers.DB.owners[0]) + .withdrawOperatorEarnings(1, helpers.CONFIG.minimalOperatorFee * 3); + expect(await ssvViews.getOperatorEarnings(1)).to.be.equals( + helpers.CONFIG.minimalOperatorFee * 6 - helpers.CONFIG.minimalOperatorFee * 6, + ); + + await expect( + ssvNetworkContract + .connect(helpers.DB.owners[0]) + .withdrawOperatorEarnings(1, helpers.CONFIG.minimalOperatorFee * 3), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'InsufficientBalance'); }); it('Withdraw the total balance from an operator I do not own reverts "CallerNotOwner"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[2]).withdrawAllOperatorEarnings(12)).to.be.revertedWithCustomError(ssvNetworkContract, 'CallerNotOwner'); + await expect( + ssvNetworkContract.connect(helpers.DB.owners[2]).withdrawAllOperatorEarnings(12), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'CallerNotOwner'); }); it('Withdraw more than the operator total balance reverts "InsufficientBalance"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[0]).withdrawAllOperatorEarnings(14)).to.be.revertedWithCustomError(ssvNetworkContract, 'InsufficientBalance'); + await expect( + ssvNetworkContract.connect(helpers.DB.owners[0]).withdrawOperatorEarnings(13, minDepositAmount), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'InsufficientBalance'); }); it('Withdraw from a cluster without validators', async () => { - cluster1 = await helpers.removeValidator(4, helpers.DataGenerator.publicKey(1), cluster1.operatorIds, cluster1.cluster); - const currentClusterBalance = minDepositAmount - (helpers.CONFIG.minimalOperatorFee * 4); - - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).withdraw(cluster1.operatorIds, currentClusterBalance, cluster1.cluster)).to.emit(ssvNetworkContract, 'ClusterWithdrawn'); - }); -}); \ No newline at end of file + cluster1 = await helpers.removeValidator( + 4, + helpers.DataGenerator.publicKey(1), + cluster1.operatorIds, + cluster1.cluster, + ); + const currentClusterBalance = minDepositAmount - helpers.CONFIG.minimalOperatorFee * 4; + + await expect( + ssvNetworkContract + .connect(helpers.DB.owners[4]) + .withdraw(cluster1.operatorIds, currentClusterBalance, cluster1.cluster), + ).to.emit(ssvNetworkContract, 'ClusterWithdrawn'); + }); +}); diff --git a/test/dao/network-fee-withdraw.ts b/test/dao/network-fee-withdraw.ts index 8a56a351..5355d356 100644 --- a/test/dao/network-fee-withdraw.ts +++ b/test/dao/network-fee-withdraw.ts @@ -10,7 +10,7 @@ let ssvNetworkContract: any, ssvViews: any, minDepositAmount: any, burnPerBlock: describe('DAO Network Fee Withdraw Tests', () => { beforeEach(async () => { // Initialize contract - const metadata = (await helpers.initializeContract()); + const metadata = await helpers.initializeContract(); ssvNetworkContract = metadata.contract; ssvViews = metadata.ssvViews; @@ -30,15 +30,22 @@ describe('DAO Network Fee Withdraw Tests', () => { // cold register await helpers.coldRegisterValidator(); - await helpers.registerValidators(4, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + await helpers.registerValidators( + 4, + minDepositAmount, + [1], + [1, 2, 3, 4], + helpers.getClusterForValidator(0, 0, 0, 0, true), + [GasGroup.REGISTER_VALIDATOR_NEW_STATE], + ); await utils.progressBlocks(10); - }); it('Withdraw network earnings emits "NetworkEarningsWithdrawn"', async () => { const amount = await ssvViews.getNetworkEarnings(); - await expect(ssvNetworkContract.withdrawNetworkEarnings(amount - )).to.emit(ssvNetworkContract, 'NetworkEarningsWithdrawn').withArgs(amount, helpers.DB.owners[0].address); + await expect(ssvNetworkContract.withdrawNetworkEarnings(amount)) + .to.emit(ssvNetworkContract, 'NetworkEarningsWithdrawn') + .withArgs(amount, helpers.DB.owners[0].address); }); it('Withdraw network earnings gas limits', async () => { @@ -55,33 +62,39 @@ describe('DAO Network Fee Withdraw Tests', () => { }); it('Withdraw network earnings with not enough balance reverts "InsufficientBalance"', async () => { - const amount = await ssvViews.getNetworkEarnings() * 2; - await expect(ssvNetworkContract.withdrawNetworkEarnings(amount - )).to.be.revertedWithCustomError(ssvNetworkContract, 'InsufficientBalance'); + const amount = (await ssvViews.getNetworkEarnings()) * 2; + await expect(ssvNetworkContract.withdrawNetworkEarnings(amount)).to.be.revertedWithCustomError( + ssvNetworkContract, + 'InsufficientBalance', + ); }); it('Withdraw network earnings from an address thats not the DAO reverts "caller is not the owner"', async () => { const amount = await ssvViews.getNetworkEarnings(); - await expect(ssvNetworkContract.connect(helpers.DB.owners[3]).withdrawNetworkEarnings(amount - )).to.be.revertedWith('Ownable: caller is not the owner'); + await expect(ssvNetworkContract.connect(helpers.DB.owners[3]).withdrawNetworkEarnings(amount)).to.be.revertedWith( + 'Ownable: caller is not the owner', + ); }); it('Withdraw network earnings providing UINT64 max value reverts "Max value exceeded"', async () => { - const amount = (ethers.BigNumber.from(2).pow(64)).mul(ethers.BigNumber.from(1e8)); - await expect(ssvNetworkContract.withdrawNetworkEarnings(amount - )).to.be.revertedWith('Max value exceeded'); + const amount = ethers.BigNumber.from(2) + .pow(64) + .mul(ethers.BigNumber.from(1e8)); + await expect(ssvNetworkContract.withdrawNetworkEarnings(amount)).to.be.revertedWith('Max value exceeded'); }); it('Withdraw network earnings sequentially when not enough balance reverts "InsufficientBalance"', async () => { - const amount = await ssvViews.getNetworkEarnings() / 2; + const amount = (await ssvViews.getNetworkEarnings()) / 2; await ssvNetworkContract.withdrawNetworkEarnings(amount); - expect(await ssvViews.getNetworkEarnings()).to.be.equals(((networkFee * 13) + (networkFee * 11) - amount)); + expect(await ssvViews.getNetworkEarnings()).to.be.equals(networkFee * 13 + networkFee * 11 - amount); await ssvNetworkContract.withdrawNetworkEarnings(amount); - expect(await ssvViews.getNetworkEarnings()).to.be.equals(((networkFee * 14) + (networkFee * 12) - amount * 2)); + expect(await ssvViews.getNetworkEarnings()).to.be.equals(networkFee * 14 + networkFee * 12 - amount * 2); - await expect(ssvNetworkContract.withdrawNetworkEarnings(amount - )).to.be.revertedWithCustomError(ssvNetworkContract, 'InsufficientBalance'); + await expect(ssvNetworkContract.withdrawNetworkEarnings(amount)).to.be.revertedWithCustomError( + ssvNetworkContract, + 'InsufficientBalance', + ); }); -}); \ No newline at end of file +}); diff --git a/test/dao/operational.ts b/test/dao/operational.ts index 27ecdfc0..b8b28785 100644 --- a/test/dao/operational.ts +++ b/test/dao/operational.ts @@ -9,76 +9,69 @@ let ssvNetworkContract: any, ssvNetworkViews: any, firstCluster: any; // Declare globals describe('DAO operational Tests', () => { - beforeEach(async () => { - // Initialize contract - const metadata = (await helpers.initializeContract()); - ssvNetworkContract = metadata.contract; - ssvNetworkViews = metadata.ssvViews; - }); - - it('Starting the transfer process does not change owner', async () => { - await ssvNetworkContract.transferOwnership(helpers.DB.owners[4].address); - - expect(await ssvNetworkContract.owner()).equals(helpers.DB.owners[0].address); - }); - - it('Ownership is transferred in a 2-step process', async () => { - await ssvNetworkContract.transferOwnership(helpers.DB.owners[4].address); - await ssvNetworkContract.connect(helpers.DB.owners[4]).acceptOwnership(); - - expect(await ssvNetworkContract.owner()).equals(helpers.DB.owners[4].address); - }); - - it('Get the network validators count (add/remove validaotor)', async () => { - await helpers.registerOperators(0, 4, helpers.CONFIG.minimalOperatorFee); - - const deposit = (helpers.CONFIG.minimalBlocksBeforeLiquidation + 2) * helpers.CONFIG.minimalOperatorFee * 13; - - await helpers.DB.ssvToken.connect(helpers.DB.owners[4]).approve(ssvNetworkContract.address, deposit); - - const register = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).registerValidator( - helpers.DataGenerator.publicKey(1), - [1, 2, 3, 4], - helpers.DataGenerator.shares(4), - deposit, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true - } - )); - - firstCluster = register.eventsByName.ValidatorAdded[0].args; - - expect((await ssvNetworkViews.getNetworkValidatorsCount())).to.equal(1); - - await ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator( - helpers.DataGenerator.publicKey(1), - firstCluster.operatorIds, - firstCluster.cluster - ); - expect((await ssvNetworkViews.getNetworkValidatorsCount())).to.equal(0); - }); - - it('Get the network validators count (add/remove validaotor)', async () => { - await helpers.registerOperators(0, 4, helpers.CONFIG.minimalOperatorFee); - - const deposit = (helpers.CONFIG.minimalBlocksBeforeLiquidation + 2) * helpers.CONFIG.minimalOperatorFee * 13; - firstCluster = await helpers.registerValidators(4, 1, deposit.toString(), helpers.DataGenerator.cluster.new()); - - expect((await ssvNetworkViews.getNetworkValidatorsCount())).to.equal(1); - - await progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - - await ssvNetworkContract.connect(helpers.DB.owners[4]).liquidate( - firstCluster.args.owner, - firstCluster.args.operatorIds, - firstCluster.args.cluster - ); - - expect((await ssvNetworkViews.getNetworkValidatorsCount())).to.equal(0); - }); - -}); \ No newline at end of file + beforeEach(async () => { + // Initialize contract + const metadata = await helpers.initializeContract(); + ssvNetworkContract = metadata.contract; + ssvNetworkViews = metadata.ssvViews; + }); + + it('Starting the transfer process does not change owner', async () => { + await ssvNetworkContract.transferOwnership(helpers.DB.owners[4].address); + + expect(await ssvNetworkContract.owner()).equals(helpers.DB.owners[0].address); + }); + + it('Ownership is transferred in a 2-step process', async () => { + await ssvNetworkContract.transferOwnership(helpers.DB.owners[4].address); + await ssvNetworkContract.connect(helpers.DB.owners[4]).acceptOwnership(); + + expect(await ssvNetworkContract.owner()).equals(helpers.DB.owners[4].address); + }); + + it('Get the network validators count (add/remove validaotor)', async () => { + await helpers.registerOperators(0, 4, helpers.CONFIG.minimalOperatorFee); + + const deposit = (helpers.CONFIG.minimalBlocksBeforeLiquidation + 2) * helpers.CONFIG.minimalOperatorFee * 13; + + const cluster = await helpers.registerValidators( + 4, + deposit.toString(), + [1], + [1, 2, 3, 4], + helpers.getClusterForValidator(0, 0, 0, 0, true), + ); + + firstCluster = cluster.args; + + expect(await ssvNetworkViews.getNetworkValidatorsCount()).to.equal(1); + + await ssvNetworkContract + .connect(helpers.DB.owners[4]) + .removeValidator(helpers.DataGenerator.publicKey(1), firstCluster.operatorIds, firstCluster.cluster); + expect(await ssvNetworkViews.getNetworkValidatorsCount()).to.equal(0); + }); + + it('Get the network validators count (add/remove validaotor)', async () => { + await helpers.registerOperators(0, 4, helpers.CONFIG.minimalOperatorFee); + + const deposit = (helpers.CONFIG.minimalBlocksBeforeLiquidation + 2) * helpers.CONFIG.minimalOperatorFee * 13; + firstCluster = await helpers.registerValidators( + 4, + deposit.toString(), + [1], + [1, 2, 3, 4], + helpers.getClusterForValidator(0, 0, 0, 0, true), + ); + + expect(await ssvNetworkViews.getNetworkValidatorsCount()).to.equal(1); + + await progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); + + await ssvNetworkContract + .connect(helpers.DB.owners[4]) + .liquidate(firstCluster.args.owner, firstCluster.args.operatorIds, firstCluster.args.cluster); + + expect(await ssvNetworkViews.getNetworkValidatorsCount()).to.equal(0); + }); +}); diff --git a/test/helpers/contract-helpers.ts b/test/helpers/contract-helpers.ts index 6dcc2885..e025eddd 100644 --- a/test/helpers/contract-helpers.ts +++ b/test/helpers/contract-helpers.ts @@ -1,38 +1,65 @@ // Imports declare const ethers: any; - +import { SSVKeys, KeyShares, EncryptShare } from 'ssv-keys'; import { trackGas, GasGroup } from './gas-usage'; +import { Validator, Operator } from './types'; +import validatorKeys from './json/validatorKeys.json'; +import operatorKeys from './json/operatorKeys.json'; export let DB: any; export let CONFIG: any; export let SSV_MODULES: any; -const SIGNATURE = "869ff0ade8cb76048fb3aa8d4c26b0d71f96eb3bfb69144c080e7fe8db6e1e2f926f365886a59a25601b290f5f4695dd5b7e8cce1c462bdef5bebee34d94711541baeadbc7546a8c3ca301d86aaab4767c809a" +const getSecretSharedPayload = async (validator: Validator, operatorIds: number[], ownerId: number) => { + const selOperators = DB.operators.filter((item: Operator) => operatorIds.includes(item.id)); + const operators = selOperators.map((item: Operator) => ({ id: item.id, operatorKey: item.operatorKey })); + + const ssvKeys = new SSVKeys(); + const keyShares = new KeyShares(); + + const publicKey = validator.publicKey; + const privateKey = validator.privateKey; -const SHARES_RSA = [ - // 4 shares - `0x${SIGNATURE}018281ac5380c3461afba00bfdd853b1cfe52cfcd9b3e43d2971848e9d95ad8ee0134aa6af6ff52b96a7eba070eb1064603e8c027bb7e3b11c399e2aeef8e25953c47cba31440c7f09b64e42d0f429e155b7fdeba9dec68e1cfb057d26659f157a7898e60347a7971b00a3332bc1c2ee6c9c8bc628a4985eeeb0d685707c8c939731c99797af712e3a1f65325748b12776938c2b5a5bd8d258a4258998be971c661837f0427bd95e189e07ec831d43aaf6cb1820fccbb735e228b741395d0386b2e3c397fe1f9fe0f3e9e998dcfb41de10b7df8d42a10387f1d6d47c721a9582cc82675fb24f50674aeeb5115e55f7382800999da85346c9ab794d154648cbcd5e7667ab0b73a0d9caeed618e015dcb66193c24c86249e2958badd1b5fb541a5865fa0cac6621580fd96191699c83d75738d899960670889a4425c5b066720e607ce1c1fe32e27e4f880758299ac2d03b6523e22895e583561cce8019f4b87fd6a99c7b1444ca10f41fb2b98d6f50717058984795d76fcfefc627e0d7a18ea9b52b8dac0b6b38c3579dc8111ff8ce14d7cb221cc51a5c113f13c86bb141030ff08e9924c97508430182ff72b3ac79f3fcfdd6fe16981ab4fa674e571c44f4a36cf5731c0e15fdc6dbceb2e129a4eb9e0eb8251b3d1e242eced9bd4b3dd6ce2c6e737b7d0d57fafb34f459d8725d216b9d5f1ff790a2e228f0376ced846b65d814ffe031ce40adeedbcee7bf158af3ee4375eee14fee246d046091ebacc8e2da3cae5d7b1ab5936f152ec2d1f7d4be4623b4db0f0e49e9940056ca4012fa1a1d3b4c81ae02a07869064d42edc76a7faa8f48d754d3f4e9942e34f5da49b7d3f2ec2eb66f427634eb43f68b9ec1cba34e368070f25a483e7b482a98c8cda30976fc791fbf376ad40fcb38a38dbbfee35b7d333daa2729769a632902f9950fd2e0f1e6174d9ebc369d002123176a3f73ec71001e0de34df65eb208d493e8c36b5da34a03e42399fc6b1c49da35096eabc77474d968653a414b9ab42cbbec502cf4705662dfbc73281757fe4535093a872072189c3b9ea3b5d6843f8221d6cb82e9cfc6d0388948c931680a8679361f38d53ea21b160e436a9f050e51c1e8453484fa1e9f3a20d16319d4626421d6b03df8a267e29407a7c04e0a43211769002ab61a1f9017f52994282a6d1699cb85cf2013d4b341081234ca3274dff0e1b77678809c92ac8181a53c72f047e972280c8eafc4be871e3faf3616f29ec389b4953469a2a30ede4a8a9e5e62792c8d37063571b075228aab33324b62850f0844d8952d1ae6a99a6b887067a66087acea207a9ef6b4f55a82c6e30d6dcb983a7c63714f6dc409f46f6b338cfc2de5969c1ecda938ce889f4aa8fb4eee8dc0d5ffc0d2ac7f0dd65a622fd515ca2a21376e9ba15e99241a85a3951871bd438b047517e8e0b4ddf2ff273a30b3ed483f6f20b183ba311e2c4de0a905e9cb4fdf2560c3b5ede0f988623dfe8d2ed27ca157e060e3558b2cfb1d87ae8751dc7432db61056b5e185356d2e72f732c29b5b47a1c287ce5f1be1c162f0b8a1ed93a30269948463679e55e013485b61775328ce08bad3e4ecf8aab485002f65407c0a1afd90e5a3e44909ba6d0d428e77b92ab873bf0217cd6ff7d6d48616efe4d4dc122ac787ee4f6d9c030b1a10403268c0158c7cd7ae821a6754601f710b9731e37c0dc067b5a2ab`, - // 7 shares - `0x${SIGNATURE}02a2871c338c3206657ce90c00655f526a2055355bde197116efcc55de8b7bc69db23f2a78c91ccee05bd48c03f1d4903631930f49165acc5e605bcdbd1a4bcdd7b44366f2af42e4126cbffc9e34ec9fa29662a401c5aa7ebef5e4ee287c895617dc930f49165acc5e605bcdbd1a4bcdd7b44366f2af42e4126cbffc9e34ec9fa29662a401c5aa7ebef5e4ee287c895617dcaf4dd395545044ac2c83fe26548751891ac655ede78d6d346d5c1611ec39cd5b828440dddc8d5739253a272b128ea962af4dd395545044ac2c83fe26548751891ac655ede78d6d346d5c1611ec39cd5b828440dddc8d5739253a272b128ea962871c338c3206657ce90c00655f526a2055355bde197116efcc55de8b7bc69db23f2a78c91ccee05bd48c03f1d4903631b7d586100b1137d7c7fc4c9b6aad63021581fcd3fa6bb55455e6eb5e42fdba1b1fe1e25b8a350c47f4904064241c034c5dc03027fb3532501eff0877819eedebeb982d651c47ccc7cecf2cc508ad3ba7dd802e993acbaf696a6dcce1eada8ad77c75fc6085a183990b6fadbfb888205b29e17a00671ce8d04b9f3dd64283c29a58ec2ea3a4f1da6227c207708024bc6243e77f41ad7c219e40e14a4b965a9e9957a44fceba379b7c0082d25446c8d3cbb5e0f81b5fea835f5277f6cb3e62df9680f182571466fdbd28585cd2571c832ce11ff9c9a1d144a505f2ff198b6ab3ba19b0ce3096967635c916be872dacefe2c5477c6da28d6a47fd49d8ecad7f161a8d69fb343ca785c795c3242639866789f8d8631693c4a5c68e5a95061e176635d39e28f9afa9a1f23b5ddaaa6212bc699982631ed39ea56134e10efd459421f4abb9a8d9881e78d538c536e0e3062dd3f0f4ac19e2bf0e8329eaf86279235e6b13507f27a3a1afb5845ffe3fe09b1865f2c9cdccd7efc2c1a45244e67cd62ea7ac5a3316e19ed019d7ba0ac6e420f303e2a951e043e7d69b98a8e0975c69c373074a69f40e423bc4787338b33fa1dc15642849a66d89be6c614c9d7372918ed3f12c8767aeda14800cdde15ed83e1df9824b71fcfe636cdb755c374a9df628a9e2f189c900b02a57306e4099b794cb42fa84dc43e186e9e10e2c786a75b32ffdeaf228a77e53b013d830ebbbbb72af84dbf2f64bd66f0584f26a38324d93ae0acb717c60daa7c947fb4cce4d1865fbbb9982631ed39ea56134e10efd459421f4abb9a8d9881e78d538c536e0e3062dd3f0f4ac19e2bf0e8329eaf86279235e6b13507f27a3a1afb5845ffe3fe09b1865f2c9cdccd7efc2c1a45244e67cd62ea7ac5a3316e19ed019d7ba0ac6e420f303e2a951e043e7d69b98a8e0975c69c373074a69f40e423bc4787338b33fa1dc15642849a66d89be6c614c9d7372918ed3f12c8767aeda14800cdde15ed83e1df9824b71fcfe636cdb755c374a9df628a9e2f189c900b02a57306e4099b794cb42fa84dc43e186e9e10e2c786a75b32ffdeaf228a77e53b013d830ebbbbb72af84dbf2f64bd66f0584f26a38324d93ae0acb717c60daa7c947fb4cce4d1865fbbb343775b368f031ebb11cf73a910c86aa91ab662ccd0dabbec26d656551c1fa4bdd55f72c8f24e0442a453f229633f2db01cb728f38dea94fa3d7319d0689c128eb60ca2935673df587f8c60901fd8ac0eba49510ba1b7f51198c7840524eb237c35da262718eb64918f7c39cf64e47bcdd88abd4c16b0ea220e4f598f721e8d1338422d8c77ea63eac77c7644c516d4d7118fbae442839563243684046c25a445b48d4678e5fd1005124b4c02e122756d4f79d8aa9fd6d2b03d1011c669a4cafa16f2e236539ce6014bf4b0e240d127c1d478db2a9e5bd3c33e79246ee208ae51e96142a76553bca928a7cc8e6f8619106f311ae58953272bc96cc5b0b3d0d57343775b368f031ebb11cf73a910c86aa91ab662ccd0dabbec26d656551c1fa4bdd55f72c8f24e0442a453f229633f2db01cb728f38dea94fa3d7319d0689c128eb60ca2935673df587f8c60901fd8ac0eba49510ba1b7f51198c7840524eb237c35da262718eb64918f7c39cf64e47bcdd88abd4c16b0ea220e4f598f721e8d1338422d8c77ea63eac77c7644c516d4d7118fbae442839563243684046c25a445b48d4678e5fd1005124b4c02e122756d4f79d8aa9fd6d2b03d1011c669a4cafa16f2e236539ce6014bf4b0e240d127c1d478db2a9e5bd3c33e79246ee208ae51e96142a76553bca928a7cc8e6f8619106f311ae58953272bc96cc5b0b3d0d579c98d5c9687ada34ee6a6734575ddbf685490ea50d88dafaa3fcc004ca41b7cc31119d92b7b9dadd5f7deefb3ffcc0e9b19d0ec70be4d07e8a657277bfb36bbb3e465c2c5edcfcc21c6be449dc5d67b2c774809e7103f81d3bd36900fc59bc92e935df496164acd8935a7734eb04ac979bc317d0525b7ecb835a79740d80b7d0643ddbd8bcafeaf7f12a61affbbe627f6c561545bd0edaaa1db01c90342c0cad0a25bd92447e27cd03dea84c53d4696f9e16df06d354ce2c34a26b481075eb53c0748e66c2a21425edf9dbc82c60b16dabfa788b78c7926166762df864e2288fb7db2e4deb57c23cce6e9a85524f10ee2b57df91054d00aa80155a376579caeb9c98d5c9687ada34ee6a6734575ddbf685490ea50d88dafaa3fcc004ca41b7cc31119d92b7b9dadd5f7deefb3ffcc0e9b19d0ec70be4d07e8a657277bfb36bbb3e465c2c5edcfcc21c6be449dc5d67b2c774809e7103f81d3bd36900fc59bc92e935df496164acd8935a7734eb04ac979bc317d0525b7ecb835a79740d80b7d0643ddbd8bcafeaf7f12a61affbbe627f6c561545bd0edaaa1db01c90342c0cad0a25bd92447e27cd03dea84c53d4696f9e16df06d354ce2c34a26b481075eb53c0748e66c2a21425edf9dbc82c60b16dabfa788b78c7926166762df864e2288fb7db2e4deb57c23cce6e9a85524f10ee2b57df91054d00aa80155a376579caeb`, - // 10 shares - `0x${SIGNATURE}03c2871c338c3206657ce90c00655f526a2055355bde197116efcc55de8b7bc69db23f2a78c91ccee05bd48c03f1d4903631930f49165acc5e605bcdbd1a4bcdd7b44366f2af42e4126cbffc9e34ec9fa29662a401c5aa7ebef5e4ee287c895617dc930f49165acc5e605bcdbd1a4bcdd7b44366f2af42e4126cbffc9e34ec9fa29662a401c5aa7ebef5e4ee287c895617dcaf4dd395545044ac2c83fe26548751891ac655ede78d6d346d5c1611ec39cd5b828440dddc8d5739253a272b128ea962af4dd395545044ac2c83fe26548751891ac655ede78d6d346d5c1611ec39cd5b828440dddc8d5739253a272b128ea962af4dd395545044ac2c83fe26548751891ac655ede78d6d346d5c1611ec39cd5b828440dddc8d5739253a272b128ea962af4dd395545044ac2c83fe26548751891ac655ede78d6d346d5c1611ec39cd5b828440dddc8d5739253a272b128ea962871c338c3206657ce90c00655f526a2055355bde197116efcc55de8b7bc69db23f2a78c91ccee05bd48c03f1d4903631871c338c3206657ce90c00655f526a2055355bde197116efcc55de8b7bc69db23f2a78c91ccee05bd48c03f1d4903631b7d586100b1137d7c7fc4c9b6aad63021581fcd3fa6bb55455e6eb5e42fdba1b1fe1e25b8a350c47f4904064241c034c5dc03027fb3532501eff0877819eedebeb982d651c47ccc7cecf2cc508ad3ba7dd802e993acbaf696a6dcce1eada8ad77c75fc6085a183990b6fadbfb888205b29e17a00671ce8d04b9f3dd64283c29a58ec2ea3a4f1da6227c207708024bc6243e77f41ad7c219e40e14a4b965a9e9957a44fceba379b7c0082d25446c8d3cbb5e0f81b5fea835f5277f6cb3e62df9680f182571466fdbd28585cd2571c832ce11ff9c9a1d144a505f2ff198b6ab3ba19b0ce3096967635c916be872dacefe2c5477c6da28d6a47fd49d8ecad7f161a8d69fb343ca785c795c3242639866789f8d8631693c4a5c68e5a95061e176635d39e28f9afa9a1f23b5ddaaa6212bc699982631ed39ea56134e10efd459421f4abb9a8d9881e78d538c536e0e3062dd3f0f4ac19e2bf0e8329eaf86279235e6b13507f27a3a1afb5845ffe3fe09b1865f2c9cdccd7efc2c1a45244e67cd62ea7ac5a3316e19ed019d7ba0ac6e420f303e2a951e043e7d69b98a8e0975c69c373074a69f40e423bc4787338b33fa1dc15642849a66d89be6c614c9d7372918ed3f12c8767aeda14800cdde15ed83e1df9824b71fcfe636cdb755c374a9df628a9e2f189c900b02a57306e4099b794cb42fa84dc43e186e9e10e2c786a75b32ffdeaf228a77e53b013d830ebbbbb72af84dbf2f64bd66f0584f26a38324d93ae0acb717c60daa7c947fb4cce4d1865fbbb9982631ed39ea56134e10efd459421f4abb9a8d9881e78d538c536e0e3062dd3f0f4ac19e2bf0e8329eaf86279235e6b13507f27a3a1afb5845ffe3fe09b1865f2c9cdccd7efc2c1a45244e67cd62ea7ac5a3316e19ed019d7ba0ac6e420f303e2a951e043e7d69b98a8e0975c69c373074a69f40e423bc4787338b33fa1dc15642849a66d89be6c614c9d7372918ed3f12c8767aeda14800cdde15ed83e1df9824b71fcfe636cdb755c374a9df628a9e2f189c900b02a57306e4099b794cb42fa84dc43e186e9e10e2c786a75b32ffdeaf228a77e53b013d830ebbbbb72af84dbf2f64bd66f0584f26a38324d93ae0acb717c60daa7c947fb4cce4d1865fbbb9982631ed39ea56134e10efd459421f4abb9a8d9881e78d538c536e0e3062dd3f0f4ac19e2bf0e8329eaf86279235e6b13507f27a3a1afb5845ffe3fe09b1865f2c9cdccd7efc2c1a45244e67cd62ea7ac5a3316e19ed019d7ba0ac6e420f303e2a951e043e7d69b98a8e0975c69c373074a69f40e423bc4787338b33fa1dc15642849a66d89be6c614c9d7372918ed3f12c8767aeda14800cdde15ed83e1df9824b71fcfe636cdb755c374a9df628a9e2f189c900b02a57306e4099b794cb42fa84dc43e186e9e10e2c786a75b32ffdeaf228a77e53b013d830ebbbbb72af84dbf2f64bd66f0584f26a38324d93ae0acb717c60daa7c947fb4cce4d1865fbbb343775b368f031ebb11cf73a910c86aa91ab662ccd0dabbec26d656551c1fa4bdd55f72c8f24e0442a453f229633f2db01cb728f38dea94fa3d7319d0689c128eb60ca2935673df587f8c60901fd8ac0eba49510ba1b7f51198c7840524eb237c35da262718eb64918f7c39cf64e47bcdd88abd4c16b0ea220e4f598f721e8d1338422d8c77ea63eac77c7644c516d4d7118fbae442839563243684046c25a445b48d4678e5fd1005124b4c02e122756d4f79d8aa9fd6d2b03d1011c669a4cafa16f2e236539ce6014bf4b0e240d127c1d478db2a9e5bd3c33e79246ee208ae51e96142a76553bca928a7cc8e6f8619106f311ae58953272bc96cc5b0b3d0d57343775b368f031ebb11cf73a910c86aa91ab662ccd0dabbec26d656551c1fa4bdd55f72c8f24e0442a453f229633f2db01cb728f38dea94fa3d7319d0689c128eb60ca2935673df587f8c60901fd8ac0eba49510ba1b7f51198c7840524eb237c35da262718eb64918f7c39cf64e47bcdd88abd4c16b0ea220e4f598f721e8d1338422d8c77ea63eac77c7644c516d4d7118fbae442839563243684046c25a445b48d4678e5fd1005124b4c02e122756d4f79d8aa9fd6d2b03d1011c669a4cafa16f2e236539ce6014bf4b0e240d127c1d478db2a9e5bd3c33e79246ee208ae51e96142a76553bca928a7cc8e6f8619106f311ae58953272bc96cc5b0b3d0d57343775b368f031ebb11cf73a910c86aa91ab662ccd0dabbec26d656551c1fa4bdd55f72c8f24e0442a453f229633f2db01cb728f38dea94fa3d7319d0689c128eb60ca2935673df587f8c60901fd8ac0eba49510ba1b7f51198c7840524eb237c35da262718eb64918f7c39cf64e47bcdd88abd4c16b0ea220e4f598f721e8d1338422d8c77ea63eac77c7644c516d4d7118fbae442839563243684046c25a445b48d4678e5fd1005124b4c02e122756d4f79d8aa9fd6d2b03d1011c669a4cafa16f2e236539ce6014bf4b0e240d127c1d478db2a9e5bd3c33e79246ee208ae51e96142a76553bca928a7cc8e6f8619106f311ae58953272bc96cc5b0b3d0d57343775b368f031ebb11cf73a910c86aa91ab662ccd0dabbec26d656551c1fa4bdd55f72c8f24e0442a453f229633f2db01cb728f38dea94fa3d7319d0689c128eb60ca2935673df587f8c60901fd8ac0eba49510ba1b7f51198c7840524eb237c35da262718eb64918f7c39cf64e47bcdd88abd4c16b0ea220e4f598f721e8d1338422d8c77ea63eac77c7644c516d4d7118fbae442839563243684046c25a445b48d4678e5fd1005124b4c02e122756d4f79d8aa9fd6d2b03d1011c669a4cafa16f2e236539ce6014bf4b0e240d127c1d478db2a9e5bd3c33e79246ee208ae51e96142a76553bca928a7cc8e6f8619106f311ae58953272bc96cc5b0b3d0d579c98d5c9687ada34ee6a6734575ddbf685490ea50d88dafaa3fcc004ca41b7cc31119d92b7b9dadd5f7deefb3ffcc0e9b19d0ec70be4d07e8a657277bfb36bbb3e465c2c5edcfcc21c6be449dc5d67b2c774809e7103f81d3bd36900fc59bc92e935df496164acd8935a7734eb04ac979bc317d0525b7ecb835a79740d80b7d0643ddbd8bcafeaf7f12a61affbbe627f6c561545bd0edaaa1db01c90342c0cad0a25bd92447e27cd03dea84c53d4696f9e16df06d354ce2c34a26b481075eb53c0748e66c2a21425edf9dbc82c60b16dabfa788b78c7926166762df864e2288fb7db2e4deb57c23cce6e9a85524f10ee2b57df91054d00aa80155a376579caeb9c98d5c9687ada34ee6a6734575ddbf685490ea50d88dafaa3fcc004ca41b7cc31119d92b7b9dadd5f7deefb3ffcc0e9b19d0ec70be4d07e8a657277bfb36bbb3e465c2c5edcfcc21c6be449dc5d67b2c774809e7103f81d3bd36900fc59bc92e935df496164acd8935a7734eb04ac979bc317d0525b7ecb835a79740d80b7d0643ddbd8bcafeaf7f12a61affbbe627f6c561545bd0edaaa1db01c90342c0cad0a25bd92447e27cd03dea84c53d4696f9e16df06d354ce2c34a26b481075eb53c0748e66c2a21425edf9dbc82c60b16dabfa788b78c7926166762df864e2288fb7db2e4deb57c23cce6e9a85524f10ee2b57df91054d00aa80155a376579caeb`, - // 13 shares - `0x${SIGNATURE}04e2871c338c3206657ce90c00655f526a2055355bde197116efcc55de8b7bc69db23f2a78c91ccee05bd48c03f1d4903631930f49165acc5e605bcdbd1a4bcdd7b44366f2af42e4126cbffc9e34ec9fa29662a401c5aa7ebef5e4ee287c895617dc930f49165acc5e605bcdbd1a4bcdd7b44366f2af42e4126cbffc9e34ec9fa29662a401c5aa7ebef5e4ee287c895617dc930f49165acc5e605bcdbd1a4bcdd7b44366f2af42e4126cbffc9e34ec9fa29662a401c5aa7ebef5e4ee287c895617dcaf4dd395545044ac2c83fe26548751891ac655ede78d6d346d5c1611ec39cd5b828440dddc8d5739253a272b128ea962af4dd395545044ac2c83fe26548751891ac655ede78d6d346d5c1611ec39cd5b828440dddc8d5739253a272b128ea962af4dd395545044ac2c83fe26548751891ac655ede78d6d346d5c1611ec39cd5b828440dddc8d5739253a272b128ea962af4dd395545044ac2c83fe26548751891ac655ede78d6d346d5c1611ec39cd5b828440dddc8d5739253a272b128ea962af4dd395545044ac2c83fe26548751891ac655ede78d6d346d5c1611ec39cd5b828440dddc8d5739253a272b128ea962871c338c3206657ce90c00655f526a2055355bde197116efcc55de8b7bc69db23f2a78c91ccee05bd48c03f1d4903631871c338c3206657ce90c00655f526a2055355bde197116efcc55de8b7bc69db23f2a78c91ccee05bd48c03f1d4903631871c338c3206657ce90c00655f526a2055355bde197116efcc55de8b7bc69db23f2a78c91ccee05bd48c03f1d4903631b7d586100b1137d7c7fc4c9b6aad63021581fcd3fa6bb55455e6eb5e42fdba1b1fe1e25b8a350c47f4904064241c034c5dc03027fb3532501eff0877819eedebeb982d651c47ccc7cecf2cc508ad3ba7dd802e993acbaf696a6dcce1eada8ad77c75fc6085a183990b6fadbfb888205b29e17a00671ce8d04b9f3dd64283c29a58ec2ea3a4f1da6227c207708024bc6243e77f41ad7c219e40e14a4b965a9e9957a44fceba379b7c0082d25446c8d3cbb5e0f81b5fea835f5277f6cb3e62df9680f182571466fdbd28585cd2571c832ce11ff9c9a1d144a505f2ff198b6ab3ba19b0ce3096967635c916be872dacefe2c5477c6da28d6a47fd49d8ecad7f161a8d69fb343ca785c795c3242639866789f8d8631693c4a5c68e5a95061e176635d39e28f9afa9a1f23b5ddaaa6212bc699982631ed39ea56134e10efd459421f4abb9a8d9881e78d538c536e0e3062dd3f0f4ac19e2bf0e8329eaf86279235e6b13507f27a3a1afb5845ffe3fe09b1865f2c9cdccd7efc2c1a45244e67cd62ea7ac5a3316e19ed019d7ba0ac6e420f303e2a951e043e7d69b98a8e0975c69c373074a69f40e423bc4787338b33fa1dc15642849a66d89be6c614c9d7372918ed3f12c8767aeda14800cdde15ed83e1df9824b71fcfe636cdb755c374a9df628a9e2f189c900b02a57306e4099b794cb42fa84dc43e186e9e10e2c786a75b32ffdeaf228a77e53b013d830ebbbbb72af84dbf2f64bd66f0584f26a38324d93ae0acb717c60daa7c947fb4cce4d1865fbbb9982631ed39ea56134e10efd459421f4abb9a8d9881e78d538c536e0e3062dd3f0f4ac19e2bf0e8329eaf86279235e6b13507f27a3a1afb5845ffe3fe09b1865f2c9cdccd7efc2c1a45244e67cd62ea7ac5a3316e19ed019d7ba0ac6e420f303e2a951e043e7d69b98a8e0975c69c373074a69f40e423bc4787338b33fa1dc15642849a66d89be6c614c9d7372918ed3f12c8767aeda14800cdde15ed83e1df9824b71fcfe636cdb755c374a9df628a9e2f189c900b02a57306e4099b794cb42fa84dc43e186e9e10e2c786a75b32ffdeaf228a77e53b013d830ebbbbb72af84dbf2f64bd66f0584f26a38324d93ae0acb717c60daa7c947fb4cce4d1865fbbb9982631ed39ea56134e10efd459421f4abb9a8d9881e78d538c536e0e3062dd3f0f4ac19e2bf0e8329eaf86279235e6b13507f27a3a1afb5845ffe3fe09b1865f2c9cdccd7efc2c1a45244e67cd62ea7ac5a3316e19ed019d7ba0ac6e420f303e2a951e043e7d69b98a8e0975c69c373074a69f40e423bc4787338b33fa1dc15642849a66d89be6c614c9d7372918ed3f12c8767aeda14800cdde15ed83e1df9824b71fcfe636cdb755c374a9df628a9e2f189c900b02a57306e4099b794cb42fa84dc43e186e9e10e2c786a75b32ffdeaf228a77e53b013d830ebbbbb72af84dbf2f64bd66f0584f26a38324d93ae0acb717c60daa7c947fb4cce4d1865fbbb9982631ed39ea56134e10efd459421f4abb9a8d9881e78d538c536e0e3062dd3f0f4ac19e2bf0e8329eaf86279235e6b13507f27a3a1afb5845ffe3fe09b1865f2c9cdccd7efc2c1a45244e67cd62ea7ac5a3316e19ed019d7ba0ac6e420f303e2a951e043e7d69b98a8e0975c69c373074a69f40e423bc4787338b33fa1dc15642849a66d89be6c614c9d7372918ed3f12c8767aeda14800cdde15ed83e1df9824b71fcfe636cdb755c374a9df628a9e2f189c900b02a57306e4099b794cb42fa84dc43e186e9e10e2c786a75b32ffdeaf228a77e53b013d830ebbbbb72af84dbf2f64bd66f0584f26a38324d93ae0acb717c60daa7c947fb4cce4d1865fbbb343775b368f031ebb11cf73a910c86aa91ab662ccd0dabbec26d656551c1fa4bdd55f72c8f24e0442a453f229633f2db01cb728f38dea94fa3d7319d0689c128eb60ca2935673df587f8c60901fd8ac0eba49510ba1b7f51198c7840524eb237c35da262718eb64918f7c39cf64e47bcdd88abd4c16b0ea220e4f598f721e8d1338422d8c77ea63eac77c7644c516d4d7118fbae442839563243684046c25a445b48d4678e5fd1005124b4c02e122756d4f79d8aa9fd6d2b03d1011c669a4cafa16f2e236539ce6014bf4b0e240d127c1d478db2a9e5bd3c33e79246ee208ae51e96142a76553bca928a7cc8e6f8619106f311ae58953272bc96cc5b0b3d0d57343775b368f031ebb11cf73a910c86aa91ab662ccd0dabbec26d656551c1fa4bdd55f72c8f24e0442a453f229633f2db01cb728f38dea94fa3d7319d0689c128eb60ca2935673df587f8c60901fd8ac0eba49510ba1b7f51198c7840524eb237c35da262718eb64918f7c39cf64e47bcdd88abd4c16b0ea220e4f598f721e8d1338422d8c77ea63eac77c7644c516d4d7118fbae442839563243684046c25a445b48d4678e5fd1005124b4c02e122756d4f79d8aa9fd6d2b03d1011c669a4cafa16f2e236539ce6014bf4b0e240d127c1d478db2a9e5bd3c33e79246ee208ae51e96142a76553bca928a7cc8e6f8619106f311ae58953272bc96cc5b0b3d0d57343775b368f031ebb11cf73a910c86aa91ab662ccd0dabbec26d656551c1fa4bdd55f72c8f24e0442a453f229633f2db01cb728f38dea94fa3d7319d0689c128eb60ca2935673df587f8c60901fd8ac0eba49510ba1b7f51198c7840524eb237c35da262718eb64918f7c39cf64e47bcdd88abd4c16b0ea220e4f598f721e8d1338422d8c77ea63eac77c7644c516d4d7118fbae442839563243684046c25a445b48d4678e5fd1005124b4c02e122756d4f79d8aa9fd6d2b03d1011c669a4cafa16f2e236539ce6014bf4b0e240d127c1d478db2a9e5bd3c33e79246ee208ae51e96142a76553bca928a7cc8e6f8619106f311ae58953272bc96cc5b0b3d0d57343775b368f031ebb11cf73a910c86aa91ab662ccd0dabbec26d656551c1fa4bdd55f72c8f24e0442a453f229633f2db01cb728f38dea94fa3d7319d0689c128eb60ca2935673df587f8c60901fd8ac0eba49510ba1b7f51198c7840524eb237c35da262718eb64918f7c39cf64e47bcdd88abd4c16b0ea220e4f598f721e8d1338422d8c77ea63eac77c7644c516d4d7118fbae442839563243684046c25a445b48d4678e5fd1005124b4c02e122756d4f79d8aa9fd6d2b03d1011c669a4cafa16f2e236539ce6014bf4b0e240d127c1d478db2a9e5bd3c33e79246ee208ae51e96142a76553bca928a7cc8e6f8619106f311ae58953272bc96cc5b0b3d0d57343775b368f031ebb11cf73a910c86aa91ab662ccd0dabbec26d656551c1fa4bdd55f72c8f24e0442a453f229633f2db01cb728f38dea94fa3d7319d0689c128eb60ca2935673df587f8c60901fd8ac0eba49510ba1b7f51198c7840524eb237c35da262718eb64918f7c39cf64e47bcdd88abd4c16b0ea220e4f598f721e8d1338422d8c77ea63eac77c7644c516d4d7118fbae442839563243684046c25a445b48d4678e5fd1005124b4c02e122756d4f79d8aa9fd6d2b03d1011c669a4cafa16f2e236539ce6014bf4b0e240d127c1d478db2a9e5bd3c33e79246ee208ae51e96142a76553bca928a7cc8e6f8619106f311ae58953272bc96cc5b0b3d0d579c98d5c9687ada34ee6a6734575ddbf685490ea50d88dafaa3fcc004ca41b7cc31119d92b7b9dadd5f7deefb3ffcc0e9b19d0ec70be4d07e8a657277bfb36bbb3e465c2c5edcfcc21c6be449dc5d67b2c774809e7103f81d3bd36900fc59bc92e935df496164acd8935a7734eb04ac979bc317d0525b7ecb835a79740d80b7d0643ddbd8bcafeaf7f12a61affbbe627f6c561545bd0edaaa1db01c90342c0cad0a25bd92447e27cd03dea84c53d4696f9e16df06d354ce2c34a26b481075eb53c0748e66c2a21425edf9dbc82c60b16dabfa788b78c7926166762df864e2288fb7db2e4deb57c23cce6e9a85524f10ee2b57df91054d00aa80155a376579caeb9c98d5c9687ada34ee6a6734575ddbf685490ea50d88dafaa3fcc004ca41b7cc31119d92b7b9dadd5f7deefb3ffcc0e9b19d0ec70be4d07e8a657277bfb36bbb3e465c2c5edcfcc21c6be449dc5d67b2c774809e7103f81d3bd36900fc59bc92e935df496164acd8935a7734eb04ac979bc317d0525b7ecb835a79740d80b7d0643ddbd8bcafeaf7f12a61affbbe627f6c561545bd0edaaa1db01c90342c0cad0a25bd92447e27cd03dea84c53d4696f9e16df06d354ce2c34a26b481075eb53c0748e66c2a21425edf9dbc82c60b16dabfa788b78c7926166762df864e2288fb7db2e4deb57c23cce6e9a85524f10ee2b57df91054d00aa80155a376579caeb9c98d5c9687ada34ee6a6734575ddbf685490ea50d88dafaa3fcc004ca41b7cc31119d92b7b9dadd5f7deefb3ffcc0e9b19d0ec70be4d07e8a657277bfb36bbb3e465c2c5edcfcc21c6be449dc5d67b2c774809e7103f81d3bd36900fc59bc92e935df496164acd8935a7734eb04ac979bc317d0525b7ecb835a79740d80b7d0643ddbd8bcafeaf7f12a61affbbe627f6c561545bd0edaaa1db01c90342c0cad0a25bd92447e27cd03dea84c53d4696f9e16df06d354ce2c34a26b481075eb53c0748e66c2a21425edf9dbc82c60b16dabfa788b78c7926166762df864e2288fb7db2e4deb57c23cce6e9a85524f10ee2b57df91054d00aa80155a376579caeb` -]; + const threshold = await ssvKeys.createThreshold(privateKey, operators); + const encryptedShares: EncryptShare[] = await ssvKeys.encryptShares(operators, threshold.shares); + const payload = await keyShares.buildPayload( + { + publicKey, + operators, + encryptedShares, + }, + { + ownerAddress: DB.owners[ownerId].address, + ownerNonce: DB.ownerNonce, + privateKey, + }, + ); + return payload; +}; export const DataGenerator = { - publicKey: (index: number) => `0x${index.toString(16).padStart(96, '0')}`, - shares: (index: number) => { - switch (index) { - case 7: - return SHARES_RSA[1]; - case 10: - return SHARES_RSA[2]; - case 13: - return SHARES_RSA[3]; - default: - return SHARES_RSA[0]; + publicKey: (id: number) => { + const validators = DB.validators.filter((item: Validator) => item.id === id); + if (validators.length > 0) { + return validators[0].publicKey; } + return `0x${id.toString(16).padStart(48, '0')}`; + }, + shares: async (ownerId: number, validatorId: number, operatorCount: number) => { + let shared: any; + const validators = DB.validators.filter((item: Operator) => item.id === validatorId); + if (validators.length > 0) { + const validator = validators[0]; + const operatorIds: number[] = []; + for (let i = 1; i <= operatorCount; i++) { + operatorIds.push(i); + } + const payload = await getSecretSharedPayload(validator, operatorIds, ownerId); + shared = payload.sharesData; + } else { + shared = `0x${validatorId.toString(16).padStart(48, '0')}`; + } + return shared; }, cluster: { new: (size = 4) => { @@ -45,9 +72,9 @@ export const DataGenerator = { const result = []; for (const operator of DB.operators) { - if (operator && !usedOperatorIds[operator.operatorId]) { - result.push(operator.operatorId); - usedOperatorIds[operator.operatorId] = true; + if (operator && !usedOperatorIds[operator.id]) { + result.push(operator.id); + usedOperatorIds[operator.id] = true; if (result.length == size) { break; @@ -59,13 +86,23 @@ export const DataGenerator = { } return result; }, - byId: (id: any) => DB.clusters[id].operatorIds - } + byId: (id: any) => DB.clusters[id].operatorIds, + }, +}; + +export const getClusterForValidator = ( + validatorCount: number, + networkFeeIndex: number, + index: number, + balance: number, + active: boolean, +) => { + return { validatorCount, networkFeeIndex, index, balance, active }; }; export const initializeContract = async () => { CONFIG = { - initialVersion: "v1.0.2", + initialVersion: 'v1.0.2', operatorMaxFeeIncrease: 1000, declareOperatorFeePeriod: 3600, // HOUR executeOperatorFeePeriod: 86400, // DAY @@ -73,13 +110,15 @@ export const initializeContract = async () => { minimalBlocksBeforeLiquidation: 100800, minimumLiquidationCollateral: 200000000, validatorsPerOperatorLimit: 500, - maximumOperatorFee: 76528650000000 + maximumOperatorFee: 76528650000000, }; DB = { owners: [], validators: [], operators: [], + registeredValidators: [], + registeredOperators: [], clusters: [], ssvNetwork: {}, ssvViews: {}, @@ -87,7 +126,8 @@ export const initializeContract = async () => { ssvOperatorsMod: {}, ssvClustersMod: {}, ssvDAOMod: {}, - ssvViewsMod: {} + ssvViewsMod: {}, + ownerNonce: 0, }; SSV_MODULES = { @@ -100,6 +140,12 @@ export const initializeContract = async () => { // Define accounts DB.owners = await ethers.getSigners(); + // Load validators + DB.validators = validatorKeys as Validator[]; + + // Load operators + DB.operators = operatorKeys as Operator[]; + // Initialize contract const ssvNetwork = await ethers.getContractFactory('SSVNetwork'); const ssvViews = await ethers.getContractFactory('SSVNetworkViews'); @@ -125,32 +171,32 @@ export const initializeContract = async () => { DB.ssvDAOMod.contract = await ssvDAOMod.deploy(); await DB.ssvDAOMod.contract.deployed(); - DB.ssvNetwork.contract = await upgrades.deployProxy(ssvNetwork, [ - DB.ssvToken.address, - DB.ssvOperatorsMod.contract.address, - DB.ssvClustersMod.contract.address, - DB.ssvDAOMod.contract.address, - DB.ssvViewsMod.contract.address, - CONFIG.minimalBlocksBeforeLiquidation, - CONFIG.minimumLiquidationCollateral, - CONFIG.validatorsPerOperatorLimit, - CONFIG.declareOperatorFeePeriod, - CONFIG.executeOperatorFeePeriod, - CONFIG.operatorMaxFeeIncrease - ], + DB.ssvNetwork.contract = await upgrades.deployProxy( + ssvNetwork, + [ + DB.ssvToken.address, + DB.ssvOperatorsMod.contract.address, + DB.ssvClustersMod.contract.address, + DB.ssvDAOMod.contract.address, + DB.ssvViewsMod.contract.address, + CONFIG.minimalBlocksBeforeLiquidation, + CONFIG.minimumLiquidationCollateral, + CONFIG.validatorsPerOperatorLimit, + CONFIG.declareOperatorFeePeriod, + CONFIG.executeOperatorFeePeriod, + CONFIG.operatorMaxFeeIncrease, + ], { kind: 'uups', - unsafeAllow: ['delegatecall'] - }); + unsafeAllow: ['delegatecall'], + }, + ); await DB.ssvNetwork.contract.deployed(); - DB.ssvViews.contract = await upgrades.deployProxy(ssvViews, [ - DB.ssvNetwork.contract.address - ], - { - kind: "uups" - }); + DB.ssvViews.contract = await upgrades.deployProxy(ssvViews, [DB.ssvNetwork.contract.address], { + kind: 'uups', + }); await DB.ssvViews.contract.deployed(); DB.ssvNetwork.owner = DB.owners[0]; @@ -164,142 +210,147 @@ export const initializeContract = async () => { await DB.ssvNetwork.contract.updateMaximumOperatorFee(CONFIG.maximumOperatorFee); - return { contract: DB.ssvNetwork.contract, owner: DB.ssvNetwork.owner, ssvToken: DB.ssvToken, ssvViews: DB.ssvViews.contract }; -}; - -export const registerOperators = async (ownerId: number, numberOfOperators: number, fee: string, gasGroups: GasGroup[] = [GasGroup.REGISTER_OPERATOR]) => { - for (let i = 0; i < numberOfOperators; ++i) { - const { eventsByName } = await trackGas( - DB.ssvNetwork.contract.connect(DB.owners[ownerId]).registerOperator(DataGenerator.publicKey(i), fee), - gasGroups - ); - const event = eventsByName.OperatorAdded[0]; - DB.operators[event.args.operatorId] = { - operatorId: event.args.operatorId, ownerId: ownerId, publicKey: DataGenerator.publicKey(i) - }; - } + return { + contract: DB.ssvNetwork.contract, + owner: DB.ssvNetwork.owner, + ssvToken: DB.ssvToken, + ssvViews: DB.ssvViews.contract, + }; }; -export const deposit = async (ownerId: number, ownerAddress: string, operatorIds: number[], amount: string, cluster: any) => { +export const deposit = async ( + ownerId: number, + ownerAddress: string, + operatorIds: number[], + amount: string, + cluster: any, +) => { await DB.ssvToken.connect(DB.owners[ownerId]).approve(DB.ssvNetwork.contract.address, amount); - const depositedCluster = await trackGas(DB.ssvNetwork.contract.connect(DB.owners[ownerId]).deposit( - ownerAddress, - operatorIds, - amount, - cluster)); + const depositedCluster = await trackGas( + DB.ssvNetwork.contract.connect(DB.owners[ownerId]).deposit(ownerAddress, operatorIds, amount, cluster), + ); return depositedCluster.eventsByName.ClusterDeposited[0].args; }; export const liquidate = async (ownerAddress: string, operatorIds: number[], cluster: any) => { - const liquidatedCluster = await trackGas(DB.ssvNetwork.contract.liquidate( - ownerAddress, - operatorIds, - cluster - )); + const liquidatedCluster = await trackGas(DB.ssvNetwork.contract.liquidate(ownerAddress, operatorIds, cluster)); return liquidatedCluster.eventsByName.ClusterLiquidated[0].args; }; -export const removeValidator = async (ownerId: number, pk: string, operatorIds: number[], cluster: any) => { - const removedValidator = await trackGas(DB.ssvNetwork.contract.connect(DB.owners[ownerId]).removeValidator( - pk, - operatorIds, - cluster - )); - return removedValidator.eventsByName.ValidatorRemoved[0].args; -}; - export const withdraw = async (ownerId: number, operatorIds: number[], amount: string, cluster: any) => { - const withdrawnCluster = await trackGas(DB.ssvNetwork.contract.connect(DB.owners[ownerId]).withdraw( - operatorIds, - amount, - cluster)); + const withdrawnCluster = await trackGas( + DB.ssvNetwork.contract.connect(DB.owners[ownerId]).withdraw(operatorIds, amount, cluster), + ); return withdrawnCluster.eventsByName.ClusterWithdrawn[0].args; }; export const reactivate = async (ownerId: number, operatorIds: number[], amount: string, cluster: any) => { await DB.ssvToken.connect(DB.owners[ownerId]).approve(DB.ssvNetwork.contract.address, amount); - const reactivatedCluster = await trackGas(DB.ssvNetwork.contract.connect(DB.owners[ownerId]).reactivate( - operatorIds, - amount, - cluster)); + const reactivatedCluster = await trackGas( + DB.ssvNetwork.contract.connect(DB.owners[ownerId]).reactivate(operatorIds, amount, cluster), + ); return reactivatedCluster.eventsByName.ClusterReactivated[0].args; }; -export const registerValidators = async (ownerId: number, numberOfValidators: number, amount: string, operatorIds: number[], gasGroups?: GasGroup[]) => { - const validators: any = []; - let args: any; - // Register validators to contract - for (let i = 0; i < numberOfValidators; i++) { - const publicKey = DataGenerator.publicKey(DB.validators.length ? DB.validators.length + 1 : 1); - const shares = DataGenerator.shares(DB.validators.length); - await DB.ssvToken.connect(DB.owners[ownerId]).approve(DB.ssvNetwork.contract.address, amount); - const result = await trackGas(DB.ssvNetwork.contract.connect(DB.owners[ownerId]).registerValidator( - publicKey, - operatorIds, - shares, - amount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true - } - ), gasGroups); - args = result.eventsByName.ValidatorAdded[0].args; - DB.validators.push({ publicKey, operatorIds, shares }); - validators.push({ publicKey, shares }); +export const registerOperators = async ( + ownerId: number, + numberOfOperators: number, + fee: string, + gasGroups: GasGroup[] = [GasGroup.REGISTER_OPERATOR], +) => { + for (let i = 0; i < numberOfOperators && i < DB.operators.length; i++) { + const operator = DB.operators[i]; + operator.publicKey = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(operator.operatorKey)); + const { eventsByName } = await trackGas( + DB.ssvNetwork.contract.connect(DB.owners[ownerId]).registerOperator(operator.publicKey, fee), + gasGroups, + ); + const event = eventsByName.OperatorAdded[0]; + operator.id = event.args[0].toNumber(); + DB.operators[i] = operator; + DB.registeredOperators.push({ id: operator.id, ownerId: ownerId }); } - - return { validators, args }; }; -export const registerValidatorsRaw = async (ownerId: number, numberOfValidators: number, amount: string, operatorIds: number[], gasGroups?: GasGroup[]) => { - let cluster: any = { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true - }; - - for (let i = 1; i <= numberOfValidators; i++) { +export const registerValidators = async ( + ownerId: number, + amount: string, + validatorIds: number[], + operatorIds: number[], + cluster: any, + gasGroups?: GasGroup[], +) => { + const regValidators: any = []; + let args: any; - const shares = DataGenerator.shares(4); - const publicKey = DataGenerator.publicKey(i); + const selValidators = DB.validators.filter((item: Validator) => validatorIds.includes(item.id)); + for (const validator of selValidators) { + const payload = await getSecretSharedPayload(validator, operatorIds, ownerId); await DB.ssvToken.connect(DB.owners[ownerId]).approve(DB.ssvNetwork.contract.address, amount); - const result = await trackGas(DB.ssvNetwork.contract.connect(DB.owners[ownerId]).registerValidator( - publicKey, - operatorIds, - shares, - amount, - cluster - ), gasGroups); - cluster = result.eventsByName.ValidatorAdded[0].args.cluster; + const result = await trackGas( + DB.ssvNetwork.contract + .connect(DB.owners[ownerId]) + .registerValidator(payload.publicKey, payload.operatorIds, payload.sharesData, amount, cluster), + gasGroups, + ); + DB.ownerNonce++; + DB.registeredValidators.push({ id: validator.id, payload }); + regValidators.push({ publicKey: payload.publicKey, shares: payload.sharesData }); + args = result.eventsByName.ValidatorAdded[0].args; } -} - -export const getCluster = (payload: any) => ethers.utils.AbiCoder.prototype.encode( - ['tuple(uint32 validatorCount, uint64 networkFee, uint64 networkFeeIndex, uint64 index, uint64 balance, bool active) cluster'], - [payload] -); + return { regValidators, args }; +}; export const coldRegisterValidator = async () => { - await DB.ssvToken.approve(DB.ssvNetwork.contract.address, '1000000000000000'); - await DB.ssvNetwork.contract.registerValidator( - DataGenerator.publicKey(90), - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], - DataGenerator.shares(14), - '1000000000000000', + const ssvKeys = new SSVKeys(); + const keyShares = new KeyShares(); + + const validator = DB.validators[0]; + const operators = DB.operators.map((item: Operator) => ({ id: item.id, operatorKey: item.operatorKey })); + const publicKey = validator.publicKey; + const privateKey = validator.privateKey; + const threshold = await ssvKeys.createThreshold(privateKey, operators); + const encryptedShares: EncryptShare[] = await ssvKeys.encryptShares(operators, threshold.shares); + const payload = await keyShares.buildPayload( + { + publicKey, + operators, + encryptedShares, + }, { + ownerAddress: DB.owners[0].address, + ownerNonce: 1, + privateKey, + }, + ); + + const amount = '1000000000000000'; + await DB.ssvToken.approve(DB.ssvNetwork.contract.address, amount); + await DB.ssvNetwork.contract + .connect(DB.owners[0]) + .registerValidator(payload.publicKey, payload.operatorIds, payload.sharesData, amount, { validatorCount: 0, networkFeeIndex: 0, index: 0, balance: 0, - active: true - } + active: true, + }); +}; + +export const removeValidator = async (ownerId: number, pk: string, operatorIds: number[], cluster: any) => { + const removedValidator = await trackGas( + DB.ssvNetwork.contract.connect(DB.owners[ownerId]).removeValidator(pk, operatorIds, cluster), + ); + return removedValidator.eventsByName.ValidatorRemoved[0].args; +}; + +export const getCluster = (payload: any) => + ethers.utils.AbiCoder.prototype.encode( + [ + 'tuple(uint32 validatorCount, uint64 networkFee, uint64 networkFeeIndex, uint64 index, uint64 balance, bool active) cluster', + ], + [payload], ); -}; \ No newline at end of file diff --git a/test/helpers/gas-usage.ts b/test/helpers/gas-usage.ts index 534ec15e..b7696de5 100644 --- a/test/helpers/gas-usage.ts +++ b/test/helpers/gas-usage.ts @@ -35,7 +35,7 @@ export enum GasGroup { WITHDRAW_CLUSTER_BALANCE, WITHDRAW_OPERATOR_BALANCE, VALIDATOR_EXIT, - + LIQUIDATE_CLUSTER_4, LIQUIDATE_CLUSTER_7, LIQUIDATE_CLUSTER_10, @@ -50,7 +50,7 @@ export enum GasGroup { DAO_UPDATE_OPERATOR_MAX_FEE, CHANGE_LIQUIDATION_THRESHOLD_PERIOD, - CHANGE_MINIMUM_COLLATERAL + CHANGE_MINIMUM_COLLATERAL, } const MAX_GAS_PER_GROUP: any = { @@ -59,14 +59,14 @@ const MAX_GAS_PER_GROUP: any = { [GasGroup.REMOVE_OPERATOR]: 70200, [GasGroup.REMOVE_OPERATOR_WITH_WITHDRAW]: 70200, [GasGroup.SET_OPERATOR_WHITELIST]: 84300, - + [GasGroup.DECLARE_OPERATOR_FEE]: 70000, [GasGroup.CANCEL_OPERATOR_FEE]: 41900, [GasGroup.EXECUTE_OPERATOR_FEE]: 52000, [GasGroup.REDUCE_OPERATOR_FEE]: 51900, [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]: 202000, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE]: 221400, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE]: 235000, [GasGroup.REGISTER_VALIDATOR_WITHOUT_DEPOSIT]: 181600, [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER_7]: 272900, @@ -81,19 +81,19 @@ const MAX_GAS_PER_GROUP: any = { [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]: 431300, [GasGroup.REGISTER_VALIDATOR_WITHOUT_DEPOSIT_13]: 394000, - [GasGroup.REMOVE_VALIDATOR]: 113500, - [GasGroup.REMOVE_VALIDATOR_7]: 155000, - [GasGroup.REMOVE_VALIDATOR_10]: 196500, - [GasGroup.REMOVE_VALIDATOR_13]: 238000, + [GasGroup.REMOVE_VALIDATOR]: 115000, + [GasGroup.REMOVE_VALIDATOR_7]: 156000, + [GasGroup.REMOVE_VALIDATOR_10]: 197500, + [GasGroup.REMOVE_VALIDATOR_13]: 239000, [GasGroup.DEPOSIT]: 77500, [GasGroup.WITHDRAW_CLUSTER_BALANCE]: 94500, [GasGroup.WITHDRAW_OPERATOR_BALANCE]: 64900, - [GasGroup.VALIDATOR_EXIT]: 42200, + [GasGroup.VALIDATOR_EXIT]: 42900, - [GasGroup.LIQUIDATE_CLUSTER_4]: 129300, - [GasGroup.LIQUIDATE_CLUSTER_7]: 170500, - [GasGroup.LIQUIDATE_CLUSTER_10]: 211600, - [GasGroup.LIQUIDATE_CLUSTER_13]: 252800, + [GasGroup.LIQUIDATE_CLUSTER_4]: 129300, + [GasGroup.LIQUIDATE_CLUSTER_7]: 170500, + [GasGroup.LIQUIDATE_CLUSTER_10]: 211600, + [GasGroup.LIQUIDATE_CLUSTER_13]: 252800, [GasGroup.REACTIVATE_CLUSTER]: 120600, [GasGroup.NETWORK_FEE_CHANGE]: 45800, @@ -105,8 +105,6 @@ const MAX_GAS_PER_GROUP: any = { [GasGroup.CHANGE_LIQUIDATION_THRESHOLD_PERIOD]: 41000, [GasGroup.CHANGE_MINIMUM_COLLATERAL]: 41200, - - }; class GasStats { @@ -115,12 +113,11 @@ class GasStats { totalGas = 0; txCount = 0; - addStat(gas: number) { this.totalGas += gas; ++this.txCount; - this.max = Math.max(gas, (this.max === null) ? -Infinity : this.max); - this.min = Math.min(gas, (this.min === null) ? Infinity : this.min); + this.max = Math.max(gas, this.max === null ? -Infinity : this.max); + this.min = Math.min(gas, this.min === null ? Infinity : this.min); } get average(): number { @@ -137,16 +134,17 @@ for (const group in MAX_GAS_PER_GROUP) { export const trackGas = async (tx: Promise, groups?: Array): Promise => { const receipt = await (await tx).wait(); - groups && [...new Set(groups)].forEach(group => { - const gasUsed = parseInt(receipt.gasUsed); + groups && + [...new Set(groups)].forEach(group => { + const gasUsed = parseInt(receipt.gasUsed); - if (!process.env.NO_GAS_ENFORCE) { - const maxGas = MAX_GAS_PER_GROUP[group]; - expect(gasUsed).to.be.lessThanOrEqual(maxGas, 'gasUsed higher than max allowed gas'); - } + if (!process.env.NO_GAS_ENFORCE) { + const maxGas = MAX_GAS_PER_GROUP[group]; + expect(gasUsed).to.be.lessThanOrEqual(maxGas, 'gasUsed higher than max allowed gas'); + } - gasUsageStats.get(group.toString()).addStat(gasUsed); - }); + gasUsageStats.get(group.toString()).addStat(gasUsed); + }); return { ...receipt, gasUsed: +receipt.gasUsed, @@ -154,11 +152,10 @@ export const trackGas = async (tx: Promise, groups?: Array): Prom aggr[item.event] = aggr[item.event] || []; aggr[item.event].push(item); return aggr; - }, {}) + }, {}), }; }; export const getGasStats = (group: string) => { return gasUsageStats.get(group) || new GasStats(); }; - diff --git a/test/helpers/json/operatorKeys.json b/test/helpers/json/operatorKeys.json new file mode 100644 index 00000000..c6a730c3 --- /dev/null +++ b/test/helpers/json/operatorKeys.json @@ -0,0 +1,41 @@ +[ + { + "operatorKey": "LS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0tCk1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBdnFSUmlsUkZPdkJoc1JWYUdOUGwKUXlMQUpLQ0dKSnlhWWpPaWJoSkNoeWJobnRaWHRDaXVZWGk1d2FRTFg3eTZlbEhIUTNvVmlnNUk4dU5RTVA1cApzbVE5cThJTXNRZHRTazZiNnBKVjJZZjNGaVlmb2xnaG5OQVJVMmtkM0VhNXF0TGdENUcxczJlbVRGZVlsemN4CmFITllUWUlWbUFSdEt5dlg2TVF0WURKM0pWTWx6QThwdmo5MnJOaHkvYnhBQkhMQlF1ZWQ0eENmZ2ZFUERuN3UKL003d3AxS2pUck0yUnpsUEFITGZNTC9FZ2ZGeHdHdUt1YlZMaHM4TnlmNkpqamR6a0NaVmJqNHc5aEJ2cE1yOApNUXBJU3BBbkx6d0N6S1Y1dXZvUmlMei84c0pkSEdhZzZDQnd6L09xSXpSZUNOSnJVd3lGRkQvSGVxUU1FK1g2CkRRSURBUUFCCi0tLS0tRU5EIFJTQSBQVUJMSUMgS0VZLS0tLS0=" + }, + { + "operatorKey": "LS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0tCk1JSUJJVEFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUTRBTUlJQkNRS0NBUUJXcEFyTXI0dzNZdGJHV3h3T3pXN0sKTmpGTWZLbGtOQUg4ZDRMTFNRV3MxNzA4OEFrUG0wK3BHcEQxcXl1NE1HTit4NFpuM2NhWGMzcWJDUlJORnFFbQpoK0dIYlRpU0x5SFJ2cnlSVjFyVHMzTnJxcUoxOHhCbk5Zajh6ZjBscCtLUkF6a0ozWlVpbC8wUzZNak84V2YrCnA5R1cyUkI2aHJ5VHphNVVvWlNpTk5JU3czMW9oWkUxOG84aW01ZS9ETXVWb2ZWZiswWUhvSjdISlAyOXhSanoKSThKeVhkbDJqaWYvZHpGWFZJaFRqQUJXNEhGdFpaWXhQY2F0TzdDamkraVRYOU8zMmFvNVNQSGJuM3ZGdVIwLwpUUExtY2U3cUVHN1JzMng3WFgyNEdkaUU5N3JzRTJBU21CdGowalJFNjgxclVZMUJUeGxORWpXN0MxN001YVN6CkFnTUJBQUU9Ci0tLS0tRU5EIFJTQSBQVUJMSUMgS0VZLS0tLS0=" + }, + { + "operatorKey": "LS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0tCk1JSUJJVEFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUTRBTUlJQkNRS0NBUUJsRExTcnJjRzQzZTJqb1QycFo2em4KSG1OTytXQ2RFM0FKbXFCMGJocWU1MklHVkVLRGpMdVU0Y1RLejlSMWd2dWxxTTVNQTlrVGd2WkFXUjFpZEl0WAphMHdFWmNJUGFjSTAyZEdTM0wrWnpuRmQ1VGJRNnZISTJvUVN3YURrcGNXS1pPWkJpS1JLQWFvWDBaS216djBiCjZ0V1YwUklvTlllNi91TkdwVXVqQzNhdUJpSWsxZGJxWXJuRm1ZTWIvM1JqYU9IUHI3U2pXeTNkYUdZV3ZUTnQKL1U3amZDY0ZlcXVJeUl3MzVRSlQ1Z2F6amErbkVrZTFyQ0piandmYnNDRldiMS9HaTNmdGpHVFhLSTFmUkNuSgp6NG1HSE9md1FOOEZ2dDlUQjh0YWFYN09pcHBSUnRJL2NlRi9rOXJqaUxMNGJkZlZyd1c2b1FxQmlDaFd5OU5UCkFnTUJBQUU9Ci0tLS0tRU5EIFJTQSBQVUJMSUMgS0VZLS0tLS0=" + }, + { + "operatorKey": "LS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0tCk1JSUJJVEFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUTRBTUlJQkNRS0NBUUJ1L0ZUN3VsOTFydXpwcWZtZ1RNMHoKdXF5UWF0ZWNPWUJtWGw4R1VOWXo5dStIeEtOR3RGRDZKQXhIeElicHJ5SEZEU3lLUzg2QTdMem9xajdGYU12SgpHSGV4RkxJOHJ0N2NVQitLSUFZdEJFaFp3V2o4YVBkTzhnUnYvT3dHclF6WndIdUhpV1c2ZVU0aGRhUXIyazJWClJLZ29jdWorMlFnaUFEeEkyMUh0YTRVeS9UeU5uaC9HVFFNcFZlK1lZRmlRRmp1S3Vta2tTdzRYczgvYmxhMUQKcFZWWFU0aStLUENXcU1BTXZCTEplTjhHSTAxVWlZc1plak5waVByYzlHR25iS3UwNFVXUlNxTEkrWWpCcEt0bgo1RWR1RncvU3hWWFhkNDE5aS9vUWthald4ZXFRMktLZTJpKy9YN2ZNRklyMUNrSGYzYWF3Unl6VkFTdnkrMlBwCkFnTUJBQUU9Ci0tLS0tRU5EIFJTQSBQVUJMSUMgS0VZLS0tLS0=" + }, + { + "operatorKey": "LS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0tCk1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBdHhHZEx6QVBnR0hhYWVoYUN6a0YKTmdiSmZ6WndCQnlsVFhMdWxPc3ErMzA2NCtBUFNQZHh3YmVXalpPRWpvWC9rRy9EaHNUVmw5eGw0SktUdWxpQwpYdlpMZXRpd3ZuM3RYQTFTKzNGTnJLZ1FjNFBnSHppd1RKL01yMEdyRzFyYWpvYm9VMGVETU5Hbi8zL3BRdk1WCks5bFNuY1QyaFhLbW1PdDdtQUUyK3ltT0JOZDhKU3g5NnA3ajFWdDNwc2d4ZzJMTUU0Nnd2dEpPVyswUWdNVDMKSDNEVjVSTWZWUlU4Z29nUFptbjNYRUR4RUJLZUtmaFZHVjlYNmFhcXkvU2Y4aEo3aG16eVcrQ3F1bkFYYWUySwo5ZDdSL0g0dStZcGovaU5NYkNQNi9GOGlIOCtQbWRyTmtUUFRPakwrb05HZVlNSVB3L1hYVStZbkhzcGp4SjRMCnBRSURBUUFCCi0tLS0tRU5EIFJTQSBQVUJMSUMgS0VZLS0tLS0K" + }, + { + "operatorKey": "LS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0tCk1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBeFArYkhwYS85WlhJUkJUR0JFWmcKN2hxa1Rra0VRUnZnTFJTV0E3K2cwbHkvVlpUczlFVTBjcXZFNURvUmxseVhrTHNVcnplOTZaOFJPNllmNC9LZQpta3hudk1YeHFUanlITGNkWlhIN1pFMmhWUnZRRVA3TE9hL3RCRHFYYVlHVklZbEYwWWIrVlFhSUczbGg4QmpCClN2ZE9rVERwblJLU1g2Z0ZnTTZVMy9FcFQyVlZRR1Y3VjIrNTF0YlM4WGJpUVQ3OTdwZmpBVEU4VmZseXBPUFIKYU5PREpjWnBlWjFjR0JCMWVJTUlGMlFGMFBCdGQzZ1ZVbDU5RFBHRFRZSUh2VnRrdkhSVHR3a1hOS2EveXV3SApnb1JhZjE4SDZTRy9vazFUM0l4WFYwdk1GdGlvUDJGWVh6UlNzaDBTcnlBR255azB0MElKb0JPMzBtZjFUeXZxCmN3SURBUUFCCi0tLS0tRU5EIFJTQSBQVUJMSUMgS0VZLS0tLS0K" + }, + { + "operatorKey": "LS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0tCk1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBem9hb09qQWIvVTQ3QitTWit6WUYKcm5TNHBMbUZnL2RYc3pCYWpaSm5zTWJoSzZISHFCdnZwRXZHWHpsU1Q3R3lWTDVQbzVaNEVSQzdPdXBHK2JQWQptQTgwNXZPb3FqYmNkVVlwclgyb1c4K1V1aFZJdUwyd2QvQXJqRDFScUc5eUV6WkRuUVdDdmplaElTQ1NXWFNPCmppbWxTbkpPZTd1Z0hwOXJWRkh3bVlwNGQyOWRBWFc2YTJZdndDRm1oVE9mdUMrSVNESzJTck9JWC9hVnZ5ekgKMU1OY0VmUTNaSGxjYmZQMDdTMVNqN25WYWhqM1hVUEIyMDMxOTRpQU9zcVRaOVFuU3NUamtydGF1MW1SV21aMQpFNm9nYTNJQ2t0YWs5M2FqcElYV3JKUzMwVERtSDhPckpKanVoQm4zaXRrK1o1Szg5SEdXa3FLME1wN2tYOGxPCi93SURBUUFCCi0tLS0tRU5EIFJTQSBQVUJMSUMgS0VZLS0tLS0K" + }, + { + "operatorKey": "LS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0tCk1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBcWMwUjlWRm9pM1NIeDl2alppb1gKRllwNFhkRjB2emRRRjRLRnozVklYaU5US3Vzck5mSW0zSm1FbWlSQmw4RmRvTmliRC9SZFc1YkFRUzN1UE5MRApGdHZVZ2p3bXBFNEdvcUpmSXZSWENWK2ROamcyNDU5aW44UnlkK0FUbm5qZXRYYWFSN3JNUlIreDRrcVlONkR4CkZoc2llZGgrZG0xTXNtMTRzc2FhMmZ3TExXamlzMDhTZlJZcXhjVHVCd24zUzFFajUwZzVrRG1RRmVyWUxBY2EKSXFOaFNsc0ZJZE50dHFkMUdSR3o0SFFPQmcyQk9iWWdwNEhEZTFLb0xmREdyMHNzRWFZMnRoeVZZOE9FaHh3YgpwUE1NTEk3NmFpUHdJQUsyM1MzWHZLS3ZtRXc1T1FFM0ptWXJrRDFDMTdoRGNWdUxkODV4YnZFSUFENms3b0NJCnB3SURBUUFCCi0tLS0tRU5EIFJTQSBQVUJMSUMgS0VZLS0tLS0K" + }, + { + "operatorKey": "LS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0tCk1JSUJJVEFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUTRBTUlJQkNRS0NBUUJUcmRQR3pBOFNtN3VSVGdWdnQ0QzQKbWRRRDFld3I0NzRsNE1uc21FZk53VzZaTGQ0S2dXK0NqdjA2dUNFbm8wc1VlKy9UVXBLSDc3cG5SWktHTWI1QgpGYklodkZ2L2h3UFZ0OC9MK1lzQ2ZxMkpYODFsdzl4MVo5b0dtaDFDczRRTTg1dkJrSGZCcWI3MXk3YXVCNTBjCk1nSlBETjF6MFVicUh0aE9OTmNGOE1ENzhGa1pLRDlNTWVVY0RMaksxZFlOdy9RaU14cHhpeDl4QXRMUHp3S28KM2VSdGNlZHNVOWZzUDgvYk1uY0tIOE1WTU1uUGY3bXNaSkJBaERIbjBnbUVzaXBucTh3dnM3VHlxSjh2dVRUYgpEbDNUYXNSVXd4aVNZM24rc3JwY0ZsOEM2Y1RLQldPd1ZhMENrWlM2b2F4Ykp4WllYc0lKQ09qTVVUM2VsZEF0CkFnTUJBQUU9Ci0tLS0tRU5EIFJTQSBQVUJMSUMgS0VZLS0tLS0=" + }, + { + "operatorKey": "LS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0tCk1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBbDkzYndYQ1Y4bGpjaU43TytHYlUKRVg1SUJPOTJTYnRmc21JV2QyUkRYTGwzdkFQMXU3SE0wQXJhT0daVDArV0t6UzZNbDJVZFNRQUxZUVI1M0p2bApOU0hIL1F3VzZqdGxJcUd0Nm9sMW9EbWJWVU8xUHB3ckpQdW9NY3BqU28rL0hvUXdGRE44ZDNvR1VWbVgxSEYyCmg0WE5mNHd0ZWxlcFhQVGM0WUlnb3YvemtEamN4NjV5eXFRUlRzUHFWNkZ1NEswelpSR1pTUlZzVzNieUI0dmQKSXl5Q2d0SGl2TklGbmNGUWpIeE92NEZpWWg3cmVBcnhoZUQwNEdiQVhIcWZrSzVyd2I1QzhXSk9vUldZZDdSWQp2WkM2V0tRTVc5eDRhUGtOTEg5ZEhLWXVyR1NFd1NrWWJMUWRDaUhIK2wyb3U4b1RDdEFCMHlOUm9tNlplcmhTClN3SURBUUFCCi0tLS0tRU5EIFJTQSBQVUJMSUMgS0VZLS0tLS0=" + }, + { + "operatorKey": "LS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0tCk1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBd3UyUG56N1ZXYmtGZGtSelBlVDMKSHRSQ0prN2grRGcyUE04RXRVY0IwVEtwa2hValBqaWdLNnN3aW9oRWUvY2ltRmxWMXFYNk1OTnpWeU0zRXVJeApkcTJRd2hZVC92NFNXOGE0UC9iUkROYmJuNHhHMDNta0NsQkRrL0V1azM2bDBvenhvY09QUEIyVVpLZlhOYlBmCktpVENTN0FuckFoL2NoVjZBcVc4T2p5N252Tk1wYWlLQXNJZk9CajdlakVEcjM2dWFLUDV5V2MvblZMcHVwTlgKQktlZ0xCNUdmTE1Wb1pPd1VvY2VXWGpYK1Q3QjNDeThtZSttUVNLQWNTQWdVK3RYK0QwdEoxKy9rWDFwb3UyeQo4a3p6U3NqRUhIVlVyekVEQ1phK213QkdvM2hJTWRJQlZLQy9kZjd2Y1VuUHV5Tit3TDlWaFZoekdYYk9mNzZvCndRSURBUUFCCi0tLS0tRU5EIFJTQSBQVUJMSUMgS0VZLS0tLS0=" + }, + { + "operatorKey": "LS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0tCk1JSUJJVEFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUTRBTUlJQkNRS0NBUUJ0emlaaXkxK3JpMFRDV2lja29RSmcKdWlXZXk4aWRpVXlUd3IxejR3Um5NT2dyL3BIb2ZaK29kVTZFZlpIUUlCM0N3OHEwOS9mUFFPWDlMZGxoQlJ5YworbUZSdGhKYXphUTZwK3FFL0ZTZm1RS0hVRkExSHlzREVPejV6Q1IyT0dFT1VZNTFaYnpLNjUzRnBHWVpaZlQyCkY3c1owV2lVenJPUzJyNTB2UEsvRDBKY1l3MVQxeFpTN3BEYjFFemlGc05vUjZiK09ZL3NTTHpMSnkwLzJwd0kKakZTc05CZm1YL281cFJ5dktrWDZYR3FaV0Q0UHNJR1RBZDB3ZWtxcGZGWXRDSHA4VTREc20rcVUvZGNVWUkxWAppeWszblpRVGpMVjhRL1RGN1NPZ2QxMG1YZWorcVFJMW9LRkJ3Z21EY3lGM1o5MDNYTE9Nci9uNFdwVlpQTk43CkFnTUJBQUU9Ci0tLS0tRU5EIFJTQSBQVUJMSUMgS0VZLS0tLS0=" + }, + { + "operatorKey": "LS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0tCk1JSUJJVEFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUTRBTUlJQkNRS0NBUUJhdExTRDNDTFRYUlo2MUc2L1UrSXcKTzhrN3Y3T3lkMnR0QzNSTndlWnp5eWw3b0lsTURZQ2U4dU1QU0I5b0hoeHB3UENyTXhtVVhSakFwQkl3YnQ5cgp3OFBRNytMOHBTUVNncmVoRWY5M3o4ZnBKeFpEV3B3L1UvZTNpSFNDWFV3bDJOd0ZiRCtBTVZGTS9jKzdHSThBCkVDaExCWkRudlZvTlhWcW0rYUJXOHVrUU1vRlh3L0U4ZmpYZ3pGYzlSamdydU9idGsxbmEzQnFnbTFOcFVUcjgKSEcwWFZ3Ukc4bmxTQ3BLMEd3RjQ2dlpiN3h1QStudGY1SXJLRVFLOTBZUithaXpERjlYZnRRZHo5Z2FFd0lVdgpiMUtSYXQ1QTJZamVJMDNxZDY5WXF4K2pOUXR5Rnk5QnZvY0g5YTR0dnRnQXZXZCs1dEdxcWhIS1VWalJ6WitkCkFnTUJBQUU9Ci0tLS0tRU5EIFJTQSBQVUJMSUMgS0VZLS0tLS0=" + } +] diff --git a/test/helpers/json/validatorKeys.json b/test/helpers/json/validatorKeys.json new file mode 100644 index 00000000..89fbd339 --- /dev/null +++ b/test/helpers/json/validatorKeys.json @@ -0,0 +1,22 @@ +[ + { + "id": 1, + "privateKey": "0x63bc15d14d1460491535700fa2b6ac8873e1ede401cfc46e0c5ce77f00633d29", + "publicKey": "0xa063fa1434f4ae9bb63488cd79e2f76dea59e0e2d6cdec7236c2bb49ffb37da37cb7966be74eca5a171f659fee7bc501" + }, + { + "id": 2, + "privateKey": "0x67a2a67dc439e87566271688576dd430bc2f5a86f5e90850610b21b243490e5f", + "publicKey": "0x821b022611c3cdea28669683ec80a930533633fe7b3489d70fdacf68044661ee2bca1d17d3d095c05f639ebe3108784c" + }, + { + "id": 3, + "privateKey": "0x194a3ffdd039f6ae995a3f2c2de008d770d50f8972c07a477a6e885a353ed4f6", + "publicKey": "0x88ab00343b787f87de60d1e8a552a69ab5fb3525128c53d68e78a3fe2e157bcce75e96a87e8968460087927552a3c891" + }, + { + "id": 4, + "privateKey": "0x52e4bdbdedd85e9e8a77c2f60d083a0693d6f7b2bd717f642a02514528db4278", + "publicKey": "0x9150572051c3496a67207b4caa371dfba34f127318a7aef145ebdba6e0de506c292af31e20831b0c537ab7478508d3e9" + } +] diff --git a/test/helpers/types.ts b/test/helpers/types.ts new file mode 100644 index 00000000..76397c3c --- /dev/null +++ b/test/helpers/types.ts @@ -0,0 +1,11 @@ +export type Validator = { + id: number; + privateKey: string; + publicKey: string; +}; + +export type Operator = { + id: number; + operatorKey: string; + publicKey: string; +}; diff --git a/test/liquidate/liquidate.ts b/test/liquidate/liquidate.ts index 5691499f..123aa94b 100644 --- a/test/liquidate/liquidate.ts +++ b/test/liquidate/liquidate.ts @@ -10,7 +10,7 @@ let ssvNetworkContract: any, ssvViews: any, minDepositAmount: any, firstCluster: describe('Liquidate Tests', () => { beforeEach(async () => { // Initialize contract - const metadata = (await helpers.initializeContract()); + const metadata = await helpers.initializeContract(); ssvNetworkContract = metadata.contract; ssvViews = metadata.ssvViews; @@ -23,306 +23,305 @@ describe('Liquidate Tests', () => { await helpers.coldRegisterValidator(); // first validator - await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); - const register = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(1), - [1, 2, 3, 4], - helpers.DataGenerator.shares(4), + const cluster = await helpers.registerValidators( + 4, minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true - } - ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); - firstCluster = register.eventsByName.ValidatorAdded[0].args; + [1], + [1, 2, 3, 4], + helpers.getClusterForValidator(0, 0, 0, 0, true), + [GasGroup.REGISTER_VALIDATOR_NEW_STATE], + ); + + firstCluster = cluster.args; }); it('Liquidate a cluster via liquidation threshold emits "ClusterLiquidated"', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - await expect(ssvNetworkContract.liquidate( - firstCluster.owner, - firstCluster.operatorIds, - firstCluster.cluster - )).to.emit(ssvNetworkContract, 'ClusterLiquidated') - .to.emit(helpers.DB.ssvToken, 'Transfer').withArgs( + await expect(ssvNetworkContract.liquidate(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster)) + .to.emit(ssvNetworkContract, 'ClusterLiquidated') + .to.emit(helpers.DB.ssvToken, 'Transfer') + .withArgs( ssvNetworkContract.address, helpers.DB.owners[0].address, - minDepositAmount - (helpers.CONFIG.minimalOperatorFee * 4 * (helpers.CONFIG.minimalBlocksBeforeLiquidation + 1)) + minDepositAmount - helpers.CONFIG.minimalOperatorFee * 4 * (helpers.CONFIG.minimalBlocksBeforeLiquidation + 1), ); }); it('Liquidate a cluster via minimum liquidation collateral emits "ClusterLiquidated"', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation - 2); - await expect(ssvNetworkContract.liquidate( - firstCluster.owner, - firstCluster.operatorIds, - firstCluster.cluster - )).to.emit(ssvNetworkContract, 'ClusterLiquidated') - .to.emit(helpers.DB.ssvToken, 'Transfer').withArgs( + await expect(ssvNetworkContract.liquidate(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster)) + .to.emit(ssvNetworkContract, 'ClusterLiquidated') + .to.emit(helpers.DB.ssvToken, 'Transfer') + .withArgs( ssvNetworkContract.address, helpers.DB.owners[0].address, - minDepositAmount - (helpers.CONFIG.minimalOperatorFee * 4 * (helpers.CONFIG.minimalBlocksBeforeLiquidation + 1 - 2)) + minDepositAmount - + helpers.CONFIG.minimalOperatorFee * 4 * (helpers.CONFIG.minimalBlocksBeforeLiquidation + 1 - 2), ); }); it('Liquidate a cluster after liquidation period emits "ClusterLiquidated"', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation + 10); - await expect(ssvNetworkContract.liquidate( - firstCluster.owner, - firstCluster.operatorIds, - firstCluster.cluster - )).to.emit(ssvNetworkContract, 'ClusterLiquidated') + await expect(ssvNetworkContract.liquidate(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster)) + .to.emit(ssvNetworkContract, 'ClusterLiquidated') .to.not.emit(helpers.DB.ssvToken, 'Transfer'); }); it('Liquidatable with removed operator', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); await ssvNetworkContract.removeOperator(1); - expect(await ssvViews.isLiquidatable(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster)).to.equal(true); + expect(await ssvViews.isLiquidatable(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster)).to.equal( + true, + ); }); it('Liquidatable with removed operator after liquidation period', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation + 10); await ssvNetworkContract.removeOperator(1); - expect(await ssvViews.isLiquidatable(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster)).to.equal(true); + expect(await ssvViews.isLiquidatable(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster)).to.equal( + true, + ); }); it('Liquidate validator with removed operator in a cluster', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); await ssvNetworkContract.removeOperator(1); - const liquidatedCluster = await trackGas(ssvNetworkContract.liquidate( - firstCluster.owner, - firstCluster.operatorIds, - firstCluster.cluster - ), [GasGroup.LIQUIDATE_CLUSTER_4]); + const liquidatedCluster = await trackGas( + ssvNetworkContract.liquidate(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster), + [GasGroup.LIQUIDATE_CLUSTER_4], + ); const updatedCluster = liquidatedCluster.eventsByName.ClusterLiquidated[0].args; - expect(await ssvViews.isLiquidatable(updatedCluster.owner, updatedCluster.operatorIds, updatedCluster.cluster)).to.be.equals(false); + expect( + await ssvViews.isLiquidatable(updatedCluster.owner, updatedCluster.operatorIds, updatedCluster.cluster), + ).to.be.equals(false); }); it('Liquidate and register validator in a disabled cluster reverts "ClusterIsLiquidated"', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - const liquidatedCluster = await trackGas(ssvNetworkContract.liquidate( - firstCluster.owner, - firstCluster.operatorIds, - firstCluster.cluster - ), [GasGroup.LIQUIDATE_CLUSTER_4]); + const liquidatedCluster = await trackGas( + ssvNetworkContract.liquidate(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster), + [GasGroup.LIQUIDATE_CLUSTER_4], + ); const updatedCluster = liquidatedCluster.eventsByName.ClusterLiquidated[0].args; await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, `${minDepositAmount * 2}`); - await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(2), - updatedCluster.operatorIds, - helpers.DataGenerator.shares(4), - `${minDepositAmount * 2}`, - updatedCluster.cluster - )).to.be.revertedWithCustomError(ssvNetworkContract, 'ClusterIsLiquidated'); + + await helpers.DB.ssvToken + .connect(helpers.DB.owners[1]) + .approve(ssvNetworkContract.address, `${minDepositAmount * 2}`); + await expect( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .registerValidator( + helpers.DataGenerator.publicKey(2), + updatedCluster.operatorIds, + helpers.DataGenerator.shares(1, 2, 4), + `${minDepositAmount * 2}`, + updatedCluster.cluster, + ), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'IncorrectClusterState'); }); it('Liquidate cluster (4 operators) and check isLiquidated true', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - const liquidatedCluster = await trackGas(ssvNetworkContract.liquidate( - firstCluster.owner, - firstCluster.operatorIds, - firstCluster.cluster - ), [GasGroup.LIQUIDATE_CLUSTER_4]); + const liquidatedCluster = await trackGas( + ssvNetworkContract.liquidate(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster), + [GasGroup.LIQUIDATE_CLUSTER_4], + ); const updatedCluster = liquidatedCluster.eventsByName.ClusterLiquidated[0].args; - expect(await ssvViews.isLiquidated(firstCluster.owner, firstCluster.operatorIds, updatedCluster.cluster)).to.equal(true); + expect(await ssvViews.isLiquidated(firstCluster.owner, firstCluster.operatorIds, updatedCluster.cluster)).to.equal( + true, + ); }); it('Liquidate cluster (7 operators) and check isLiquidated true', async () => { const depositAmount = (helpers.CONFIG.minimalBlocksBeforeLiquidation + 10) * helpers.CONFIG.minimalOperatorFee * 7; - await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, depositAmount); - const { eventsByName } = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(2), + const culster = await helpers.registerValidators( + 1, + depositAmount.toString(), + [1], [1, 2, 3, 4, 5, 6, 7], - helpers.DataGenerator.shares(7), - depositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true - } - )); - firstCluster = eventsByName.ValidatorAdded[0].args; + helpers.getClusterForValidator(0, 0, 0, 0, true), + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7], + ); + firstCluster = culster.args; await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - const liquidatedCluster = await trackGas(ssvNetworkContract.liquidate( - firstCluster.owner, - firstCluster.operatorIds, - firstCluster.cluster - ), [GasGroup.LIQUIDATE_CLUSTER_7]); + const liquidatedCluster = await trackGas( + ssvNetworkContract.liquidate(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster), + [GasGroup.LIQUIDATE_CLUSTER_7], + ); firstCluster = liquidatedCluster.eventsByName.ClusterLiquidated[0].args; - expect(await ssvViews.isLiquidated(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster)).to.equal(true); + expect(await ssvViews.isLiquidated(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster)).to.equal( + true, + ); }); it('Liquidate cluster (10 operators) and check isLiquidated true', async () => { const depositAmount = (helpers.CONFIG.minimalBlocksBeforeLiquidation + 10) * helpers.CONFIG.minimalOperatorFee * 10; - await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, depositAmount); - const { eventsByName } = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(2), + const cluster = await helpers.registerValidators( + 1, + depositAmount.toString(), + [1], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], - helpers.DataGenerator.shares(10), - depositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true - } - )); - firstCluster = eventsByName.ValidatorAdded[0].args; + helpers.getClusterForValidator(0, 0, 0, 0, true), + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_10], + ); + firstCluster = cluster.args; await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - const liquidatedCluster = await trackGas(ssvNetworkContract.liquidate( - firstCluster.owner, - firstCluster.operatorIds, - firstCluster.cluster - ), [GasGroup.LIQUIDATE_CLUSTER_10]); + const liquidatedCluster = await trackGas( + ssvNetworkContract.liquidate(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster), + [GasGroup.LIQUIDATE_CLUSTER_10], + ); firstCluster = liquidatedCluster.eventsByName.ClusterLiquidated[0].args; - expect(await ssvViews.isLiquidated(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster)).to.equal(true); + expect(await ssvViews.isLiquidated(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster)).to.equal( + true, + ); }); it('Liquidate cluster (13 operators) and check isLiquidated true', async () => { const depositAmount = (helpers.CONFIG.minimalBlocksBeforeLiquidation + 10) * helpers.CONFIG.minimalOperatorFee * 13; - await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, depositAmount); - const { eventsByName } = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(2), + const cluster = await helpers.registerValidators( + 1, + depositAmount.toString(), + [1], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], - helpers.DataGenerator.shares(13), - depositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true - } - )); - firstCluster = eventsByName.ValidatorAdded[0].args; + helpers.getClusterForValidator(0, 0, 0, 0, true), + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13], + ); + firstCluster = cluster.args; await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - const liquidatedCluster = await trackGas(ssvNetworkContract.liquidate( - firstCluster.owner, - firstCluster.operatorIds, - firstCluster.cluster - ), [GasGroup.LIQUIDATE_CLUSTER_13]); + const liquidatedCluster = await trackGas( + ssvNetworkContract.liquidate(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster), + [GasGroup.LIQUIDATE_CLUSTER_13], + ); firstCluster = liquidatedCluster.eventsByName.ClusterLiquidated[0].args; - expect(await ssvViews.isLiquidated(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster)).to.equal(true); + expect(await ssvViews.isLiquidated(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster)).to.equal( + true, + ); }); it('Liquidate a non liquidatable cluster that I own', async () => { - const liquidatedCluster = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).liquidate( - firstCluster.owner, - firstCluster.operatorIds, - firstCluster.cluster - ), [GasGroup.LIQUIDATE_CLUSTER_4]); + const liquidatedCluster = await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[4]) + .liquidate(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster), + [GasGroup.LIQUIDATE_CLUSTER_4], + ); const updatedCluster = liquidatedCluster.eventsByName.ClusterLiquidated[0].args; - expect(await ssvViews.isLiquidated(firstCluster.owner, firstCluster.operatorIds, updatedCluster.cluster)).to.equal(true); + expect(await ssvViews.isLiquidated(firstCluster.owner, firstCluster.operatorIds, updatedCluster.cluster)).to.equal( + true, + ); }); it('Liquidate cluster that I own', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - const liquidatedCluster = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).liquidate( - firstCluster.owner, - firstCluster.operatorIds, - firstCluster.cluster - ), [GasGroup.LIQUIDATE_CLUSTER_4]); + const liquidatedCluster = await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .liquidate(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster), + [GasGroup.LIQUIDATE_CLUSTER_4], + ); const updatedCluster = liquidatedCluster.eventsByName.ClusterLiquidated[0].args; - expect(await ssvViews.isLiquidated(firstCluster.owner, firstCluster.operatorIds, updatedCluster.cluster)).to.equal(true); + expect(await ssvViews.isLiquidated(firstCluster.owner, firstCluster.operatorIds, updatedCluster.cluster)).to.equal( + true, + ); }); it('Liquidate cluster that I own after liquidation period', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation + 10); - const liquidatedCluster = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).liquidate( - firstCluster.owner, - firstCluster.operatorIds, - firstCluster.cluster - ), [GasGroup.LIQUIDATE_CLUSTER_4]); + const liquidatedCluster = await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .liquidate(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster), + [GasGroup.LIQUIDATE_CLUSTER_4], + ); const updatedCluster = liquidatedCluster.eventsByName.ClusterLiquidated[0].args; - expect(await ssvViews.isLiquidated(firstCluster.owner, firstCluster.operatorIds, updatedCluster.cluster)).to.equal(true); + expect(await ssvViews.isLiquidated(firstCluster.owner, firstCluster.operatorIds, updatedCluster.cluster)).to.equal( + true, + ); }); it('Get if the cluster is liquidatable', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - expect(await ssvViews.isLiquidatable(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster)).to.equal(true); + expect(await ssvViews.isLiquidatable(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster)).to.equal( + true, + ); }); it('Get if the cluster is liquidatable after liquidation period', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation + 10); - expect(await ssvViews.isLiquidatable(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster)).to.equal(true); + expect(await ssvViews.isLiquidatable(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster)).to.equal( + true, + ); }); it('Get if the cluster is not liquidatable', async () => { - expect(await ssvViews.isLiquidatable(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster)).to.equal(false); + expect(await ssvViews.isLiquidatable(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster)).to.equal( + false, + ); }); it('Liquidate a cluster that is not liquidatable reverts "ClusterNotLiquidatable"', async () => { - await expect(ssvNetworkContract.liquidate( - firstCluster.owner, - firstCluster.operatorIds, - firstCluster.cluster - )).to.be.revertedWithCustomError(ssvNetworkContract, 'ClusterNotLiquidatable'); - expect(await ssvViews.isLiquidatable(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster)).to.equal(false); + await expect( + ssvNetworkContract.liquidate(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'ClusterNotLiquidatable'); + expect(await ssvViews.isLiquidatable(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster)).to.equal( + false, + ); }); it('Liquidate a cluster that is not liquidatable reverts "IncorrectClusterState"', async () => { - await expect(ssvNetworkContract.liquidate( - firstCluster.owner, - firstCluster.operatorIds, - { + await expect( + ssvNetworkContract.liquidate(firstCluster.owner, firstCluster.operatorIds, { validatorCount: 0, networkFeeIndex: 0, index: 0, balance: 0, - active: true - } - )).to.be.revertedWithCustomError(ssvNetworkContract, 'IncorrectClusterState'); + active: true, + }), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'IncorrectClusterState'); }); it('Liquidate already liquidated cluster reverts "ClusterIsLiquidated"', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - const liquidatedCluster = await trackGas(ssvNetworkContract.liquidate( - firstCluster.owner, - firstCluster.operatorIds, - firstCluster.cluster - ), [GasGroup.LIQUIDATE_CLUSTER_4]); + const liquidatedCluster = await trackGas( + ssvNetworkContract.liquidate(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster), + [GasGroup.LIQUIDATE_CLUSTER_4], + ); const updatedCluster = liquidatedCluster.eventsByName.ClusterLiquidated[0].args; - await expect(ssvNetworkContract.liquidate( - firstCluster.owner, - updatedCluster.operatorIds, - updatedCluster.cluster - )).to.be.revertedWithCustomError(ssvNetworkContract, 'ClusterIsLiquidated'); + await expect( + ssvNetworkContract.liquidate(firstCluster.owner, updatedCluster.operatorIds, updatedCluster.cluster), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'ClusterIsLiquidated'); }); it('Is liquidated reverts "ClusterDoesNotExists"', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - const liquidatedCluster = await trackGas(ssvNetworkContract.liquidate( - firstCluster.owner, - firstCluster.operatorIds, - firstCluster.cluster - ), [GasGroup.LIQUIDATE_CLUSTER_4]); + const liquidatedCluster = await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[4]) + .liquidate(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster), + [GasGroup.LIQUIDATE_CLUSTER_4], + ); const updatedCluster = liquidatedCluster.eventsByName.ClusterLiquidated[0].args; - await expect(ssvViews.isLiquidated(helpers.DB.owners[4].address, firstCluster.operatorIds, updatedCluster.cluster)).to.be.revertedWithCustomError(ssvNetworkContract, 'ClusterDoesNotExists'); + await expect( + ssvViews.isLiquidated(helpers.DB.owners[1].address, firstCluster.operatorIds, updatedCluster.cluster), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'ClusterDoesNotExists'); }); -}); \ No newline at end of file +}); diff --git a/test/liquidate/liquidated-cluster.ts b/test/liquidate/liquidated-cluster.ts index a0afb027..36fd9d14 100644 --- a/test/liquidate/liquidated-cluster.ts +++ b/test/liquidate/liquidated-cluster.ts @@ -4,13 +4,18 @@ import * as utils from '../helpers/utils'; import { expect } from 'chai'; import { trackGas, GasGroup } from '../helpers/gas-usage'; -let ssvNetworkContract: any, ssvViews: any, minDepositAmount: any, firstCluster: any, burnPerBlock: any, networkFee: any; +let ssvNetworkContract: any, + ssvViews: any, + minDepositAmount: any, + firstCluster: any, + burnPerBlock: any, + networkFee: any; // Declare globals -describe('Liquidate Tests', () => { +describe('Liquidate Cluster Tests', () => { beforeEach(async () => { // Initialize contract - const metadata = (await helpers.initializeContract()); + const metadata = await helpers.initializeContract(); ssvNetworkContract = metadata.contract; ssvViews = metadata.ssvViews; @@ -24,142 +29,168 @@ describe('Liquidate Tests', () => { await ssvNetworkContract.updateNetworkFee(networkFee); // first validator - await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount * 2); - const register = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(1), + const cluster = await helpers.registerValidators( + 1, + (minDepositAmount * 2).toString(), + [1], [1, 2, 3, 4], - helpers.DataGenerator.shares(4), - minDepositAmount * 2, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true - } - )); - firstCluster = register.eventsByName.ValidatorAdded[0].args; + helpers.getClusterForValidator(0, 0, 0, 0, true), + [GasGroup.REGISTER_VALIDATOR_NEW_STATE], + ); + + firstCluster = cluster.args; }); it('Liquidate -> deposit -> reactivate', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - let clusterEventData = await helpers.liquidate(firstCluster.owner, - firstCluster.operatorIds, - firstCluster.cluster); + let clusterEventData = await helpers.liquidate(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster); - expect(await ssvViews.isLiquidated(firstCluster.owner, - firstCluster.operatorIds, - clusterEventData.cluster)).to.equal(true); + expect( + await ssvViews.isLiquidated(firstCluster.owner, firstCluster.operatorIds, clusterEventData.cluster), + ).to.equal(true); - clusterEventData = await helpers.deposit(1, + clusterEventData = await helpers.deposit( + 1, firstCluster.owner, firstCluster.operatorIds, minDepositAmount, - clusterEventData.cluster); + clusterEventData.cluster, + ); await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); - await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).reactivate(clusterEventData.operatorIds, minDepositAmount, clusterEventData.cluster)).to.emit(ssvNetworkContract, 'ClusterReactivated'); + await expect( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .reactivate(clusterEventData.operatorIds, minDepositAmount, clusterEventData.cluster), + ).to.emit(ssvNetworkContract, 'ClusterReactivated'); }); it('RegisterValidator -> liquidate -> removeValidator -> deposit -> withdraw', async () => { - await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); - const register = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(2), - [1, 2, 3, 4], - helpers.DataGenerator.shares(4), + let clusterEventData = await helpers.registerValidators( + 1, minDepositAmount, - firstCluster.cluster - )); - let clusterEventData = register.eventsByName.ValidatorAdded[0].args; + [2], + [1, 2, 3, 4], + firstCluster.cluster, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE], + ); await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - clusterEventData = await helpers.liquidate(clusterEventData.owner, clusterEventData.operatorIds, clusterEventData.cluster); - await expect(clusterEventData.cluster.balance).to.be.equals(0); - - clusterEventData = await helpers.removeValidator(1, helpers.DataGenerator.publicKey(1), clusterEventData.operatorIds, clusterEventData.cluster); - - clusterEventData = await helpers.deposit(1, clusterEventData.owner, clusterEventData.operatorIds, minDepositAmount, clusterEventData.cluster); - await expect(clusterEventData.cluster.balance).to.be.equals(minDepositAmount); // shrink + clusterEventData.args = await helpers.liquidate( + clusterEventData.args.owner, + clusterEventData.args.operatorIds, + clusterEventData.args.cluster, + ); + await expect(clusterEventData.args.cluster.balance).to.be.equals(0); - await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).withdraw( - clusterEventData.operatorIds, + clusterEventData.args = await helpers.removeValidator( + 1, + helpers.DataGenerator.publicKey(1), + clusterEventData.args.operatorIds, + clusterEventData.args.cluster, + ); + + clusterEventData.args = await helpers.deposit( + 1, + clusterEventData.args.owner, + clusterEventData.args.operatorIds, minDepositAmount, - clusterEventData.cluster)).to.be.revertedWithCustomError(ssvNetworkContract, 'ClusterIsLiquidated'); + clusterEventData.args.cluster, + ); + await expect(clusterEventData.args.cluster.balance).to.be.equals(minDepositAmount); // shrink + + await expect( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .withdraw(clusterEventData.args.operatorIds, minDepositAmount, clusterEventData.args.cluster), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'ClusterIsLiquidated'); }); it('Withdraw -> liquidate -> deposit -> reactivate', async () => { await utils.progressBlocks(2); const withdrawAmount = 2e7; - - let clusterEventData = await helpers.withdraw(1, + let clusterEventData = await helpers.withdraw( + 1, firstCluster.operatorIds, withdrawAmount.toString(), - firstCluster.cluster) - expect(await ssvViews.getBalance(helpers.DB.owners[1].address, clusterEventData.operatorIds, clusterEventData.cluster)).to.be.equals(minDepositAmount * 2 - withdrawAmount - (burnPerBlock * 3)); + firstCluster.cluster, + ); + expect( + await ssvViews.getBalance(helpers.DB.owners[1].address, clusterEventData.operatorIds, clusterEventData.cluster), + ).to.be.equals(minDepositAmount * 2 - withdrawAmount - burnPerBlock * 3); await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation - 2); - clusterEventData = await helpers.liquidate(clusterEventData.owner, + clusterEventData = await helpers.liquidate( + clusterEventData.owner, clusterEventData.operatorIds, - clusterEventData.cluster); - await expect(ssvViews.getBalance(helpers.DB.owners[1].address, clusterEventData.operatorIds, clusterEventData.cluster)).to.be.revertedWithCustomError(ssvNetworkContract, 'ClusterIsLiquidated'); - - clusterEventData = await helpers.deposit(1, + clusterEventData.cluster, + ); + await expect( + ssvViews.getBalance(helpers.DB.owners[1].address, clusterEventData.operatorIds, clusterEventData.cluster), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'ClusterIsLiquidated'); + + clusterEventData = await helpers.deposit( + 1, clusterEventData.owner, clusterEventData.operatorIds, minDepositAmount, - clusterEventData.cluster) + clusterEventData.cluster, + ); - clusterEventData = await helpers.reactivate(1, + clusterEventData = await helpers.reactivate( + 1, clusterEventData.operatorIds, minDepositAmount, - clusterEventData.cluster); - expect(await ssvViews.getBalance(helpers.DB.owners[1].address, clusterEventData.operatorIds, clusterEventData.cluster)).to.be.equals(minDepositAmount * 2); + clusterEventData.cluster, + ); + expect( + await ssvViews.getBalance(helpers.DB.owners[1].address, clusterEventData.operatorIds, clusterEventData.cluster), + ).to.be.equals(minDepositAmount * 2); await utils.progressBlocks(2); - expect(await ssvViews.getBalance(helpers.DB.owners[1].address, clusterEventData.operatorIds, clusterEventData.cluster)).to.be.equals(minDepositAmount * 2 - burnPerBlock * 2); + expect( + await ssvViews.getBalance(helpers.DB.owners[1].address, clusterEventData.operatorIds, clusterEventData.cluster), + ).to.be.equals(minDepositAmount * 2 - burnPerBlock * 2); }); it('Remove validator -> withdraw -> try liquidate reverts "ClusterNotLiquidatable"', async () => { - await helpers.DB.ssvToken.connect(helpers.DB.owners[2]).approve(ssvNetworkContract.address, minDepositAmount); - const register = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[2]).registerValidator( - helpers.DataGenerator.publicKey(2), - [1, 2, 3, 4], - helpers.DataGenerator.shares(4), + let cluster = await helpers.registerValidators( + 2, minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true - } - )); - let clusterEventData = register.eventsByName.ValidatorAdded[0].args; + [2], + [1, 2, 3, 4], + helpers.getClusterForValidator(0, 0, 0, 0, true), + [GasGroup.REGISTER_VALIDATOR_NEW_STATE], + ); + let clusterEventData = cluster.args; await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation - 10); - const remove = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[2]).removeValidator( - helpers.DataGenerator.publicKey(2), - clusterEventData.operatorIds, - clusterEventData.cluster - )); + const remove = await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[2]) + .removeValidator(helpers.DataGenerator.publicKey(2), clusterEventData.operatorIds, clusterEventData.cluster), + ); clusterEventData = remove.eventsByName.ValidatorRemoved[0].args; - let balance = await ssvViews.getBalance(helpers.DB.owners[2].address, clusterEventData.operatorIds, clusterEventData.cluster); - - clusterEventData = await helpers.withdraw(2, + let balance = await ssvViews.getBalance( + helpers.DB.owners[2].address, clusterEventData.operatorIds, - ((balance - helpers.CONFIG.minimumLiquidationCollateral) * 1.01).toString(), - clusterEventData.cluster); + clusterEventData.cluster, + ); - await expect(ssvNetworkContract.liquidate( - clusterEventData.owner, + clusterEventData = await helpers.withdraw( + 2, clusterEventData.operatorIds, - clusterEventData.cluster - )).to.be.revertedWithCustomError(ssvNetworkContract, 'ClusterNotLiquidatable'); + ((balance - helpers.CONFIG.minimumLiquidationCollateral) * 1.01).toString(), + clusterEventData.cluster, + ); + await expect( + ssvNetworkContract.liquidate(clusterEventData.owner, clusterEventData.operatorIds, clusterEventData.cluster), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'ClusterNotLiquidatable'); }); -}); \ No newline at end of file +}); diff --git a/test/liquidate/reactivate.ts b/test/liquidate/reactivate.ts index 8a6c5d42..0d184ce7 100644 --- a/test/liquidate/reactivate.ts +++ b/test/liquidate/reactivate.ts @@ -10,7 +10,7 @@ let ssvNetworkContract: any, minDepositAmount: any, firstCluster: any; describe('Reactivate Tests', () => { beforeEach(async () => { // Initialize contract - const metadata = (await helpers.initializeContract()); + const metadata = await helpers.initializeContract(); ssvNetworkContract = metadata.contract; // Register operators @@ -24,75 +24,119 @@ describe('Reactivate Tests', () => { // first validator await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); - const register = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(1), - [1, 2, 3, 4], - helpers.DataGenerator.shares(4), - minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true - } - ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + const register = await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .registerValidator( + helpers.DataGenerator.publicKey(1), + [1, 2, 3, 4], + helpers.DataGenerator.shares(1, 1, 4), + minDepositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true, + }, + ), + [GasGroup.REGISTER_VALIDATOR_NEW_STATE], + ); firstCluster = register.eventsByName.ValidatorAdded[0].args; }); it('Reactivate a disabled cluster emits "ClusterReactivated"', async () => { await progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - const liquidatedCluster = await trackGas(ssvNetworkContract.liquidate(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster), [GasGroup.LIQUIDATE_CLUSTER_4]); + const liquidatedCluster = await trackGas( + ssvNetworkContract.liquidate(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster), + [GasGroup.LIQUIDATE_CLUSTER_4], + ); const updatedCluster = liquidatedCluster.eventsByName.ClusterLiquidated[0].args; await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); - await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).reactivate(updatedCluster.operatorIds, minDepositAmount, updatedCluster.cluster)).to.emit(ssvNetworkContract, 'ClusterReactivated'); + await expect( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .reactivate(updatedCluster.operatorIds, minDepositAmount, updatedCluster.cluster), + ).to.emit(ssvNetworkContract, 'ClusterReactivated'); }); it('Reactivate a cluster with a removed operator in the cluster', async () => { await progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - const liquidatedCluster = await trackGas(ssvNetworkContract.liquidate(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster), [GasGroup.LIQUIDATE_CLUSTER_4]); + const liquidatedCluster = await trackGas( + ssvNetworkContract.liquidate(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster), + [GasGroup.LIQUIDATE_CLUSTER_4], + ); const updatedCluster = liquidatedCluster.eventsByName.ClusterLiquidated[0].args; await ssvNetworkContract.removeOperator(1); await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).reactivate(updatedCluster.operatorIds, minDepositAmount, updatedCluster.cluster), [GasGroup.REACTIVATE_CLUSTER]); + await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .reactivate(updatedCluster.operatorIds, minDepositAmount, updatedCluster.cluster), + [GasGroup.REACTIVATE_CLUSTER], + ); }); it('Reactivate an enabled cluster reverts "ClusterAlreadyEnabled"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).reactivate(firstCluster.operatorIds, minDepositAmount, firstCluster.cluster)).to.be.revertedWithCustomError(ssvNetworkContract, 'ClusterAlreadyEnabled'); + await expect( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .reactivate(firstCluster.operatorIds, minDepositAmount, firstCluster.cluster), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'ClusterAlreadyEnabled'); }); it('Reactivate a cluster when the amount is not enough reverts "InsufficientBalance"', async () => { await progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - const liquidatedCluster = await trackGas(ssvNetworkContract.liquidate(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster), [GasGroup.LIQUIDATE_CLUSTER_4]); + const liquidatedCluster = await trackGas( + ssvNetworkContract.liquidate(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster), + [GasGroup.LIQUIDATE_CLUSTER_4], + ); const updatedCluster = liquidatedCluster.eventsByName.ClusterLiquidated[0].args; - await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).reactivate(updatedCluster.operatorIds, helpers.CONFIG.minimalOperatorFee, updatedCluster.cluster)).to.be.revertedWithCustomError(ssvNetworkContract, 'InsufficientBalance'); + await expect( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .reactivate(updatedCluster.operatorIds, helpers.CONFIG.minimalOperatorFee, updatedCluster.cluster), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'InsufficientBalance'); }); it('Reactivate a liquidated cluster after making a deposit', async () => { await progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - const liquidatedCluster = await trackGas(ssvNetworkContract.liquidate(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster)); + const liquidatedCluster = await trackGas( + ssvNetworkContract.liquidate(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster), + ); let clusterData = liquidatedCluster.eventsByName.ClusterLiquidated[0].args; await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); - const depositedCluster = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).deposit( - firstCluster.owner, - firstCluster.operatorIds, - minDepositAmount, - clusterData.cluster)); + const depositedCluster = await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .deposit(firstCluster.owner, firstCluster.operatorIds, minDepositAmount, clusterData.cluster), + ); clusterData = depositedCluster.eventsByName.ClusterDeposited[0].args; - await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).reactivate(firstCluster.operatorIds, 0, clusterData.cluster)).to.emit(ssvNetworkContract, 'ClusterReactivated'); + await expect( + ssvNetworkContract.connect(helpers.DB.owners[1]).reactivate(firstCluster.operatorIds, 0, clusterData.cluster), + ).to.emit(ssvNetworkContract, 'ClusterReactivated'); }); it('Reactivate a cluster after liquidation period when the amount is not enough reverts "InsufficientBalance"', async () => { await progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - const liquidatedCluster = await trackGas(ssvNetworkContract.liquidate(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster), [GasGroup.LIQUIDATE_CLUSTER_4]); + const liquidatedCluster = await trackGas( + ssvNetworkContract.liquidate(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster), + [GasGroup.LIQUIDATE_CLUSTER_4], + ); const updatedCluster = liquidatedCluster.eventsByName.ClusterLiquidated[0].args; - await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, helpers.CONFIG.minimalOperatorFee); - await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).reactivate(updatedCluster.operatorIds, helpers.CONFIG.minimalOperatorFee, updatedCluster.cluster)).to.be.revertedWithCustomError(ssvNetworkContract, 'InsufficientBalance'); + await helpers.DB.ssvToken + .connect(helpers.DB.owners[1]) + .approve(ssvNetworkContract.address, helpers.CONFIG.minimalOperatorFee); + await expect( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .reactivate(updatedCluster.operatorIds, helpers.CONFIG.minimalOperatorFee, updatedCluster.cluster), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'InsufficientBalance'); }); -}); \ No newline at end of file +}); diff --git a/test/operators/remove.ts b/test/operators/remove.ts index c3bffdec..b415616b 100644 --- a/test/operators/remove.ts +++ b/test/operators/remove.ts @@ -1,4 +1,5 @@ // Declare imports +declare const ethers: any; import * as helpers from '../helpers/contract-helpers'; import { expect } from 'chai'; import { trackGas, GasGroup } from '../helpers/gas-usage'; @@ -8,7 +9,7 @@ let ssvNetworkContract: any, ssvViews: any; describe('Remove Operator Tests', () => { beforeEach(async () => { - const metadata = (await helpers.initializeContract()); + const metadata = await helpers.initializeContract(); ssvNetworkContract = metadata.contract; ssvViews = metadata.ssvViews; @@ -22,57 +23,72 @@ describe('Remove Operator Tests', () => { it('Remove operator emits "OperatorRemoved"', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[0]).removeOperator(1)) - .to.emit(ssvNetworkContract, 'OperatorRemoved').withArgs(1); + .to.emit(ssvNetworkContract, 'OperatorRemoved') + .withArgs(1); }); it('Remove private operator emits "OperatorRemoved"', async () => { - const result = await trackGas(ssvNetworkContract.registerOperator( - helpers.DataGenerator.publicKey(22), - helpers.CONFIG.minimalOperatorFee - )); + const result = await trackGas( + ssvNetworkContract.registerOperator(helpers.DataGenerator.publicKey(22), helpers.CONFIG.minimalOperatorFee), + ); const { operatorId } = result.eventsByName.OperatorAdded[0].args; await ssvNetworkContract.setOperatorWhitelist(operatorId, helpers.DB.owners[2].address); await expect(ssvNetworkContract.removeOperator(operatorId)) - .to.emit(ssvNetworkContract, 'OperatorRemoved').withArgs(operatorId); + .to.emit(ssvNetworkContract, 'OperatorRemoved') + .withArgs(operatorId); - expect(await ssvViews.getOperatorById(operatorId)).to.deep.equal( - [helpers.DB.owners[0].address, // owner - 0, // fee - 0, // validatorCount + expect(await ssvViews.getOperatorById(operatorId)).to.deep.equal([ + helpers.DB.owners[0].address, // owner + 0, // fee + 0, // validatorCount ethers.constants.AddressZero, // whitelisted address - false, // isPrivate - false // active - ]); + false, // isPrivate + false, // active + ]); }); it('Remove operator gas limits', async () => { await trackGas(ssvNetworkContract.removeOperator(1), [GasGroup.REMOVE_OPERATOR]); }); - it('Remove operator with 0 balance emits "OperatorWithdrawn"', async () => { - await expect(ssvNetworkContract.removeOperator(14)).not.to.emit(ssvNetworkContract, 'OperatorWithdrawn'); - }); - it('Remove operator with a balance emits "OperatorWithdrawn"', async () => { - await helpers.registerValidators(4, 1, `${helpers.CONFIG.minimalBlocksBeforeLiquidation * helpers.CONFIG.minimalOperatorFee * 4}`, [1, 2, 3, 4], [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + await helpers.registerValidators( + 4, + `${helpers.CONFIG.minimalBlocksBeforeLiquidation * helpers.CONFIG.minimalOperatorFee * 4}`, + [1], + [1, 2, 3, 4], + helpers.getClusterForValidator(0, 0, 0, 0, true), + [GasGroup.REGISTER_VALIDATOR_NEW_STATE], + ); await expect(ssvNetworkContract.removeOperator(1)).to.emit(ssvNetworkContract, 'OperatorWithdrawn'); }); it('Remove operator with a balance gas limits', async () => { - await helpers.registerValidators(4, 1, `${helpers.CONFIG.minimalBlocksBeforeLiquidation * helpers.CONFIG.minimalOperatorFee * 4}`, [1, 2, 3, 4], [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + await helpers.registerValidators( + 4, + `${helpers.CONFIG.minimalBlocksBeforeLiquidation * helpers.CONFIG.minimalOperatorFee * 4}`, + [1], + [1, 2, 3, 4], + helpers.getClusterForValidator(0, 0, 0, 0, true), + [GasGroup.REGISTER_VALIDATOR_NEW_STATE], + ); await trackGas(ssvNetworkContract.removeOperator(1), [GasGroup.REMOVE_OPERATOR_WITH_WITHDRAW]); }); it('Remove operator I do not own reverts "CallerNotOwner"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).removeOperator(1)) - .to.be.revertedWithCustomError(ssvNetworkContract, 'CallerNotOwner'); + await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).removeOperator(1)).to.be.revertedWithCustomError( + ssvNetworkContract, + 'CallerNotOwner', + ); }); it('Remove same operator twice reverts "OperatorDoesNotExist"', async () => { await ssvNetworkContract.connect(helpers.DB.owners[0]).removeOperator(1); - await expect(ssvNetworkContract.connect(helpers.DB.owners[0]).removeOperator(1)) - .to.be.revertedWithCustomError(ssvNetworkContract, 'OperatorDoesNotExist'); + await expect(ssvNetworkContract.connect(helpers.DB.owners[0]).removeOperator(1)).to.be.revertedWithCustomError( + ssvNetworkContract, + 'OperatorDoesNotExist', + ); }); -}); \ No newline at end of file +}); diff --git a/test/sanity/balances.ts b/test/sanity/balances.ts index 876cecf3..910b8e1a 100644 --- a/test/sanity/balances.ts +++ b/test/sanity/balances.ts @@ -4,13 +4,19 @@ import * as utils from '../helpers/utils'; import { expect } from 'chai'; import { trackGas, GasGroup } from '../helpers/gas-usage'; -let ssvNetworkContract: any, ssvViews: any, cluster1: any, minDepositAmount: any, burnPerBlock: any, networkFee: any, initNetworkFeeBalance: any; +let ssvNetworkContract: any, + ssvViews: any, + cluster1: any, + minDepositAmount: any, + burnPerBlock: any, + networkFee: any, + initNetworkFeeBalance: any; // Declare globals describe('Balance Tests', () => { beforeEach(async () => { // Initialize contract - const metadata = (await helpers.initializeContract()); + const metadata = await helpers.initializeContract(); ssvNetworkContract = metadata.contract; ssvViews = metadata.ssvViews; @@ -28,102 +34,157 @@ describe('Balance Tests', () => { // cold register await helpers.coldRegisterValidator(); - cluster1 = await helpers.registerValidators(4, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + cluster1 = await helpers.registerValidators( + 4, + minDepositAmount, + [1], + helpers.DataGenerator.cluster.new(), + helpers.getClusterForValidator(0, 0, 0, 0, true), + [GasGroup.REGISTER_VALIDATOR_NEW_STATE], + ); initNetworkFeeBalance = await ssvViews.getNetworkEarnings(); }); it('Check cluster balance in three blocks, one after the other', async () => { await utils.progressBlocks(1); - expect(await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster)).to.equal(minDepositAmount - burnPerBlock); + expect( + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), + ).to.equal(minDepositAmount - burnPerBlock); await utils.progressBlocks(1); - expect(await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster)).to.equal(minDepositAmount - burnPerBlock * 2); + expect( + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), + ).to.equal(minDepositAmount - burnPerBlock * 2); await utils.progressBlocks(1); - expect(await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster)).to.equal(minDepositAmount - burnPerBlock * 3); + expect( + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), + ).to.equal(minDepositAmount - burnPerBlock * 3); }); it('Check cluster balance in two and twelve blocks, after network fee updates', async () => { await utils.progressBlocks(1); - expect(await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster)).to.equal(minDepositAmount - burnPerBlock); + expect( + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), + ).to.equal(minDepositAmount - burnPerBlock); const newBurnPerBlock = burnPerBlock + networkFee; await ssvNetworkContract.updateNetworkFee(networkFee * 2); await utils.progressBlocks(1); - expect(await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster)).to.equal(minDepositAmount - burnPerBlock * 2 - newBurnPerBlock); + expect( + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), + ).to.equal(minDepositAmount - burnPerBlock * 2 - newBurnPerBlock); await utils.progressBlocks(1); - expect(await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster)).to.equal(minDepositAmount - burnPerBlock * 2 - newBurnPerBlock * 2); + expect( + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), + ).to.equal(minDepositAmount - burnPerBlock * 2 - newBurnPerBlock * 2); await utils.progressBlocks(10); - expect(await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster)).to.equal(minDepositAmount - burnPerBlock * 2 - newBurnPerBlock * 12); + expect( + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), + ).to.equal(minDepositAmount - burnPerBlock * 2 - newBurnPerBlock * 12); }); it('Check DAO earnings in three blocks, one after the other', async () => { await utils.progressBlocks(1); - expect(await ssvViews.getNetworkEarnings() - initNetworkFeeBalance).to.equal(networkFee * 2); + expect((await ssvViews.getNetworkEarnings()) - initNetworkFeeBalance).to.equal(networkFee * 2); await utils.progressBlocks(1); - expect(await ssvViews.getNetworkEarnings() - initNetworkFeeBalance).to.equal(networkFee * 4); + expect((await ssvViews.getNetworkEarnings()) - initNetworkFeeBalance).to.equal(networkFee * 4); await utils.progressBlocks(1); - expect(await ssvViews.getNetworkEarnings() - initNetworkFeeBalance).to.equal(networkFee * 6); + expect((await ssvViews.getNetworkEarnings()) - initNetworkFeeBalance).to.equal(networkFee * 6); }); it('Check DAO earnings in two and twelve blocks, after network fee updates', async () => { await utils.progressBlocks(1); - expect(await ssvViews.getNetworkEarnings() - initNetworkFeeBalance).to.equal(networkFee * 2); + expect((await ssvViews.getNetworkEarnings()) - initNetworkFeeBalance).to.equal(networkFee * 2); const newNetworkFee = networkFee * 2; await ssvNetworkContract.updateNetworkFee(newNetworkFee); await utils.progressBlocks(1); - expect(await ssvViews.getNetworkEarnings() - initNetworkFeeBalance).to.equal(networkFee * 4 + newNetworkFee * 2); + expect((await ssvViews.getNetworkEarnings()) - initNetworkFeeBalance).to.equal(networkFee * 4 + newNetworkFee * 2); await utils.progressBlocks(1); - expect(await ssvViews.getNetworkEarnings() - initNetworkFeeBalance).to.equal(networkFee * 4 + newNetworkFee * 4); + expect((await ssvViews.getNetworkEarnings()) - initNetworkFeeBalance).to.equal(networkFee * 4 + newNetworkFee * 4); await utils.progressBlocks(10); - expect(await ssvViews.getNetworkEarnings() - initNetworkFeeBalance).to.equal(networkFee * 4 + newNetworkFee * 24); + expect((await ssvViews.getNetworkEarnings()) - initNetworkFeeBalance).to.equal(networkFee * 4 + newNetworkFee * 24); }); it('Check operators earnings in three blocks, one after the other', async () => { await utils.progressBlocks(1); - expect(await ssvViews.getOperatorEarnings(1)).to.equal(helpers.CONFIG.minimalOperatorFee * 2 + helpers.CONFIG.minimalOperatorFee * 2); - expect(await ssvViews.getOperatorEarnings(2)).to.equal(helpers.CONFIG.minimalOperatorFee * 2 + helpers.CONFIG.minimalOperatorFee * 2); - expect(await ssvViews.getOperatorEarnings(3)).to.equal(helpers.CONFIG.minimalOperatorFee * 2 + helpers.CONFIG.minimalOperatorFee * 2); - expect(await ssvViews.getOperatorEarnings(4)).to.equal(helpers.CONFIG.minimalOperatorFee * 2 + helpers.CONFIG.minimalOperatorFee * 2); + expect(await ssvViews.getOperatorEarnings(1)).to.equal( + helpers.CONFIG.minimalOperatorFee * 2 + helpers.CONFIG.minimalOperatorFee * 2, + ); + expect(await ssvViews.getOperatorEarnings(2)).to.equal( + helpers.CONFIG.minimalOperatorFee * 2 + helpers.CONFIG.minimalOperatorFee * 2, + ); + expect(await ssvViews.getOperatorEarnings(3)).to.equal( + helpers.CONFIG.minimalOperatorFee * 2 + helpers.CONFIG.minimalOperatorFee * 2, + ); + expect(await ssvViews.getOperatorEarnings(4)).to.equal( + helpers.CONFIG.minimalOperatorFee * 2 + helpers.CONFIG.minimalOperatorFee * 2, + ); await utils.progressBlocks(1); - expect(await ssvViews.getOperatorEarnings(1)).to.equal(helpers.CONFIG.minimalOperatorFee * 4 + helpers.CONFIG.minimalOperatorFee * 2); - expect(await ssvViews.getOperatorEarnings(2)).to.equal(helpers.CONFIG.minimalOperatorFee * 4 + helpers.CONFIG.minimalOperatorFee * 2); - expect(await ssvViews.getOperatorEarnings(3)).to.equal(helpers.CONFIG.minimalOperatorFee * 4 + helpers.CONFIG.minimalOperatorFee * 2); - expect(await ssvViews.getOperatorEarnings(4)).to.equal(helpers.CONFIG.minimalOperatorFee * 4 + helpers.CONFIG.minimalOperatorFee * 2); + expect(await ssvViews.getOperatorEarnings(1)).to.equal( + helpers.CONFIG.minimalOperatorFee * 4 + helpers.CONFIG.minimalOperatorFee * 2, + ); + expect(await ssvViews.getOperatorEarnings(2)).to.equal( + helpers.CONFIG.minimalOperatorFee * 4 + helpers.CONFIG.minimalOperatorFee * 2, + ); + expect(await ssvViews.getOperatorEarnings(3)).to.equal( + helpers.CONFIG.minimalOperatorFee * 4 + helpers.CONFIG.minimalOperatorFee * 2, + ); + expect(await ssvViews.getOperatorEarnings(4)).to.equal( + helpers.CONFIG.minimalOperatorFee * 4 + helpers.CONFIG.minimalOperatorFee * 2, + ); await utils.progressBlocks(1); - expect(await ssvViews.getOperatorEarnings(1)).to.equal(helpers.CONFIG.minimalOperatorFee * 6 + helpers.CONFIG.minimalOperatorFee * 2); - expect(await ssvViews.getOperatorEarnings(2)).to.equal(helpers.CONFIG.minimalOperatorFee * 6 + helpers.CONFIG.minimalOperatorFee * 2); - expect(await ssvViews.getOperatorEarnings(3)).to.equal(helpers.CONFIG.minimalOperatorFee * 6 + helpers.CONFIG.minimalOperatorFee * 2); - expect(await ssvViews.getOperatorEarnings(4)).to.equal(helpers.CONFIG.minimalOperatorFee * 6 + helpers.CONFIG.minimalOperatorFee * 2); + expect(await ssvViews.getOperatorEarnings(1)).to.equal( + helpers.CONFIG.minimalOperatorFee * 6 + helpers.CONFIG.minimalOperatorFee * 2, + ); + expect(await ssvViews.getOperatorEarnings(2)).to.equal( + helpers.CONFIG.minimalOperatorFee * 6 + helpers.CONFIG.minimalOperatorFee * 2, + ); + expect(await ssvViews.getOperatorEarnings(3)).to.equal( + helpers.CONFIG.minimalOperatorFee * 6 + helpers.CONFIG.minimalOperatorFee * 2, + ); + expect(await ssvViews.getOperatorEarnings(4)).to.equal( + helpers.CONFIG.minimalOperatorFee * 6 + helpers.CONFIG.minimalOperatorFee * 2, + ); }); it('Check cluster balance with removed operator', async () => { await ssvNetworkContract.removeOperator(1); - expect(await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster)).not.equals(0); + expect( + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), + ).not.equals(0); }); it('Check cluster balance with not enough balance', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation + 10); - expect(await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster)).to.be.equals(0); + expect( + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), + ).to.be.equals(0); }); it('Check cluster balance in a non liquidated cluster', async () => { await utils.progressBlocks(1); - expect(await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster)).to.equal(minDepositAmount - burnPerBlock); + expect( + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), + ).to.equal(minDepositAmount - burnPerBlock); }); it('Check cluster balance in a liquidated cluster reverts "ClusterIsLiquidated"', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation - 1); - const liquidatedCluster = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[6]).liquidate( - cluster1.args.owner, - cluster1.args.operatorIds, - cluster1.args.cluster - )); + const liquidatedCluster = await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[4]) + .liquidate(cluster1.args.owner, cluster1.args.operatorIds, cluster1.args.cluster), + ); const updatedCluster = liquidatedCluster.eventsByName.ClusterLiquidated[0].args; - expect(await ssvViews.isLiquidated(updatedCluster.owner, updatedCluster.operatorIds, updatedCluster.cluster)).to.equal(true); - await expect(ssvViews.getBalance(helpers.DB.owners[4].address, updatedCluster.operatorIds, updatedCluster.cluster)).to.be.revertedWithCustomError(ssvViews, 'ClusterIsLiquidated'); + expect( + await ssvViews.isLiquidated(updatedCluster.owner, updatedCluster.operatorIds, updatedCluster.cluster), + ).to.equal(true); + await expect( + ssvViews.getBalance(helpers.DB.owners[4].address, updatedCluster.operatorIds, updatedCluster.cluster), + ).to.be.revertedWithCustomError(ssvViews, 'ClusterIsLiquidated'); }); - it('Check operator earnings, cluster balances and network earnings"', async () => { + it('Check operator earnings, cluster balances and network earnings', async () => { // 2 exisiting clusters // update network fee // register a new validator with some shared operators @@ -132,9 +193,13 @@ describe('Balance Tests', () => { // progress blocks in the process await utils.progressBlocks(1); - expect(await ssvViews.getOperatorEarnings(1)).to.equal(helpers.CONFIG.minimalOperatorFee * 3 + helpers.CONFIG.minimalOperatorFee); - expect(await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster)).to.equal(minDepositAmount - burnPerBlock); - expect(await ssvViews.getNetworkEarnings() - initNetworkFeeBalance).to.equal(networkFee * 2); + expect(await ssvViews.getOperatorEarnings(1)).to.equal( + helpers.CONFIG.minimalOperatorFee * 3 + helpers.CONFIG.minimalOperatorFee, + ); + expect( + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), + ).to.equal(minDepositAmount - burnPerBlock); + expect((await ssvViews.getNetworkEarnings()) - initNetworkFeeBalance).to.equal(networkFee * 2); const newNetworkFee = networkFee * 2; await ssvNetworkContract.updateNetworkFee(newNetworkFee); @@ -142,35 +207,71 @@ describe('Balance Tests', () => { const newBurnPerBlock = helpers.CONFIG.minimalOperatorFee * 4 + newNetworkFee; await utils.progressBlocks(1); - expect(await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster)).to.equal(minDepositAmount - burnPerBlock * 2 - newBurnPerBlock); - expect(await ssvViews.getNetworkEarnings() - initNetworkFeeBalance).to.equal(networkFee * 4 + newNetworkFee * 2); + expect( + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), + ).to.equal(minDepositAmount - burnPerBlock * 2 - newBurnPerBlock); + expect((await ssvViews.getNetworkEarnings()) - initNetworkFeeBalance).to.equal(networkFee * 4 + newNetworkFee * 2); const minDep2 = minDepositAmount * 2; - const cluster2 = await helpers.registerValidators(4, 1, minDep2.toString(), [3, 4, 5, 6]); + const cluster2 = await helpers.registerValidators( + 4, + minDep2.toString(), + [2], + [3, 4, 5, 6], + helpers.getClusterForValidator(0, 0, 0, 0, true), + ); await utils.progressBlocks(2); - expect(await ssvViews.getOperatorEarnings(1)).to.equal(helpers.CONFIG.minimalOperatorFee * 8 + helpers.CONFIG.minimalOperatorFee * 8); - expect(await ssvViews.getOperatorEarnings(3)).to.equal(helpers.CONFIG.minimalOperatorFee * 8 + helpers.CONFIG.minimalOperatorFee * 8 + helpers.CONFIG.minimalOperatorFee * 2); - - expect(await ssvViews.getOperatorEarnings(5)).to.equal(helpers.CONFIG.minimalOperatorFee * 6 + helpers.CONFIG.minimalOperatorFee * 5); - expect(await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster)).to.equal(minDepositAmount - burnPerBlock * 2 - newBurnPerBlock * 5); - expect(await ssvViews.getBalance(helpers.DB.owners[4].address, cluster2.args.operatorIds, cluster2.args.cluster)).to.equal(minDep2 - newBurnPerBlock * 2); + expect(await ssvViews.getOperatorEarnings(1)).to.equal( + helpers.CONFIG.minimalOperatorFee * 8 + helpers.CONFIG.minimalOperatorFee * 8, + ); + expect(await ssvViews.getOperatorEarnings(3)).to.equal( + helpers.CONFIG.minimalOperatorFee * 8 + + helpers.CONFIG.minimalOperatorFee * 8 + + helpers.CONFIG.minimalOperatorFee * 2, + ); + + expect(await ssvViews.getOperatorEarnings(5)).to.equal( + helpers.CONFIG.minimalOperatorFee * 6 + helpers.CONFIG.minimalOperatorFee * 5, + ); + expect( + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), + ).to.equal(minDepositAmount - burnPerBlock * 2 - newBurnPerBlock * 5); + expect( + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster2.args.operatorIds, cluster2.args.cluster), + ).to.equal(minDep2 - newBurnPerBlock * 2); // cold cluster + cluster1 * networkFee (4) + (cold cluster + cluster1 * newNetworkFee (5 + 5)) + cluster2 * newNetworkFee (2) - expect(await ssvViews.getNetworkEarnings() - initNetworkFeeBalance).to.equal(networkFee * 4 + newNetworkFee * 5 + newNetworkFee * 4 + newNetworkFee * 3); + expect((await ssvViews.getNetworkEarnings()) - initNetworkFeeBalance).to.equal( + networkFee * 4 + newNetworkFee * 5 + newNetworkFee * 4 + newNetworkFee * 3, + ); await ssvNetworkContract.updateNetworkFee(networkFee); await utils.progressBlocks(4); - expect(await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster)).to.equal(minDepositAmount - burnPerBlock * 2 - newBurnPerBlock * 6 - burnPerBlock * 4); - expect(await ssvViews.getBalance(helpers.DB.owners[4].address, cluster2.args.operatorIds, cluster2.args.cluster)).to.equal(minDep2 - newBurnPerBlock * 3 - burnPerBlock * 4); - - expect(await ssvViews.getOperatorEarnings(1)).to.equal(helpers.CONFIG.minimalOperatorFee * 14 + helpers.CONFIG.minimalOperatorFee * 12); - expect(await ssvViews.getOperatorEarnings(3)).to.equal(helpers.CONFIG.minimalOperatorFee * 14 + helpers.CONFIG.minimalOperatorFee * 12 + helpers.CONFIG.minimalOperatorFee * 7); - expect(await ssvViews.getOperatorEarnings(5)).to.equal(helpers.CONFIG.minimalOperatorFee * 11 + helpers.CONFIG.minimalOperatorFee * 10); + expect( + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), + ).to.equal(minDepositAmount - burnPerBlock * 2 - newBurnPerBlock * 6 - burnPerBlock * 4); + expect( + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster2.args.operatorIds, cluster2.args.cluster), + ).to.equal(minDep2 - newBurnPerBlock * 3 - burnPerBlock * 4); + + expect(await ssvViews.getOperatorEarnings(1)).to.equal( + helpers.CONFIG.minimalOperatorFee * 14 + helpers.CONFIG.minimalOperatorFee * 12, + ); + expect(await ssvViews.getOperatorEarnings(3)).to.equal( + helpers.CONFIG.minimalOperatorFee * 14 + + helpers.CONFIG.minimalOperatorFee * 12 + + helpers.CONFIG.minimalOperatorFee * 7, + ); + expect(await ssvViews.getOperatorEarnings(5)).to.equal( + helpers.CONFIG.minimalOperatorFee * 11 + helpers.CONFIG.minimalOperatorFee * 10, + ); // cold cluster + cluster1 * networkFee (4) + (cold cluster + cluster1 * newNetworkFee (6 + 6)) + cluster2 * newNetworkFee (3) + (cold cluster + cluster1 + cluster2 * networkFee (4 + 4 + 4)) - expect(await ssvViews.getNetworkEarnings() - initNetworkFeeBalance).to.equal(networkFee * 4 + newNetworkFee * 6 + newNetworkFee * 6 + newNetworkFee * 3 + networkFee * 12); + expect((await ssvViews.getNetworkEarnings()) - initNetworkFeeBalance).to.equal( + networkFee * 4 + newNetworkFee * 6 + newNetworkFee * 6 + newNetworkFee * 3 + networkFee * 12, + ); }); it('Check operator earnings and cluster balance when reducing operator fee"', async () => { @@ -179,36 +280,75 @@ describe('Balance Tests', () => { await utils.progressBlocks(2); - expect(await ssvViews.getOperatorEarnings(1)).to.equal(helpers.CONFIG.minimalOperatorFee * 4 + helpers.CONFIG.minimalOperatorFee + newFee * 2); - expect(await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster)).to.equal(minDepositAmount - burnPerBlock - ((helpers.CONFIG.minimalOperatorFee * 3 + networkFee) * 2) - newFee * 2); + expect(await ssvViews.getOperatorEarnings(1)).to.equal( + helpers.CONFIG.minimalOperatorFee * 4 + helpers.CONFIG.minimalOperatorFee + newFee * 2, + ); + expect( + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), + ).to.equal(minDepositAmount - burnPerBlock - (helpers.CONFIG.minimalOperatorFee * 3 + networkFee) * 2 - newFee * 2); }); it('Check cluster balance after withdraw and deposit"', async () => { await utils.progressBlocks(1); - expect(await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster)).to.equal(minDepositAmount - burnPerBlock); - - await helpers.DB.ssvToken.connect(helpers.DB.owners[4]).approve(helpers.DB.ssvNetwork.contract.address, minDepositAmount * 2); - let validator2 = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).registerValidator( - helpers.DataGenerator.publicKey(3), - [1, 2, 3, 4], - helpers.DataGenerator.shares(4), - minDepositAmount * 2, - cluster1.args.cluster - )); + expect( + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), + ).to.equal(minDepositAmount - burnPerBlock); + + await helpers.DB.ssvToken + .connect(helpers.DB.owners[4]) + .approve(helpers.DB.ssvNetwork.contract.address, minDepositAmount * 2); + let validator2 = await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[4]) + .registerValidator( + helpers.DataGenerator.publicKey(3), + [1, 2, 3, 4], + helpers.DataGenerator.shares(4, 3, 4), + minDepositAmount * 2, + cluster1.args.cluster, + ), + ); let cluster2 = validator2.eventsByName.ValidatorAdded[0]; - expect(await ssvViews.getBalance(helpers.DB.owners[4].address, cluster2.args.operatorIds, cluster2.args.cluster)).to.equal(minDepositAmount * 3 - burnPerBlock * 3); + expect( + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster2.args.operatorIds, cluster2.args.cluster), + ).to.equal(minDepositAmount * 3 - burnPerBlock * 3); - validator2 = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).withdraw(cluster2.args.operatorIds, helpers.CONFIG.minimalOperatorFee, cluster2.args.cluster)); + validator2 = await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[4]) + .withdraw(cluster2.args.operatorIds, helpers.CONFIG.minimalOperatorFee, cluster2.args.cluster), + ); cluster2 = validator2.eventsByName.ClusterWithdrawn[0]; - expect(await ssvViews.getBalance(helpers.DB.owners[4].address, cluster2.args.operatorIds, cluster2.args.cluster)).to.equal(minDepositAmount * 3 - burnPerBlock * 4 - burnPerBlock - helpers.CONFIG.minimalOperatorFee); - - await helpers.DB.ssvToken.connect(helpers.DB.owners[4]).approve(helpers.DB.ssvNetwork.contract.address, minDepositAmount); - validator2 = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).deposit(helpers.DB.owners[4].address, cluster2.args.operatorIds, helpers.CONFIG.minimalOperatorFee, cluster2.args.cluster)); + expect( + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster2.args.operatorIds, cluster2.args.cluster), + ).to.equal(minDepositAmount * 3 - burnPerBlock * 4 - burnPerBlock - helpers.CONFIG.minimalOperatorFee); + + await helpers.DB.ssvToken + .connect(helpers.DB.owners[4]) + .approve(helpers.DB.ssvNetwork.contract.address, minDepositAmount); + validator2 = await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[4]) + .deposit( + helpers.DB.owners[4].address, + cluster2.args.operatorIds, + helpers.CONFIG.minimalOperatorFee, + cluster2.args.cluster, + ), + ); cluster2 = validator2.eventsByName.ClusterDeposited[0]; await utils.progressBlocks(2); - expect(await ssvViews.getBalance(helpers.DB.owners[4].address, cluster2.args.operatorIds, cluster2.args.cluster)).to.equal(minDepositAmount * 3 - burnPerBlock * 8 - burnPerBlock * 5 - helpers.CONFIG.minimalOperatorFee + helpers.CONFIG.minimalOperatorFee); + expect( + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster2.args.operatorIds, cluster2.args.cluster), + ).to.equal( + minDepositAmount * 3 - + burnPerBlock * 8 - + burnPerBlock * 5 - + helpers.CONFIG.minimalOperatorFee + + helpers.CONFIG.minimalOperatorFee, + ); }); -}); \ No newline at end of file +}); diff --git a/test/validators/others.ts b/test/validators/others.ts index 705e103c..3c7f5c5b 100644 --- a/test/validators/others.ts +++ b/test/validators/others.ts @@ -7,148 +7,166 @@ import { trackGas, GasGroup } from '../helpers/gas-usage'; let ssvNetworkContract: any, minDepositAmount: any, firstCluster: any; describe('Other Validator Tests', () => { - beforeEach(async () => { - // Initialize contract - const metadata = (await helpers.initializeContract()); - ssvNetworkContract = metadata.contract; - - minDepositAmount = (helpers.CONFIG.minimalBlocksBeforeLiquidation + 10) * helpers.CONFIG.minimalOperatorFee * 4; - - // Register operators - await helpers.registerOperators(0, 14, helpers.CONFIG.minimalOperatorFee); - - // Register a validator - // cold register - await helpers.coldRegisterValidator(); - - // first validator - await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); - const register = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(1), - [1, 2, 3, 4], - helpers.DataGenerator.shares(4), - minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true - } - ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); - firstCluster = register.eventsByName.ValidatorAdded[0].args; - }); - - it('Exiting a validator emits "ValidatorExited"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).exitValidator( - helpers.DataGenerator.publicKey(1), - firstCluster.operatorIds, - )).to.emit(ssvNetworkContract, 'ValidatorExited') - .withArgs(helpers.DB.owners[1].address, firstCluster.operatorIds, helpers.DataGenerator.publicKey(1)); - }); - - it('Exiting a validator gas limit', async () => { - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).exitValidator( - helpers.DataGenerator.publicKey(1), - firstCluster.operatorIds, - ), [GasGroup.VALIDATOR_EXIT]); - }); - - it('Exiting one of the validators in a cluster emits "ValidatorExited"', async () => { - await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(2), - [1, 2, 3, 4], - helpers.DataGenerator.shares(4), - minDepositAmount, - firstCluster.cluster - )); - - await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).exitValidator( - helpers.DataGenerator.publicKey(2), - firstCluster.operatorIds, - )).to.emit(ssvNetworkContract, 'ValidatorExited') - .withArgs(helpers.DB.owners[1].address, firstCluster.operatorIds, helpers.DataGenerator.publicKey(2)); - }); - - it('Exiting a removed validator reverts "ValidatorDoesNotExist"', async () => { - await ssvNetworkContract.connect(helpers.DB.owners[1]).removeValidator( - helpers.DataGenerator.publicKey(1), - firstCluster.operatorIds, - firstCluster.cluster - ); - - await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).exitValidator( - helpers.DataGenerator.publicKey(1), - firstCluster.operatorIds - )).to.be.revertedWithCustomError(ssvNetworkContract, 'ValidatorDoesNotExist'); - }); - - it('Exiting a non-existing validator reverts "ValidatorDoesNotExist"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).exitValidator( - helpers.DataGenerator.publicKey(12), - firstCluster.operatorIds - )).to.be.revertedWithCustomError(ssvNetworkContract, 'ValidatorDoesNotExist'); - }); - - it('Exiting a validator with empty operator list reverts "IncorrectValidatorState"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).exitValidator( - helpers.DataGenerator.publicKey(1), - [] - )).to.be.revertedWithCustomError(ssvNetworkContract, 'IncorrectValidatorState'); - }); - - it('Exiting a validator with empty public key reverts "ValidatorDoesNotExist"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).exitValidator( - '0x', - firstCluster.operatorIds - )).to.be.revertedWithCustomError(ssvNetworkContract, 'ValidatorDoesNotExist'); - }); - - it('Exiting a validator using the wrong account reverts "ValidatorDoesNotExist"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[2]).exitValidator( - helpers.DataGenerator.publicKey(1), - firstCluster.operatorIds - )).to.be.revertedWithCustomError(ssvNetworkContract, 'ValidatorDoesNotExist'); - }); - - it('Exiting a validator with incorrect operators (unsorted list) reverts with "IncorrectValidatorState"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).exitValidator( - helpers.DataGenerator.publicKey(1), - [4, 3, 2, 1] - )).to.be.revertedWithCustomError(ssvNetworkContract, 'IncorrectValidatorState'); - }); - - it('Exiting a validator with incorrect operators (too many operators) reverts with "IncorrectValidatorState"', async () => { - minDepositAmount = (helpers.CONFIG.minimalBlocksBeforeLiquidation + 10) * helpers.CONFIG.minimalOperatorFee * 13; - - await helpers.DB.ssvToken.connect(helpers.DB.owners[2]).approve(ssvNetworkContract.address, minDepositAmount); - const register = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[2]).registerValidator( - helpers.DataGenerator.publicKey(2), - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], - helpers.DataGenerator.shares(13), - minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true - } - )); - const secondCluster = register.eventsByName.ValidatorAdded[0].args; - - await expect(ssvNetworkContract.connect(helpers.DB.owners[2]).exitValidator( - helpers.DataGenerator.publicKey(2), - secondCluster.operatorIds, - )).to.emit(ssvNetworkContract, 'ValidatorExited') - .withArgs(helpers.DB.owners[2].address, secondCluster.operatorIds, helpers.DataGenerator.publicKey(2)); - }); - - it('Exiting a validator with incorrect operators reverts with "IncorrectValidatorState"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).exitValidator( - helpers.DataGenerator.publicKey(1), - [1, 2, 3, 5] - )).to.be.revertedWithCustomError(ssvNetworkContract, 'IncorrectValidatorState'); - }); -}); \ No newline at end of file + beforeEach(async () => { + // Initialize contract + const metadata = await helpers.initializeContract(); + ssvNetworkContract = metadata.contract; + + minDepositAmount = (helpers.CONFIG.minimalBlocksBeforeLiquidation + 10) * helpers.CONFIG.minimalOperatorFee * 4; + + // Register operators + await helpers.registerOperators(0, 14, helpers.CONFIG.minimalOperatorFee); + + // Register a validator + // cold register + await helpers.coldRegisterValidator(); + + // first validator + await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); + const register = await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .registerValidator( + helpers.DataGenerator.publicKey(1), + [1, 2, 3, 4], + helpers.DataGenerator.shares(1, 1, 4), + minDepositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true, + }, + ), + [GasGroup.REGISTER_VALIDATOR_NEW_STATE], + ); + firstCluster = register.eventsByName.ValidatorAdded[0].args; + }); + + it('Exiting a validator emits "ValidatorExited"', async () => { + await expect( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .exitValidator(helpers.DataGenerator.publicKey(1), firstCluster.operatorIds), + ) + .to.emit(ssvNetworkContract, 'ValidatorExited') + .withArgs(helpers.DB.owners[1].address, firstCluster.operatorIds, helpers.DataGenerator.publicKey(1)); + }); + + it('Exiting a validator gas limit', async () => { + await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .exitValidator(helpers.DataGenerator.publicKey(1), firstCluster.operatorIds), + [GasGroup.VALIDATOR_EXIT], + ); + }); + + it('Exiting one of the validators in a cluster emits "ValidatorExited"', async () => { + await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); + await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .registerValidator( + helpers.DataGenerator.publicKey(2), + [1, 2, 3, 4], + helpers.DataGenerator.shares(1, 2, 4), + minDepositAmount, + firstCluster.cluster, + ), + ); + + await expect( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .exitValidator(helpers.DataGenerator.publicKey(2), firstCluster.operatorIds), + ) + .to.emit(ssvNetworkContract, 'ValidatorExited') + .withArgs(helpers.DB.owners[1].address, firstCluster.operatorIds, helpers.DataGenerator.publicKey(2)); + }); + + it('Exiting a removed validator reverts "ValidatorDoesNotExist"', async () => { + await ssvNetworkContract + .connect(helpers.DB.owners[1]) + .removeValidator(helpers.DataGenerator.publicKey(1), firstCluster.operatorIds, firstCluster.cluster); + + await expect( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .exitValidator(helpers.DataGenerator.publicKey(1), firstCluster.operatorIds), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'ValidatorDoesNotExist'); + }); + + it('Exiting a non-existing validator reverts "ValidatorDoesNotExist"', async () => { + await expect( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .exitValidator(helpers.DataGenerator.publicKey(12), firstCluster.operatorIds), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'ValidatorDoesNotExist'); + }); + + it('Exiting a validator with empty operator list reverts "IncorrectValidatorState"', async () => { + await expect( + ssvNetworkContract.connect(helpers.DB.owners[1]).exitValidator(helpers.DataGenerator.publicKey(1), []), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'IncorrectValidatorState'); + }); + + it('Exiting a validator with empty public key reverts "ValidatorDoesNotExist"', async () => { + await expect( + ssvNetworkContract.connect(helpers.DB.owners[1]).exitValidator('0x', firstCluster.operatorIds), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'ValidatorDoesNotExist'); + }); + + it('Exiting a validator using the wrong account reverts "ValidatorDoesNotExist"', async () => { + await expect( + ssvNetworkContract + .connect(helpers.DB.owners[2]) + .exitValidator(helpers.DataGenerator.publicKey(1), firstCluster.operatorIds), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'ValidatorDoesNotExist'); + }); + + it('Exiting a validator with incorrect operators (unsorted list) reverts with "IncorrectValidatorState"', async () => { + await expect( + ssvNetworkContract.connect(helpers.DB.owners[1]).exitValidator(helpers.DataGenerator.publicKey(1), [4, 3, 2, 1]), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'IncorrectValidatorState'); + }); + + it('Exiting a validator with incorrect operators (too many operators) reverts with "IncorrectValidatorState"', async () => { + minDepositAmount = (helpers.CONFIG.minimalBlocksBeforeLiquidation + 10) * helpers.CONFIG.minimalOperatorFee * 13; + + await helpers.DB.ssvToken.connect(helpers.DB.owners[2]).approve(ssvNetworkContract.address, minDepositAmount); + const register = await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[2]) + .registerValidator( + helpers.DataGenerator.publicKey(2), + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], + helpers.DataGenerator.shares(2, 2, 13), + minDepositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true, + }, + ), + ); + const secondCluster = register.eventsByName.ValidatorAdded[0].args; + + await expect( + ssvNetworkContract + .connect(helpers.DB.owners[2]) + .exitValidator(helpers.DataGenerator.publicKey(2), secondCluster.operatorIds), + ) + .to.emit(ssvNetworkContract, 'ValidatorExited') + .withArgs(helpers.DB.owners[2].address, secondCluster.operatorIds, helpers.DataGenerator.publicKey(2)); + }); + + it('Exiting a validator with incorrect operators reverts with "IncorrectValidatorState"', async () => { + await expect( + ssvNetworkContract.connect(helpers.DB.owners[1]).exitValidator(helpers.DataGenerator.publicKey(1), [1, 2, 3, 5]), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'IncorrectValidatorState'); + }); +}); diff --git a/test/validators/register.ts b/test/validators/register.ts index 52f5f9c0..fe36cbff 100644 --- a/test/validators/register.ts +++ b/test/validators/register.ts @@ -9,7 +9,7 @@ let ssvNetworkContract: any, ssvViews: any, ssvToken: any, minDepositAmount: any describe('Register Validator Tests', () => { beforeEach(async () => { // Initialize contract - const metadata = (await helpers.initializeContract()); + const metadata = await helpers.initializeContract(); ssvNetworkContract = metadata.contract; ssvToken = metadata.ssvToken; ssvViews = metadata.ssvViews; @@ -20,503 +20,681 @@ describe('Register Validator Tests', () => { minDepositAmount = (helpers.CONFIG.minimalBlocksBeforeLiquidation + 2) * helpers.CONFIG.minimalOperatorFee * 13; // cold register - await helpers.DB.ssvToken.connect(helpers.DB.owners[6]).approve(helpers.DB.ssvNetwork.contract.address, '1000000000000000'); - cluster1 = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[6]).registerValidator( - helpers.DataGenerator.publicKey(90), - [1, 2, 3, 4], - helpers.DataGenerator.shares(4), - '1000000000000000', - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true - } - )); + await helpers.DB.ssvToken + .connect(helpers.DB.owners[6]) + .approve(helpers.DB.ssvNetwork.contract.address, '1000000000000000'); + cluster1 = await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[6]) + .registerValidator( + helpers.DataGenerator.publicKey(1), + [1, 2, 3, 4], + helpers.DataGenerator.shares(6, 1, 4), + '1000000000000000', + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true, + }, + ), + ); }); it('Register validator with 4 operators emits "ValidatorAdded"', async () => { await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); - await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(1), - [1, 2, 3, 4], - helpers.DataGenerator.shares(4), - minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true - } - )).to.emit(ssvNetworkContract, 'ValidatorAdded'); + await expect( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .registerValidator( + helpers.DataGenerator.publicKey(1), + [1, 2, 3, 4], + helpers.DataGenerator.shares(1, 1, 4), + minDepositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true, + }, + ), + ).to.emit(ssvNetworkContract, 'ValidatorAdded'); }); it('Register validator with 4 operators gas limit', async () => { await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); const balance = await ssvToken.balanceOf(ssvNetworkContract.address); - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(1), - helpers.DataGenerator.cluster.new(), - helpers.DataGenerator.shares(4), - minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true - } - ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .registerValidator( + helpers.DataGenerator.publicKey(1), + helpers.DataGenerator.cluster.new(), + helpers.DataGenerator.shares(1, 1, 4), + minDepositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true, + }, + ), + [GasGroup.REGISTER_VALIDATOR_NEW_STATE], + ); - expect(await ssvToken.balanceOf(ssvNetworkContract.address)).to.be.equal(balance.add(ethers.BigNumber.from(minDepositAmount))); + expect(await ssvToken.balanceOf(ssvNetworkContract.address)).to.be.equal( + balance.add(ethers.BigNumber.from(minDepositAmount)), + ); }); it('Register 2 validators into the same cluster gas limit', async () => { await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); - const { eventsByName } = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(1), - [1, 2, 3, 4], - helpers.DataGenerator.shares(4), - minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true - } - ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + const { eventsByName } = await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .registerValidator( + helpers.DataGenerator.publicKey(1), + [1, 2, 3, 4], + helpers.DataGenerator.shares(1, 1, 4), + minDepositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true, + }, + ), + [GasGroup.REGISTER_VALIDATOR_NEW_STATE], + ); const args = eventsByName.ValidatorAdded[0].args; await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(2), - [1, 2, 3, 4], - helpers.DataGenerator.shares(4), - minDepositAmount, - args.cluster - ), [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]); + await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .registerValidator( + helpers.DataGenerator.publicKey(2), + [1, 2, 3, 4], + helpers.DataGenerator.shares(1, 2, 4), + minDepositAmount, + args.cluster, + ), + [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER], + ); }); it('Register 2 validators into the same cluster and 1 validator into a new cluster gas limit', async () => { await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); - const { eventsByName } = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(1), - [1, 2, 3, 4], - helpers.DataGenerator.shares(4), - minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true - } - ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + const { eventsByName } = await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .registerValidator( + helpers.DataGenerator.publicKey(1), + [1, 2, 3, 4], + helpers.DataGenerator.shares(1, 1, 4), + minDepositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true, + }, + ), + [GasGroup.REGISTER_VALIDATOR_NEW_STATE], + ); const args = eventsByName.ValidatorAdded[0].args; await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(2), - [1, 2, 3, 4], - helpers.DataGenerator.shares(4), - minDepositAmount, - args.cluster - ), [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]); + await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .registerValidator( + helpers.DataGenerator.publicKey(2), + [1, 2, 3, 4], + helpers.DataGenerator.shares(1, 2, 4), + minDepositAmount, + args.cluster, + ), + [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER], + ); await helpers.DB.ssvToken.connect(helpers.DB.owners[2]).approve(ssvNetworkContract.address, minDepositAmount); - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[2]).registerValidator( - helpers.DataGenerator.publicKey(4), - [2, 3, 4, 5], - helpers.DataGenerator.shares(4), - minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true - } - ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[2]) + .registerValidator( + helpers.DataGenerator.publicKey(4), + [2, 3, 4, 5], + helpers.DataGenerator.shares(2, 4, 4), + minDepositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true, + }, + ), + [GasGroup.REGISTER_VALIDATOR_NEW_STATE], + ); }); it('Register 2 validators into the same cluster with one time deposit gas limit', async () => { - await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, `${minDepositAmount * 2}`); - const { eventsByName } = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(1), - [1, 2, 3, 4], - helpers.DataGenerator.shares(4), - `${minDepositAmount * 2}`, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true - } - ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + await helpers.DB.ssvToken + .connect(helpers.DB.owners[1]) + .approve(ssvNetworkContract.address, `${minDepositAmount * 2}`); + const { eventsByName } = await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .registerValidator( + helpers.DataGenerator.publicKey(1), + [1, 2, 3, 4], + helpers.DataGenerator.shares(1, 1, 4), + `${minDepositAmount * 2}`, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true, + }, + ), + [GasGroup.REGISTER_VALIDATOR_NEW_STATE], + ); const args = eventsByName.ValidatorAdded[0].args; - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(2), - [1, 2, 3, 4], - helpers.DataGenerator.shares(4), - 0, - args.cluster - ), [GasGroup.REGISTER_VALIDATOR_WITHOUT_DEPOSIT]); + await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .registerValidator( + helpers.DataGenerator.publicKey(2), + [1, 2, 3, 4], + helpers.DataGenerator.shares(1, 2, 4), + 0, + args.cluster, + ), + [GasGroup.REGISTER_VALIDATOR_WITHOUT_DEPOSIT], + ); }); // 7 operators it('Register validator with 7 operators gas limit', async () => { await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(1), - helpers.DataGenerator.cluster.new(7), - helpers.DataGenerator.shares(7), - minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true - } - ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]); + await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .registerValidator( + helpers.DataGenerator.publicKey(1), + helpers.DataGenerator.cluster.new(7), + helpers.DataGenerator.shares(1, 1, 7), + minDepositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true, + }, + ), + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7], + ); }); it('Register 2 validators with 7 operators into the same cluster gas limit', async () => { await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); - const { eventsByName } = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(1), - [1, 2, 3, 4, 5, 6, 7], - helpers.DataGenerator.shares(7), - minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true - } - ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]); + const { eventsByName } = await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .registerValidator( + helpers.DataGenerator.publicKey(1), + [1, 2, 3, 4, 5, 6, 7], + helpers.DataGenerator.shares(1, 1, 7), + minDepositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true, + }, + ), + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7], + ); const args = eventsByName.ValidatorAdded[0].args; await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(2), - [1, 2, 3, 4, 5, 6, 7], - helpers.DataGenerator.shares(7), - minDepositAmount, - args.cluster - ), [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER_7]); + await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .registerValidator( + helpers.DataGenerator.publicKey(2), + [1, 2, 3, 4, 5, 6, 7], + helpers.DataGenerator.shares(1, 2, 7), + minDepositAmount, + args.cluster, + ), + [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER_7], + ); }); it('Register 2 validators with 7 operators into the same cluster and 1 validator into a new cluster with 7 operators gas limit', async () => { await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); - const { eventsByName } = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(1), - [1, 2, 3, 4, 5, 6, 7], - helpers.DataGenerator.shares(7), - minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true - } - ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]); + const { eventsByName } = await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .registerValidator( + helpers.DataGenerator.publicKey(1), + [1, 2, 3, 4, 5, 6, 7], + helpers.DataGenerator.shares(1, 1, 7), + minDepositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true, + }, + ), + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7], + ); const args = eventsByName.ValidatorAdded[0].args; await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(2), - [1, 2, 3, 4, 5, 6, 7], - helpers.DataGenerator.shares(7), - minDepositAmount, - args.cluster - ), [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER_7]); + await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .registerValidator( + helpers.DataGenerator.publicKey(2), + [1, 2, 3, 4, 5, 6, 7], + helpers.DataGenerator.shares(1, 2, 7), + minDepositAmount, + args.cluster, + ), + [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER_7], + ); await helpers.DB.ssvToken.connect(helpers.DB.owners[2]).approve(ssvNetworkContract.address, minDepositAmount); - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[2]).registerValidator( - helpers.DataGenerator.publicKey(4), - [2, 3, 4, 5, 6, 7, 8], - helpers.DataGenerator.shares(7), - minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true - } - ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]); + await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[2]) + .registerValidator( + helpers.DataGenerator.publicKey(4), + [2, 3, 4, 5, 6, 7, 8], + helpers.DataGenerator.shares(2, 4, 7), + minDepositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true, + }, + ), + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7], + ); }); it('Register 2 validators with 7 operators into the same cluster with one time deposit gas limit', async () => { - await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, `${minDepositAmount * 2}`); - const { eventsByName } = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(1), - [1, 2, 3, 4, 5, 6, 7], - helpers.DataGenerator.shares(7), - `${minDepositAmount * 2}`, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true - } - ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]); + await helpers.DB.ssvToken + .connect(helpers.DB.owners[1]) + .approve(ssvNetworkContract.address, `${minDepositAmount * 2}`); + const { eventsByName } = await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .registerValidator( + helpers.DataGenerator.publicKey(1), + [1, 2, 3, 4, 5, 6, 7], + helpers.DataGenerator.shares(1, 1, 7), + `${minDepositAmount * 2}`, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true, + }, + ), + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7], + ); const args = eventsByName.ValidatorAdded[0].args; - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(2), - [1, 2, 3, 4, 5, 6, 7], - helpers.DataGenerator.shares(7), - 0, - args.cluster - ), [GasGroup.REGISTER_VALIDATOR_WITHOUT_DEPOSIT_7]); + await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .registerValidator( + helpers.DataGenerator.publicKey(2), + [1, 2, 3, 4, 5, 6, 7], + helpers.DataGenerator.shares(1, 2, 7), + 0, + args.cluster, + ), + [GasGroup.REGISTER_VALIDATOR_WITHOUT_DEPOSIT_7], + ); }); // 10 operators it('Register validator with 10 operators gas limit', async () => { await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(1), - helpers.DataGenerator.cluster.new(10), - helpers.DataGenerator.shares(10), - minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true - } - ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_10]); + await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .registerValidator( + helpers.DataGenerator.publicKey(1), + helpers.DataGenerator.cluster.new(10), + helpers.DataGenerator.shares(1, 1, 10), + minDepositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true, + }, + ), + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_10], + ); }); it('Register 2 validators with 10 operators into the same cluster gas limit', async () => { await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); - const { eventsByName } = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(1), - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], - helpers.DataGenerator.shares(10), - minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true - } - ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_10]); + const { eventsByName } = await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .registerValidator( + helpers.DataGenerator.publicKey(1), + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + helpers.DataGenerator.shares(1, 1, 10), + minDepositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true, + }, + ), + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_10], + ); const args = eventsByName.ValidatorAdded[0].args; await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(2), - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], - helpers.DataGenerator.shares(10), - minDepositAmount, - args.cluster - ), [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER_10]); + await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .registerValidator( + helpers.DataGenerator.publicKey(2), + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + helpers.DataGenerator.shares(1, 2, 10), + minDepositAmount, + args.cluster, + ), + [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER_10], + ); }); it('Register 2 validators with 10 operators into the same cluster and 1 validator into a new cluster with 10 operators gas limit', async () => { await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); - const { eventsByName } = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(1), - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], - helpers.DataGenerator.shares(10), - minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true - } - ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_10]); + const { eventsByName } = await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .registerValidator( + helpers.DataGenerator.publicKey(1), + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + helpers.DataGenerator.shares(1, 1, 10), + minDepositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true, + }, + ), + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_10], + ); const args = eventsByName.ValidatorAdded[0].args; await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(2), - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], - helpers.DataGenerator.shares(10), - minDepositAmount, - args.cluster - ), [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER_10]); + await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .registerValidator( + helpers.DataGenerator.publicKey(2), + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + helpers.DataGenerator.shares(1, 2, 10), + minDepositAmount, + args.cluster, + ), + [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER_10], + ); await helpers.DB.ssvToken.connect(helpers.DB.owners[2]).approve(ssvNetworkContract.address, minDepositAmount); - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[2]).registerValidator( - helpers.DataGenerator.publicKey(4), - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], - helpers.DataGenerator.shares(10), - minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true - } - ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_10]); + await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[2]) + .registerValidator( + helpers.DataGenerator.publicKey(4), + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + helpers.DataGenerator.shares(2, 4, 10), + minDepositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true, + }, + ), + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_10], + ); }); it('Register 2 validators with 10 operators into the same cluster with one time deposit gas limit', async () => { - await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, `${minDepositAmount * 2}`); - const { eventsByName } = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(1), - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], - helpers.DataGenerator.shares(10), - `${minDepositAmount * 2}`, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true - } - ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_10]); + await helpers.DB.ssvToken + .connect(helpers.DB.owners[1]) + .approve(ssvNetworkContract.address, `${minDepositAmount * 2}`); + const { eventsByName } = await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .registerValidator( + helpers.DataGenerator.publicKey(1), + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + helpers.DataGenerator.shares(1, 1, 10), + `${minDepositAmount * 2}`, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true, + }, + ), + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_10], + ); const args = eventsByName.ValidatorAdded[0].args; - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(2), - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], - helpers.DataGenerator.shares(10), - 0, - args.cluster - ), [GasGroup.REGISTER_VALIDATOR_WITHOUT_DEPOSIT_10]); + await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .registerValidator( + helpers.DataGenerator.publicKey(2), + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + helpers.DataGenerator.shares(1, 2, 10), + 0, + args.cluster, + ), + [GasGroup.REGISTER_VALIDATOR_WITHOUT_DEPOSIT_10], + ); }); // 13 operators it('Register validator with 13 operators gas limit', async () => { await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(1), - helpers.DataGenerator.cluster.new(13), - helpers.DataGenerator.shares(13), - minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true - } - ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]); + await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .registerValidator( + helpers.DataGenerator.publicKey(1), + helpers.DataGenerator.cluster.new(13), + helpers.DataGenerator.shares(1, 1, 13), + minDepositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true, + }, + ), + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13], + ); }); it('Register 2 validators with 13 operators into the same cluster gas limit', async () => { await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); - const { eventsByName } = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(1), - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], - helpers.DataGenerator.shares(13), - minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true - } - ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]); - + const { eventsByName } = await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .registerValidator( + helpers.DataGenerator.publicKey(1), + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], + helpers.DataGenerator.shares(1, 1, 13), + minDepositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true, + }, + ), + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13], + ); const args = eventsByName.ValidatorAdded[0].args; await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(2), - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], - helpers.DataGenerator.shares(13), - minDepositAmount, - args.cluster - ), [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER_13]); + await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .registerValidator( + helpers.DataGenerator.publicKey(2), + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], + helpers.DataGenerator.shares(1, 2, 13), + minDepositAmount, + args.cluster, + ), + [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER_13], + ); }); it('Register 2 validators with 13 operators into the same cluster and 1 validator into a new cluster with 13 operators gas limit', async () => { await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); - const { eventsByName } = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(1), - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], - helpers.DataGenerator.shares(13), - minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true - } - ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]); - + const { eventsByName } = await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .registerValidator( + helpers.DataGenerator.publicKey(1), + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], + helpers.DataGenerator.shares(1, 1, 13), + minDepositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true, + }, + ), + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13], + ); const args = eventsByName.ValidatorAdded[0].args; await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(2), - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], - helpers.DataGenerator.shares(13), - minDepositAmount, - args.cluster - ), [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER_13]); + await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .registerValidator( + helpers.DataGenerator.publicKey(2), + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], + helpers.DataGenerator.shares(1, 2, 13), + minDepositAmount, + args.cluster, + ), + [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER_13], + ); await helpers.DB.ssvToken.connect(helpers.DB.owners[2]).approve(ssvNetworkContract.address, minDepositAmount); - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[2]).registerValidator( - helpers.DataGenerator.publicKey(4), - [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], - helpers.DataGenerator.shares(13), - minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true - } - ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]); + await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[2]) + .registerValidator( + helpers.DataGenerator.publicKey(4), + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], + helpers.DataGenerator.shares(2, 4, 13), + minDepositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true, + }, + ), + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13], + ); }); it('Register 2 validators with 13 operators into the same cluster with one time deposit gas limit', async () => { - await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, `${minDepositAmount * 2}`); - const { eventsByName } = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(1), - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], - helpers.DataGenerator.shares(13), - `${minDepositAmount * 2}`, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true - } - ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]); + await helpers.DB.ssvToken + .connect(helpers.DB.owners[1]) + .approve(ssvNetworkContract.address, `${minDepositAmount * 2}`); + const { eventsByName } = await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .registerValidator( + helpers.DataGenerator.publicKey(1), + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], + helpers.DataGenerator.shares(1, 1, 13), + `${minDepositAmount * 2}`, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true, + }, + ), + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13], + ); const args = eventsByName.ValidatorAdded[0].args; - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(2), - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], - helpers.DataGenerator.shares(13), - 0, - args.cluster - ), [GasGroup.REGISTER_VALIDATOR_WITHOUT_DEPOSIT_13]); + await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .registerValidator( + helpers.DataGenerator.publicKey(2), + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], + helpers.DataGenerator.shares(1, 2, 13), + 0, + args.cluster, + ), + [GasGroup.REGISTER_VALIDATOR_WITHOUT_DEPOSIT_13], + ); }); it('Get cluster burn rate', async () => { @@ -524,312 +702,351 @@ describe('Register Validator Tests', () => { await ssvNetworkContract.updateNetworkFee(networkFee); let clusterData = cluster1.eventsByName.ValidatorAdded[0].args.cluster; - expect(await ssvViews.getBurnRate(helpers.DB.owners[6].address, [1, 2, 3, 4], clusterData)).to.equal((helpers.CONFIG.minimalOperatorFee * 4) + networkFee); - - await helpers.DB.ssvToken.connect(helpers.DB.owners[6]).approve(helpers.DB.ssvNetwork.contract.address, '1000000000000000'); - const validator2 = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[6]).registerValidator( - helpers.DataGenerator.publicKey(2), - [1, 2, 3, 4], - helpers.DataGenerator.shares(4), - '1000000000000000', - clusterData - )); + expect(await ssvViews.getBurnRate(helpers.DB.owners[6].address, [1, 2, 3, 4], clusterData)).to.equal( + helpers.CONFIG.minimalOperatorFee * 4 + networkFee, + ); + + await helpers.DB.ssvToken + .connect(helpers.DB.owners[6]) + .approve(helpers.DB.ssvNetwork.contract.address, '1000000000000000'); + const validator2 = await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[6]) + .registerValidator( + helpers.DataGenerator.publicKey(2), + [1, 2, 3, 4], + helpers.DataGenerator.shares(6, 2, 4), + '1000000000000000', + clusterData, + ), + ); clusterData = validator2.eventsByName.ValidatorAdded[0].args.cluster; - expect(await ssvViews.getBurnRate(helpers.DB.owners[6].address, [1, 2, 3, 4], clusterData)).to.equal(((helpers.CONFIG.minimalOperatorFee * 4) + networkFee) * 2); + expect(await ssvViews.getBurnRate(helpers.DB.owners[6].address, [1, 2, 3, 4], clusterData)).to.equal( + (helpers.CONFIG.minimalOperatorFee * 4 + networkFee) * 2, + ); }); it('Get cluster burn rate when one of the operators does not exist', async () => { const clusterData = cluster1.eventsByName.ValidatorAdded[0].args.cluster; - await expect(ssvViews.getBurnRate(helpers.DB.owners[6].address, [1, 2, 3, 41], clusterData)).to.be.revertedWithCustomError(ssvNetworkContract, 'ClusterDoesNotExists'); + await expect( + ssvViews.getBurnRate(helpers.DB.owners[6].address, [1, 2, 3, 41], clusterData), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'ClusterDoesNotExists'); }); it('Register validator with incorrect input data reverts "IncorrectClusterState"', async () => { - await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, `${minDepositAmount * 2}`); - await ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(2), - [1, 2, 3, 4], - helpers.DataGenerator.shares(4), - minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true - } - ); - - await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(3), - [1, 2, 3, 4], - helpers.DataGenerator.shares(4), - minDepositAmount, - { - validatorCount: 2, - networkFeeIndex: 10, - index: 0, - balance: 0, - active: true - } - )).to.be.revertedWithCustomError(ssvNetworkContract, 'IncorrectClusterState'); + await helpers.DB.ssvToken + .connect(helpers.DB.owners[1]) + .approve(ssvNetworkContract.address, `${minDepositAmount * 2}`); + await ssvNetworkContract + .connect(helpers.DB.owners[1]) + .registerValidator( + helpers.DataGenerator.publicKey(2), + [1, 2, 3, 4], + helpers.DataGenerator.shares(1, 2, 4), + minDepositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true, + }, + ); + + await expect( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .registerValidator( + helpers.DataGenerator.publicKey(3), + [1, 2, 3, 4], + helpers.DataGenerator.shares(1, 3, 4), + minDepositAmount, + { + validatorCount: 2, + networkFeeIndex: 10, + index: 0, + balance: 0, + active: true, + }, + ), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'IncorrectClusterState'); }); it('Register validator in a new cluster with incorrect input data reverts "IncorrectClusterState"', async () => { - await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, `${minDepositAmount * 2}`); - await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(3), - [1, 2, 3, 4], - helpers.DataGenerator.shares(4), - minDepositAmount, - { - validatorCount: 2, - networkFee: 10, - networkFeeIndex: 10, - index: 10, - balance: 10, - active: false - } - )).to.be.revertedWithCustomError(ssvNetworkContract, 'IncorrectClusterState'); + await helpers.DB.ssvToken + .connect(helpers.DB.owners[1]) + .approve(ssvNetworkContract.address, `${minDepositAmount * 2}`); + await expect( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .registerValidator( + helpers.DataGenerator.publicKey(3), + [1, 2, 3, 4], + helpers.DataGenerator.shares(1, 3, 4), + minDepositAmount, + { + validatorCount: 2, + networkFee: 10, + networkFeeIndex: 10, + index: 10, + balance: 10, + active: false, + }, + ), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'IncorrectClusterState'); }); it('Register validator when an operator does not exist in the cluster reverts "OperatorDoesNotExist"', async () => { - await expect(ssvNetworkContract.registerValidator( - helpers.DataGenerator.publicKey(2), - [1, 2, 3, 25], - helpers.DataGenerator.shares(4), - minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true - } - )).to.be.revertedWithCustomError(ssvNetworkContract, 'OperatorDoesNotExist'); + await expect( + ssvNetworkContract.registerValidator( + helpers.DataGenerator.publicKey(2), + [1, 2, 3, 25], + helpers.DataGenerator.shares(1, 2, 4), + minDepositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true, + }, + ), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'OperatorDoesNotExist'); }); it('Register validator with a removed operator in the cluster reverts "OperatorDoesNotExist"', async () => { await ssvNetworkContract.removeOperator(1); - await expect(ssvNetworkContract.registerValidator( - helpers.DataGenerator.publicKey(4), - [1, 2, 3, 4], - helpers.DataGenerator.shares(4), - minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true - } - )).to.be.revertedWithCustomError(ssvNetworkContract, 'OperatorDoesNotExist'); + await expect( + ssvNetworkContract.registerValidator( + helpers.DataGenerator.publicKey(4), + [1, 2, 3, 4], + helpers.DataGenerator.shares(0, 4, 4), + minDepositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true, + }, + ), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'OperatorDoesNotExist'); }); - it('Register cluster with unsorted operators reverts "UnsortedOperatorsList"', async () => { - await expect(helpers.registerValidators(2, 1, minDepositAmount, [3, 2, 1, 4])).to.be.revertedWithCustomError(ssvNetworkContract, 'UnsortedOperatorsList'); + await expect( + ssvNetworkContract.registerValidator( + helpers.DataGenerator.publicKey(1), + [3, 2, 1, 4], + helpers.DataGenerator.shares(0, 1, 4), + minDepositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true, + }, + ), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'UnsortedOperatorsList'); }); it('Register cluster with duplicated operators reverts "OperatorsListNotUnique"', async () => { - await expect(helpers.registerValidators(2, 1, minDepositAmount, [3, 6, 9, 12, 12, 17, 20])).to.be.revertedWithCustomError(ssvNetworkContract, 'OperatorsListNotUnique'); - }); - - it('Register validator into a cluster with an invalid amount of operators reverts "InvalidOperatorIdsLength"', async () => { - // 2 Operators - await expect(helpers.registerValidators(2, 1, minDepositAmount, [1, 2])).to.be.revertedWithCustomError(ssvNetworkContract, 'InvalidOperatorIdsLength'); - - // 6 Operators - await expect(helpers.registerValidators(2, 1, minDepositAmount, [1, 2, 3, 4, 5, 6])).to.be.revertedWithCustomError(ssvNetworkContract, 'InvalidOperatorIdsLength'); - - // 14 Operators - await expect(helpers.registerValidators(2, 1, minDepositAmount, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])).to.be.revertedWithCustomError(ssvNetworkContract, 'InvalidOperatorIdsLength'); - }); - - it('Register validator with an invalid public key length reverts "InvalidPublicKeyLength"', async () => { - await expect(ssvNetworkContract.registerValidator( - helpers.DataGenerator.shares(0), - [1, 2, 3, 4], - helpers.DataGenerator.shares(4), - minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true - } - )).to.be.revertedWithCustomError(ssvNetworkContract, 'InvalidPublicKeyLength'); + await expect( + ssvNetworkContract.registerValidator( + helpers.DataGenerator.publicKey(1), + [3, 6, 12, 12], + helpers.DataGenerator.shares(0, 5, 6), + minDepositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true, + }, + ), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'OperatorsListNotUnique'); }); it('Register validator with not enough balance reverts "InsufficientBalance"', async () => { await helpers.DB.ssvToken.approve(ssvNetworkContract.address, helpers.CONFIG.minimalOperatorFee); - await expect(ssvNetworkContract.registerValidator( - helpers.DataGenerator.publicKey(1), - [1, 2, 3, 4], - helpers.DataGenerator.shares(4), - helpers.CONFIG.minimalOperatorFee, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true - } - )).to.be.revertedWithCustomError(ssvNetworkContract, 'InsufficientBalance'); + await expect( + ssvNetworkContract.registerValidator( + helpers.DataGenerator.publicKey(1), + [1, 2, 3, 4], + helpers.DataGenerator.shares(0, 1, 4), + helpers.CONFIG.minimalOperatorFee, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true, + }, + ), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'InsufficientBalance'); }); it('Register validator in a liquidatable cluster with not enough balance reverts "InsufficientBalance"', async () => { const depositAmount = helpers.CONFIG.minimalBlocksBeforeLiquidation * helpers.CONFIG.minimalOperatorFee * 4; await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, depositAmount); - const { eventsByName } = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(1), - [1, 2, 3, 4], - helpers.DataGenerator.shares(4), - depositAmount, - { - validatorCount: 0, - networkFee: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true - } - )); + const { eventsByName } = await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .registerValidator( + helpers.DataGenerator.publicKey(1), + [1, 2, 3, 4], + helpers.DataGenerator.shares(1, 1, 4), + depositAmount, + { + validatorCount: 0, + networkFee: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true, + }, + ), + ); const cluster1 = eventsByName.ValidatorAdded[0].args; await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation + 10); - await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, helpers.CONFIG.minimalOperatorFee); - await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(2), - [1, 2, 3, 4], - helpers.DataGenerator.shares(3), - helpers.CONFIG.minimalOperatorFee, - cluster1.cluster - )).to.be.revertedWithCustomError(ssvNetworkContract, 'InsufficientBalance'); + await helpers.DB.ssvToken + .connect(helpers.DB.owners[1]) + .approve(ssvNetworkContract.address, helpers.CONFIG.minimalOperatorFee); + await expect( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .registerValidator( + helpers.DataGenerator.publicKey(2), + [1, 2, 3, 4], + helpers.DataGenerator.shares(1, 2, 4), + helpers.CONFIG.minimalOperatorFee, + cluster1.cluster, + ), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'InsufficientBalance'); }); - it('Register an existing validator with same operators setup reverts "ValidatorAlreadyExists"', async () => { - await helpers.DB.ssvToken.connect(helpers.DB.owners[6]).approve(ssvNetworkContract.address, helpers.CONFIG.minimalOperatorFee); - await expect(ssvNetworkContract.connect(helpers.DB.owners[6]).registerValidator( - helpers.DataGenerator.publicKey(90), - [1, 2, 3, 4], - helpers.DataGenerator.shares(4), - minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true - } - )).to.be.revertedWithCustomError(ssvNetworkContract, 'ValidatorAlreadyExists'); + await helpers.DB.ssvToken + .connect(helpers.DB.owners[6]) + .approve(ssvNetworkContract.address, helpers.CONFIG.minimalOperatorFee); + await expect( + ssvNetworkContract + .connect(helpers.DB.owners[6]) + .registerValidator( + helpers.DataGenerator.publicKey(1), + [1, 2, 3, 4], + helpers.DataGenerator.shares(6, 1, 4), + minDepositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true, + }, + ), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'ValidatorAlreadyExists'); }); it('Register an existing validator with different operators setup reverts "ValidatorAlreadyExists"', async () => { - await helpers.DB.ssvToken.connect(helpers.DB.owners[6]).approve(ssvNetworkContract.address, helpers.CONFIG.minimalOperatorFee); - await expect(ssvNetworkContract.connect(helpers.DB.owners[6]).registerValidator( - helpers.DataGenerator.publicKey(90), - [1, 2, 5, 6], - helpers.DataGenerator.shares(4), - minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true - } - )).to.be.revertedWithCustomError(ssvNetworkContract, 'ValidatorAlreadyExists'); - }); - - it('Surpassing max number of validators per operator reverts "ExceedValidatorLimit"', async () => { - await helpers.registerValidatorsRaw(2, 50, minDepositAmount, [8, 9, 10, 11]); - - const SSVNetworkValidatorsPerOperator = await ethers.getContractFactory("SSVNetworkValidatorsPerOperatorUpgrade"); - const ssvNetwork = await upgrades.upgradeProxy(ssvNetworkContract.address, SSVNetworkValidatorsPerOperator, { - kind: 'uups', - call: { - fn: 'initializev2', - args: [25] - } - }); - await ssvNetwork.deployed(); - - await helpers.DB.ssvToken.connect(helpers.DB.owners[6]).approve(ssvNetwork.address, minDepositAmount); - await expect(ssvNetwork.connect(helpers.DB.owners[6]).registerValidator( - helpers.DataGenerator.publicKey(55), - [8, 9, 12, 14], - helpers.DataGenerator.shares(4), - minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true - } - )).to.be.revertedWithCustomError(ssvNetwork, 'ExceedValidatorLimit'); - + await helpers.DB.ssvToken + .connect(helpers.DB.owners[6]) + .approve(ssvNetworkContract.address, helpers.CONFIG.minimalOperatorFee); + await expect( + ssvNetworkContract + .connect(helpers.DB.owners[6]) + .registerValidator( + helpers.DataGenerator.publicKey(1), + [1, 2, 5, 6], + helpers.DataGenerator.shares(6, 1, 4), + minDepositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true, + }, + ), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'ValidatorAlreadyExists'); }); it('Register whitelisted validator in 1 operator with 4 operators emits "ValidatorAdded"', async () => { - const result = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerOperator( - helpers.DataGenerator.publicKey(20), - helpers.CONFIG.minimalOperatorFee - )); + const result = await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .registerOperator(helpers.DataGenerator.publicKey(20), helpers.CONFIG.minimalOperatorFee), + ); const { operatorId } = result.eventsByName.OperatorAdded[0].args; - await ssvNetworkContract.connect(helpers.DB.owners[1]).setOperatorWhitelist(operatorId, helpers.DB.owners[3].address); + await ssvNetworkContract + .connect(helpers.DB.owners[1]) + .setOperatorWhitelist(operatorId, helpers.DB.owners[3].address); await helpers.DB.ssvToken.connect(helpers.DB.owners[3]).approve(ssvNetworkContract.address, minDepositAmount); - await expect(ssvNetworkContract.connect(helpers.DB.owners[3]).registerValidator( - helpers.DataGenerator.publicKey(1), - [1, 2, 3, operatorId], - helpers.DataGenerator.shares(4), - minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true - } - )).to.emit(ssvNetworkContract, 'ValidatorAdded'); + await expect( + ssvNetworkContract + .connect(helpers.DB.owners[3]) + .registerValidator( + helpers.DataGenerator.publicKey(1), + [1, 2, 3, operatorId], + helpers.DataGenerator.shares(3, 1, 4), + minDepositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true, + }, + ), + ).to.emit(ssvNetworkContract, 'ValidatorAdded'); }); it('Register a non whitelisted validator reverts "CallerNotWhitelisted"', async () => { - const result = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerOperator( - helpers.DataGenerator.publicKey(22), - helpers.CONFIG.minimalOperatorFee - )); + const result = await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .registerOperator(helpers.DataGenerator.publicKey(22), helpers.CONFIG.minimalOperatorFee), + ); const { operatorId } = result.eventsByName.OperatorAdded[0].args; - await ssvNetworkContract.connect(helpers.DB.owners[1]).setOperatorWhitelist(operatorId, helpers.DB.owners[3].address); + await ssvNetworkContract + .connect(helpers.DB.owners[1]) + .setOperatorWhitelist(operatorId, helpers.DB.owners[3].address); await helpers.DB.ssvToken.approve(ssvNetworkContract.address, minDepositAmount); - await expect(ssvNetworkContract.registerValidator( - helpers.DataGenerator.publicKey(1), - [1, 2, 3, operatorId], - helpers.DataGenerator.shares(4), - minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true - } - )).to.be.revertedWithCustomError(ssvNetworkContract, 'CallerNotWhitelisted'); + await expect( + ssvNetworkContract.registerValidator( + helpers.DataGenerator.publicKey(1), + [1, 2, 3, operatorId], + helpers.DataGenerator.shares(0, 1, 4), + minDepositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true, + }, + ), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'CallerNotWhitelisted'); }); it('Retrieve an existing validator', async () => { - expect(await ssvViews.getValidator(helpers.DB.owners[6].address, helpers.DataGenerator.publicKey(90))).to.be.equals(true); + expect(await ssvViews.getValidator(helpers.DB.owners[6].address, helpers.DataGenerator.publicKey(1))).to.be.equals( + true, + ); }); it('Retrieve a non-existing validator', async () => { - expect(await ssvViews.getValidator(helpers.DB.owners[2].address, helpers.DataGenerator.publicKey(90))).to.equal(false); + expect(await ssvViews.getValidator(helpers.DB.owners[2].address, helpers.DataGenerator.publicKey(1))).to.equal( + false, + ); }); }); diff --git a/test/validators/remove.ts b/test/validators/remove.ts index dbae9393..92fbadf6 100644 --- a/test/validators/remove.ts +++ b/test/validators/remove.ts @@ -10,7 +10,7 @@ let ssvNetworkContract: any, minDepositAmount: any, firstCluster: any; describe('Remove Validator Tests', () => { beforeEach(async () => { // Initialize contract - const metadata = (await helpers.initializeContract()); + const metadata = await helpers.initializeContract(); ssvNetworkContract = metadata.contract; minDepositAmount = (helpers.CONFIG.minimalBlocksBeforeLiquidation + 10) * helpers.CONFIG.minimalOperatorFee * 4; @@ -23,205 +23,196 @@ describe('Remove Validator Tests', () => { await helpers.coldRegisterValidator(); // first validator - await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); - const register = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(1), - [1, 2, 3, 4], - helpers.DataGenerator.shares(4), + const cluster = await helpers.registerValidators( + 1, minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true - } - ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); - firstCluster = register.eventsByName.ValidatorAdded[0].args; + [1], + [1, 2, 3, 4], + helpers.getClusterForValidator(0, 0, 0, 0, true), + [GasGroup.REGISTER_VALIDATOR_NEW_STATE], + ); + + firstCluster = cluster.args; }); it('Remove validator emits "ValidatorRemoved"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).removeValidator( - helpers.DataGenerator.publicKey(1), - firstCluster.operatorIds, - firstCluster.cluster - )).to.emit(ssvNetworkContract, 'ValidatorRemoved'); + await expect( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .removeValidator(helpers.DataGenerator.publicKey(1), firstCluster.operatorIds, firstCluster.cluster), + ).to.emit(ssvNetworkContract, 'ValidatorRemoved'); }); it('Remove validator after cluster liquidation period emits "ValidatorRemoved"', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation + 10); - await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).removeValidator( - helpers.DataGenerator.publicKey(1), - firstCluster.operatorIds, - firstCluster.cluster - )).to.emit(ssvNetworkContract, 'ValidatorRemoved'); + await expect( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .removeValidator(helpers.DataGenerator.publicKey(1), firstCluster.operatorIds, firstCluster.cluster), + ).to.emit(ssvNetworkContract, 'ValidatorRemoved'); }); it('Remove validator gas limit (4 operators cluster)', async () => { - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).removeValidator( - helpers.DataGenerator.publicKey(1), - firstCluster.operatorIds, - firstCluster.cluster - ), [GasGroup.REMOVE_VALIDATOR]); + await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .removeValidator(helpers.DataGenerator.publicKey(1), firstCluster.operatorIds, firstCluster.cluster), + [GasGroup.REMOVE_VALIDATOR], + ); }); it('Remove validator gas limit (7 operators cluster)', async () => { - await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount * 2); - - const register = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(2), + const cluster = await helpers.registerValidators( + 1, + (minDepositAmount * 2).toString(), + [2], [1, 2, 3, 4, 5, 6, 7], - helpers.DataGenerator.shares(7), - minDepositAmount * 2, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true - } - )); - firstCluster = register.eventsByName.ValidatorAdded[0].args; - - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).removeValidator( - helpers.DataGenerator.publicKey(2), - firstCluster.operatorIds, - firstCluster.cluster - ), [GasGroup.REMOVE_VALIDATOR_7]); + helpers.getClusterForValidator(0, 0, 0, 0, true), + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7], + ); + firstCluster = cluster.args; + + await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .removeValidator(helpers.DataGenerator.publicKey(2), firstCluster.operatorIds, firstCluster.cluster), + [GasGroup.REMOVE_VALIDATOR_7], + ); }); it('Remove validator gas limit (10 operators cluster)', async () => { - await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount * 3); - - const register = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(2), + const cluster = await helpers.registerValidators( + 1, + (minDepositAmount * 3).toString(), + [2], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], - helpers.DataGenerator.shares(10), - minDepositAmount * 3, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true - } - )); - firstCluster = register.eventsByName.ValidatorAdded[0].args; - - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).removeValidator( - helpers.DataGenerator.publicKey(2), - firstCluster.operatorIds, - firstCluster.cluster - ), [GasGroup.REMOVE_VALIDATOR_10]); + helpers.getClusterForValidator(0, 0, 0, 0, true), + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_10], + ); + firstCluster = cluster.args; + + await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .removeValidator(helpers.DataGenerator.publicKey(2), firstCluster.operatorIds, firstCluster.cluster), + [GasGroup.REMOVE_VALIDATOR_10], + ); }); it('Remove validator gas limit (13 operators cluster)', async () => { - await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount * 4); - - const register = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(2), + const cluster = await helpers.registerValidators( + 1, + (minDepositAmount * 4).toString(), + [2], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], - helpers.DataGenerator.shares(10), - minDepositAmount * 4, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true - } - )); - firstCluster = register.eventsByName.ValidatorAdded[0].args; - - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).removeValidator( - helpers.DataGenerator.publicKey(2), - firstCluster.operatorIds, - firstCluster.cluster - ), [GasGroup.REMOVE_VALIDATOR_13]); + helpers.getClusterForValidator(0, 0, 0, 0, true), + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13], + ); + firstCluster = cluster.args; + + await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .removeValidator(helpers.DataGenerator.publicKey(2), firstCluster.operatorIds, firstCluster.cluster), + [GasGroup.REMOVE_VALIDATOR_13], + ); }); it('Remove validator with a removed operator in the cluster', async () => { await trackGas(ssvNetworkContract.removeOperator(1), [GasGroup.REMOVE_OPERATOR_WITH_WITHDRAW]); - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).removeValidator( - helpers.DataGenerator.publicKey(1), - firstCluster.operatorIds, - firstCluster.cluster - ), [GasGroup.REMOVE_VALIDATOR]); + await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .removeValidator(helpers.DataGenerator.publicKey(1), firstCluster.operatorIds, firstCluster.cluster), + [GasGroup.REMOVE_VALIDATOR], + ); }); it('Register a removed validator and remove the same validator again', async () => { // Remove validator - const remove = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).removeValidator( - helpers.DataGenerator.publicKey(1), - firstCluster.operatorIds, - firstCluster.cluster - ), [GasGroup.REMOVE_VALIDATOR]); + const remove = await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .removeValidator(helpers.DataGenerator.publicKey(1), firstCluster.operatorIds, firstCluster.cluster), + [GasGroup.REMOVE_VALIDATOR], + ); const updatedCluster = remove.eventsByName.ValidatorRemoved[0].args; // Re-register validator - const newRegister = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(1), - updatedCluster.operatorIds, - helpers.DataGenerator.shares(4), - 0, - updatedCluster.cluster - ), [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]); + const newRegister = await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .registerValidator( + helpers.DataGenerator.publicKey(1), + updatedCluster.operatorIds, + helpers.DataGenerator.shares(1, 1, 4), + 0, + updatedCluster.cluster, + ), + [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER], + ); const afterRegisterCluster = newRegister.eventsByName.ValidatorAdded[0].args; // Remove the validator again - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).removeValidator( - helpers.DataGenerator.publicKey(1), - afterRegisterCluster.operatorIds, - afterRegisterCluster.cluster - ), [GasGroup.REMOVE_VALIDATOR]); + await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .removeValidator( + helpers.DataGenerator.publicKey(1), + afterRegisterCluster.operatorIds, + afterRegisterCluster.cluster, + ), + [GasGroup.REMOVE_VALIDATOR], + ); }); it('Remove validator from a liquidated cluster', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - const liquidatedCluster = await trackGas(ssvNetworkContract.liquidate( - firstCluster.owner, - firstCluster.operatorIds, - firstCluster.cluster - ), [GasGroup.LIQUIDATE_CLUSTER_4]); + const liquidatedCluster = await trackGas( + ssvNetworkContract.liquidate(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster), + [GasGroup.LIQUIDATE_CLUSTER_4], + ); const updatedCluster = liquidatedCluster.eventsByName.ClusterLiquidated[0].args; - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).removeValidator( - helpers.DataGenerator.publicKey(1), - updatedCluster.operatorIds, - updatedCluster.cluster - ), [GasGroup.REMOVE_VALIDATOR]); + await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .removeValidator(helpers.DataGenerator.publicKey(1), updatedCluster.operatorIds, updatedCluster.cluster), + [GasGroup.REMOVE_VALIDATOR], + ); }); it('Remove validator with an invalid owner reverts "ValidatorDoesNotExist"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[2]).removeValidator( - helpers.DataGenerator.publicKey(1), - firstCluster.operatorIds, - firstCluster.cluster - )).to.be.revertedWithCustomError(ssvNetworkContract, 'ValidatorDoesNotExist'); + await expect( + ssvNetworkContract + .connect(helpers.DB.owners[2]) + .removeValidator(helpers.DataGenerator.publicKey(1), firstCluster.operatorIds, firstCluster.cluster), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'ValidatorDoesNotExist'); }); it('Remove validator with an invalid operator setup reverts "IncorrectValidatorState"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).removeValidator( - helpers.DataGenerator.publicKey(1), - [1, 2, 3, 5], - firstCluster.cluster - )).to.be.revertedWithCustomError(ssvNetworkContract, 'IncorrectValidatorState'); + await expect( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .removeValidator(helpers.DataGenerator.publicKey(1), [1, 2, 3, 5], firstCluster.cluster), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'IncorrectValidatorState'); }); it('Remove the same validator twice reverts "ValidatorDoesNotExist"', async () => { // Remove validator - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).removeValidator( - helpers.DataGenerator.publicKey(1), - firstCluster.operatorIds, - firstCluster.cluster - ), [GasGroup.REMOVE_VALIDATOR]); + await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .removeValidator(helpers.DataGenerator.publicKey(1), firstCluster.operatorIds, firstCluster.cluster), + [GasGroup.REMOVE_VALIDATOR], + ); // Remove validator again - await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).removeValidator( - helpers.DataGenerator.publicKey(1), - firstCluster.operatorIds, - firstCluster.cluster - )).to.be.revertedWithCustomError(ssvNetworkContract, 'ValidatorDoesNotExist'); + await expect( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .removeValidator(helpers.DataGenerator.publicKey(1), firstCluster.operatorIds, firstCluster.cluster), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'ValidatorDoesNotExist'); }); -}); \ No newline at end of file +}); diff --git a/tsconfig.json b/tsconfig.json index 7dae5df1..f09655ec 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,8 +5,10 @@ "module": "commonjs", "strict": true, "esModuleInterop": true, - "outDir": "dist" + "outDir": "dist", + "resolveJsonModule": true, + "moduleResolution": "node" }, "include": ["./scripts", "./test"], "files": ["./hardhat.config.ts"] -} \ No newline at end of file +} From 4471f0533a1f35668ccf1159b99b5857f3c357e3 Mon Sep 17 00:00:00 2001 From: Mohsen-T <61871540+Mohsen-T@users.noreply.github.com> Date: Tue, 5 Dec 2023 11:02:34 +0000 Subject: [PATCH 11/38] [Update]: deployment tests and update task and documentation (#282) * fix: updated documentations --- docs/local-dev.md | 25 +++- docs/tasks.md | 3 + tasks/deploy.ts | 275 +++++++++++++++++++---------------------- tasks/update-module.ts | 38 +++--- 4 files changed, 174 insertions(+), 167 deletions(-) diff --git a/docs/local-dev.md b/docs/local-dev.md index 6a68f3bb..d57c216a 100644 --- a/docs/local-dev.md +++ b/docs/local-dev.md @@ -92,9 +92,19 @@ Open `.openzeppelin/.json` file and find `[impls..address]` value You will find 2 `[impls.]` entries, one for `SSVNetwork` and another for `SSVNetworkViews`. Run this verification process for both. -You can take it from the output of the `deploy-all.ts` script. +You can take it from the output of the `npx hardhat --network deploy:all` command. -To verify an implementation contract (SSVNetwork, SSVNetworkViews or any module), run this: +To verify a proxy contract (SSVNetwork, SSVNetworkViews), run this: + +```sh +npx hardhat verify --network +``` + +By verifying a contract using its proxy address, the verification process for both the proxy and the implementation contracts is conducted seamlessly. +The proxy contract is automatically linked to the implementation contract. +As a result, users will be able to view interfaces of both the proxy and the implementation contracts on the Etherscan website's contract page, ensuring comprehensive visibility and transparency. + +To verify a module contract (SSVClusters, SSVOperators, SSVDAO, SSVViews), run this: ```sh npx hardhat verify --network @@ -114,3 +124,14 @@ https://goerli.etherscan.io/address/0x227...#code ``` After this action, you can go to the proxy contract in Etherscan and start interacting with it. + +### How to resolve issues during the verification + +- Error: no such file or directory, open ‘…/artifacts/build-info/XXXX...XXXX.json’ + +This issue can be resolved by executing the following commands. + +```sh +npx hardhat clean +npx hardhat compile +``` diff --git a/docs/tasks.md b/docs/tasks.md index 7e595677..7d428809 100644 --- a/docs/tasks.md +++ b/docs/tasks.md @@ -97,6 +97,9 @@ Example: npx hardhat --network goerli_testnet upgrade:proxy --proxy-address 0x1234... --contract SSVNetworkV2 --init-function initializev2 param1 param2 ``` +It is crucial to verify the upgraded contract using its proxy address. +This ensures that users can interact with the correct, upgraded implementation on Etherscan. + ### Update a module Sometimes you only need to perform changes in the logic of a function of a module, add a private function or do something that doesn't affect other components in the architecture. Then you can use the task to update a module. diff --git a/tasks/deploy.ts b/tasks/deploy.ts index 8a3ad9b0..826cd2a1 100644 --- a/tasks/deploy.ts +++ b/tasks/deploy.ts @@ -1,5 +1,5 @@ -import { task, subtask, types } from "hardhat/config"; -import { SSVModules } from "./config"; +import { task, subtask, types } from 'hardhat/config'; +import { SSVModules } from './config'; /** @title Hardhat task to deploy all required contracts for SSVNetwork. @@ -15,32 +15,28 @@ The deployer account used will be the first one returned by ethers.getSigners(). Therefore, it should be appropriately configured in your Hardhat network configuration. This task assumes that the SSVModules enum and deployment tasks for individual contracts have been properly defined. */ -task("deploy:all", "Deploy SSVNetwork, SSVNetworkViews and module contracts") - .setAction(async ({ }, hre) => { - const [deployer] = await ethers.getSigners(); - console.log(`Deploying contracts with the account:${deployer.address}`); - - const ssvTokenAddress = await hre.run("deploy:mock-token"); - const operatorsModAddress = await hre.run("deploy:module", { module: SSVModules[SSVModules.SSVOperators] }); - const clustersModAddress = await hre.run("deploy:module", { module: SSVModules[SSVModules.SSVClusters] }); - const daoModAddress = await hre.run("deploy:module", { module: SSVModules[SSVModules.SSVDAO] }); - const viewsModAddress = await hre.run("deploy:module", { module: SSVModules[SSVModules.SSVViews] }); - - const { ssvNetworkProxyAddress: ssvNetworkAddress } = await hre.run("deploy:ssv-network", - { - operatorsModAddress, - clustersModAddress, - daoModAddress, - viewsModAddress, - ssvTokenAddress - }); - - await hre.run("deploy:ssv-network-views", - { - ssvNetworkAddress - }); - }); - +task('deploy:all', 'Deploy SSVNetwork, SSVNetworkViews and module contracts').setAction(async ({}, hre) => { + const [deployer] = await ethers.getSigners(); + console.log(`Deploying contracts with the account:${deployer.address}`); + + const ssvTokenAddress = await hre.run('deploy:mock-token'); + const operatorsModAddress = await hre.run('deploy:module', { module: SSVModules[SSVModules.SSVOperators] }); + const clustersModAddress = await hre.run('deploy:module', { module: SSVModules[SSVModules.SSVClusters] }); + const daoModAddress = await hre.run('deploy:module', { module: SSVModules[SSVModules.SSVDAO] }); + const viewsModAddress = await hre.run('deploy:module', { module: SSVModules[SSVModules.SSVViews] }); + + const { ssvNetworkProxyAddress: ssvNetworkAddress } = await hre.run('deploy:ssv-network', { + operatorsModAddress, + clustersModAddress, + daoModAddress, + viewsModAddress, + ssvTokenAddress, + }); + + await hre.run('deploy:ssv-network-views', { + ssvNetworkAddress, + }); +}); /** @title Hardhat task to deploy a main implementation contract for SSVNetwork or SSVNetworkViews. @@ -56,13 +52,11 @@ The deployer account used will be the first one returned by ethers.getSigners(). Therefore, it should be appropriately configured in your Hardhat network configuration. This task uses the "deploy:impl" subtask for the actual deployment. */ -task("deploy:main-impl", "Deploys SSVNetwork / SSVNetworkViews implementation contract") - .addParam("contract", "New contract implemetation", null, types.string) - .setAction(async ({ contract }, hre) => { - - await hre.run("deploy:impl", { contract }); - }); - +task('deploy:main-impl', 'Deploys SSVNetwork / SSVNetworkViews implementation contract') + .addParam('contract', 'New contract implemetation', null, types.string) + .setAction(async ({ contract }, hre) => { + await hre.run('deploy:impl', { contract }); + }); /** @title Hardhat subtask to deploy an SSV module contract. @@ -76,48 +70,45 @@ The deployer account used will be the first one returned by ethers.getSigners(). Therefore, it should be appropriately configured in your Hardhat network configuration. This subtask uses the "deploy:impl" subtask for the actual deployment. */ -subtask("deploy:module", "Deploys a new module contract") - .addParam("module", "SSV Module", null, types.string) - .setAction(async ({ module }, hre) => { - const moduleValues = Object.values(SSVModules); - if (!moduleValues.includes(module)) { - throw new Error(`Invalid SSVModule: ${module}. Expected one of: ${moduleValues.join(", ")}`); - } - - const moduleAddress = await hre.run("deploy:impl", { contract: module }); - return moduleAddress; - }); +subtask('deploy:module', 'Deploys a new module contract') + .addParam('module', 'SSV Module', null, types.string) + .setAction(async ({ module }, hre) => { + const moduleValues = Object.values(SSVModules); + if (!moduleValues.includes(module)) { + throw new Error(`Invalid SSVModule: ${module}. Expected one of: ${moduleValues.join(', ')}`); + } -task("deploy:token", "Deploys SSV Token") - .setAction(async ({ }, hre) => { - console.log('Deploying SSV Network Token'); + const moduleAddress = await hre.run('deploy:impl', { module }); + return moduleAddress; + }); - const ssvTokenFactory = await ethers.getContractFactory('SSVToken'); - const ssvToken = await ssvTokenFactory.deploy(); - await ssvToken.deployed(); +task('deploy:token', 'Deploys SSV Token').setAction(async ({}, hre) => { + console.log('Deploying SSV Network Token'); - console.log(`SSV Network Token deployed to: ${ssvToken.address}`); + const ssvTokenFactory = await ethers.getContractFactory('SSVToken'); + const ssvToken = await ssvTokenFactory.deploy(); + await ssvToken.deployed(); - }); + console.log(`SSV Network Token deployed to: ${ssvToken.address}`); +}); /** -* @title Hardhat subtask to deploy or fetch an SSV Token contract. -* The ssvToken parameter in the hardhat's network section, specifies the address of the SSV Token contract. -* If not provided, it will deploy a new MockToken contract. -* @returns {string} The address of the deployed or fetched SSV Token contract. -*/ -subtask("deploy:mock-token", "Deploys / fetch SSV Token") - .setAction(async ({ }, hre) => { - const tokenAddress = hre.network.config.ssvToken; - if (tokenAddress) return tokenAddress; - - // Local networks, deploy mock token - const ssvTokenFactory = await ethers.getContractFactory('SSVTokenMock'); - const ssvToken = await ssvTokenFactory.deploy(); - await ssvToken.deployed(); - - return ssvToken.address; - }); + * @title Hardhat subtask to deploy or fetch an SSV Token contract. + * The ssvToken parameter in the hardhat's network section, specifies the address of the SSV Token contract. + * If not provided, it will deploy a new MockToken contract. + * @returns {string} The address of the deployed or fetched SSV Token contract. + */ +subtask('deploy:mock-token', 'Deploys / fetch SSV Token').setAction(async ({}, hre) => { + const tokenAddress = hre.network.config.ssvToken; + if (tokenAddress) return tokenAddress; + + // Local networks, deploy mock token + const ssvTokenFactory = await ethers.getContractFactory('SSVTokenMock'); + const ssvToken = await ssvTokenFactory.deploy(); + await ssvToken.deployed(); + + return ssvToken.address; +}); /** @title Hardhat subtask to deploy a new implementation contract. @@ -130,19 +121,19 @@ The deployer account used will be the first one returned by ethers.getSigners(). Therefore, it should be appropriately configured in your Hardhat network configuration. The contract specified should be already compiled and exist in the 'artifacts' directory. */ -subtask("deploy:impl", "Deploys an implementation contract") - .addParam("contract", "New contract implemetation", null, types.string) - .setAction(async ({ contract }) => { - // Initialize contract - const contractFactory = await ethers.getContractFactory(contract); - - // Deploy implemetation contract - const contractImpl = await contractFactory.deploy(); - await contractImpl.deployed(); - console.log(`${contract} implementation deployed to: ${contractImpl.address}`); - - return contractImpl.address; - }); +subtask('deploy:impl', 'Deploys an implementation contract') + .addParam('contract', 'New contract implemetation', null, types.string) + .setAction(async ({ contract }) => { + // Initialize contract + const contractFactory = await ethers.getContractFactory(contract); + + // Deploy implemetation contract + const contractImpl = await contractFactory.deploy(); + await contractImpl.deployed(); + console.log(`${contract} implementation deployed to: ${contractImpl.address}`); + + return contractImpl.address; + }); /** @title Hardhat subtask to deploy the SSVNetwork contract. @@ -161,50 +152,46 @@ The deployer account used will be the first one returned by ethers.getSigners(). Therefore, it should be appropriately configured in your Hardhat network configuration. The 'SSVNetwork' contract specified should be already compiled and exist in the 'artifacts' directory. */ -subtask("deploy:ssv-network", "Deploys SSVNetwork contract") - .addPositionalParam("operatorsModAddress", "Operators module address", null, types.string) - .addPositionalParam("clustersModAddress", "Clusters module address", null, types.string) - .addPositionalParam("daoModAddress", "DAO module address", null, types.string) - .addPositionalParam("viewsModAddress", "Views module address", null, types.string) - .addPositionalParam("ssvTokenAddress", "SSV Token address", null, types.string) - .setAction(async ({ +subtask('deploy:ssv-network', 'Deploys SSVNetwork contract') + .addPositionalParam('operatorsModAddress', 'Operators module address', null, types.string) + .addPositionalParam('clustersModAddress', 'Clusters module address', null, types.string) + .addPositionalParam('daoModAddress', 'DAO module address', null, types.string) + .addPositionalParam('viewsModAddress', 'Views module address', null, types.string) + .addPositionalParam('ssvTokenAddress', 'SSV Token address', null, types.string) + .setAction(async ({ operatorsModAddress, clustersModAddress, daoModAddress, viewsModAddress, ssvTokenAddress }) => { + const ssvNetworkFactory = await ethers.getContractFactory('SSVNetwork'); + + // deploy SSVNetwork + console.log(`Deploying SSVNetwork with ssvToken ${ssvTokenAddress}`); + const ssvNetwork = await upgrades.deployProxy( + ssvNetworkFactory, + [ + ssvTokenAddress, operatorsModAddress, clustersModAddress, daoModAddress, viewsModAddress, - ssvTokenAddress }) => { - - - const ssvNetworkFactory = await ethers.getContractFactory('SSVNetwork'); - - // deploy SSVNetwork - console.log(`Deploying SSVNetwork with ssvToken ${ssvTokenAddress}`); - const ssvNetwork = await upgrades.deployProxy(ssvNetworkFactory, [ - ssvTokenAddress, - operatorsModAddress, - clustersModAddress, - daoModAddress, - viewsModAddress, - process.env.MINIMUM_BLOCKS_BEFORE_LIQUIDATION, - process.env.MINIMUM_LIQUIDATION_COLLATERAL, - process.env.VALIDATORS_PER_OPERATOR_LIMIT, - process.env.DECLARE_OPERATOR_FEE_PERIOD, - process.env.EXECUTE_OPERATOR_FEE_PERIOD, - process.env.OPERATOR_MAX_FEE_INCREASE - ], - { - kind: "uups" - }); - await ssvNetwork.deployed(); - - const ssvNetworkProxyAddress = ssvNetwork.address; - const ssvNetworkImplAddress = await upgrades.erc1967.getImplementationAddress(ssvNetwork.address); - - console.log(`SSVNetwork proxy deployed to: ${ssvNetworkProxyAddress}`); - console.log(`SSVNetwork implementation deployed to: ${ssvNetworkImplAddress}`); - - return { ssvNetworkProxyAddress, ssvNetworkImplAddress }; - }); + process.env.MINIMUM_BLOCKS_BEFORE_LIQUIDATION, + process.env.MINIMUM_LIQUIDATION_COLLATERAL, + process.env.VALIDATORS_PER_OPERATOR_LIMIT, + process.env.DECLARE_OPERATOR_FEE_PERIOD, + process.env.EXECUTE_OPERATOR_FEE_PERIOD, + process.env.OPERATOR_MAX_FEE_INCREASE, + ], + { + kind: 'uups', + }, + ); + await ssvNetwork.deployed(); + + const ssvNetworkProxyAddress = ssvNetwork.address; + const ssvNetworkImplAddress = await upgrades.erc1967.getImplementationAddress(ssvNetwork.address); + + console.log(`SSVNetwork proxy deployed to: ${ssvNetworkProxyAddress}`); + console.log(`SSVNetwork implementation deployed to: ${ssvNetworkImplAddress}`); + + return { ssvNetworkProxyAddress, ssvNetworkImplAddress }; + }); /** @title Hardhat subtask to deploy the SSVNetworkViews contract. @@ -217,26 +204,22 @@ The deployer account used will be the first one returned by ethers.getSigners(). Therefore, it should be appropriately configured in your Hardhat network configuration. The 'SSVNetworkViews' contract specified should be already compiled and exist in the 'artifacts' directory. */ -subtask("deploy:ssv-network-views", "Deploys SSVNetworkViews contract") - .addParam("ssvNetworkAddress", "SSVNetwork address", null, types.string) - .setAction(async ({ - ssvNetworkAddress }) => { - const ssvNetworkViewsFactory = await ethers.getContractFactory('SSVNetworkViews'); - - // deploy SSVNetwork - const ssvNetworkViews = await upgrades.deployProxy(ssvNetworkViewsFactory, [ - ssvNetworkAddress - ], - { - kind: "uups" - }); - await ssvNetworkViews.deployed(); - - const ssvNetworkViewsProxyAddress = ssvNetworkViews.address; - const ssvNetworkViewsImplAddress = await upgrades.erc1967.getImplementationAddress(ssvNetworkViews.address); - - console.log(`SSVNetworkViews proxy deployed to: ${ssvNetworkViewsProxyAddress}`); - console.log(`SSVNetworkViews implementation deployed to: ${ssvNetworkViewsImplAddress}`); - - return { ssvNetworkViewsProxyAddress, ssvNetworkViewsImplAddress }; +subtask('deploy:ssv-network-views', 'Deploys SSVNetworkViews contract') + .addParam('ssvNetworkAddress', 'SSVNetwork address', null, types.string) + .setAction(async ({ ssvNetworkAddress }) => { + const ssvNetworkViewsFactory = await ethers.getContractFactory('SSVNetworkViews'); + + // deploy SSVNetwork + const ssvNetworkViews = await upgrades.deployProxy(ssvNetworkViewsFactory, [ssvNetworkAddress], { + kind: 'uups', }); + await ssvNetworkViews.deployed(); + + const ssvNetworkViewsProxyAddress = ssvNetworkViews.address; + const ssvNetworkViewsImplAddress = await upgrades.erc1967.getImplementationAddress(ssvNetworkViews.address); + + console.log(`SSVNetworkViews proxy deployed to: ${ssvNetworkViewsProxyAddress}`); + console.log(`SSVNetworkViews implementation deployed to: ${ssvNetworkViewsImplAddress}`); + + return { ssvNetworkViewsProxyAddress, ssvNetworkViewsImplAddress }; + }); diff --git a/tasks/update-module.ts b/tasks/update-module.ts index f2221357..e8dbbeef 100644 --- a/tasks/update-module.ts +++ b/tasks/update-module.ts @@ -1,5 +1,5 @@ -import { task, types } from "hardhat/config"; -import { SSVModules } from "./config"; +import { task, types } from 'hardhat/config'; +import { SSVModules } from './config'; /** @title Hardhat task to update a module contract in the SSVNetwork. @@ -17,24 +17,24 @@ The deployer account used will be the first one returned by ethers.getSigners(). Therefore, it should be appropriately configured in your Hardhat network configuration. The module's contract specified should be already compiled and exist in the 'artifacts' directory. */ -task("update:module", "Deploys a new module contract and links it to SSVNetwork") - .addParam("module", "SSV Module", null, types.string) - .addOptionalParam("attachModule", "Attach module to SSVNetwork contract", false, types.boolean) - .addOptionalParam("proxyAddress", "Proxy address of SSVNetwork / SSVNetworkViews", '', types.string) - .setAction(async ({ module, attachModule, proxyAddress }, hre) => { - if (attachModule && !proxyAddress) throw new Error("SSVNetwork proxy address not set."); +task('update:module', 'Deploys a new module contract and links it to SSVNetwork') + .addParam('module', 'SSV Module', null, types.string) + .addOptionalParam('attachModule', 'Attach module to SSVNetwork contract', false, types.boolean) + .addOptionalParam('proxyAddress', 'Proxy address of SSVNetwork / SSVNetworkViews', '', types.string) + .setAction(async ({ module, attachModule, proxyAddress }, hre) => { + if (attachModule && !proxyAddress) throw new Error('SSVNetwork proxy address not set.'); - const [deployer] = await ethers.getSigners(); - console.log(`Deploying contracts with the account: ${deployer.address}`); - const moduleAddress = await hre.run("deploy:module", { module }); + const [deployer] = await ethers.getSigners(); + console.log(`Deploying contracts with the account: ${deployer.address}`); + const moduleAddress = await hre.run('deploy:module', { module }); - if (attachModule) { - if (!proxyAddress) throw new Error("SSVNetwork proxy address not set."); + if (attachModule) { + if (!proxyAddress) throw new Error('SSVNetwork proxy address not set.'); - const ssvNetworkFactory = await ethers.getContractFactory('SSVNetwork'); - const ssvNetwork = await ssvNetworkFactory.attach(proxyAddress); + const ssvNetworkFactory = await ethers.getContractFactory('SSVNetwork'); + const ssvNetwork = await ssvNetworkFactory.attach(proxyAddress); - await ssvNetwork.updateModule(SSVModules[module], moduleAddress); - console.log(`${module} module attached to SSVNetwork succesfully`); - } - }); \ No newline at end of file + await ssvNetwork.updateModule(SSVModules[module], moduleAddress); + console.log(`${module} module attached to SSVNetwork succesfully`); + } + }); From c9a90b10fc491c8854fefa12607338146096f7c3 Mon Sep 17 00:00:00 2001 From: Mohsen-T <61871540+Mohsen-T@users.noreply.github.com> Date: Tue, 5 Dec 2023 11:47:12 +0000 Subject: [PATCH 12/38] [Update] Added triggers for compilation in a few tasks (upgrading / updating) (#285) * feat: added trigger for compilation in tasks --- tasks/deploy.ts | 13 ++++++-- tasks/upgrade.ts | 77 ++++++++++++++++++++++++++---------------------- 2 files changed, 52 insertions(+), 38 deletions(-) diff --git a/tasks/deploy.ts b/tasks/deploy.ts index 826cd2a1..bf1f5dc7 100644 --- a/tasks/deploy.ts +++ b/tasks/deploy.ts @@ -16,6 +16,9 @@ Therefore, it should be appropriately configured in your Hardhat network configu This task assumes that the SSVModules enum and deployment tasks for individual contracts have been properly defined. */ task('deploy:all', 'Deploy SSVNetwork, SSVNetworkViews and module contracts').setAction(async ({}, hre) => { + // Triggering compilation + await hre.run('compile'); + const [deployer] = await ethers.getSigners(); console.log(`Deploying contracts with the account:${deployer.address}`); @@ -78,11 +81,14 @@ subtask('deploy:module', 'Deploys a new module contract') throw new Error(`Invalid SSVModule: ${module}. Expected one of: ${moduleValues.join(', ')}`); } - const moduleAddress = await hre.run('deploy:impl', { module }); + const moduleAddress = await hre.run('deploy:impl', { contract: module }); return moduleAddress; }); task('deploy:token', 'Deploys SSV Token').setAction(async ({}, hre) => { + // Triggering compilation + await hre.run('compile'); + console.log('Deploying SSV Network Token'); const ssvTokenFactory = await ethers.getContractFactory('SSVToken'); @@ -123,7 +129,10 @@ The contract specified should be already compiled and exist in the 'artifacts' d */ subtask('deploy:impl', 'Deploys an implementation contract') .addParam('contract', 'New contract implemetation', null, types.string) - .setAction(async ({ contract }) => { + .setAction(async ({ contract }, hre) => { + // Triggering compilation + await hre.run('compile'); + // Initialize contract const contractFactory = await ethers.getContractFactory(contract); diff --git a/tasks/upgrade.ts b/tasks/upgrade.ts index 30db9eef..d0ddccf4 100644 --- a/tasks/upgrade.ts +++ b/tasks/upgrade.ts @@ -1,4 +1,4 @@ -import { task, types } from "hardhat/config"; +import { task, types } from 'hardhat/config'; /** @title Hardhat task to upgrade a UUPS proxy contract. @@ -18,33 +18,36 @@ If 'initFunction' is not provided, this parameter has no effect. // Upgrade the SSVNetwork contract to a new version 'SSVNetworkV2', and call a function 'initializev2' with parameters after upgrade: npx hardhat --network goerli_testnet upgrade:proxy --proxyAddress 0x1234... --contract SSVNetworkV2 --initFunction initializev2 --params param1 param2 */ -task("upgrade:proxy", "Upgrade SSVNetwork / SSVNetworkViews proxy via hardhat upgrades plugin") - .addParam("proxyAddress", "Proxy address of SSVNetwork / SSVNetworkViews", null, types.string) - .addParam("contract", "New contract upgrade", null, types.string) - .addOptionalParam("initFunction", "Function to be executed after upgrading") - .addOptionalVariadicPositionalParam("params", "Function parameters") - .setAction(async ({ proxyAddress, contract, initFunction, params }) => { - const [deployer] = await ethers.getSigners(); - console.log(`Upgading ${proxyAddress} with the account: ${deployer.address}`); +task('upgrade:proxy', 'Upgrade SSVNetwork / SSVNetworkViews proxy via hardhat upgrades plugin') + .addParam('proxyAddress', 'Proxy address of SSVNetwork / SSVNetworkViews', null, types.string) + .addParam('contract', 'New contract upgrade', null, types.string) + .addOptionalParam('initFunction', 'Function to be executed after upgrading') + .addOptionalVariadicPositionalParam('params', 'Function parameters') + .setAction(async ({ proxyAddress, contract, initFunction, params }, hre) => { + // Triggering compilation + await hre.run('compile'); - const SSVUpgradeFactory = await ethers.getContractFactory(contract); + // Upgrading proxy + const [deployer] = await ethers.getSigners(); + console.log(`Upgading ${proxyAddress} with the account: ${deployer.address}`); - const ssvUpgrade = await upgrades.upgradeProxy(proxyAddress, SSVUpgradeFactory, - { - kind: 'uups', - call: initFunction - ? { - fn: initFunction, - args: params ? params : '' - } : - '' - }); - await ssvUpgrade.deployed(); - console.log(`${proxyAddress} upgraded successfully`); + const SSVUpgradeFactory = await ethers.getContractFactory(contract); - const implAddress = await upgrades.erc1967.getImplementationAddress(ssvUpgrade.address); - console.log(`Implementation deployed to: ${implAddress}`); + const ssvUpgrade = await upgrades.upgradeProxy(proxyAddress, SSVUpgradeFactory, { + kind: 'uups', + call: initFunction + ? { + fn: initFunction, + args: params ? params : '', + } + : '', }); + await ssvUpgrade.deployed(); + console.log(`${proxyAddress} upgraded successfully`); + + const implAddress = await upgrades.erc1967.getImplementationAddress(ssvUpgrade.address); + console.log(`Implementation deployed to: ${implAddress}`); + }); /** @title Hardhat task to prepare the upgrade of the SSVNetwork or SSVNetworkViews proxy contract. @@ -62,18 +65,20 @@ The deployer account used will be the first one returned by ethers.getSigners(). Therefore, it should be appropriately configured in your Hardhat network configuration. The new implementation contract specified should be already compiled and exist in the 'artifacts' directory. */ -task("upgrade:prepare", "Prepares the upgrade of SSVNetwork / SSVNetworkViews proxy") - .addParam("proxyAddress", "Proxy address of SSVNetwork / SSVNetworkViews", null, types.string) - .addParam("contract", "New contract upgrade", null, types.string) - .setAction(async ({ proxyAddress, contract }) => { - const [deployer] = await ethers.getSigners(); - console.log(`Preparing the upgrade of ${proxyAddress} with the account: ${deployer.address}`); +task('upgrade:prepare', 'Prepares the upgrade of SSVNetwork / SSVNetworkViews proxy') + .addParam('proxyAddress', 'Proxy address of SSVNetwork / SSVNetworkViews', null, types.string) + .addParam('contract', 'New contract upgrade', null, types.string) + .setAction(async ({ proxyAddress, contract }, hre) => { + // Triggering compilation + await hre.run('compile'); + + const [deployer] = await ethers.getSigners(); + console.log(`Preparing the upgrade of ${proxyAddress} with the account: ${deployer.address}`); - const SSVUpgradeFactory = await ethers.getContractFactory(contract); + const SSVUpgradeFactory = await ethers.getContractFactory(contract); - const implAddress = await upgrades.prepareUpgrade(proxyAddress, SSVUpgradeFactory, - { - kind: 'uups', - }); - console.log(`Implementation deployed to: ${implAddress}`); + const implAddress = await upgrades.prepareUpgrade(proxyAddress, SSVUpgradeFactory, { + kind: 'uups', }); + console.log(`Implementation deployed to: ${implAddress}`); + }); From 88e22a355fe69657f67c9a9c962e1d860cea27db Mon Sep 17 00:00:00 2001 From: Mohsen-T Date: Mon, 11 Dec 2023 05:20:06 +0100 Subject: [PATCH 13/38] fix: changed before test --- test/sanity/balances.ts | 111 +++++++++++++++++++++++----------------- 1 file changed, 64 insertions(+), 47 deletions(-) diff --git a/test/sanity/balances.ts b/test/sanity/balances.ts index 1774202a..6832ddb0 100644 --- a/test/sanity/balances.ts +++ b/test/sanity/balances.ts @@ -34,9 +34,14 @@ describe('Balance Tests', () => { // cold register await helpers.coldRegisterValidator(); - cluster1 = await helpers.registerValidators(0, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [ - GasGroup.REGISTER_VALIDATOR_NEW_STATE, - ]); + cluster1 = await helpers.registerValidators( + 4, + minDepositAmount, + [1], + helpers.DataGenerator.cluster.new(), + helpers.getClusterForValidator(0, 0, 0, 0, true), + [GasGroup.REGISTER_VALIDATOR_NEW_STATE], + ); initNetworkFeeBalance = await ssvViews.getNetworkEarnings(); }); @@ -46,7 +51,7 @@ describe('Balance Tests', () => { let prevBalance: any; for (let i = 1; i <= 13; i++) { await ssvNetworkContract.connect(helpers.DB.owners[0]).removeOperator(i); - let balance = await ssvViews.getBalance(helpers.DB.owners[0].address, operatorIds, cluster); + let balance = await ssvViews.getBalance(helpers.DB.owners[4].address, operatorIds, cluster); let networkFee = await ssvViews.getNetworkFee(); if (i > 4) { expect(prevBalance - balance).to.equal(networkFee); @@ -61,79 +66,85 @@ describe('Balance Tests', () => { const owner = cluster1.args.owner; // get difference of account balance between blocks before removing operator - let balance1 = await ssvViews.getBalance(helpers.DB.owners[0].address, operatorIds, cluster); + let balance1 = await ssvViews.getBalance(helpers.DB.owners[4].address, operatorIds, cluster); await utils.progressBlocks(1); - let balance2 = await ssvViews.getBalance(helpers.DB.owners[0].address, operatorIds, cluster); + let balance2 = await ssvViews.getBalance(helpers.DB.owners[4].address, operatorIds, cluster); await ssvNetworkContract.connect(helpers.DB.owners[0]).removeOperator(1); // get difference of account balance between blocks after removing operator - let balance3 = await ssvViews.getBalance(helpers.DB.owners[0].address, operatorIds, cluster); + let balance3 = await ssvViews.getBalance(helpers.DB.owners[4].address, operatorIds, cluster); await utils.progressBlocks(1); - let balance4 = await ssvViews.getBalance(helpers.DB.owners[0].address, operatorIds, cluster); + let balance4 = await ssvViews.getBalance(helpers.DB.owners[4].address, operatorIds, cluster); // check the reducing the balance after removing operator (only 3 operators) expect(balance1 - balance2).to.be.greaterThan(balance3 - balance4); // try to register a new validator in the new cluster with the same operator Ids, check revert const newOperatorIds = operatorIds.map((id: any) => id.toNumber()); - await expect(helpers.registerValidators(1, 1, minDepositAmount, newOperatorIds)).to.be.revertedWithCustomError( - ssvNetworkContract, - 'OperatorDoesNotExist', - ); + await expect( + helpers.registerValidators( + 1, + minDepositAmount, + [1], + newOperatorIds, + helpers.getClusterForValidator(0, 0, 0, 0, true), + [GasGroup.REGISTER_VALIDATOR_NEW_STATE], + ), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'OperatorDoesNotExist'); // try to remove the validator again and check the operator removed is skipped const removed = await trackGas( ssvNetworkContract - .connect(helpers.DB.owners[0]) + .connect(helpers.DB.owners[4]) .removeValidator(helpers.DataGenerator.publicKey(1), operatorIds, cluster), ); const cluster2 = removed.eventsByName.ValidatorRemoved[0]; // try to liquidate const liquidated = await trackGas( - ssvNetworkContract.connect(helpers.DB.owners[0]).liquidate(owner, operatorIds, cluster2.args.cluster), + ssvNetworkContract.connect(helpers.DB.owners[4]).liquidate(owner, operatorIds, cluster2.args.cluster), ); const cluster3 = liquidated.eventsByName.ClusterLiquidated[0]; await expect( - ssvViews.getBalance(helpers.DB.owners[0].address, operatorIds, cluster3.args.cluster), + ssvViews.getBalance(helpers.DB.owners[4].address, operatorIds, cluster3.args.cluster), ).to.be.revertedWithCustomError(ssvViews, 'ClusterIsLiquidated'); }); it('Check cluster balance in three blocks, one after the other', async () => { await utils.progressBlocks(1); expect( - await ssvViews.getBalance(helpers.DB.owners[0].address, cluster1.args.operatorIds, cluster1.args.cluster), + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), ).to.equal(minDepositAmount - burnPerBlock); await utils.progressBlocks(1); expect( - await ssvViews.getBalance(helpers.DB.owners[0].address, cluster1.args.operatorIds, cluster1.args.cluster), + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), ).to.equal(minDepositAmount - burnPerBlock * 2); await utils.progressBlocks(1); expect( - await ssvViews.getBalance(helpers.DB.owners[0].address, cluster1.args.operatorIds, cluster1.args.cluster), + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), ).to.equal(minDepositAmount - burnPerBlock * 3); }); it('Check cluster balance in two and twelve blocks, after network fee updates', async () => { await utils.progressBlocks(1); expect( - await ssvViews.getBalance(helpers.DB.owners[0].address, cluster1.args.operatorIds, cluster1.args.cluster), + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), ).to.equal(minDepositAmount - burnPerBlock); const newBurnPerBlock = burnPerBlock + networkFee; await ssvNetworkContract.updateNetworkFee(networkFee * 2); await utils.progressBlocks(1); expect( - await ssvViews.getBalance(helpers.DB.owners[0].address, cluster1.args.operatorIds, cluster1.args.cluster), + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), ).to.equal(minDepositAmount - burnPerBlock * 2 - newBurnPerBlock); await utils.progressBlocks(1); expect( - await ssvViews.getBalance(helpers.DB.owners[0].address, cluster1.args.operatorIds, cluster1.args.cluster), + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), ).to.equal(minDepositAmount - burnPerBlock * 2 - newBurnPerBlock * 2); await utils.progressBlocks(10); expect( - await ssvViews.getBalance(helpers.DB.owners[0].address, cluster1.args.operatorIds, cluster1.args.cluster), + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), ).to.equal(minDepositAmount - burnPerBlock * 2 - newBurnPerBlock * 12); }); @@ -205,21 +216,21 @@ describe('Balance Tests', () => { it('Check cluster balance with removed operator', async () => { await ssvNetworkContract.removeOperator(1); expect( - await ssvViews.getBalance(helpers.DB.owners[0].address, cluster1.args.operatorIds, cluster1.args.cluster), + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), ).not.equals(0); }); it('Check cluster balance with not enough balance', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation + 10); expect( - await ssvViews.getBalance(helpers.DB.owners[0].address, cluster1.args.operatorIds, cluster1.args.cluster), + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), ).to.be.equals(0); }); it('Check cluster balance in a non liquidated cluster', async () => { await utils.progressBlocks(1); expect( - await ssvViews.getBalance(helpers.DB.owners[0].address, cluster1.args.operatorIds, cluster1.args.cluster), + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), ).to.equal(minDepositAmount - burnPerBlock); }); @@ -227,7 +238,7 @@ describe('Balance Tests', () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation - 1); const liquidatedCluster = await trackGas( ssvNetworkContract - .connect(helpers.DB.owners[6]) + .connect(helpers.DB.owners[4]) .liquidate(cluster1.args.owner, cluster1.args.operatorIds, cluster1.args.cluster), ); const updatedCluster = liquidatedCluster.eventsByName.ClusterLiquidated[0].args; @@ -236,11 +247,11 @@ describe('Balance Tests', () => { await ssvViews.isLiquidated(updatedCluster.owner, updatedCluster.operatorIds, updatedCluster.cluster), ).to.equal(true); await expect( - ssvViews.getBalance(helpers.DB.owners[0].address, updatedCluster.operatorIds, updatedCluster.cluster), + ssvViews.getBalance(helpers.DB.owners[4].address, updatedCluster.operatorIds, updatedCluster.cluster), ).to.be.revertedWithCustomError(ssvViews, 'ClusterIsLiquidated'); }); - it('Check operator earnings, cluster balances and network earnings"', async () => { + it('Check operator earnings, cluster balances and network earnings', async () => { // 2 exisiting clusters // update network fee // register a new validator with some shared operators @@ -253,7 +264,7 @@ describe('Balance Tests', () => { helpers.CONFIG.minimalOperatorFee * 3 + helpers.CONFIG.minimalOperatorFee, ); expect( - await ssvViews.getBalance(helpers.DB.owners[0].address, cluster1.args.operatorIds, cluster1.args.cluster), + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), ).to.equal(minDepositAmount - burnPerBlock); expect((await ssvViews.getNetworkEarnings()) - initNetworkFeeBalance).to.equal(networkFee * 2); @@ -264,12 +275,18 @@ describe('Balance Tests', () => { await utils.progressBlocks(1); expect( - await ssvViews.getBalance(helpers.DB.owners[0].address, cluster1.args.operatorIds, cluster1.args.cluster), + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), ).to.equal(minDepositAmount - burnPerBlock * 2 - newBurnPerBlock); expect((await ssvViews.getNetworkEarnings()) - initNetworkFeeBalance).to.equal(networkFee * 4 + newNetworkFee * 2); const minDep2 = minDepositAmount * 2; - const cluster2 = await helpers.registerValidators(0, 1, minDep2.toString(), [3, 4, 5, 6]); + const cluster2 = await helpers.registerValidators( + 4, + minDep2.toString(), + [2], + [3, 4, 5, 6], + helpers.getClusterForValidator(0, 0, 0, 0, true), + ); await utils.progressBlocks(2); expect(await ssvViews.getOperatorEarnings(1)).to.equal( @@ -285,10 +302,10 @@ describe('Balance Tests', () => { helpers.CONFIG.minimalOperatorFee * 6 + helpers.CONFIG.minimalOperatorFee * 5, ); expect( - await ssvViews.getBalance(helpers.DB.owners[0].address, cluster1.args.operatorIds, cluster1.args.cluster), + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), ).to.equal(minDepositAmount - burnPerBlock * 2 - newBurnPerBlock * 5); expect( - await ssvViews.getBalance(helpers.DB.owners[0].address, cluster2.args.operatorIds, cluster2.args.cluster), + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster2.args.operatorIds, cluster2.args.cluster), ).to.equal(minDep2 - newBurnPerBlock * 2); // cold cluster + cluster1 * networkFee (4) + (cold cluster + cluster1 * newNetworkFee (5 + 5)) + cluster2 * newNetworkFee (2) @@ -300,10 +317,10 @@ describe('Balance Tests', () => { await utils.progressBlocks(4); expect( - await ssvViews.getBalance(helpers.DB.owners[0].address, cluster1.args.operatorIds, cluster1.args.cluster), + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), ).to.equal(minDepositAmount - burnPerBlock * 2 - newBurnPerBlock * 6 - burnPerBlock * 4); expect( - await ssvViews.getBalance(helpers.DB.owners[0].address, cluster2.args.operatorIds, cluster2.args.cluster), + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster2.args.operatorIds, cluster2.args.cluster), ).to.equal(minDep2 - newBurnPerBlock * 3 - burnPerBlock * 4); expect(await ssvViews.getOperatorEarnings(1)).to.equal( @@ -334,26 +351,26 @@ describe('Balance Tests', () => { helpers.CONFIG.minimalOperatorFee * 4 + helpers.CONFIG.minimalOperatorFee + newFee * 2, ); expect( - await ssvViews.getBalance(helpers.DB.owners[0].address, cluster1.args.operatorIds, cluster1.args.cluster), + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), ).to.equal(minDepositAmount - burnPerBlock - (helpers.CONFIG.minimalOperatorFee * 3 + networkFee) * 2 - newFee * 2); }); it('Check cluster balance after withdraw and deposit"', async () => { await utils.progressBlocks(1); expect( - await ssvViews.getBalance(helpers.DB.owners[0].address, cluster1.args.operatorIds, cluster1.args.cluster), + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), ).to.equal(minDepositAmount - burnPerBlock); await helpers.DB.ssvToken - .connect(helpers.DB.owners[0]) + .connect(helpers.DB.owners[4]) .approve(helpers.DB.ssvNetwork.contract.address, minDepositAmount * 2); let validator2 = await trackGas( ssvNetworkContract - .connect(helpers.DB.owners[0]) + .connect(helpers.DB.owners[4]) .registerValidator( helpers.DataGenerator.publicKey(3), [1, 2, 3, 4], - helpers.DataGenerator.shares(4), + helpers.DataGenerator.shares(4, 3, 4), minDepositAmount * 2, cluster1.args.cluster, ), @@ -361,28 +378,28 @@ describe('Balance Tests', () => { let cluster2 = validator2.eventsByName.ValidatorAdded[0]; expect( - await ssvViews.getBalance(helpers.DB.owners[0].address, cluster2.args.operatorIds, cluster2.args.cluster), + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster2.args.operatorIds, cluster2.args.cluster), ).to.equal(minDepositAmount * 3 - burnPerBlock * 3); validator2 = await trackGas( ssvNetworkContract - .connect(helpers.DB.owners[0]) + .connect(helpers.DB.owners[4]) .withdraw(cluster2.args.operatorIds, helpers.CONFIG.minimalOperatorFee, cluster2.args.cluster), ); cluster2 = validator2.eventsByName.ClusterWithdrawn[0]; expect( - await ssvViews.getBalance(helpers.DB.owners[0].address, cluster2.args.operatorIds, cluster2.args.cluster), + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster2.args.operatorIds, cluster2.args.cluster), ).to.equal(minDepositAmount * 3 - burnPerBlock * 4 - burnPerBlock - helpers.CONFIG.minimalOperatorFee); await helpers.DB.ssvToken - .connect(helpers.DB.owners[0]) + .connect(helpers.DB.owners[4]) .approve(helpers.DB.ssvNetwork.contract.address, minDepositAmount); validator2 = await trackGas( ssvNetworkContract - .connect(helpers.DB.owners[0]) + .connect(helpers.DB.owners[4]) .deposit( - helpers.DB.owners[0].address, + helpers.DB.owners[4].address, cluster2.args.operatorIds, helpers.CONFIG.minimalOperatorFee, cluster2.args.cluster, @@ -392,7 +409,7 @@ describe('Balance Tests', () => { await utils.progressBlocks(2); expect( - await ssvViews.getBalance(helpers.DB.owners[0].address, cluster2.args.operatorIds, cluster2.args.cluster), + await ssvViews.getBalance(helpers.DB.owners[4].address, cluster2.args.operatorIds, cluster2.args.cluster), ).to.equal( minDepositAmount * 3 - burnPerBlock * 8 - From c5b63db1eb602becc6ff728a85534590085cab9f Mon Sep 17 00:00:00 2001 From: Marco Tabasco Date: Tue, 12 Dec 2023 14:40:54 +0100 Subject: [PATCH 14/38] bulk validator registration (init) --- contracts/SSVNetwork.sol | 4 +- contracts/interfaces/ISSVClusters.sol | 8 ++-- contracts/interfaces/ISSVNetworkCore.sol | 1 + contracts/libraries/ValidatorLib.sol | 18 ++++++++ contracts/modules/SSVClusters.sol | 36 +++++++++------- contracts/test/SSVNetworkUpgrade.sol | 8 ++-- test/validators/register.ts | 53 +++++++++++++++++++++++- 7 files changed, 100 insertions(+), 28 deletions(-) diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index 3380af0a..e98e2b50 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -166,9 +166,9 @@ contract SSVNetwork is /*******************************/ function registerValidator( - bytes calldata publicKey, + bytes[] calldata publicKeys, uint64[] memory operatorIds, - bytes calldata sharesData, + bytes[] calldata shares, uint256 amount, ISSVNetworkCore.Cluster memory cluster ) external override { diff --git a/contracts/interfaces/ISSVClusters.sol b/contracts/interfaces/ISSVClusters.sol index b3d82d87..9633a5ef 100644 --- a/contracts/interfaces/ISSVClusters.sol +++ b/contracts/interfaces/ISSVClusters.sol @@ -5,15 +5,15 @@ import "./ISSVNetworkCore.sol"; interface ISSVClusters is ISSVNetworkCore { /// @notice Registers a new validator on the SSV Network - /// @param publicKey The public key of the new validator + /// @param publicKeys The public key of the new validator /// @param operatorIds Array of IDs of operators managing this validator - /// @param sharesData Encrypted shares related to the new validator + /// @param shares Encrypted shares related to the new validator /// @param amount Amount of SSV tokens to be deposited /// @param cluster Cluster to be used with the new validator function registerValidator( - bytes calldata publicKey, + bytes[] calldata publicKeys, uint64[] memory operatorIds, - bytes calldata sharesData, + bytes[] calldata shares, uint256 amount, Cluster memory cluster ) external; diff --git a/contracts/interfaces/ISSVNetworkCore.sol b/contracts/interfaces/ISSVNetworkCore.sol index 401d715b..fb2d0104 100644 --- a/contracts/interfaces/ISSVNetworkCore.sol +++ b/contracts/interfaces/ISSVNetworkCore.sol @@ -88,4 +88,5 @@ interface ISSVNetworkCore { error TargetModuleDoesNotExist(); // 0x8f9195fb error MaxValueExceeded(); // 0x91aa3017 error FeeTooHigh(); // 0xcd4e6167 + error PublicKeysSharesLengthMismatch(); // 0x9ad467b8 } diff --git a/contracts/libraries/ValidatorLib.sol b/contracts/libraries/ValidatorLib.sol index ad98ee5e..b8a8ee76 100644 --- a/contracts/libraries/ValidatorLib.sol +++ b/contracts/libraries/ValidatorLib.sol @@ -5,6 +5,24 @@ import "../interfaces/ISSVNetworkCore.sol"; import "./SSVStorage.sol"; library ValidatorLib { + uint64 private constant PUBLIC_KEY_LENGTH = 48; + + function registerPublicKeys(bytes[] calldata publicKeys, uint64[] memory operatorIds, StorageData storage s) internal { + for (uint i; i < publicKeys.length; ++i) { + if (publicKeys[i].length != PUBLIC_KEY_LENGTH) { + revert ISSVNetworkCore.InvalidPublicKeyLength(); + } + + bytes32 hashedPk = keccak256(abi.encodePacked(publicKeys[i], msg.sender)); + + if (s.validatorPKs[hashedPk] != bytes32(0)) { + revert ISSVNetworkCore.ValidatorAlreadyExists(); + } + + s.validatorPKs[hashedPk] = bytes32(uint256(keccak256(abi.encodePacked(operatorIds))) | uint256(0x01)); // set LSB to 1 + } + } + function validateState( bytes calldata publicKey, uint64[] calldata operatorIds, diff --git a/contracts/modules/SSVClusters.sol b/contracts/modules/SSVClusters.sol index b05355e2..a3fee023 100644 --- a/contracts/modules/SSVClusters.sol +++ b/contracts/modules/SSVClusters.sol @@ -17,19 +17,22 @@ contract SSVClusters is ISSVClusters { uint64 private constant MIN_OPERATORS_LENGTH = 4; uint64 private constant MAX_OPERATORS_LENGTH = 13; uint64 private constant MODULO_OPERATORS_LENGTH = 3; - uint64 private constant PUBLIC_KEY_LENGTH = 48; function registerValidator( - bytes calldata publicKey, + bytes[] calldata publicKeys, uint64[] memory operatorIds, - bytes calldata sharesData, + bytes[] calldata shares, uint256 amount, Cluster memory cluster ) external override { + if (publicKeys.length != shares.length) revert PublicKeysSharesLengthMismatch(); + StorageData storage s = SSVStorage.load(); StorageProtocol storage sp = SSVStorageProtocol.load(); uint256 operatorsLength = operatorIds.length; + uint32 validatorsLength = uint32(publicKeys.length); + { if ( operatorsLength < MIN_OPERATORS_LENGTH || @@ -39,15 +42,7 @@ contract SSVClusters is ISSVClusters { revert InvalidOperatorIdsLength(); } - if (publicKey.length != PUBLIC_KEY_LENGTH) revert InvalidPublicKeyLength(); - - bytes32 hashedPk = keccak256(abi.encodePacked(publicKey, msg.sender)); - - if (s.validatorPKs[hashedPk] != bytes32(0)) { - revert ValidatorAlreadyExists(); - } - - s.validatorPKs[hashedPk] = bytes32(uint256(keccak256(abi.encodePacked(operatorIds))) | uint256(0x01)); // set LSB to 1 + ValidatorLib.registerPublicKeys(publicKeys, operatorIds, s); } bytes32 hashedCluster = keccak256(abi.encodePacked(msg.sender, operatorIds)); @@ -100,7 +95,8 @@ contract SSVClusters is ISSVClusters { } } operator.updateSnapshot(); - if (++operator.validatorCount > sp.validatorsPerOperatorLimit) { + operator.validatorCount += validatorsLength; + if (operator.validatorCount > sp.validatorsPerOperatorLimit) { revert ExceedValidatorLimit(); } clusterIndex += operator.snapshot.index; @@ -114,10 +110,10 @@ contract SSVClusters is ISSVClusters { } cluster.updateClusterData(clusterIndex, sp.currentNetworkFeeIndex()); - sp.updateDAO(true, 1); + sp.updateDAO(true, validatorsLength); } - ++cluster.validatorCount; + cluster.validatorCount += validatorsLength; if ( cluster.isLiquidatable( @@ -136,7 +132,15 @@ contract SSVClusters is ISSVClusters { CoreLib.deposit(amount); } - emit ValidatorAdded(msg.sender, operatorIds, publicKey, sharesData, cluster); + for (uint i; i < validatorsLength; ) { + bytes memory pk = publicKeys[i]; + bytes memory sh = shares[i]; + emit ValidatorAdded(msg.sender, operatorIds, pk, sh, cluster); + + unchecked { + ++i; + } + } } function removeValidator( diff --git a/contracts/test/SSVNetworkUpgrade.sol b/contracts/test/SSVNetworkUpgrade.sol index c7288c17..3b62cdaf 100644 --- a/contracts/test/SSVNetworkUpgrade.sol +++ b/contracts/test/SSVNetworkUpgrade.sol @@ -189,19 +189,19 @@ contract SSVNetworkUpgrade is } function registerValidator( - bytes calldata publicKey, + bytes[] calldata publicKey, uint64[] memory operatorIds, - bytes calldata sharesData, + bytes[] calldata shares, uint256 amount, ISSVNetworkCore.Cluster memory cluster ) external override { _delegateCall( SSVStorage.load().ssvContracts[SSVModules.SSV_CLUSTERS], abi.encodeWithSignature( - "registerValidator(bytes,uint64[],bytes,uint256,(uint32,uint64,uint64,bool,uint256))", + "registerValidator(bytes[],uint64[],bytes,uint256,(uint32,uint64,uint64,bool,uint256))", publicKey, operatorIds, - sharesData, + shares, amount, cluster ) diff --git a/test/validators/register.ts b/test/validators/register.ts index 52f5f9c0..d385b1e6 100644 --- a/test/validators/register.ts +++ b/test/validators/register.ts @@ -3,6 +3,7 @@ import * as helpers from '../helpers/contract-helpers'; import * as utils from '../helpers/utils'; import { expect } from 'chai'; import { trackGas, GasGroup } from '../helpers/gas-usage'; +import { anyValue } from "@nomicfoundation/hardhat-chai-matchers/withArgs"; let ssvNetworkContract: any, ssvViews: any, ssvToken: any, minDepositAmount: any, cluster1: any; @@ -22,9 +23,9 @@ describe('Register Validator Tests', () => { // cold register await helpers.DB.ssvToken.connect(helpers.DB.owners[6]).approve(helpers.DB.ssvNetwork.contract.address, '1000000000000000'); cluster1 = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[6]).registerValidator( - helpers.DataGenerator.publicKey(90), + [helpers.DataGenerator.publicKey(90)], [1, 2, 3, 4], - helpers.DataGenerator.shares(4), + [helpers.DataGenerator.shares(4)], '1000000000000000', { validatorCount: 0, @@ -171,6 +172,54 @@ describe('Register Validator Tests', () => { ), [GasGroup.REGISTER_VALIDATOR_WITHOUT_DEPOSIT]); }); + it('Bulk register 2 validators with 4 operators into the same cluster', async () => { + const pks = [helpers.DataGenerator.publicKey(1), helpers.DataGenerator.publicKey(2)]; + const operatorIds = [1, 2, 3, 4]; + const shares = [helpers.DataGenerator.shares(4), helpers.DataGenerator.shares(4)]; + const depositAmount = minDepositAmount * 2; + + await helpers.DB.ssvToken.approve(ssvNetworkContract.address, depositAmount); + await expect(ssvNetworkContract.registerValidator( + pks, + operatorIds, + shares, + depositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true + } + )).to.emit(ssvNetworkContract, 'ValidatorAdded'); + }); + + it.only('Bulk register 10 validators with 4 operators into the same cluster', async () => { + const pks = Array.from({ length: 10 }, (_, index) => helpers.DataGenerator.publicKey(index + 1)); + const operatorIds = [1, 2, 3, 4]; + const shares = Array.from({ length: 10 }, (_, __) => helpers.DataGenerator.shares(4)); + + const depositAmount = minDepositAmount * 10; + + await helpers.DB.ssvToken.approve(ssvNetworkContract.address, depositAmount); + await expect(ssvNetworkContract.registerValidator( + pks, + operatorIds, + shares, + depositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true + } + )).to.emit(ssvNetworkContract, 'ValidatorAdded') + .withArgs(helpers.DB.owners[0].address,operatorIds, pks[0], shares[0],anyValue) + .and.to.emit(ssvNetworkContract, 'ValidatorAdded') + .withArgs(helpers.DB.owners[0].address,operatorIds, pks[1], shares[1],anyValue); + }); + // 7 operators it('Register validator with 7 operators gas limit', async () => { From d24c4a207b0ab04225e4ea520179ee89173933f1 Mon Sep 17 00:00:00 2001 From: Marco Tabasco Date: Wed, 13 Dec 2023 01:57:48 +0100 Subject: [PATCH 15/38] 2 register validator functions, all tests pass --- .openzeppelin/unknown-17000.json | 248 +++++++++++++++++++++++ contracts/SSVNetwork.sol | 12 +- contracts/interfaces/ISSVClusters.sol | 20 +- contracts/interfaces/ISSVNetworkCore.sol | 2 +- contracts/libraries/ValidatorLib.sol | 26 ++- contracts/modules/SSVClusters.sol | 118 ++++++++++- contracts/test/SSVNetworkUpgrade.sol | 20 ++ test/helpers/gas-usage.ts | 26 ++- test/validators/register.ts | 237 +++++++++++++++++++--- 9 files changed, 663 insertions(+), 46 deletions(-) diff --git a/.openzeppelin/unknown-17000.json b/.openzeppelin/unknown-17000.json index badd63e8..722498d0 100644 --- a/.openzeppelin/unknown-17000.json +++ b/.openzeppelin/unknown-17000.json @@ -20,6 +20,16 @@ "address": "0x352A18AEe90cdcd825d1E37d9939dCA86C00e281", "txHash": "0xf36e0e114031e961a1e3452477ed71658cf0f809be94832b4dc4a99a293ef664", "kind": "uups" + }, + { + "address": "0x4fA60408D9c0428b43FCa0E26c2f9aAa510cCeE2", + "txHash": "0x72d9a2c0e2442046a87816203f08b0ad4cb65ef25de40c59c5fe4f83b8834370", + "kind": "uups" + }, + { + "address": "0xEa0Fd295Be44Fb909d654dA90198c8E9d766FB74", + "txHash": "0x8cbbb4f8c3fa01e88d0aed6ffcccab3c063d332bf465541a4515fe3070177687", + "kind": "uups" } ], "impls": { @@ -366,6 +376,244 @@ } } } + }, + "a2e4bdeb66cec5b0f1a0fc4da857b0ca0211440ce18b5bd191e6a9b185e68499": { + "address": "0xe2a32e5501d4DdF3384b154caed0767f1a1eAdA5", + "txHash": "0x412ecc146a6550790a9140a97df6f3744b4f1e01e3f465717c0665abed59d045", + "layout": { + "solcVersion": "0.8.18", + "storage": [ + { + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_uint8", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:63", + "retypedFrom": "bool" + }, + { + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:68" + }, + { + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)50_storage", + "contract": "ERC1967UpgradeUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol:169" + }, + { + "label": "__gap", + "offset": 0, + "slot": "51", + "type": "t_array(t_uint256)50_storage", + "contract": "UUPSUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol:111" + }, + { + "label": "__gap", + "offset": 0, + "slot": "101", + "type": "t_array(t_uint256)50_storage", + "contract": "ContextUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" + }, + { + "label": "_owner", + "offset": 0, + "slot": "151", + "type": "t_address", + "contract": "OwnableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" + }, + { + "label": "__gap", + "offset": 0, + "slot": "152", + "type": "t_array(t_uint256)49_storage", + "contract": "OwnableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:94" + }, + { + "label": "_pendingOwner", + "offset": 0, + "slot": "201", + "type": "t_address", + "contract": "Ownable2StepUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol:27" + }, + { + "label": "__gap", + "offset": 0, + "slot": "202", + "type": "t_array(t_uint256)49_storage", + "contract": "Ownable2StepUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol:70" + } + ], + "types": { + "t_address": { + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_uint256)49_storage": { + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_array(t_uint256)50_storage": { + "label": "uint256[50]", + "numberOfBytes": "1600" + }, + "t_bool": { + "label": "bool", + "numberOfBytes": "1" + }, + "t_uint256": { + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint8": { + "label": "uint8", + "numberOfBytes": "1" + } + }, + "namespaces": {} + } + }, + "8a3382629da06790720d2d37ed76d51b1f949d6c3b17919f08f3b6842b9de108": { + "address": "0x559f1C453E01B91864864C9BBEB353916f4fF2EE", + "txHash": "0x5287d31696b60626b0e02ddb29ae27adc75ab7ad1311f1fe5181eb915e7413a4", + "layout": { + "solcVersion": "0.8.18", + "storage": [ + { + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_uint8", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:63", + "retypedFrom": "bool" + }, + { + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:68" + }, + { + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)50_storage", + "contract": "ERC1967UpgradeUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol:169" + }, + { + "label": "__gap", + "offset": 0, + "slot": "51", + "type": "t_array(t_uint256)50_storage", + "contract": "UUPSUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol:111" + }, + { + "label": "__gap", + "offset": 0, + "slot": "101", + "type": "t_array(t_uint256)50_storage", + "contract": "ContextUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" + }, + { + "label": "_owner", + "offset": 0, + "slot": "151", + "type": "t_address", + "contract": "OwnableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" + }, + { + "label": "__gap", + "offset": 0, + "slot": "152", + "type": "t_array(t_uint256)49_storage", + "contract": "OwnableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:94" + }, + { + "label": "_pendingOwner", + "offset": 0, + "slot": "201", + "type": "t_address", + "contract": "Ownable2StepUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol:27" + }, + { + "label": "__gap", + "offset": 0, + "slot": "202", + "type": "t_array(t_uint256)49_storage", + "contract": "Ownable2StepUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol:70" + }, + { + "label": "ssvNetwork", + "offset": 0, + "slot": "251", + "type": "t_contract(ISSVViews)4299", + "contract": "SSVNetworkViews", + "src": "contracts/SSVNetworkViews.sol:19" + }, + { + "label": "__gap", + "offset": 0, + "slot": "252", + "type": "t_array(t_uint256)50_storage", + "contract": "SSVNetworkViews", + "src": "contracts/SSVNetworkViews.sol:23" + } + ], + "types": { + "t_address": { + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_uint256)49_storage": { + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_array(t_uint256)50_storage": { + "label": "uint256[50]", + "numberOfBytes": "1600" + }, + "t_bool": { + "label": "bool", + "numberOfBytes": "1" + }, + "t_contract(ISSVViews)4299": { + "label": "contract ISSVViews", + "numberOfBytes": "20" + }, + "t_uint256": { + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint8": { + "label": "uint8", + "numberOfBytes": "1" + } + }, + "namespaces": {} + } } } } diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index e98e2b50..e6a058e4 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -166,9 +166,19 @@ contract SSVNetwork is /*******************************/ function registerValidator( + bytes calldata publicKey, + uint64[] memory operatorIds, + bytes calldata shares, + uint256 amount, + ISSVNetworkCore.Cluster memory cluster + ) external override { + _delegate(SSVStorage.load().ssvContracts[SSVModules.SSV_CLUSTERS]); + } + + function bulkRegisterValidator( bytes[] calldata publicKeys, uint64[] memory operatorIds, - bytes[] calldata shares, + bytes[] calldata sharesData, uint256 amount, ISSVNetworkCore.Cluster memory cluster ) external override { diff --git a/contracts/interfaces/ISSVClusters.sol b/contracts/interfaces/ISSVClusters.sol index 9633a5ef..ca6fb727 100644 --- a/contracts/interfaces/ISSVClusters.sol +++ b/contracts/interfaces/ISSVClusters.sol @@ -5,15 +5,29 @@ import "./ISSVNetworkCore.sol"; interface ISSVClusters is ISSVNetworkCore { /// @notice Registers a new validator on the SSV Network - /// @param publicKeys The public key of the new validator + /// @param publicKey The public key of the new validator /// @param operatorIds Array of IDs of operators managing this validator - /// @param shares Encrypted shares related to the new validator + /// @param sharesData Encrypted shares related to the new validator /// @param amount Amount of SSV tokens to be deposited /// @param cluster Cluster to be used with the new validator function registerValidator( + bytes calldata publicKey, + uint64[] memory operatorIds, + bytes calldata sharesData, + uint256 amount, + Cluster memory cluster + ) external; + + /// @notice Registers new validators on the SSV Network + /// @param publicKeys The public key of the new validator + /// @param operatorIds Array of IDs of operators managing this validator + /// @param sharesData Encrypted shares related to the new validator + /// @param amount Amount of SSV tokens to be deposited + /// @param cluster Cluster to be used with the new validator + function bulkRegisterValidator( bytes[] calldata publicKeys, uint64[] memory operatorIds, - bytes[] calldata shares, + bytes[] calldata sharesData, uint256 amount, Cluster memory cluster ) external; diff --git a/contracts/interfaces/ISSVNetworkCore.sol b/contracts/interfaces/ISSVNetworkCore.sol index fb2d0104..c577e402 100644 --- a/contracts/interfaces/ISSVNetworkCore.sol +++ b/contracts/interfaces/ISSVNetworkCore.sol @@ -41,7 +41,7 @@ interface ISSVNetworkCore { } /// @notice Represents a cluster of validators - struct Cluster { + struct Cluster { /// @dev The number of validators in the cluster uint32 validatorCount; /// @dev The index of network fees related to this cluster diff --git a/contracts/libraries/ValidatorLib.sol b/contracts/libraries/ValidatorLib.sol index b8a8ee76..08711c92 100644 --- a/contracts/libraries/ValidatorLib.sol +++ b/contracts/libraries/ValidatorLib.sol @@ -7,20 +7,28 @@ import "./SSVStorage.sol"; library ValidatorLib { uint64 private constant PUBLIC_KEY_LENGTH = 48; - function registerPublicKeys(bytes[] calldata publicKeys, uint64[] memory operatorIds, StorageData storage s) internal { + function registerPublicKeys( + bytes[] calldata publicKeys, + uint64[] memory operatorIds, + StorageData storage s + ) internal { for (uint i; i < publicKeys.length; ++i) { - if (publicKeys[i].length != PUBLIC_KEY_LENGTH) { - revert ISSVNetworkCore.InvalidPublicKeyLength(); - } + resgisterPublicKey(publicKeys[i], operatorIds, s); + } + } - bytes32 hashedPk = keccak256(abi.encodePacked(publicKeys[i], msg.sender)); + function resgisterPublicKey(bytes memory publicKey, uint64[] memory operatorIds, StorageData storage s) internal { + if (publicKey.length != PUBLIC_KEY_LENGTH) { + revert ISSVNetworkCore.InvalidPublicKeyLength(); + } - if (s.validatorPKs[hashedPk] != bytes32(0)) { - revert ISSVNetworkCore.ValidatorAlreadyExists(); - } + bytes32 hashedPk = keccak256(abi.encodePacked(publicKey, msg.sender)); - s.validatorPKs[hashedPk] = bytes32(uint256(keccak256(abi.encodePacked(operatorIds))) | uint256(0x01)); // set LSB to 1 + if (s.validatorPKs[hashedPk] != bytes32(0)) { + revert ISSVNetworkCore.ValidatorAlreadyExists(); } + + s.validatorPKs[hashedPk] = bytes32(uint256(keccak256(abi.encodePacked(operatorIds))) | uint256(0x01)); // set LSB to 1 } function validateState( diff --git a/contracts/modules/SSVClusters.sol b/contracts/modules/SSVClusters.sol index a3fee023..16d2f1f0 100644 --- a/contracts/modules/SSVClusters.sol +++ b/contracts/modules/SSVClusters.sol @@ -19,13 +19,125 @@ contract SSVClusters is ISSVClusters { uint64 private constant MODULO_OPERATORS_LENGTH = 3; function registerValidator( + bytes calldata publicKey, + uint64[] memory operatorIds, + bytes calldata sharesData, + uint256 amount, + Cluster memory cluster + ) external override { + StorageData storage s = SSVStorage.load(); + StorageProtocol storage sp = SSVStorageProtocol.load(); + + uint256 operatorsLength = operatorIds.length; + { + if ( + operatorsLength < MIN_OPERATORS_LENGTH || + operatorsLength > MAX_OPERATORS_LENGTH || + operatorsLength % MODULO_OPERATORS_LENGTH != 1 + ) { + revert InvalidOperatorIdsLength(); + } + + ValidatorLib.resgisterPublicKey(publicKey, operatorIds, s); + } + bytes32 hashedCluster = keccak256(abi.encodePacked(msg.sender, operatorIds)); + + { + bytes32 clusterData = s.clusters[hashedCluster]; + if (clusterData == bytes32(0)) { + if ( + cluster.validatorCount != 0 || + cluster.networkFeeIndex != 0 || + cluster.index != 0 || + cluster.balance != 0 || + !cluster.active + ) { + revert IncorrectClusterState(); + } + } else if (clusterData != cluster.hashClusterData()) { + revert IncorrectClusterState(); + } else { + cluster.validateClusterIsNotLiquidated(); + } + } + + cluster.balance += amount; + + uint64 burnRate; + + if (cluster.active) { + uint64 clusterIndex; + + for (uint256 i; i < operatorsLength; ) { + uint64 operatorId = operatorIds[i]; + { + if (i + 1 < operatorsLength) { + if (operatorId > operatorIds[i + 1]) { + revert UnsortedOperatorsList(); + } else if (operatorId == operatorIds[i + 1]) { + revert OperatorsListNotUnique(); + } + } + } + + Operator memory operator = s.operators[operatorId]; + if (operator.snapshot.block == 0) { + revert OperatorDoesNotExist(); + } + if (operator.whitelisted) { + address whitelisted = s.operatorsWhitelist[operatorId]; + if (whitelisted != address(0) && whitelisted != msg.sender) { + revert CallerNotWhitelisted(); + } + } + operator.updateSnapshot(); + if (++operator.validatorCount > sp.validatorsPerOperatorLimit) { + revert ExceedValidatorLimit(); + } + clusterIndex += operator.snapshot.index; + burnRate += operator.fee; + + s.operators[operatorId] = operator; + + unchecked { + ++i; + } + } + cluster.updateClusterData(clusterIndex, sp.currentNetworkFeeIndex()); + + sp.updateDAO(true, 1); + } + + ++cluster.validatorCount; + + if ( + cluster.isLiquidatable( + burnRate, + sp.networkFee, + sp.minimumBlocksBeforeLiquidation, + sp.minimumLiquidationCollateral + ) + ) { + revert InsufficientBalance(); + } + + s.clusters[hashedCluster] = cluster.hashClusterData(); + + if (amount != 0) { + CoreLib.deposit(amount); + } + + emit ValidatorAdded(msg.sender, operatorIds, publicKey, sharesData, cluster); + } + + function bulkRegisterValidator( bytes[] calldata publicKeys, uint64[] memory operatorIds, - bytes[] calldata shares, + bytes[] calldata sharesData, uint256 amount, Cluster memory cluster ) external override { - if (publicKeys.length != shares.length) revert PublicKeysSharesLengthMismatch(); + if (publicKeys.length != sharesData.length) revert PublicKeysSharesLengthMismatch(); StorageData storage s = SSVStorage.load(); StorageProtocol storage sp = SSVStorageProtocol.load(); @@ -134,7 +246,7 @@ contract SSVClusters is ISSVClusters { for (uint i; i < validatorsLength; ) { bytes memory pk = publicKeys[i]; - bytes memory sh = shares[i]; + bytes memory sh = sharesData[i]; emit ValidatorAdded(msg.sender, operatorIds, pk, sh, cluster); unchecked { diff --git a/contracts/test/SSVNetworkUpgrade.sol b/contracts/test/SSVNetworkUpgrade.sol index 3b62cdaf..924dc6ab 100644 --- a/contracts/test/SSVNetworkUpgrade.sol +++ b/contracts/test/SSVNetworkUpgrade.sol @@ -189,6 +189,26 @@ contract SSVNetworkUpgrade is } function registerValidator( + bytes calldata publicKey, + uint64[] memory operatorIds, + bytes calldata shares, + uint256 amount, + ISSVNetworkCore.Cluster memory cluster + ) external override { + _delegateCall( + SSVStorage.load().ssvContracts[SSVModules.SSV_CLUSTERS], + abi.encodeWithSignature( + "registerValidator(bytes[],uint64[],bytes,uint256,(uint32,uint64,uint64,bool,uint256))", + publicKey, + operatorIds, + shares, + amount, + cluster + ) + ); + } + + function bulkRegisterValidator( bytes[] calldata publicKey, uint64[] memory operatorIds, bytes[] calldata shares, diff --git a/test/helpers/gas-usage.ts b/test/helpers/gas-usage.ts index 534ec15e..8748530f 100644 --- a/test/helpers/gas-usage.ts +++ b/test/helpers/gas-usage.ts @@ -15,18 +15,30 @@ export enum GasGroup { REGISTER_VALIDATOR_NEW_STATE, REGISTER_VALIDATOR_WITHOUT_DEPOSIT, + BULK_REGISTER_10_VALIDATOR_NEW_STATE_4, + BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_4, + REGISTER_VALIDATOR_EXISTING_CLUSTER_7, REGISTER_VALIDATOR_NEW_STATE_7, REGISTER_VALIDATOR_WITHOUT_DEPOSIT_7, + BULK_REGISTER_10_VALIDATOR_NEW_STATE_7, + BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_7, + REGISTER_VALIDATOR_EXISTING_CLUSTER_10, REGISTER_VALIDATOR_NEW_STATE_10, REGISTER_VALIDATOR_WITHOUT_DEPOSIT_10, + BULK_REGISTER_10_VALIDATOR_NEW_STATE_10, + BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_10, + REGISTER_VALIDATOR_EXISTING_CLUSTER_13, REGISTER_VALIDATOR_NEW_STATE_13, REGISTER_VALIDATOR_WITHOUT_DEPOSIT_13, + BULK_REGISTER_10_VALIDATOR_NEW_STATE_13, + BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_13, + REMOVE_VALIDATOR, REMOVE_VALIDATOR_7, REMOVE_VALIDATOR_10, @@ -69,18 +81,30 @@ const MAX_GAS_PER_GROUP: any = { [GasGroup.REGISTER_VALIDATOR_NEW_STATE]: 221400, [GasGroup.REGISTER_VALIDATOR_WITHOUT_DEPOSIT]: 181600, + [GasGroup.BULK_REGISTER_10_VALIDATOR_NEW_STATE_4]: 889900, + [GasGroup.BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_4]: 814900, + [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER_7]: 272900, [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]: 289634, [GasGroup.REGISTER_VALIDATOR_WITHOUT_DEPOSIT_7]: 252500, + [GasGroup.BULK_REGISTER_10_VALIDATOR_NEW_STATE_7]: 891900, + [GasGroup.BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_7]: 875200, + [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER_10]: 343600, [GasGroup.REGISTER_VALIDATOR_NEW_STATE_10]: 360300, [GasGroup.REGISTER_VALIDATOR_WITHOUT_DEPOSIT_10]: 323000, + [GasGroup.BULK_REGISTER_10_VALIDATOR_NEW_STATE_10]: 952159, + [GasGroup.BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_10]: 935500, + [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER_13]: 414500, [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]: 431300, [GasGroup.REGISTER_VALIDATOR_WITHOUT_DEPOSIT_13]: 394000, + [GasGroup.BULK_REGISTER_10_VALIDATOR_NEW_STATE_13]: 1010500, + [GasGroup.BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_13]: 995706, + [GasGroup.REMOVE_VALIDATOR]: 113500, [GasGroup.REMOVE_VALIDATOR_7]: 155000, [GasGroup.REMOVE_VALIDATOR_10]: 196500, @@ -88,7 +112,7 @@ const MAX_GAS_PER_GROUP: any = { [GasGroup.DEPOSIT]: 77500, [GasGroup.WITHDRAW_CLUSTER_BALANCE]: 94500, [GasGroup.WITHDRAW_OPERATOR_BALANCE]: 64900, - [GasGroup.VALIDATOR_EXIT]: 42200, + [GasGroup.VALIDATOR_EXIT]: 42300, [GasGroup.LIQUIDATE_CLUSTER_4]: 129300, [GasGroup.LIQUIDATE_CLUSTER_7]: 170500, diff --git a/test/validators/register.ts b/test/validators/register.ts index d385b1e6..c5a936cb 100644 --- a/test/validators/register.ts +++ b/test/validators/register.ts @@ -23,9 +23,9 @@ describe('Register Validator Tests', () => { // cold register await helpers.DB.ssvToken.connect(helpers.DB.owners[6]).approve(helpers.DB.ssvNetwork.contract.address, '1000000000000000'); cluster1 = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[6]).registerValidator( - [helpers.DataGenerator.publicKey(90)], + helpers.DataGenerator.publicKey(90), [1, 2, 3, 4], - [helpers.DataGenerator.shares(4)], + helpers.DataGenerator.shares(4), '1000000000000000', { validatorCount: 0, @@ -172,18 +172,13 @@ describe('Register Validator Tests', () => { ), [GasGroup.REGISTER_VALIDATOR_WITHOUT_DEPOSIT]); }); - it('Bulk register 2 validators with 4 operators into the same cluster', async () => { - const pks = [helpers.DataGenerator.publicKey(1), helpers.DataGenerator.publicKey(2)]; - const operatorIds = [1, 2, 3, 4]; - const shares = [helpers.DataGenerator.shares(4), helpers.DataGenerator.shares(4)]; - const depositAmount = minDepositAmount * 2; - - await helpers.DB.ssvToken.approve(ssvNetworkContract.address, depositAmount); - await expect(ssvNetworkContract.registerValidator( - pks, - operatorIds, - shares, - depositAmount, + it('Bulk register 10 validators with 4 operators into the same cluster', async () => { + await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); + const { eventsByName } = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).bulkRegisterValidator( + [helpers.DataGenerator.publicKey(100)], + [1, 2, 3, 4], + [helpers.DataGenerator.shares(4)], + minDepositAmount, { validatorCount: 0, networkFeeIndex: 0, @@ -191,10 +186,25 @@ describe('Register Validator Tests', () => { balance: 0, active: true } - )).to.emit(ssvNetworkContract, 'ValidatorAdded'); + )); + + const args = eventsByName.ValidatorAdded[0].args; + + const pks = Array.from({ length: 10 }, (_, index) => helpers.DataGenerator.publicKey(index + 1)); + const shares = Array.from({ length: 10 }, (_, __) => helpers.DataGenerator.shares(4)); + const depositAmount = minDepositAmount * 10; + + await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, depositAmount); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).bulkRegisterValidator( + pks, + [1, 2, 3, 4], + shares, + depositAmount, + args.cluster + ), [GasGroup.BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_4]); }); - it.only('Bulk register 10 validators with 4 operators into the same cluster', async () => { + it('Bulk register 10 validators with 4 operators new cluster', async () => { const pks = Array.from({ length: 10 }, (_, index) => helpers.DataGenerator.publicKey(index + 1)); const operatorIds = [1, 2, 3, 4]; const shares = Array.from({ length: 10 }, (_, __) => helpers.DataGenerator.shares(4)); @@ -202,7 +212,7 @@ describe('Register Validator Tests', () => { const depositAmount = minDepositAmount * 10; await helpers.DB.ssvToken.approve(ssvNetworkContract.address, depositAmount); - await expect(ssvNetworkContract.registerValidator( + await trackGas(ssvNetworkContract.bulkRegisterValidator( pks, operatorIds, shares, @@ -214,21 +224,18 @@ describe('Register Validator Tests', () => { balance: 0, active: true } - )).to.emit(ssvNetworkContract, 'ValidatorAdded') - .withArgs(helpers.DB.owners[0].address,operatorIds, pks[0], shares[0],anyValue) - .and.to.emit(ssvNetworkContract, 'ValidatorAdded') - .withArgs(helpers.DB.owners[0].address,operatorIds, pks[1], shares[1],anyValue); + ), [GasGroup.BULK_REGISTER_10_VALIDATOR_NEW_STATE_4]); }); // 7 operators it('Register validator with 7 operators gas limit', async () => { - await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(1), - helpers.DataGenerator.cluster.new(7), - helpers.DataGenerator.shares(7), - minDepositAmount, + await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(helpers.DB.ssvNetwork.contract.address, '1000000000000000'); + cluster1 = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( + helpers.DataGenerator.publicKey(90), + [1, 2, 3, 4], + helpers.DataGenerator.shares(4), + '1000000000000000', { validatorCount: 0, networkFeeIndex: 0, @@ -236,7 +243,7 @@ describe('Register Validator Tests', () => { balance: 0, active: true } - ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]); + )); }); it('Register 2 validators with 7 operators into the same cluster gas limit', async () => { @@ -336,6 +343,64 @@ describe('Register Validator Tests', () => { ), [GasGroup.REGISTER_VALIDATOR_WITHOUT_DEPOSIT_7]); }); + it('Bulk register 10 validators with 7 operators into the same cluster', async () => { + const operatorIds = [1, 2, 3, 4, 5, 6, 7]; + + await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); + const { eventsByName } = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).bulkRegisterValidator( + [helpers.DataGenerator.publicKey(100)], + operatorIds, + [helpers.DataGenerator.shares(4)], + minDepositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true + } + )); + + const args = eventsByName.ValidatorAdded[0].args; + + const pks = Array.from({ length: 10 }, (_, index) => helpers.DataGenerator.publicKey(index + 1)); + const shares = Array.from({ length: 10 }, (_, __) => helpers.DataGenerator.shares(4)); + const depositAmount = minDepositAmount * 10; + + await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, depositAmount); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).bulkRegisterValidator( + pks, + operatorIds, + shares, + depositAmount, + args.cluster + ), [GasGroup.BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_7]); + }); + + it('Bulk register 10 validators with 7 operators new cluster', async () => { + const operatorIds = [1, 2, 3, 4, 5, 6, 7]; + + const pks = Array.from({ length: 10 }, (_, index) => helpers.DataGenerator.publicKey(index + 1)); + const shares = Array.from({ length: 10 }, (_, __) => helpers.DataGenerator.shares(4)); + + const depositAmount = minDepositAmount * 10; + + await helpers.DB.ssvToken.approve(ssvNetworkContract.address, depositAmount); + await trackGas(ssvNetworkContract.bulkRegisterValidator( + pks, + operatorIds, + shares, + depositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true + } + ), [GasGroup.BULK_REGISTER_10_VALIDATOR_NEW_STATE_4]); + }); + // 10 operators it('Register validator with 10 operators gas limit', async () => { @@ -452,6 +517,64 @@ describe('Register Validator Tests', () => { ), [GasGroup.REGISTER_VALIDATOR_WITHOUT_DEPOSIT_10]); }); + it('Bulk register 10 validators with 10 operators into the same cluster', async () => { + const operatorIds = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + + await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); + const { eventsByName } = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).bulkRegisterValidator( + [helpers.DataGenerator.publicKey(100)], + operatorIds, + [helpers.DataGenerator.shares(4)], + minDepositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true + } + )); + + const args = eventsByName.ValidatorAdded[0].args; + + const pks = Array.from({ length: 10 }, (_, index) => helpers.DataGenerator.publicKey(index + 1)); + const shares = Array.from({ length: 10 }, (_, __) => helpers.DataGenerator.shares(4)); + const depositAmount = minDepositAmount * 10; + + await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, depositAmount); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).bulkRegisterValidator( + pks, + operatorIds, + shares, + depositAmount, + args.cluster + ), [GasGroup.BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_10]); + }); + + it('Bulk register 10 validators with 10 operators new cluster', async () => { + const operatorIds = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + + const pks = Array.from({ length: 10 }, (_, index) => helpers.DataGenerator.publicKey(index + 1)); + const shares = Array.from({ length: 10 }, (_, __) => helpers.DataGenerator.shares(4)); + + const depositAmount = minDepositAmount * 10; + + await helpers.DB.ssvToken.approve(ssvNetworkContract.address, depositAmount); + await trackGas(ssvNetworkContract.bulkRegisterValidator( + pks, + operatorIds, + shares, + depositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true + } + ), [GasGroup.BULK_REGISTER_10_VALIDATOR_NEW_STATE_10]); + }); + // 13 operators it('Register validator with 13 operators gas limit', async () => { @@ -568,6 +691,64 @@ describe('Register Validator Tests', () => { ), [GasGroup.REGISTER_VALIDATOR_WITHOUT_DEPOSIT_13]); }); + it('Bulk register 10 validators with 13 operators into the same cluster', async () => { + const operatorIds = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]; + + await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); + const { eventsByName } = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).bulkRegisterValidator( + [helpers.DataGenerator.publicKey(100)], + operatorIds, + [helpers.DataGenerator.shares(4)], + minDepositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true + } + )); + + const args = eventsByName.ValidatorAdded[0].args; + + const pks = Array.from({ length: 10 }, (_, index) => helpers.DataGenerator.publicKey(index + 1)); + const shares = Array.from({ length: 10 }, (_, __) => helpers.DataGenerator.shares(4)); + const depositAmount = minDepositAmount * 10; + + await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, depositAmount); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).bulkRegisterValidator( + pks, + operatorIds, + shares, + depositAmount, + args.cluster + ), [GasGroup.BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_13]); + }); + + it('Bulk register 10 validators with 13 operators new cluster', async () => { + const operatorIds = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]; + + const pks = Array.from({ length: 10 }, (_, index) => helpers.DataGenerator.publicKey(index + 1)); + const shares = Array.from({ length: 10 }, (_, __) => helpers.DataGenerator.shares(4)); + + const depositAmount = minDepositAmount * 10; + + await helpers.DB.ssvToken.approve(ssvNetworkContract.address, depositAmount); + await trackGas(ssvNetworkContract.bulkRegisterValidator( + pks, + operatorIds, + shares, + depositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true + } + ), [GasGroup.BULK_REGISTER_10_VALIDATOR_NEW_STATE_13]); + }); + it('Get cluster burn rate', async () => { const networkFee = helpers.CONFIG.minimalOperatorFee; await ssvNetworkContract.updateNetworkFee(networkFee); From 331420f94302ecccf8aa51a528f1017a1e4d6e90 Mon Sep 17 00:00:00 2001 From: Marco Tabasco Date: Fri, 15 Dec 2023 19:32:03 +0100 Subject: [PATCH 16/38] refactor cluster and operators libraries --- contracts/libraries/ClusterLib.sol | 71 ++++++++++ contracts/libraries/OperatorLib.sol | 55 ++++++-- contracts/libraries/ValidatorLib.sol | 15 ++ contracts/modules/SSVClusters.sol | 198 ++------------------------- test/helpers/gas-usage.ts | 50 +++---- test/validators/register.ts | 3 +- 6 files changed, 170 insertions(+), 222 deletions(-) diff --git a/contracts/libraries/ClusterLib.sol b/contracts/libraries/ClusterLib.sol index 178701f7..b839501d 100644 --- a/contracts/libraries/ClusterLib.sol +++ b/contracts/libraries/ClusterLib.sol @@ -3,10 +3,14 @@ pragma solidity 0.8.18; import "../interfaces/ISSVNetworkCore.sol"; import "./SSVStorage.sol"; +import "./SSVStorageProtocol.sol"; +import "./OperatorLib.sol"; +import "./ProtocolLib.sol"; import "./Types.sol"; library ClusterLib { using Types64 for uint64; + using ProtocolLib for StorageProtocol; function updateBalance( ISSVNetworkCore.Cluster memory cluster, @@ -80,4 +84,71 @@ library ClusterLib { ) ); } + + function validateClusterOnRegistration( + ISSVNetworkCore.Cluster memory cluster, + uint64[] memory operatorIds, + StorageData storage s + ) internal view returns (bytes32 hashedCluster) { + hashedCluster = keccak256(abi.encodePacked(msg.sender, operatorIds)); + + bytes32 clusterData = s.clusters[hashedCluster]; + if (clusterData == bytes32(0)) { + if ( + cluster.validatorCount != 0 || + cluster.networkFeeIndex != 0 || + cluster.index != 0 || + cluster.balance != 0 || + !cluster.active + ) { + revert ISSVNetworkCore.IncorrectClusterState(); + } + } else if (clusterData != hashClusterData(cluster)) { + revert ISSVNetworkCore.IncorrectClusterState(); + } else { + validateClusterIsNotLiquidated(cluster); + } + } + + function updateClusterOnRegistration( + ISSVNetworkCore.Cluster memory cluster, + uint64[] memory operatorIds, + bytes32 hashedCluster, + uint32 validatorCountDelta, + StorageData storage s, + StorageProtocol storage sp + ) internal { + uint64 burnRate; + + if (cluster.active) { + (uint64 clusterIndex, uint64 burnRate) = OperatorLib.updateClusterOperators( + operatorIds, + true, + true, + validatorCountDelta, + s, + sp + ); + + updateClusterData(cluster, clusterIndex, sp.currentNetworkFeeIndex()); + + sp.updateDAO(true, validatorCountDelta); + } + + cluster.validatorCount += validatorCountDelta; + + if ( + isLiquidatable( + cluster, + burnRate, + sp.networkFee, + sp.minimumBlocksBeforeLiquidation, + sp.minimumLiquidationCollateral + ) + ) { + revert ISSVNetworkCore.InsufficientBalance(); + } + + s.clusters[hashedCluster] = hashClusterData(cluster); + } } diff --git a/contracts/libraries/OperatorLib.sol b/contracts/libraries/OperatorLib.sol index f0672d59..cf2adcd4 100644 --- a/contracts/libraries/OperatorLib.sol +++ b/contracts/libraries/OperatorLib.sol @@ -30,29 +30,64 @@ library OperatorLib { if (operator.owner != msg.sender) revert ISSVNetworkCore.CallerNotOwner(); } - function updateOperators( + function updateClusterOperators( uint64[] memory operatorIds, + bool isRegisteringValidator, bool increaseValidatorCount, uint32 deltaValidatorCount, StorageData storage s, StorageProtocol storage sp - ) internal returns (uint64 clusterIndex, uint64 burnRate) { + ) internal returns (uint64 cumulativeIndex, uint64 cumulativeFee) { uint256 operatorsLength = operatorIds.length; for (uint256 i; i < operatorsLength; ) { uint64 operatorId = operatorIds[i]; - ISSVNetworkCore.Operator storage operator = s.operators[operatorId]; - if (operator.snapshot.block != 0) { - updateSnapshotSt(operator); - if (!increaseValidatorCount) { - operator.validatorCount -= deltaValidatorCount; - } else if ((operator.validatorCount += deltaValidatorCount) > sp.validatorsPerOperatorLimit) { + + if (!isRegisteringValidator) { + ISSVNetworkCore.Operator storage operator = s.operators[operatorId]; + + if (operator.snapshot.block != 0) { + updateSnapshotSt(operator); + if (!increaseValidatorCount) { + operator.validatorCount -= deltaValidatorCount; + } else if ((operator.validatorCount += deltaValidatorCount) > sp.validatorsPerOperatorLimit) { + revert ISSVNetworkCore.ExceedValidatorLimit(); + } + + cumulativeFee += operator.fee; + } + cumulativeIndex += operator.snapshot.index; + } else { + if (i + 1 < operatorsLength) { + if (operatorId > operatorIds[i + 1]) { + revert ISSVNetworkCore.UnsortedOperatorsList(); + } else if (operatorId == operatorIds[i + 1]) { + revert ISSVNetworkCore.OperatorsListNotUnique(); + } + } + ISSVNetworkCore.Operator memory operator = s.operators[operatorId]; + + if (operator.snapshot.block == 0) { + revert ISSVNetworkCore.OperatorDoesNotExist(); + } + if (operator.whitelisted) { + address whitelisted = s.operatorsWhitelist[operatorId]; + if (whitelisted != address(0) && whitelisted != msg.sender) { + revert ISSVNetworkCore.CallerNotWhitelisted(); + } + } + + updateSnapshot(operator); + if ((operator.validatorCount += deltaValidatorCount) > sp.validatorsPerOperatorLimit) { revert ISSVNetworkCore.ExceedValidatorLimit(); } - burnRate += operator.fee; + + cumulativeFee += operator.fee; + cumulativeIndex += operator.snapshot.index; + + s.operators[operatorId] = operator; } - clusterIndex += operator.snapshot.index; unchecked { ++i; } diff --git a/contracts/libraries/ValidatorLib.sol b/contracts/libraries/ValidatorLib.sol index 08711c92..2f26e32f 100644 --- a/contracts/libraries/ValidatorLib.sol +++ b/contracts/libraries/ValidatorLib.sol @@ -5,8 +5,23 @@ import "../interfaces/ISSVNetworkCore.sol"; import "./SSVStorage.sol"; library ValidatorLib { + uint64 private constant MIN_OPERATORS_LENGTH = 4; + uint64 private constant MAX_OPERATORS_LENGTH = 13; + uint64 private constant MODULO_OPERATORS_LENGTH = 3; uint64 private constant PUBLIC_KEY_LENGTH = 48; + function validateOperatorsLength(uint64[] memory operatorIds) internal pure { + uint256 operatorsLength = operatorIds.length; + + if ( + operatorsLength < MIN_OPERATORS_LENGTH || + operatorsLength > MAX_OPERATORS_LENGTH || + operatorsLength % MODULO_OPERATORS_LENGTH != 1 + ) { + revert ISSVNetworkCore.InvalidOperatorIdsLength(); + } + } + function registerPublicKeys( bytes[] calldata publicKeys, uint64[] memory operatorIds, diff --git a/contracts/modules/SSVClusters.sol b/contracts/modules/SSVClusters.sol index 16d2f1f0..0a40c5dd 100644 --- a/contracts/modules/SSVClusters.sol +++ b/contracts/modules/SSVClusters.sol @@ -14,9 +14,6 @@ contract SSVClusters is ISSVClusters { using ClusterLib for Cluster; using OperatorLib for Operator; using ProtocolLib for StorageProtocol; - uint64 private constant MIN_OPERATORS_LENGTH = 4; - uint64 private constant MAX_OPERATORS_LENGTH = 13; - uint64 private constant MODULO_OPERATORS_LENGTH = 3; function registerValidator( bytes calldata publicKey, @@ -28,100 +25,15 @@ contract SSVClusters is ISSVClusters { StorageData storage s = SSVStorage.load(); StorageProtocol storage sp = SSVStorageProtocol.load(); - uint256 operatorsLength = operatorIds.length; - { - if ( - operatorsLength < MIN_OPERATORS_LENGTH || - operatorsLength > MAX_OPERATORS_LENGTH || - operatorsLength % MODULO_OPERATORS_LENGTH != 1 - ) { - revert InvalidOperatorIdsLength(); - } + ValidatorLib.validateOperatorsLength(operatorIds); - ValidatorLib.resgisterPublicKey(publicKey, operatorIds, s); - } - bytes32 hashedCluster = keccak256(abi.encodePacked(msg.sender, operatorIds)); + ValidatorLib.resgisterPublicKey(publicKey, operatorIds, s); - { - bytes32 clusterData = s.clusters[hashedCluster]; - if (clusterData == bytes32(0)) { - if ( - cluster.validatorCount != 0 || - cluster.networkFeeIndex != 0 || - cluster.index != 0 || - cluster.balance != 0 || - !cluster.active - ) { - revert IncorrectClusterState(); - } - } else if (clusterData != cluster.hashClusterData()) { - revert IncorrectClusterState(); - } else { - cluster.validateClusterIsNotLiquidated(); - } - } + bytes32 hashedCluster = cluster.validateClusterOnRegistration(operatorIds, s); cluster.balance += amount; - uint64 burnRate; - - if (cluster.active) { - uint64 clusterIndex; - - for (uint256 i; i < operatorsLength; ) { - uint64 operatorId = operatorIds[i]; - { - if (i + 1 < operatorsLength) { - if (operatorId > operatorIds[i + 1]) { - revert UnsortedOperatorsList(); - } else if (operatorId == operatorIds[i + 1]) { - revert OperatorsListNotUnique(); - } - } - } - - Operator memory operator = s.operators[operatorId]; - if (operator.snapshot.block == 0) { - revert OperatorDoesNotExist(); - } - if (operator.whitelisted) { - address whitelisted = s.operatorsWhitelist[operatorId]; - if (whitelisted != address(0) && whitelisted != msg.sender) { - revert CallerNotWhitelisted(); - } - } - operator.updateSnapshot(); - if (++operator.validatorCount > sp.validatorsPerOperatorLimit) { - revert ExceedValidatorLimit(); - } - clusterIndex += operator.snapshot.index; - burnRate += operator.fee; - - s.operators[operatorId] = operator; - - unchecked { - ++i; - } - } - cluster.updateClusterData(clusterIndex, sp.currentNetworkFeeIndex()); - - sp.updateDAO(true, 1); - } - - ++cluster.validatorCount; - - if ( - cluster.isLiquidatable( - burnRate, - sp.networkFee, - sp.minimumBlocksBeforeLiquidation, - sp.minimumLiquidationCollateral - ) - ) { - revert InsufficientBalance(); - } - - s.clusters[hashedCluster] = cluster.hashClusterData(); + cluster.updateClusterOnRegistration(operatorIds, hashedCluster, 1, s, sp); if (amount != 0) { CoreLib.deposit(amount); @@ -142,103 +54,17 @@ contract SSVClusters is ISSVClusters { StorageData storage s = SSVStorage.load(); StorageProtocol storage sp = SSVStorageProtocol.load(); - uint256 operatorsLength = operatorIds.length; uint32 validatorsLength = uint32(publicKeys.length); - { - if ( - operatorsLength < MIN_OPERATORS_LENGTH || - operatorsLength > MAX_OPERATORS_LENGTH || - operatorsLength % MODULO_OPERATORS_LENGTH != 1 - ) { - revert InvalidOperatorIdsLength(); - } + ValidatorLib.validateOperatorsLength(operatorIds); - ValidatorLib.registerPublicKeys(publicKeys, operatorIds, s); - } - bytes32 hashedCluster = keccak256(abi.encodePacked(msg.sender, operatorIds)); + ValidatorLib.registerPublicKeys(publicKeys, operatorIds, s); - { - bytes32 clusterData = s.clusters[hashedCluster]; - if (clusterData == bytes32(0)) { - if ( - cluster.validatorCount != 0 || - cluster.networkFeeIndex != 0 || - cluster.index != 0 || - cluster.balance != 0 || - !cluster.active - ) { - revert IncorrectClusterState(); - } - } else if (clusterData != cluster.hashClusterData()) { - revert IncorrectClusterState(); - } else { - cluster.validateClusterIsNotLiquidated(); - } - } + bytes32 hashedCluster = cluster.validateClusterOnRegistration(operatorIds, s); cluster.balance += amount; - uint64 burnRate; - - if (cluster.active) { - uint64 clusterIndex; - - for (uint256 i; i < operatorsLength; ) { - uint64 operatorId = operatorIds[i]; - { - if (i + 1 < operatorsLength) { - if (operatorId > operatorIds[i + 1]) { - revert UnsortedOperatorsList(); - } else if (operatorId == operatorIds[i + 1]) { - revert OperatorsListNotUnique(); - } - } - } - - Operator memory operator = s.operators[operatorId]; - if (operator.snapshot.block == 0) { - revert OperatorDoesNotExist(); - } - if (operator.whitelisted) { - address whitelisted = s.operatorsWhitelist[operatorId]; - if (whitelisted != address(0) && whitelisted != msg.sender) { - revert CallerNotWhitelisted(); - } - } - operator.updateSnapshot(); - operator.validatorCount += validatorsLength; - if (operator.validatorCount > sp.validatorsPerOperatorLimit) { - revert ExceedValidatorLimit(); - } - clusterIndex += operator.snapshot.index; - burnRate += operator.fee; - - s.operators[operatorId] = operator; - - unchecked { - ++i; - } - } - cluster.updateClusterData(clusterIndex, sp.currentNetworkFeeIndex()); - - sp.updateDAO(true, validatorsLength); - } - - cluster.validatorCount += validatorsLength; - - if ( - cluster.isLiquidatable( - burnRate, - sp.networkFee, - sp.minimumBlocksBeforeLiquidation, - sp.minimumLiquidationCollateral - ) - ) { - revert InsufficientBalance(); - } - - s.clusters[hashedCluster] = cluster.hashClusterData(); + cluster.updateClusterOnRegistration(operatorIds, hashedCluster, validatorsLength, s, sp); if (amount != 0) { CoreLib.deposit(amount); @@ -269,7 +95,7 @@ contract SSVClusters is ISSVClusters { { if (cluster.active) { StorageProtocol storage sp = SSVStorageProtocol.load(); - (uint64 clusterIndex, ) = OperatorLib.updateOperators(operatorIds, false, 1, s, sp); + (uint64 clusterIndex, ) = OperatorLib.updateClusterOperators(operatorIds, false, false, 1, s, sp); cluster.updateClusterData(clusterIndex, sp.currentNetworkFeeIndex()); @@ -294,9 +120,10 @@ contract SSVClusters is ISSVClusters { StorageProtocol storage sp = SSVStorageProtocol.load(); - (uint64 clusterIndex, uint64 burnRate) = OperatorLib.updateOperators( + (uint64 clusterIndex, uint64 burnRate) = OperatorLib.updateClusterOperators( operatorIds, false, + false, cluster.validatorCount, s, sp @@ -345,8 +172,9 @@ contract SSVClusters is ISSVClusters { StorageProtocol storage sp = SSVStorageProtocol.load(); - (uint64 clusterIndex, uint64 burnRate) = OperatorLib.updateOperators( + (uint64 clusterIndex, uint64 burnRate) = OperatorLib.updateClusterOperators( operatorIds, + false, true, cluster.validatorCount, s, diff --git a/test/helpers/gas-usage.ts b/test/helpers/gas-usage.ts index 8748530f..a066383f 100644 --- a/test/helpers/gas-usage.ts +++ b/test/helpers/gas-usage.ts @@ -47,7 +47,7 @@ export enum GasGroup { WITHDRAW_CLUSTER_BALANCE, WITHDRAW_OPERATOR_BALANCE, VALIDATOR_EXIT, - + LIQUIDATE_CLUSTER_4, LIQUIDATE_CLUSTER_7, LIQUIDATE_CLUSTER_10, @@ -71,39 +71,39 @@ const MAX_GAS_PER_GROUP: any = { [GasGroup.REMOVE_OPERATOR]: 70200, [GasGroup.REMOVE_OPERATOR_WITH_WITHDRAW]: 70200, [GasGroup.SET_OPERATOR_WHITELIST]: 84300, - + [GasGroup.DECLARE_OPERATOR_FEE]: 70000, [GasGroup.CANCEL_OPERATOR_FEE]: 41900, [GasGroup.EXECUTE_OPERATOR_FEE]: 52000, [GasGroup.REDUCE_OPERATOR_FEE]: 51900, - [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]: 202000, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE]: 221400, - [GasGroup.REGISTER_VALIDATOR_WITHOUT_DEPOSIT]: 181600, + [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]: 200500, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE]: 220000, + [GasGroup.REGISTER_VALIDATOR_WITHOUT_DEPOSIT]: 180000, [GasGroup.BULK_REGISTER_10_VALIDATOR_NEW_STATE_4]: 889900, - [GasGroup.BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_4]: 814900, + [GasGroup.BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_4]: 813000, - [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER_7]: 272900, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]: 289634, - [GasGroup.REGISTER_VALIDATOR_WITHOUT_DEPOSIT_7]: 252500, + [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER_7]: 271500, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]: 288500, + [GasGroup.REGISTER_VALIDATOR_WITHOUT_DEPOSIT_7]: 251000, - [GasGroup.BULK_REGISTER_10_VALIDATOR_NEW_STATE_7]: 891900, - [GasGroup.BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_7]: 875200, + [GasGroup.BULK_REGISTER_10_VALIDATOR_NEW_STATE_7]: 890000, + [GasGroup.BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_7]: 873500, - [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER_10]: 343600, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_10]: 360300, - [GasGroup.REGISTER_VALIDATOR_WITHOUT_DEPOSIT_10]: 323000, + [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER_10]: 342000, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_10]: 359000, + [GasGroup.REGISTER_VALIDATOR_WITHOUT_DEPOSIT_10]: 321500, - [GasGroup.BULK_REGISTER_10_VALIDATOR_NEW_STATE_10]: 952159, - [GasGroup.BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_10]: 935500, + [GasGroup.BULK_REGISTER_10_VALIDATOR_NEW_STATE_10]: 950500, + [GasGroup.BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_10]: 933500, - [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER_13]: 414500, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]: 431300, - [GasGroup.REGISTER_VALIDATOR_WITHOUT_DEPOSIT_13]: 394000, + [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER_13]: 413000, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]: 430000, + [GasGroup.REGISTER_VALIDATOR_WITHOUT_DEPOSIT_13]: 392500, [GasGroup.BULK_REGISTER_10_VALIDATOR_NEW_STATE_13]: 1010500, - [GasGroup.BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_13]: 995706, + [GasGroup.BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_13]: 994000, [GasGroup.REMOVE_VALIDATOR]: 113500, [GasGroup.REMOVE_VALIDATOR_7]: 155000, @@ -114,10 +114,10 @@ const MAX_GAS_PER_GROUP: any = { [GasGroup.WITHDRAW_OPERATOR_BALANCE]: 64900, [GasGroup.VALIDATOR_EXIT]: 42300, - [GasGroup.LIQUIDATE_CLUSTER_4]: 129300, - [GasGroup.LIQUIDATE_CLUSTER_7]: 170500, - [GasGroup.LIQUIDATE_CLUSTER_10]: 211600, - [GasGroup.LIQUIDATE_CLUSTER_13]: 252800, + [GasGroup.LIQUIDATE_CLUSTER_4]: 129300, + [GasGroup.LIQUIDATE_CLUSTER_7]: 170500, + [GasGroup.LIQUIDATE_CLUSTER_10]: 211600, + [GasGroup.LIQUIDATE_CLUSTER_13]: 252800, [GasGroup.REACTIVATE_CLUSTER]: 120600, [GasGroup.NETWORK_FEE_CHANGE]: 45800, @@ -130,7 +130,7 @@ const MAX_GAS_PER_GROUP: any = { [GasGroup.CHANGE_LIQUIDATION_THRESHOLD_PERIOD]: 41000, [GasGroup.CHANGE_MINIMUM_COLLATERAL]: 41200, - + }; class GasStats { diff --git a/test/validators/register.ts b/test/validators/register.ts index c5a936cb..b29d58ab 100644 --- a/test/validators/register.ts +++ b/test/validators/register.ts @@ -3,7 +3,6 @@ import * as helpers from '../helpers/contract-helpers'; import * as utils from '../helpers/utils'; import { expect } from 'chai'; import { trackGas, GasGroup } from '../helpers/gas-usage'; -import { anyValue } from "@nomicfoundation/hardhat-chai-matchers/withArgs"; let ssvNetworkContract: any, ssvViews: any, ssvToken: any, minDepositAmount: any, cluster1: any; @@ -398,7 +397,7 @@ describe('Register Validator Tests', () => { balance: 0, active: true } - ), [GasGroup.BULK_REGISTER_10_VALIDATOR_NEW_STATE_4]); + ), [GasGroup.BULK_REGISTER_10_VALIDATOR_NEW_STATE_7]); }); // 10 operators From 335f0089e1a20b669fa0034477564389cb3d8fe9 Mon Sep 17 00:00:00 2001 From: Marco Tabasco Date: Mon, 18 Dec 2023 13:11:12 +0100 Subject: [PATCH 17/38] V1.0.2 deployment metadata (#283) * v1.0.2 deployment metadata --- .openzeppelin/goerli.json | 236 +++++++++++++++++++++++++++++++ .openzeppelin/unknown-17000.json | 236 +++++++++++++++++++++++++++++++ 2 files changed, 472 insertions(+) diff --git a/.openzeppelin/goerli.json b/.openzeppelin/goerli.json index 59b7ac36..443c72ad 100644 --- a/.openzeppelin/goerli.json +++ b/.openzeppelin/goerli.json @@ -7345,6 +7345,242 @@ } } } + }, + "c319dae004e883cdd24ab7834715e77958c6beccd0f2cea7e46e804b8f89f295": { + "address": "0xFA2e88093a4Ad20E204290f6169410CcF96e8858", + "txHash": "0xa476d771b2ad2793f613e84194fbfd393e61d6641371592337cadddbca813245", + "layout": { + "solcVersion": "0.8.18", + "storage": [ + { + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_uint8", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:63", + "retypedFrom": "bool" + }, + { + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:68" + }, + { + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)50_storage", + "contract": "ERC1967UpgradeUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol:169" + }, + { + "label": "__gap", + "offset": 0, + "slot": "51", + "type": "t_array(t_uint256)50_storage", + "contract": "UUPSUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol:111" + }, + { + "label": "__gap", + "offset": 0, + "slot": "101", + "type": "t_array(t_uint256)50_storage", + "contract": "ContextUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" + }, + { + "label": "_owner", + "offset": 0, + "slot": "151", + "type": "t_address", + "contract": "OwnableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" + }, + { + "label": "__gap", + "offset": 0, + "slot": "152", + "type": "t_array(t_uint256)49_storage", + "contract": "OwnableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:94" + }, + { + "label": "_pendingOwner", + "offset": 0, + "slot": "201", + "type": "t_address", + "contract": "Ownable2StepUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol:27" + }, + { + "label": "__gap", + "offset": 0, + "slot": "202", + "type": "t_array(t_uint256)49_storage", + "contract": "Ownable2StepUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol:70" + } + ], + "types": { + "t_address": { + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_uint256)49_storage": { + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_array(t_uint256)50_storage": { + "label": "uint256[50]", + "numberOfBytes": "1600" + }, + "t_bool": { + "label": "bool", + "numberOfBytes": "1" + }, + "t_uint256": { + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint8": { + "label": "uint8", + "numberOfBytes": "1" + } + } + } + }, + "8a3382629da06790720d2d37ed76d51b1f949d6c3b17919f08f3b6842b9de108": { + "address": "0x7450a96d73E070210a52ceC327029F52fd156043", + "txHash": "0x9b95840ebe867c296beabe54ce9e7421ea9eb720ee26234d9e8418479cd7903d", + "layout": { + "solcVersion": "0.8.18", + "storage": [ + { + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_uint8", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:63", + "retypedFrom": "bool" + }, + { + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:68" + }, + { + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)50_storage", + "contract": "ERC1967UpgradeUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol:169" + }, + { + "label": "__gap", + "offset": 0, + "slot": "51", + "type": "t_array(t_uint256)50_storage", + "contract": "UUPSUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol:111" + }, + { + "label": "__gap", + "offset": 0, + "slot": "101", + "type": "t_array(t_uint256)50_storage", + "contract": "ContextUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" + }, + { + "label": "_owner", + "offset": 0, + "slot": "151", + "type": "t_address", + "contract": "OwnableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" + }, + { + "label": "__gap", + "offset": 0, + "slot": "152", + "type": "t_array(t_uint256)49_storage", + "contract": "OwnableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:94" + }, + { + "label": "_pendingOwner", + "offset": 0, + "slot": "201", + "type": "t_address", + "contract": "Ownable2StepUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol:27" + }, + { + "label": "__gap", + "offset": 0, + "slot": "202", + "type": "t_array(t_uint256)49_storage", + "contract": "Ownable2StepUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol:70" + }, + { + "label": "ssvNetwork", + "offset": 0, + "slot": "251", + "type": "t_contract(ISSVViews)4293", + "contract": "SSVNetworkViews", + "src": "contracts/SSVNetworkViews.sol:19" + }, + { + "label": "__gap", + "offset": 0, + "slot": "252", + "type": "t_array(t_uint256)50_storage", + "contract": "SSVNetworkViews", + "src": "contracts/SSVNetworkViews.sol:23" + } + ], + "types": { + "t_address": { + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_uint256)49_storage": { + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_array(t_uint256)50_storage": { + "label": "uint256[50]", + "numberOfBytes": "1600" + }, + "t_bool": { + "label": "bool", + "numberOfBytes": "1" + }, + "t_contract(ISSVViews)4293": { + "label": "contract ISSVViews", + "numberOfBytes": "20" + }, + "t_uint256": { + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint8": { + "label": "uint8", + "numberOfBytes": "1" + } + } + } } } } diff --git a/.openzeppelin/unknown-17000.json b/.openzeppelin/unknown-17000.json index badd63e8..9d902d19 100644 --- a/.openzeppelin/unknown-17000.json +++ b/.openzeppelin/unknown-17000.json @@ -366,6 +366,242 @@ } } } + }, + "c319dae004e883cdd24ab7834715e77958c6beccd0f2cea7e46e804b8f89f295": { + "address": "0xE74C70Ea8A688de29d3b1F631b1FF8decAd52833", + "txHash": "0x5500f4fcf7c7487ea6c16c5f11fb7e81abc28a6dc0e33207ab5a15e696287aef", + "layout": { + "solcVersion": "0.8.18", + "storage": [ + { + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_uint8", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:63", + "retypedFrom": "bool" + }, + { + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:68" + }, + { + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)50_storage", + "contract": "ERC1967UpgradeUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol:169" + }, + { + "label": "__gap", + "offset": 0, + "slot": "51", + "type": "t_array(t_uint256)50_storage", + "contract": "UUPSUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol:111" + }, + { + "label": "__gap", + "offset": 0, + "slot": "101", + "type": "t_array(t_uint256)50_storage", + "contract": "ContextUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" + }, + { + "label": "_owner", + "offset": 0, + "slot": "151", + "type": "t_address", + "contract": "OwnableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" + }, + { + "label": "__gap", + "offset": 0, + "slot": "152", + "type": "t_array(t_uint256)49_storage", + "contract": "OwnableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:94" + }, + { + "label": "_pendingOwner", + "offset": 0, + "slot": "201", + "type": "t_address", + "contract": "Ownable2StepUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol:27" + }, + { + "label": "__gap", + "offset": 0, + "slot": "202", + "type": "t_array(t_uint256)49_storage", + "contract": "Ownable2StepUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol:70" + } + ], + "types": { + "t_address": { + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_uint256)49_storage": { + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_array(t_uint256)50_storage": { + "label": "uint256[50]", + "numberOfBytes": "1600" + }, + "t_bool": { + "label": "bool", + "numberOfBytes": "1" + }, + "t_uint256": { + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint8": { + "label": "uint8", + "numberOfBytes": "1" + } + } + } + }, + "8a3382629da06790720d2d37ed76d51b1f949d6c3b17919f08f3b6842b9de108": { + "address": "0x7118C9B049E834B2351C1c9a0ECEE12610A1a29E", + "txHash": "0x1f189d0a9a3a88acfeefcfd6bec1309f969d6249550cac23396bfff6e4e39d17", + "layout": { + "solcVersion": "0.8.18", + "storage": [ + { + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_uint8", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:63", + "retypedFrom": "bool" + }, + { + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:68" + }, + { + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)50_storage", + "contract": "ERC1967UpgradeUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol:169" + }, + { + "label": "__gap", + "offset": 0, + "slot": "51", + "type": "t_array(t_uint256)50_storage", + "contract": "UUPSUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol:111" + }, + { + "label": "__gap", + "offset": 0, + "slot": "101", + "type": "t_array(t_uint256)50_storage", + "contract": "ContextUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" + }, + { + "label": "_owner", + "offset": 0, + "slot": "151", + "type": "t_address", + "contract": "OwnableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" + }, + { + "label": "__gap", + "offset": 0, + "slot": "152", + "type": "t_array(t_uint256)49_storage", + "contract": "OwnableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:94" + }, + { + "label": "_pendingOwner", + "offset": 0, + "slot": "201", + "type": "t_address", + "contract": "Ownable2StepUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol:27" + }, + { + "label": "__gap", + "offset": 0, + "slot": "202", + "type": "t_array(t_uint256)49_storage", + "contract": "Ownable2StepUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol:70" + }, + { + "label": "ssvNetwork", + "offset": 0, + "slot": "251", + "type": "t_contract(ISSVViews)4293", + "contract": "SSVNetworkViews", + "src": "contracts/SSVNetworkViews.sol:19" + }, + { + "label": "__gap", + "offset": 0, + "slot": "252", + "type": "t_array(t_uint256)50_storage", + "contract": "SSVNetworkViews", + "src": "contracts/SSVNetworkViews.sol:23" + } + ], + "types": { + "t_address": { + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_uint256)49_storage": { + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_array(t_uint256)50_storage": { + "label": "uint256[50]", + "numberOfBytes": "1600" + }, + "t_bool": { + "label": "bool", + "numberOfBytes": "1" + }, + "t_contract(ISSVViews)4293": { + "label": "contract ISSVViews", + "numberOfBytes": "20" + }, + "t_uint256": { + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint8": { + "label": "uint8", + "numberOfBytes": "1" + } + } + } } } } From 9c609cd8c301bfd895f738a86d7d9626587e53e9 Mon Sep 17 00:00:00 2001 From: Marco Tabasco Date: Mon, 8 Jan 2024 14:13:19 +0100 Subject: [PATCH 18/38] Bulk registration of validators (#287) * bulk validator registration --- .openzeppelin/unknown-17000.json | 228 ++++++++++++++++++++++ CHANGELOG.md | 3 + abis/SSVNetwork.json | 67 ++++++- abis/SSVNetworkViews.json | 5 + contracts/SSVNetwork.sol | 12 +- contracts/interfaces/ISSVClusters.sol | 14 ++ contracts/interfaces/ISSVNetworkCore.sol | 3 +- contracts/libraries/ClusterLib.sol | 71 +++++++ contracts/libraries/CoreLib.sol | 2 +- contracts/libraries/OperatorLib.sol | 55 +++++- contracts/libraries/ValidatorLib.sol | 41 ++++ contracts/modules/SSVClusters.sol | 134 ++++--------- contracts/test/SSVNetworkUpgrade.sol | 26 ++- contracts/test/libraries/CoreLibT.sol | 2 +- hardhat.config.ts | 1 + test/deployment/version.ts | 2 +- test/helpers/contract-helpers.ts | 2 +- test/helpers/gas-usage.ts | 48 +++-- test/helpers/json/validatorKeys.json | 42 +++- test/validators/register.ts | 237 ++++++++++++++++++++++- 20 files changed, 863 insertions(+), 132 deletions(-) diff --git a/.openzeppelin/unknown-17000.json b/.openzeppelin/unknown-17000.json index 9d902d19..fef1b41c 100644 --- a/.openzeppelin/unknown-17000.json +++ b/.openzeppelin/unknown-17000.json @@ -20,6 +20,16 @@ "address": "0x352A18AEe90cdcd825d1E37d9939dCA86C00e281", "txHash": "0xf36e0e114031e961a1e3452477ed71658cf0f809be94832b4dc4a99a293ef664", "kind": "uups" + }, + { + "address": "0x4fA60408D9c0428b43FCa0E26c2f9aAa510cCeE2", + "txHash": "0x72d9a2c0e2442046a87816203f08b0ad4cb65ef25de40c59c5fe4f83b8834370", + "kind": "uups" + }, + { + "address": "0xEa0Fd295Be44Fb909d654dA90198c8E9d766FB74", + "txHash": "0x8cbbb4f8c3fa01e88d0aed6ffcccab3c063d332bf465541a4515fe3070177687", + "kind": "uups" } ], "impls": { @@ -602,6 +612,224 @@ } } } + }, + "141551db18457f12435a89572b53feb0543d6d3f184915332fb095bfb8164fdf": { + "address": "0x21A40764aFEb2DA98eEB95Ce720212A15F87c5d7", + "txHash": "0x5433d717bd39e46df0e0345050bf5a0a7f136f96289b6d20b6f9b40b51dcab90", + "layout": { + "solcVersion": "0.8.18", + "storage": [ + { + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_uint8", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:63", + "retypedFrom": "bool" + }, + { + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:68" + }, + { + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)50_storage", + "contract": "ERC1967UpgradeUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol:169" + }, + { + "label": "__gap", + "offset": 0, + "slot": "51", + "type": "t_array(t_uint256)50_storage", + "contract": "UUPSUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol:111" + }, + { + "label": "__gap", + "offset": 0, + "slot": "101", + "type": "t_array(t_uint256)50_storage", + "contract": "ContextUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" + }, + { + "label": "_owner", + "offset": 0, + "slot": "151", + "type": "t_address", + "contract": "OwnableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" + }, + { + "label": "__gap", + "offset": 0, + "slot": "152", + "type": "t_array(t_uint256)49_storage", + "contract": "OwnableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:94" + }, + { + "label": "_pendingOwner", + "offset": 0, + "slot": "201", + "type": "t_address", + "contract": "Ownable2StepUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol:27" + }, + { + "label": "__gap", + "offset": 0, + "slot": "202", + "type": "t_array(t_uint256)49_storage", + "contract": "Ownable2StepUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol:70" + } + ], + "types": { + "t_address": { + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_uint256)49_storage": { + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_array(t_uint256)50_storage": { + "label": "uint256[50]", + "numberOfBytes": "1600" + }, + "t_bool": { + "label": "bool", + "numberOfBytes": "1" + }, + "t_uint256": { + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint8": { + "label": "uint8", + "numberOfBytes": "1" + } + }, + "namespaces": {} + } + }, + "e311afb1f25419f9f90569ca2bf47a87990372364d587ec21789bb9aa6e83966": { + "address": "0x249e2769bF15082e1e44D15D819c0230d4500d54", + "txHash": "0x61e70aa81e1c355fdfd3a0554a42043651d7a032435c3a87d06de6f67854ddf8", + "layout": { + "solcVersion": "0.8.18", + "storage": [ + { + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_uint8", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:63", + "retypedFrom": "bool" + }, + { + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:68" + }, + { + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)50_storage", + "contract": "ERC1967UpgradeUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol:169" + }, + { + "label": "__gap", + "offset": 0, + "slot": "51", + "type": "t_array(t_uint256)50_storage", + "contract": "UUPSUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol:111" + }, + { + "label": "__gap", + "offset": 0, + "slot": "101", + "type": "t_array(t_uint256)50_storage", + "contract": "ContextUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" + }, + { + "label": "_owner", + "offset": 0, + "slot": "151", + "type": "t_address", + "contract": "OwnableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" + }, + { + "label": "__gap", + "offset": 0, + "slot": "152", + "type": "t_array(t_uint256)49_storage", + "contract": "OwnableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:94" + }, + { + "label": "_pendingOwner", + "offset": 0, + "slot": "201", + "type": "t_address", + "contract": "Ownable2StepUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol:27" + }, + { + "label": "__gap", + "offset": 0, + "slot": "202", + "type": "t_array(t_uint256)49_storage", + "contract": "Ownable2StepUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol:70" + } + ], + "types": { + "t_address": { + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_uint256)49_storage": { + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_array(t_uint256)50_storage": { + "label": "uint256[50]", + "numberOfBytes": "1600" + }, + "t_bool": { + "label": "bool", + "numberOfBytes": "1" + }, + "t_uint256": { + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint8": { + "label": "uint8", + "numberOfBytes": "1" + } + }, + "namespaces": {} + } } } } diff --git a/CHANGELOG.md b/CHANGELOG.md index a11ed7d2..ec5a4fb4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ## [Unreleased] +## [v1.1.0] 2023-12-18 +- Bulk registration of validators. + ## [v1.0.2] 2023-11-08 - [8f5df42](https://github.com/bloxapp/ssv-network/commit/8f5df42633d2b92c6bb70253a41e6afa80b9f111) - Change ValidatorExited signature: owner indexed. diff --git a/abis/SSVNetwork.json b/abis/SSVNetwork.json index 9a017710..5526f48b 100644 --- a/abis/SSVNetwork.json +++ b/abis/SSVNetwork.json @@ -124,6 +124,11 @@ "name": "OperatorsListNotUnique", "type": "error" }, + { + "inputs": [], + "name": "PublicKeysSharesLengthMismatch", + "type": "error" + }, { "inputs": [], "name": "SameFeeChangeNotAllowed", @@ -932,6 +937,66 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "bytes[]", + "name": "publicKeys", + "type": "bytes[]" + }, + { + "internalType": "uint64[]", + "name": "operatorIds", + "type": "uint64[]" + }, + { + "internalType": "bytes[]", + "name": "sharesData", + "type": "bytes[]" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint32", + "name": "validatorCount", + "type": "uint32" + }, + { + "internalType": "uint64", + "name": "networkFeeIndex", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "index", + "type": "uint64" + }, + { + "internalType": "bool", + "name": "active", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + } + ], + "internalType": "struct ISSVNetworkCore.Cluster", + "name": "cluster", + "type": "tuple" + } + ], + "name": "bulkRegisterValidator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -1320,7 +1385,7 @@ }, { "internalType": "bytes", - "name": "sharesData", + "name": "shares", "type": "bytes" }, { diff --git a/abis/SSVNetworkViews.json b/abis/SSVNetworkViews.json index 64cc9826..2ae195d5 100644 --- a/abis/SSVNetworkViews.json +++ b/abis/SSVNetworkViews.json @@ -124,6 +124,11 @@ "name": "OperatorsListNotUnique", "type": "error" }, + { + "inputs": [], + "name": "PublicKeysSharesLengthMismatch", + "type": "error" + }, { "inputs": [], "name": "SameFeeChangeNotAllowed", diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index 3380af0a..e6a058e4 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -168,7 +168,17 @@ contract SSVNetwork is function registerValidator( bytes calldata publicKey, uint64[] memory operatorIds, - bytes calldata sharesData, + bytes calldata shares, + uint256 amount, + ISSVNetworkCore.Cluster memory cluster + ) external override { + _delegate(SSVStorage.load().ssvContracts[SSVModules.SSV_CLUSTERS]); + } + + function bulkRegisterValidator( + bytes[] calldata publicKeys, + uint64[] memory operatorIds, + bytes[] calldata sharesData, uint256 amount, ISSVNetworkCore.Cluster memory cluster ) external override { diff --git a/contracts/interfaces/ISSVClusters.sol b/contracts/interfaces/ISSVClusters.sol index b3d82d87..ca6fb727 100644 --- a/contracts/interfaces/ISSVClusters.sol +++ b/contracts/interfaces/ISSVClusters.sol @@ -18,6 +18,20 @@ interface ISSVClusters is ISSVNetworkCore { Cluster memory cluster ) external; + /// @notice Registers new validators on the SSV Network + /// @param publicKeys The public key of the new validator + /// @param operatorIds Array of IDs of operators managing this validator + /// @param sharesData Encrypted shares related to the new validator + /// @param amount Amount of SSV tokens to be deposited + /// @param cluster Cluster to be used with the new validator + function bulkRegisterValidator( + bytes[] calldata publicKeys, + uint64[] memory operatorIds, + bytes[] calldata sharesData, + uint256 amount, + Cluster memory cluster + ) external; + /// @notice Removes an existing validator from the SSV Network /// @param publicKey The public key of the validator to be removed /// @param operatorIds Array of IDs of operators managing the validator diff --git a/contracts/interfaces/ISSVNetworkCore.sol b/contracts/interfaces/ISSVNetworkCore.sol index 401d715b..c577e402 100644 --- a/contracts/interfaces/ISSVNetworkCore.sol +++ b/contracts/interfaces/ISSVNetworkCore.sol @@ -41,7 +41,7 @@ interface ISSVNetworkCore { } /// @notice Represents a cluster of validators - struct Cluster { + struct Cluster { /// @dev The number of validators in the cluster uint32 validatorCount; /// @dev The index of network fees related to this cluster @@ -88,4 +88,5 @@ interface ISSVNetworkCore { error TargetModuleDoesNotExist(); // 0x8f9195fb error MaxValueExceeded(); // 0x91aa3017 error FeeTooHigh(); // 0xcd4e6167 + error PublicKeysSharesLengthMismatch(); // 0x9ad467b8 } diff --git a/contracts/libraries/ClusterLib.sol b/contracts/libraries/ClusterLib.sol index 178701f7..b839501d 100644 --- a/contracts/libraries/ClusterLib.sol +++ b/contracts/libraries/ClusterLib.sol @@ -3,10 +3,14 @@ pragma solidity 0.8.18; import "../interfaces/ISSVNetworkCore.sol"; import "./SSVStorage.sol"; +import "./SSVStorageProtocol.sol"; +import "./OperatorLib.sol"; +import "./ProtocolLib.sol"; import "./Types.sol"; library ClusterLib { using Types64 for uint64; + using ProtocolLib for StorageProtocol; function updateBalance( ISSVNetworkCore.Cluster memory cluster, @@ -80,4 +84,71 @@ library ClusterLib { ) ); } + + function validateClusterOnRegistration( + ISSVNetworkCore.Cluster memory cluster, + uint64[] memory operatorIds, + StorageData storage s + ) internal view returns (bytes32 hashedCluster) { + hashedCluster = keccak256(abi.encodePacked(msg.sender, operatorIds)); + + bytes32 clusterData = s.clusters[hashedCluster]; + if (clusterData == bytes32(0)) { + if ( + cluster.validatorCount != 0 || + cluster.networkFeeIndex != 0 || + cluster.index != 0 || + cluster.balance != 0 || + !cluster.active + ) { + revert ISSVNetworkCore.IncorrectClusterState(); + } + } else if (clusterData != hashClusterData(cluster)) { + revert ISSVNetworkCore.IncorrectClusterState(); + } else { + validateClusterIsNotLiquidated(cluster); + } + } + + function updateClusterOnRegistration( + ISSVNetworkCore.Cluster memory cluster, + uint64[] memory operatorIds, + bytes32 hashedCluster, + uint32 validatorCountDelta, + StorageData storage s, + StorageProtocol storage sp + ) internal { + uint64 burnRate; + + if (cluster.active) { + (uint64 clusterIndex, uint64 burnRate) = OperatorLib.updateClusterOperators( + operatorIds, + true, + true, + validatorCountDelta, + s, + sp + ); + + updateClusterData(cluster, clusterIndex, sp.currentNetworkFeeIndex()); + + sp.updateDAO(true, validatorCountDelta); + } + + cluster.validatorCount += validatorCountDelta; + + if ( + isLiquidatable( + cluster, + burnRate, + sp.networkFee, + sp.minimumBlocksBeforeLiquidation, + sp.minimumLiquidationCollateral + ) + ) { + revert ISSVNetworkCore.InsufficientBalance(); + } + + s.clusters[hashedCluster] = hashClusterData(cluster); + } } diff --git a/contracts/libraries/CoreLib.sol b/contracts/libraries/CoreLib.sol index f508d6ee..c2b7cbe7 100644 --- a/contracts/libraries/CoreLib.sol +++ b/contracts/libraries/CoreLib.sol @@ -7,7 +7,7 @@ library CoreLib { event ModuleUpgraded(SSVModules indexed moduleId, address moduleAddress); function getVersion() internal pure returns (string memory) { - return "v1.0.2"; + return "v1.1.0"; } function transferBalance(address to, uint256 amount) internal { diff --git a/contracts/libraries/OperatorLib.sol b/contracts/libraries/OperatorLib.sol index f0672d59..cf2adcd4 100644 --- a/contracts/libraries/OperatorLib.sol +++ b/contracts/libraries/OperatorLib.sol @@ -30,29 +30,64 @@ library OperatorLib { if (operator.owner != msg.sender) revert ISSVNetworkCore.CallerNotOwner(); } - function updateOperators( + function updateClusterOperators( uint64[] memory operatorIds, + bool isRegisteringValidator, bool increaseValidatorCount, uint32 deltaValidatorCount, StorageData storage s, StorageProtocol storage sp - ) internal returns (uint64 clusterIndex, uint64 burnRate) { + ) internal returns (uint64 cumulativeIndex, uint64 cumulativeFee) { uint256 operatorsLength = operatorIds.length; for (uint256 i; i < operatorsLength; ) { uint64 operatorId = operatorIds[i]; - ISSVNetworkCore.Operator storage operator = s.operators[operatorId]; - if (operator.snapshot.block != 0) { - updateSnapshotSt(operator); - if (!increaseValidatorCount) { - operator.validatorCount -= deltaValidatorCount; - } else if ((operator.validatorCount += deltaValidatorCount) > sp.validatorsPerOperatorLimit) { + + if (!isRegisteringValidator) { + ISSVNetworkCore.Operator storage operator = s.operators[operatorId]; + + if (operator.snapshot.block != 0) { + updateSnapshotSt(operator); + if (!increaseValidatorCount) { + operator.validatorCount -= deltaValidatorCount; + } else if ((operator.validatorCount += deltaValidatorCount) > sp.validatorsPerOperatorLimit) { + revert ISSVNetworkCore.ExceedValidatorLimit(); + } + + cumulativeFee += operator.fee; + } + cumulativeIndex += operator.snapshot.index; + } else { + if (i + 1 < operatorsLength) { + if (operatorId > operatorIds[i + 1]) { + revert ISSVNetworkCore.UnsortedOperatorsList(); + } else if (operatorId == operatorIds[i + 1]) { + revert ISSVNetworkCore.OperatorsListNotUnique(); + } + } + ISSVNetworkCore.Operator memory operator = s.operators[operatorId]; + + if (operator.snapshot.block == 0) { + revert ISSVNetworkCore.OperatorDoesNotExist(); + } + if (operator.whitelisted) { + address whitelisted = s.operatorsWhitelist[operatorId]; + if (whitelisted != address(0) && whitelisted != msg.sender) { + revert ISSVNetworkCore.CallerNotWhitelisted(); + } + } + + updateSnapshot(operator); + if ((operator.validatorCount += deltaValidatorCount) > sp.validatorsPerOperatorLimit) { revert ISSVNetworkCore.ExceedValidatorLimit(); } - burnRate += operator.fee; + + cumulativeFee += operator.fee; + cumulativeIndex += operator.snapshot.index; + + s.operators[operatorId] = operator; } - clusterIndex += operator.snapshot.index; unchecked { ++i; } diff --git a/contracts/libraries/ValidatorLib.sol b/contracts/libraries/ValidatorLib.sol index ad98ee5e..2f26e32f 100644 --- a/contracts/libraries/ValidatorLib.sol +++ b/contracts/libraries/ValidatorLib.sol @@ -5,6 +5,47 @@ import "../interfaces/ISSVNetworkCore.sol"; import "./SSVStorage.sol"; library ValidatorLib { + uint64 private constant MIN_OPERATORS_LENGTH = 4; + uint64 private constant MAX_OPERATORS_LENGTH = 13; + uint64 private constant MODULO_OPERATORS_LENGTH = 3; + uint64 private constant PUBLIC_KEY_LENGTH = 48; + + function validateOperatorsLength(uint64[] memory operatorIds) internal pure { + uint256 operatorsLength = operatorIds.length; + + if ( + operatorsLength < MIN_OPERATORS_LENGTH || + operatorsLength > MAX_OPERATORS_LENGTH || + operatorsLength % MODULO_OPERATORS_LENGTH != 1 + ) { + revert ISSVNetworkCore.InvalidOperatorIdsLength(); + } + } + + function registerPublicKeys( + bytes[] calldata publicKeys, + uint64[] memory operatorIds, + StorageData storage s + ) internal { + for (uint i; i < publicKeys.length; ++i) { + resgisterPublicKey(publicKeys[i], operatorIds, s); + } + } + + function resgisterPublicKey(bytes memory publicKey, uint64[] memory operatorIds, StorageData storage s) internal { + if (publicKey.length != PUBLIC_KEY_LENGTH) { + revert ISSVNetworkCore.InvalidPublicKeyLength(); + } + + bytes32 hashedPk = keccak256(abi.encodePacked(publicKey, msg.sender)); + + if (s.validatorPKs[hashedPk] != bytes32(0)) { + revert ISSVNetworkCore.ValidatorAlreadyExists(); + } + + s.validatorPKs[hashedPk] = bytes32(uint256(keccak256(abi.encodePacked(operatorIds))) | uint256(0x01)); // set LSB to 1 + } + function validateState( bytes calldata publicKey, uint64[] calldata operatorIds, diff --git a/contracts/modules/SSVClusters.sol b/contracts/modules/SSVClusters.sol index b05355e2..0a40c5dd 100644 --- a/contracts/modules/SSVClusters.sol +++ b/contracts/modules/SSVClusters.sol @@ -14,10 +14,6 @@ contract SSVClusters is ISSVClusters { using ClusterLib for Cluster; using OperatorLib for Operator; using ProtocolLib for StorageProtocol; - uint64 private constant MIN_OPERATORS_LENGTH = 4; - uint64 private constant MAX_OPERATORS_LENGTH = 13; - uint64 private constant MODULO_OPERATORS_LENGTH = 3; - uint64 private constant PUBLIC_KEY_LENGTH = 48; function registerValidator( bytes calldata publicKey, @@ -29,114 +25,60 @@ contract SSVClusters is ISSVClusters { StorageData storage s = SSVStorage.load(); StorageProtocol storage sp = SSVStorageProtocol.load(); - uint256 operatorsLength = operatorIds.length; - { - if ( - operatorsLength < MIN_OPERATORS_LENGTH || - operatorsLength > MAX_OPERATORS_LENGTH || - operatorsLength % MODULO_OPERATORS_LENGTH != 1 - ) { - revert InvalidOperatorIdsLength(); - } + ValidatorLib.validateOperatorsLength(operatorIds); - if (publicKey.length != PUBLIC_KEY_LENGTH) revert InvalidPublicKeyLength(); + ValidatorLib.resgisterPublicKey(publicKey, operatorIds, s); - bytes32 hashedPk = keccak256(abi.encodePacked(publicKey, msg.sender)); + bytes32 hashedCluster = cluster.validateClusterOnRegistration(operatorIds, s); - if (s.validatorPKs[hashedPk] != bytes32(0)) { - revert ValidatorAlreadyExists(); - } + cluster.balance += amount; - s.validatorPKs[hashedPk] = bytes32(uint256(keccak256(abi.encodePacked(operatorIds))) | uint256(0x01)); // set LSB to 1 - } - bytes32 hashedCluster = keccak256(abi.encodePacked(msg.sender, operatorIds)); + cluster.updateClusterOnRegistration(operatorIds, hashedCluster, 1, s, sp); - { - bytes32 clusterData = s.clusters[hashedCluster]; - if (clusterData == bytes32(0)) { - if ( - cluster.validatorCount != 0 || - cluster.networkFeeIndex != 0 || - cluster.index != 0 || - cluster.balance != 0 || - !cluster.active - ) { - revert IncorrectClusterState(); - } - } else if (clusterData != cluster.hashClusterData()) { - revert IncorrectClusterState(); - } else { - cluster.validateClusterIsNotLiquidated(); - } + if (amount != 0) { + CoreLib.deposit(amount); } - cluster.balance += amount; - - uint64 burnRate; - - if (cluster.active) { - uint64 clusterIndex; + emit ValidatorAdded(msg.sender, operatorIds, publicKey, sharesData, cluster); + } - for (uint256 i; i < operatorsLength; ) { - uint64 operatorId = operatorIds[i]; - { - if (i + 1 < operatorsLength) { - if (operatorId > operatorIds[i + 1]) { - revert UnsortedOperatorsList(); - } else if (operatorId == operatorIds[i + 1]) { - revert OperatorsListNotUnique(); - } - } - } + function bulkRegisterValidator( + bytes[] calldata publicKeys, + uint64[] memory operatorIds, + bytes[] calldata sharesData, + uint256 amount, + Cluster memory cluster + ) external override { + if (publicKeys.length != sharesData.length) revert PublicKeysSharesLengthMismatch(); - Operator memory operator = s.operators[operatorId]; - if (operator.snapshot.block == 0) { - revert OperatorDoesNotExist(); - } - if (operator.whitelisted) { - address whitelisted = s.operatorsWhitelist[operatorId]; - if (whitelisted != address(0) && whitelisted != msg.sender) { - revert CallerNotWhitelisted(); - } - } - operator.updateSnapshot(); - if (++operator.validatorCount > sp.validatorsPerOperatorLimit) { - revert ExceedValidatorLimit(); - } - clusterIndex += operator.snapshot.index; - burnRate += operator.fee; + StorageData storage s = SSVStorage.load(); + StorageProtocol storage sp = SSVStorageProtocol.load(); - s.operators[operatorId] = operator; + uint32 validatorsLength = uint32(publicKeys.length); - unchecked { - ++i; - } - } - cluster.updateClusterData(clusterIndex, sp.currentNetworkFeeIndex()); + ValidatorLib.validateOperatorsLength(operatorIds); - sp.updateDAO(true, 1); - } + ValidatorLib.registerPublicKeys(publicKeys, operatorIds, s); - ++cluster.validatorCount; + bytes32 hashedCluster = cluster.validateClusterOnRegistration(operatorIds, s); - if ( - cluster.isLiquidatable( - burnRate, - sp.networkFee, - sp.minimumBlocksBeforeLiquidation, - sp.minimumLiquidationCollateral - ) - ) { - revert InsufficientBalance(); - } + cluster.balance += amount; - s.clusters[hashedCluster] = cluster.hashClusterData(); + cluster.updateClusterOnRegistration(operatorIds, hashedCluster, validatorsLength, s, sp); if (amount != 0) { CoreLib.deposit(amount); } - emit ValidatorAdded(msg.sender, operatorIds, publicKey, sharesData, cluster); + for (uint i; i < validatorsLength; ) { + bytes memory pk = publicKeys[i]; + bytes memory sh = sharesData[i]; + emit ValidatorAdded(msg.sender, operatorIds, pk, sh, cluster); + + unchecked { + ++i; + } + } } function removeValidator( @@ -153,7 +95,7 @@ contract SSVClusters is ISSVClusters { { if (cluster.active) { StorageProtocol storage sp = SSVStorageProtocol.load(); - (uint64 clusterIndex, ) = OperatorLib.updateOperators(operatorIds, false, 1, s, sp); + (uint64 clusterIndex, ) = OperatorLib.updateClusterOperators(operatorIds, false, false, 1, s, sp); cluster.updateClusterData(clusterIndex, sp.currentNetworkFeeIndex()); @@ -178,9 +120,10 @@ contract SSVClusters is ISSVClusters { StorageProtocol storage sp = SSVStorageProtocol.load(); - (uint64 clusterIndex, uint64 burnRate) = OperatorLib.updateOperators( + (uint64 clusterIndex, uint64 burnRate) = OperatorLib.updateClusterOperators( operatorIds, false, + false, cluster.validatorCount, s, sp @@ -229,8 +172,9 @@ contract SSVClusters is ISSVClusters { StorageProtocol storage sp = SSVStorageProtocol.load(); - (uint64 clusterIndex, uint64 burnRate) = OperatorLib.updateOperators( + (uint64 clusterIndex, uint64 burnRate) = OperatorLib.updateClusterOperators( operatorIds, + false, true, cluster.validatorCount, s, diff --git a/contracts/test/SSVNetworkUpgrade.sol b/contracts/test/SSVNetworkUpgrade.sol index c7288c17..924dc6ab 100644 --- a/contracts/test/SSVNetworkUpgrade.sol +++ b/contracts/test/SSVNetworkUpgrade.sol @@ -191,17 +191,37 @@ contract SSVNetworkUpgrade is function registerValidator( bytes calldata publicKey, uint64[] memory operatorIds, - bytes calldata sharesData, + bytes calldata shares, uint256 amount, ISSVNetworkCore.Cluster memory cluster ) external override { _delegateCall( SSVStorage.load().ssvContracts[SSVModules.SSV_CLUSTERS], abi.encodeWithSignature( - "registerValidator(bytes,uint64[],bytes,uint256,(uint32,uint64,uint64,bool,uint256))", + "registerValidator(bytes[],uint64[],bytes,uint256,(uint32,uint64,uint64,bool,uint256))", publicKey, operatorIds, - sharesData, + shares, + amount, + cluster + ) + ); + } + + function bulkRegisterValidator( + bytes[] calldata publicKey, + uint64[] memory operatorIds, + bytes[] calldata shares, + uint256 amount, + ISSVNetworkCore.Cluster memory cluster + ) external override { + _delegateCall( + SSVStorage.load().ssvContracts[SSVModules.SSV_CLUSTERS], + abi.encodeWithSignature( + "registerValidator(bytes[],uint64[],bytes,uint256,(uint32,uint64,uint64,bool,uint256))", + publicKey, + operatorIds, + shares, amount, cluster ) diff --git a/contracts/test/libraries/CoreLibT.sol b/contracts/test/libraries/CoreLibT.sol index fc9bd614..285b1365 100644 --- a/contracts/test/libraries/CoreLibT.sol +++ b/contracts/test/libraries/CoreLibT.sol @@ -6,7 +6,7 @@ import "../../libraries/SSVStorage.sol"; library CoreLibT { function getVersion() internal pure returns (string memory) { - return "v1.0.2"; + return "v1.1.0"; } function transfer(address to, uint256 amount) internal { diff --git a/hardhat.config.ts b/hardhat.config.ts index 47473be1..9295be50 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -46,6 +46,7 @@ const config: HardhatUserConfig = { } as SSVNetworkConfig, hardhat: { allowUnlimitedContractSize: true, + gas: 5000000, }, }, etherscan: { diff --git a/test/deployment/version.ts b/test/deployment/version.ts index d6548c84..8611a20f 100644 --- a/test/deployment/version.ts +++ b/test/deployment/version.ts @@ -20,7 +20,7 @@ describe('Version upgrade tests', () => { await ssvNetworkContract.updateModule(helpers.SSV_MODULES.SSV_VIEWS, viewsContract.address) - expect(await ssvNetworkViews.getVersion()).to.equal("v1.0.2"); + expect(await ssvNetworkViews.getVersion()).to.equal("v1.1.0"); }); }); \ No newline at end of file diff --git a/test/helpers/contract-helpers.ts b/test/helpers/contract-helpers.ts index e025eddd..74d80eca 100644 --- a/test/helpers/contract-helpers.ts +++ b/test/helpers/contract-helpers.ts @@ -102,7 +102,7 @@ export const getClusterForValidator = ( export const initializeContract = async () => { CONFIG = { - initialVersion: 'v1.0.2', + initialVersion: 'v1.1.0', operatorMaxFeeIncrease: 1000, declareOperatorFeePeriod: 3600, // HOUR executeOperatorFeePeriod: 86400, // DAY diff --git a/test/helpers/gas-usage.ts b/test/helpers/gas-usage.ts index b7696de5..5614e03e 100644 --- a/test/helpers/gas-usage.ts +++ b/test/helpers/gas-usage.ts @@ -15,18 +15,30 @@ export enum GasGroup { REGISTER_VALIDATOR_NEW_STATE, REGISTER_VALIDATOR_WITHOUT_DEPOSIT, + BULK_REGISTER_10_VALIDATOR_NEW_STATE_4, + BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_4, + REGISTER_VALIDATOR_EXISTING_CLUSTER_7, REGISTER_VALIDATOR_NEW_STATE_7, REGISTER_VALIDATOR_WITHOUT_DEPOSIT_7, + BULK_REGISTER_10_VALIDATOR_NEW_STATE_7, + BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_7, + REGISTER_VALIDATOR_EXISTING_CLUSTER_10, REGISTER_VALIDATOR_NEW_STATE_10, REGISTER_VALIDATOR_WITHOUT_DEPOSIT_10, + BULK_REGISTER_10_VALIDATOR_NEW_STATE_10, + BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_10, + REGISTER_VALIDATOR_EXISTING_CLUSTER_13, REGISTER_VALIDATOR_NEW_STATE_13, REGISTER_VALIDATOR_WITHOUT_DEPOSIT_13, + BULK_REGISTER_10_VALIDATOR_NEW_STATE_13, + BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_13, + REMOVE_VALIDATOR, REMOVE_VALIDATOR_7, REMOVE_VALIDATOR_10, @@ -65,21 +77,33 @@ const MAX_GAS_PER_GROUP: any = { [GasGroup.EXECUTE_OPERATOR_FEE]: 52000, [GasGroup.REDUCE_OPERATOR_FEE]: 51900, - [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]: 202000, + [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]: 201200, [GasGroup.REGISTER_VALIDATOR_NEW_STATE]: 235000, - [GasGroup.REGISTER_VALIDATOR_WITHOUT_DEPOSIT]: 181600, + [GasGroup.REGISTER_VALIDATOR_WITHOUT_DEPOSIT]: 180600, + + [GasGroup.BULK_REGISTER_10_VALIDATOR_NEW_STATE_4]: 889900, + [GasGroup.BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_4]: 813000, + + [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER_7]: 272500, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]: 289000, + [GasGroup.REGISTER_VALIDATOR_WITHOUT_DEPOSIT_7]: 251600, + + [GasGroup.BULK_REGISTER_10_VALIDATOR_NEW_STATE_7]: 1085000, + [GasGroup.BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_7]: 1068000, + + [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER_10]: 342700, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_10]: 359500, + [GasGroup.REGISTER_VALIDATOR_WITHOUT_DEPOSIT_10]: 322200, - [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER_7]: 272900, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]: 289634, - [GasGroup.REGISTER_VALIDATOR_WITHOUT_DEPOSIT_7]: 252500, + [GasGroup.BULK_REGISTER_10_VALIDATOR_NEW_STATE_10]: 1364500, + [GasGroup.BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_10]: 1348000, - [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER_10]: 343600, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_10]: 360300, - [GasGroup.REGISTER_VALIDATOR_WITHOUT_DEPOSIT_10]: 323000, + [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER_13]: 413700, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]: 430500, + [GasGroup.REGISTER_VALIDATOR_WITHOUT_DEPOSIT_13]: 393200, - [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER_13]: 414500, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]: 431300, - [GasGroup.REGISTER_VALIDATOR_WITHOUT_DEPOSIT_13]: 394000, + [GasGroup.BULK_REGISTER_10_VALIDATOR_NEW_STATE_13]: 1649500, + [GasGroup.BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_13]: 1633000, [GasGroup.REMOVE_VALIDATOR]: 115000, [GasGroup.REMOVE_VALIDATOR_7]: 156000, @@ -88,7 +112,7 @@ const MAX_GAS_PER_GROUP: any = { [GasGroup.DEPOSIT]: 77500, [GasGroup.WITHDRAW_CLUSTER_BALANCE]: 94500, [GasGroup.WITHDRAW_OPERATOR_BALANCE]: 64900, - [GasGroup.VALIDATOR_EXIT]: 42900, + [GasGroup.VALIDATOR_EXIT]: 43000, [GasGroup.LIQUIDATE_CLUSTER_4]: 129300, [GasGroup.LIQUIDATE_CLUSTER_7]: 170500, diff --git a/test/helpers/json/validatorKeys.json b/test/helpers/json/validatorKeys.json index 89fbd339..e3b2a544 100644 --- a/test/helpers/json/validatorKeys.json +++ b/test/helpers/json/validatorKeys.json @@ -18,5 +18,45 @@ "id": 4, "privateKey": "0x52e4bdbdedd85e9e8a77c2f60d083a0693d6f7b2bd717f642a02514528db4278", "publicKey": "0x9150572051c3496a67207b4caa371dfba34f127318a7aef145ebdba6e0de506c292af31e20831b0c537ab7478508d3e9" + }, + { + "id": 5, + "privateKey": "0x577f673585c58ca8a105c83bf2882e46e1c4e1cfd6d850e5fbe34991da6c2db5", + "publicKey": "0x96a561928f5f54b9d114423543af93ac3c33a30f73797476c1c7f4ee5ab2cea79180c3cea460285f24177e89dcab8d9b" + }, + { + "id": 6, + "privateKey": "0x37dd327f92e790d26cb6e5b8d33076956dcb6126b9636f66e4982a1d3f122541", + "publicKey": "0x93ccd3ae7289abbac58037ac653c1a0b5cc999262da8da8f1a3547aec640267badfdf572aa93db40cab284268a7e76aa" + }, + { + "id": 7, + "privateKey": "0x68fa98ec09059c8e1b2b19e77980ee08a687da0836a0ccf6f662a5bf5340e98a", + "publicKey": "0x8871b2b0d32b6095ec0e55cece80527a813361d4b888e5da23b7c7178ceced7170cba917bb9edb225ebadd0dec649a95" + }, + { + "id": 8, + "privateKey": "0x5ee465c57bd0424b50a60c384627691e7dc3669a9f4cf27dffa375dd1edf7533", + "publicKey": "0x97d81ef3de604273711521bc780ef88ad510b8d3112c96fab917c7a060fa89b3d489a84e1050038f76ddbd2a23315fdd" + }, + { + "id": 9, + "privateKey": "0x696246c682a90413eab2a138f9e1d30aebd580332430b31b6614ee02d8cf97ed", + "publicKey": "0x8941eb35ff2eb3775bb202dc77034704e29f936823fbd615a9224ebb97cfff8a18cb4448c429669e29d6f12c74d8e684" + }, + { + "id": 10, + "privateKey": "0x4bee4207ab3d375085bfb194a333bccc9eb5bb15ff84e134f23626176013b18b", + "publicKey": "0xb2a9e7d7fbad825b30de6b5a9fd8ff5c0604ba0719bd188d5606bc34ac1046dd9dc1aee6b3ca823b1da2897f965ced49" + }, + { + "id": 11, + "privateKey": "0x687d72d8ac9f8ccab3c7145701d651a919c2ef9c65e8508370b82af11fe8bb60", + "publicKey": "0xa750714a3b02a92070995ac3094b16ff8e025fafc156dce53babecf03df4e62dbe4da9edad802bf0afdbd24742312ab2" + }, + { + "id": 12, + "privateKey": "0x040ad8e3dfcda106f9a5772084aebc417ab83632973b609904f07943d75f87e5", + "publicKey": "0xaec659ca36bb2fef6770144adb1411f7348fc7171b6c65dd276dac806c643e180160c1da521b65a5b7ea9da9f0704a30" } -] +] \ No newline at end of file diff --git a/test/validators/register.ts b/test/validators/register.ts index fe36cbff..08fe6048 100644 --- a/test/validators/register.ts +++ b/test/validators/register.ts @@ -225,17 +225,72 @@ describe('Register Validator Tests', () => { ); }); + it('Bulk register 10 validators with 4 operators into the same cluster', async () => { + await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); + const { eventsByName } = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).bulkRegisterValidator( + [helpers.DataGenerator.publicKey(11)], + [1, 2, 3, 4], + [helpers.DataGenerator.shares(1,11,4)], + minDepositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true + } + )); + + const args = eventsByName.ValidatorAdded[0].args; + + const pks = Array.from({ length: 10 }, (_, index) => helpers.DataGenerator.publicKey(index + 1)); + const shares = Array.from({ length: 10 }, (_, index) => helpers.DataGenerator.shares(1, index, 4)); + const depositAmount = minDepositAmount * 10; + + await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, depositAmount); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).bulkRegisterValidator( + pks, + [1, 2, 3, 4], + shares, + depositAmount, + args.cluster + ), [GasGroup.BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_4]); + }); + + it('Bulk register 10 validators with 4 operators new cluster', async () => { + const pks = Array.from({ length: 10 }, (_, index) => helpers.DataGenerator.publicKey(index + 1)); + const operatorIds = [1, 2, 3, 4]; + const shares = Array.from({ length: 10 }, (_, index) => helpers.DataGenerator.shares(1, index, 4)); + + const depositAmount = minDepositAmount * 10; + + await helpers.DB.ssvToken.approve(ssvNetworkContract.address, depositAmount); + await trackGas(ssvNetworkContract.bulkRegisterValidator( + pks, + operatorIds, + shares, + depositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true + } + ), [GasGroup.BULK_REGISTER_10_VALIDATOR_NEW_STATE_4]); + }); + // 7 operators it('Register validator with 7 operators gas limit', async () => { - await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); + await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(helpers.DB.ssvNetwork.contract.address, minDepositAmount); await trackGas( ssvNetworkContract .connect(helpers.DB.owners[1]) .registerValidator( - helpers.DataGenerator.publicKey(1), + helpers.DataGenerator.publicKey(2), helpers.DataGenerator.cluster.new(7), - helpers.DataGenerator.shares(1, 1, 7), + helpers.DataGenerator.shares(1, 2, 7), minDepositAmount, { validatorCount: 0, @@ -383,6 +438,64 @@ describe('Register Validator Tests', () => { ); }); + it('Bulk register 10 validators with 7 operators into the same cluster', async () => { + const operatorIds = [1, 2, 3, 4, 5, 6, 7]; + + await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); + const { eventsByName } = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).bulkRegisterValidator( + [helpers.DataGenerator.publicKey(11)], + operatorIds, + [helpers.DataGenerator.shares(1,11,operatorIds.length)], + minDepositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true + } + )); + + const args = eventsByName.ValidatorAdded[0].args; + + const pks = Array.from({ length: 10 }, (_, index) => helpers.DataGenerator.publicKey(index + 1)); + const shares = Array.from({ length: 10 }, (_, index) => helpers.DataGenerator.shares(1, index, operatorIds.length)); + const depositAmount = minDepositAmount * 10; + + await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, depositAmount); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).bulkRegisterValidator( + pks, + operatorIds, + shares, + depositAmount, + args.cluster + ), [GasGroup.BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_7]); + }); + + it('Bulk register 10 validators with 7 operators new cluster', async () => { + const operatorIds = [1, 2, 3, 4, 5, 6, 7]; + + const pks = Array.from({ length: 10 }, (_, index) => helpers.DataGenerator.publicKey(index + 1)); + const shares = Array.from({ length: 10 }, (_, index) => helpers.DataGenerator.shares(1, index, operatorIds.length)); + const depositAmount = minDepositAmount * 10; + + await helpers.DB.ssvToken.approve(ssvNetworkContract.address, depositAmount); + + await trackGas(ssvNetworkContract.bulkRegisterValidator( + pks, + operatorIds, + shares, + depositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true + } + ), [GasGroup.BULK_REGISTER_10_VALIDATOR_NEW_STATE_7]); + }); + // 10 operators it('Register validator with 10 operators gas limit', async () => { @@ -541,6 +654,64 @@ describe('Register Validator Tests', () => { ); }); + it('Bulk register 10 validators with 10 operators into the same cluster', async () => { + const operatorIds = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + + await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); + const { eventsByName } = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).bulkRegisterValidator( + [helpers.DataGenerator.publicKey(11)], + operatorIds, + [helpers.DataGenerator.shares(1,10,operatorIds.length)], + minDepositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true + } + )); + + const args = eventsByName.ValidatorAdded[0].args; + + const pks = Array.from({ length: 10 }, (_, index) => helpers.DataGenerator.publicKey(index + 1)); + const shares = Array.from({ length: 10 }, (_, index) => helpers.DataGenerator.shares(1,index, operatorIds.length)); + const depositAmount = minDepositAmount * 10; + + await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, depositAmount); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).bulkRegisterValidator( + pks, + operatorIds, + shares, + depositAmount, + args.cluster + ), [GasGroup.BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_10]); + }); + + it('Bulk register 10 validators with 10 operators new cluster', async () => { + const operatorIds = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + + const pks = Array.from({ length: 10 }, (_, index) => helpers.DataGenerator.publicKey(index + 1)); + const shares = Array.from({ length: 10 }, (_, index) => helpers.DataGenerator.shares(1, index, operatorIds.length)); + + const depositAmount = minDepositAmount * 10; + + await helpers.DB.ssvToken.approve(ssvNetworkContract.address, depositAmount); + await trackGas(ssvNetworkContract.bulkRegisterValidator( + pks, + operatorIds, + shares, + depositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true + } + ), [GasGroup.BULK_REGISTER_10_VALIDATOR_NEW_STATE_10]); + }); + // 13 operators it('Register validator with 13 operators gas limit', async () => { @@ -697,6 +868,64 @@ describe('Register Validator Tests', () => { ); }); + it('Bulk register 10 validators with 13 operators into the same cluster', async () => { + const operatorIds = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]; + + await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); + const { eventsByName } = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).bulkRegisterValidator( + [helpers.DataGenerator.publicKey(11)], + operatorIds, + [helpers.DataGenerator.shares(1, 11, operatorIds.length)], + minDepositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true + } + )); + + const args = eventsByName.ValidatorAdded[0].args; + + const pks = Array.from({ length: 10 }, (_, index) => helpers.DataGenerator.publicKey(index + 1)); + const shares = Array.from({ length: 10 }, (_, index) => helpers.DataGenerator.shares(1, index, operatorIds.length)); + const depositAmount = minDepositAmount * 10; + + await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, depositAmount); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).bulkRegisterValidator( + pks, + operatorIds, + shares, + depositAmount, + args.cluster + ), [GasGroup.BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_13]); + }); + + it('Bulk register 10 validators with 13 operators new cluster', async () => { + const operatorIds = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]; + + const pks = Array.from({ length: 10 }, (_, index) => helpers.DataGenerator.publicKey(index + 1)); + const shares = Array.from({ length: 10 }, (_, index) => helpers.DataGenerator.shares(1, index, operatorIds.length)); + + const depositAmount = minDepositAmount * 10; + + await helpers.DB.ssvToken.approve(ssvNetworkContract.address, depositAmount); + await trackGas(ssvNetworkContract.bulkRegisterValidator( + pks, + operatorIds, + shares, + depositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true + } + ), [GasGroup.BULK_REGISTER_10_VALIDATOR_NEW_STATE_13]); + }); + it('Get cluster burn rate', async () => { const networkFee = helpers.CONFIG.minimalOperatorFee; await ssvNetworkContract.updateNetworkFee(networkFee); @@ -856,7 +1085,7 @@ describe('Register Validator Tests', () => { ssvNetworkContract.registerValidator( helpers.DataGenerator.publicKey(1), [3, 6, 12, 12], - helpers.DataGenerator.shares(0, 5, 6), + helpers.DataGenerator.shares(0, 1, 4), minDepositAmount, { validatorCount: 0, From 5638b7fc9af1806187679204f16d6f7cbd33d5ad Mon Sep 17 00:00:00 2001 From: Marco Tabasco Date: Mon, 8 Jan 2024 14:23:22 +0100 Subject: [PATCH 19/38] update CHANGELOG --- CHANGELOG.md | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ec5a4fb4..a96f4d6b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,35 +6,39 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ## [Unreleased] -## [v1.1.0] 2023-12-18 -- Bulk registration of validators. +### [v1.1.0] 2024-01-08 +- [9c609cd](https://github.com/bloxapp/ssv-network/commit/9c609cd) - Bulk registration of validators. +- [c9a90b1](https://github.com/bloxapp/ssv-network/commit/c9a90b1) - [Update] Added triggers for compilation in a few tasks (upgrading / updating). +- [4471f05](https://github.com/bloxapp/ssv-network/commit/4471f05) - [Update] Deployment tests and update task and documentation. +- [7564dfe](https://github.com/bloxapp/ssv-network/commit/7564dfe) - [Feature] Integration ssv-keys in ssv-network for generating keyshares. +- [8647401](https://github.com/bloxapp/ssv-network/commit/8647401) - [Update]: Configuration for publishing npm package. -## [v1.0.2] 2023-11-08 -- [8f5df42](https://github.com/bloxapp/ssv-network/commit/8f5df42633d2b92c6bb70253a41e6afa80b9f111) - Change ValidatorExited signature: owner indexed. +## [Released] -## [v1.0.1] 2023-11-08 +### [v1.0.2] 2023-11-08 +- [8f5df42](https://github.com/bloxapp/ssv-network/commit/8f5df42633d2b92c6bb70253a41e6afa80b9f111) - Change ValidatorExited signature: owner indexed. -### Added +### [v1.0.1] 2023-11-08 +#### Added - [0ab954e](https://github.com/bloxapp/ssv-network/commit/0ab954ec24fc0b32b51c278958c3d51480940f1a) - Permissionless audited version. -## [v1.0.0-rc3-permissionless-validators] 2023-11-08 +### [v1.0.0-rc3-permissionless-validators] 2023-11-08 Takes v1.0.0-rc3 as the base tag. - [8878241](https://github.com/bloxapp/ssv-network/commit/88782410ad3223c75f205484811a010231c64152) Enable permissionless validator registration. -## [v1.0.0] - 2023-10-30 - -### Fixed +### [v1.0.0] - 2023-10-30 +#### Fixed - [22d2859](https://github.com/bloxapp/ssv-network/pull/262/commits/22d2859d8fe6267b09c7a1c9c645df19bdaa03ff) Fix bug in network earnings withdrawals. - [d25d188](https://github.com/bloxapp/ssv-network/pull/265/commits/d25d18886459e631fb4453df7a47db19982ec80e) Fix Types.shrink() bug. -### Added +#### Added - [bf0c51d](https://github.com/bloxapp/ssv-network/pull/263/commits/bf0c51d4df191018052d11425c9fcc252de61431) A validator can voluntarily exit. -## [v1.0.0.rc4] - 2023-08-31 +### [v1.0.0.rc4] - 2023-08-31 - Audit fixes/recommendations - Validate a cluster with 0 validators can not be liquidated From 6431a00f6aeaabe5ffa99e25861152be334b588e Mon Sep 17 00:00:00 2001 From: Marco Tabasco Date: Tue, 16 Jan 2024 00:33:56 +0100 Subject: [PATCH 20/38] bulk remove validators --- contracts/SSVNetwork.sol | 8 + contracts/interfaces/ISSVClusters.sol | 14 +- contracts/libraries/ValidatorLib.sol | 24 +- contracts/modules/SSVClusters.sol | 60 ++++- contracts/test/SSVNetworkUpgrade.sol | 16 ++ test/helpers/contract-helpers.ts | 44 ++- test/helpers/gas-usage.ts | 14 +- test/sanity/balances.ts | 80 +++++- test/validators/register.ts | 367 ++++++-------------------- test/validators/remove.ts | 120 ++++++++- 10 files changed, 436 insertions(+), 311 deletions(-) diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index e6a058e4..adbe0ac8 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -193,6 +193,14 @@ contract SSVNetwork is _delegate(SSVStorage.load().ssvContracts[SSVModules.SSV_CLUSTERS]); } + function bulkRemoveValidator( + bytes[] calldata publicKeys, + uint64[] calldata operatorIds, + Cluster memory cluster + ) external override { + _delegate(SSVStorage.load().ssvContracts[SSVModules.SSV_CLUSTERS]); + } + function liquidate( address clusterOwner, uint64[] calldata operatorIds, diff --git a/contracts/interfaces/ISSVClusters.sol b/contracts/interfaces/ISSVClusters.sol index ca6fb727..21b993de 100644 --- a/contracts/interfaces/ISSVClusters.sol +++ b/contracts/interfaces/ISSVClusters.sol @@ -19,9 +19,9 @@ interface ISSVClusters is ISSVNetworkCore { ) external; /// @notice Registers new validators on the SSV Network - /// @param publicKeys The public key of the new validator + /// @param publicKeys The public keys of the new validators /// @param operatorIds Array of IDs of operators managing this validator - /// @param sharesData Encrypted shares related to the new validator + /// @param sharesData Encrypted shares related to the new validators /// @param amount Amount of SSV tokens to be deposited /// @param cluster Cluster to be used with the new validator function bulkRegisterValidator( @@ -38,6 +38,16 @@ interface ISSVClusters is ISSVNetworkCore { /// @param cluster Cluster associated with the validator function removeValidator(bytes calldata publicKey, uint64[] memory operatorIds, Cluster memory cluster) external; + /// @notice Removes an existing validator from the SSV Network + /// @param publicKeys The public keys of the validators to be removed + /// @param operatorIds Array of IDs of operators managing the validator + /// @param cluster Cluster associated with the validator + function bulkRemoveValidator( + bytes[] calldata publicKeys, + uint64[] memory operatorIds, + Cluster memory cluster + ) external; + /**************************/ /* Cluster External Functions */ /**************************/ diff --git a/contracts/libraries/ValidatorLib.sol b/contracts/libraries/ValidatorLib.sol index 2f26e32f..ae12e02f 100644 --- a/contracts/libraries/ValidatorLib.sol +++ b/contracts/libraries/ValidatorLib.sol @@ -46,9 +46,27 @@ library ValidatorLib { s.validatorPKs[hashedPk] = bytes32(uint256(keccak256(abi.encodePacked(operatorIds))) | uint256(0x01)); // set LSB to 1 } + function hashOperatorIds(uint64[] calldata operatorIds) internal pure returns (bytes32) { + bytes32 mask = ~bytes32(uint256(1)); // All bits set to 1 except LSB + return keccak256(abi.encodePacked(operatorIds)) & mask; // Clear LSB of provided operator ids + } + + function validateStates( + bytes[] calldata publicKeys, + uint64[] calldata operatorIds, + StorageData storage s + ) internal view returns (bytes32[] memory hashedValidator) { + hashedValidator = new bytes32[](publicKeys.length); + bytes32 hashedOperatorIds = hashOperatorIds(operatorIds); + + for (uint i; i < publicKeys.length; ++i) { + hashedValidator[i] = validateState(publicKeys[i], hashedOperatorIds, s); + } + } + function validateState( bytes calldata publicKey, - uint64[] calldata operatorIds, + bytes32 hashedOperatorIds, StorageData storage s ) internal view returns (bytes32 hashedValidator) { hashedValidator = keccak256(abi.encodePacked(publicKey, msg.sender)); @@ -57,10 +75,8 @@ library ValidatorLib { if (validatorData == bytes32(0)) { revert ISSVNetworkCore.ValidatorDoesNotExist(); } - bytes32 mask = ~bytes32(uint256(1)); // All bits set to 1 except LSB - bytes32 hashedOperatorIds = keccak256(abi.encodePacked(operatorIds)) & mask; // Clear LSB of provided operator ids - if ((validatorData & mask) != hashedOperatorIds) { + if ((validatorData & ~bytes32(uint256(1))) != hashedOperatorIds) { // All bits set to 1 except LSB // Clear LSB of stored validator data and compare revert ISSVNetworkCore.IncorrectValidatorState(); } diff --git a/contracts/modules/SSVClusters.sol b/contracts/modules/SSVClusters.sol index 0a40c5dd..dba001f6 100644 --- a/contracts/modules/SSVClusters.sol +++ b/contracts/modules/SSVClusters.sol @@ -88,19 +88,18 @@ contract SSVClusters is ISSVClusters { ) external override { StorageData storage s = SSVStorage.load(); - bytes32 hashedValidator = ValidatorLib.validateState(publicKey, operatorIds, s); + bytes32 hashedOperatorIds = ValidatorLib.hashOperatorIds(operatorIds); + bytes32 hashedValidator = ValidatorLib.validateState(publicKey, hashedOperatorIds, s); bytes32 hashedCluster = cluster.validateHashedCluster(msg.sender, operatorIds, s); - { - if (cluster.active) { - StorageProtocol storage sp = SSVStorageProtocol.load(); - (uint64 clusterIndex, ) = OperatorLib.updateClusterOperators(operatorIds, false, false, 1, s, sp); + if (cluster.active) { + StorageProtocol storage sp = SSVStorageProtocol.load(); + (uint64 clusterIndex, ) = OperatorLib.updateClusterOperators(operatorIds, false, false, 1, s, sp); - cluster.updateClusterData(clusterIndex, sp.currentNetworkFeeIndex()); + cluster.updateClusterData(clusterIndex, sp.currentNetworkFeeIndex()); - sp.updateDAO(false, 1); - } + sp.updateDAO(false, 1); } --cluster.validatorCount; @@ -112,6 +111,48 @@ contract SSVClusters is ISSVClusters { emit ValidatorRemoved(msg.sender, operatorIds, publicKey, cluster); } + function bulkRemoveValidator( + bytes[] calldata publicKeys, + uint64[] calldata operatorIds, + Cluster memory cluster + ) external override { + StorageData storage s = SSVStorage.load(); + + bytes32 hashedCluster = cluster.validateHashedCluster(msg.sender, operatorIds, s); + + bytes32[] memory hashedValidators = ValidatorLib.validateStates(publicKeys, operatorIds, s); + + uint32 validatorsLength = uint32(publicKeys.length); + + if (cluster.active) { + StorageProtocol storage sp = SSVStorageProtocol.load(); + (uint64 clusterIndex, ) = OperatorLib.updateClusterOperators( + operatorIds, + false, + false, + validatorsLength, + s, + sp + ); + + cluster.updateClusterData(clusterIndex, sp.currentNetworkFeeIndex()); + + sp.updateDAO(false, validatorsLength); + } + + for (uint i; i < validatorsLength; ++i) { + delete s.validatorPKs[hashedValidators[i]]; + } + + cluster.validatorCount -= validatorsLength; + + s.clusters[hashedCluster] = cluster.hashClusterData(); + + for (uint i; i < validatorsLength; ++i) { + emit ValidatorRemoved(msg.sender, operatorIds, publicKeys[i], cluster); + } + } + function liquidate(address clusterOwner, uint64[] calldata operatorIds, Cluster memory cluster) external override { StorageData storage s = SSVStorage.load(); @@ -280,7 +321,8 @@ contract SSVClusters is ISSVClusters { } function exitValidator(bytes calldata publicKey, uint64[] calldata operatorIds) external override { - ValidatorLib.validateState(publicKey, operatorIds, SSVStorage.load()); + bytes32 hashedOperatorIds = ValidatorLib.hashOperatorIds(operatorIds); + ValidatorLib.validateState(publicKey, hashedOperatorIds, SSVStorage.load()); emit ValidatorExited(msg.sender, operatorIds, publicKey); } diff --git a/contracts/test/SSVNetworkUpgrade.sol b/contracts/test/SSVNetworkUpgrade.sol index 924dc6ab..9731270d 100644 --- a/contracts/test/SSVNetworkUpgrade.sol +++ b/contracts/test/SSVNetworkUpgrade.sol @@ -244,6 +244,22 @@ contract SSVNetworkUpgrade is ); } + function bulkRemoveValidator( + bytes[] calldata publicKeys, + uint64[] calldata operatorIds, + ISSVNetworkCore.Cluster memory cluster + ) external override { + _delegateCall( + SSVStorage.load().ssvContracts[SSVModules.SSV_CLUSTERS], + abi.encodeWithSignature( + "bulkRemoveValidator(bytes[],uint64[],(uint32,uint64,uint64,bool,uint256))", + publicKeys, + operatorIds, + cluster + ) + ); + } + function liquidate(address owner, uint64[] calldata operatorIds, ISSVNetworkCore.Cluster memory cluster) external { _delegateCall( SSVStorage.load().ssvContracts[SSVModules.SSV_CLUSTERS], diff --git a/test/helpers/contract-helpers.ts b/test/helpers/contract-helpers.ts index 74d80eca..80148605 100644 --- a/test/helpers/contract-helpers.ts +++ b/test/helpers/contract-helpers.ts @@ -10,6 +10,13 @@ export let DB: any; export let CONFIG: any; export let SSV_MODULES: any; +export const DEFAULT_OPERATOR_IDS = { + 4: [1, 2, 3, 4], + 7: [1, 2, 3, 4, 5, 6, 7], + 10: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + 13: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13] +}; + const getSecretSharedPayload = async (validator: Validator, operatorIds: number[], ownerId: number) => { const selOperators = DB.operators.filter((item: Operator) => operatorIds.includes(item.id)); const operators = selOperators.map((item: Operator) => ({ id: item.id, operatorKey: item.operatorKey })); @@ -128,6 +135,13 @@ export const initializeContract = async () => { ssvDAOMod: {}, ssvViewsMod: {}, ownerNonce: 0, + initialClusterState: { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true + } }; SSV_MODULES = { @@ -304,12 +318,40 @@ export const registerValidators = async ( return { regValidators, args }; }; +export const bulkRegisterValidators = async ( + ownerId: number, + numberOfValidators: number, + operatorIds: number[], + minDepositAmount: any, + cluster: any, + gasGroups?: GasGroup[] +) => { + const pks = Array.from({ length: numberOfValidators }, (_, index) => DataGenerator.publicKey(index + 1)); + const shares = Array.from({ length: numberOfValidators }, (_, index) => DataGenerator.shares(1, index, operatorIds.length)); + const depositAmount = minDepositAmount * numberOfValidators; + + await DB.ssvToken.connect(DB.owners[ownerId]).approve(DB.ssvNetwork.contract.address, depositAmount); + + const result = await trackGas(DB.ssvNetwork.contract.connect(DB.owners[ownerId]).bulkRegisterValidator( + pks, + operatorIds, + shares, + depositAmount, + cluster + ), gasGroups); + + return { + args: result.eventsByName.ValidatorAdded[0].args, + pks + }; +}; + export const coldRegisterValidator = async () => { const ssvKeys = new SSVKeys(); const keyShares = new KeyShares(); const validator = DB.validators[0]; - const operators = DB.operators.map((item: Operator) => ({ id: item.id, operatorKey: item.operatorKey })); + const operators = DB.operators.slice(0, 4).map((item: Operator) => ({ id: item.id, operatorKey: item.operatorKey })); const publicKey = validator.publicKey; const privateKey = validator.privateKey; const threshold = await ssvKeys.createThreshold(privateKey, operators); diff --git a/test/helpers/gas-usage.ts b/test/helpers/gas-usage.ts index 5614e03e..e40ad15f 100644 --- a/test/helpers/gas-usage.ts +++ b/test/helpers/gas-usage.ts @@ -40,9 +40,13 @@ export enum GasGroup { BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_13, REMOVE_VALIDATOR, + BULK_REMOVE_10_VALIDATOR_4, REMOVE_VALIDATOR_7, + BULK_REMOVE_10_VALIDATOR_7, REMOVE_VALIDATOR_10, + BULK_REMOVE_10_VALIDATOR_10, REMOVE_VALIDATOR_13, + BULK_REMOVE_10_VALIDATOR_13, DEPOSIT, WITHDRAW_CLUSTER_BALANCE, WITHDRAW_OPERATOR_BALANCE, @@ -102,13 +106,21 @@ const MAX_GAS_PER_GROUP: any = { [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]: 430500, [GasGroup.REGISTER_VALIDATOR_WITHOUT_DEPOSIT_13]: 393200, - [GasGroup.BULK_REGISTER_10_VALIDATOR_NEW_STATE_13]: 1649500, + [GasGroup.BULK_REGISTER_10_VALIDATOR_NEW_STATE_13]: 1649600, [GasGroup.BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_13]: 1633000, [GasGroup.REMOVE_VALIDATOR]: 115000, + [GasGroup.BULK_REMOVE_10_VALIDATOR_4]: 196000, + [GasGroup.REMOVE_VALIDATOR_7]: 156000, + [GasGroup.BULK_REMOVE_10_VALIDATOR_7]: 248500, + [GasGroup.REMOVE_VALIDATOR_10]: 197500, + [GasGroup.BULK_REMOVE_10_VALIDATOR_10]: 301000, + [GasGroup.REMOVE_VALIDATOR_13]: 239000, + [GasGroup.BULK_REMOVE_10_VALIDATOR_13]: 353200, + [GasGroup.DEPOSIT]: 77500, [GasGroup.WITHDRAW_CLUSTER_BALANCE]: 94500, [GasGroup.WITHDRAW_OPERATOR_BALANCE]: 64900, diff --git a/test/sanity/balances.ts b/test/sanity/balances.ts index 6832ddb0..e19da092 100644 --- a/test/sanity/balances.ts +++ b/test/sanity/balances.ts @@ -290,16 +290,17 @@ describe('Balance Tests', () => { await utils.progressBlocks(2); expect(await ssvViews.getOperatorEarnings(1)).to.equal( - helpers.CONFIG.minimalOperatorFee * 8 + helpers.CONFIG.minimalOperatorFee * 8, + helpers.CONFIG.minimalOperatorFee * 8 + + helpers.CONFIG.minimalOperatorFee * 8 ); expect(await ssvViews.getOperatorEarnings(3)).to.equal( helpers.CONFIG.minimalOperatorFee * 8 + - helpers.CONFIG.minimalOperatorFee * 8 + - helpers.CONFIG.minimalOperatorFee * 2, + helpers.CONFIG.minimalOperatorFee * 8 + + helpers.CONFIG.minimalOperatorFee * 2, ); expect(await ssvViews.getOperatorEarnings(5)).to.equal( - helpers.CONFIG.minimalOperatorFee * 6 + helpers.CONFIG.minimalOperatorFee * 5, + helpers.CONFIG.minimalOperatorFee * 2 ); expect( await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), @@ -328,11 +329,12 @@ describe('Balance Tests', () => { ); expect(await ssvViews.getOperatorEarnings(3)).to.equal( helpers.CONFIG.minimalOperatorFee * 14 + - helpers.CONFIG.minimalOperatorFee * 12 + - helpers.CONFIG.minimalOperatorFee * 7, + helpers.CONFIG.minimalOperatorFee * 12 + + helpers.CONFIG.minimalOperatorFee * 7, ); expect(await ssvViews.getOperatorEarnings(5)).to.equal( - helpers.CONFIG.minimalOperatorFee * 11 + helpers.CONFIG.minimalOperatorFee * 10, + helpers.CONFIG.minimalOperatorFee * 2 + + helpers.CONFIG.minimalOperatorFee * 5 ); // cold cluster + cluster1 * networkFee (4) + (cold cluster + cluster1 * newNetworkFee (6 + 6)) + cluster2 * newNetworkFee (3) + (cold cluster + cluster1 + cluster2 * networkFee (4 + 4 + 4)) @@ -355,7 +357,7 @@ describe('Balance Tests', () => { ).to.equal(minDepositAmount - burnPerBlock - (helpers.CONFIG.minimalOperatorFee * 3 + networkFee) * 2 - newFee * 2); }); - it('Check cluster balance after withdraw and deposit"', async () => { + it('Check cluster balance after withdraw and deposit', async () => { await utils.progressBlocks(1); expect( await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster), @@ -412,10 +414,64 @@ describe('Balance Tests', () => { await ssvViews.getBalance(helpers.DB.owners[4].address, cluster2.args.operatorIds, cluster2.args.cluster), ).to.equal( minDepositAmount * 3 - - burnPerBlock * 8 - - burnPerBlock * 5 - - helpers.CONFIG.minimalOperatorFee + - helpers.CONFIG.minimalOperatorFee, + burnPerBlock * 8 - + burnPerBlock * 5 - + helpers.CONFIG.minimalOperatorFee + + helpers.CONFIG.minimalOperatorFee, + ); + }); + + it('Check cluster and operators balance after 10 validators bulk registration and removal', async () => { + const clusterDeposit = minDepositAmount * 10; + + // Register 10 validators in a cluster + const { args, pks } = await helpers.bulkRegisterValidators( + 2, + 10, + [5, 6, 7, 8], + minDepositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true, + }, + ); + + await utils.progressBlocks(2); + + // check cluster balance + expect( + await ssvViews.getBalance(helpers.DB.owners[2].address, args.operatorIds, args.cluster), + ).to.equal(clusterDeposit - (burnPerBlock * 10 * 2)); + + // check operators' earnings + expect(await ssvViews.getOperatorEarnings(5)).to.equal(helpers.CONFIG.minimalOperatorFee * 10 * 2); + expect(await ssvViews.getOperatorEarnings(6)).to.equal(helpers.CONFIG.minimalOperatorFee * 10 * 2); + expect(await ssvViews.getOperatorEarnings(7)).to.equal(helpers.CONFIG.minimalOperatorFee * 10 * 2); + expect(await ssvViews.getOperatorEarnings(8)).to.equal(helpers.CONFIG.minimalOperatorFee * 10 * 2); + + // bulk remove 5 validators + const result = await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[2]) + .bulkRemoveValidator(pks.slice(0, 5), args.operatorIds, args.cluster) ); + + const removed = result.eventsByName.ValidatorRemoved[0].args; + + await utils.progressBlocks(2); + + // check cluster balance + expect( + await ssvViews.getBalance(helpers.DB.owners[2].address, removed.operatorIds, removed.cluster), + ).to.equal(clusterDeposit - (burnPerBlock * 10 * 3) - (burnPerBlock * 5 * 2)); + + // check operators' earnings + expect(await ssvViews.getOperatorEarnings(5)).to.equal((helpers.CONFIG.minimalOperatorFee * 10 * 3) + (helpers.CONFIG.minimalOperatorFee * 5 * 2)); + expect(await ssvViews.getOperatorEarnings(6)).to.equal((helpers.CONFIG.minimalOperatorFee * 10 * 3) + (helpers.CONFIG.minimalOperatorFee * 5 * 2)); + expect(await ssvViews.getOperatorEarnings(7)).to.equal((helpers.CONFIG.minimalOperatorFee * 10 * 3) + (helpers.CONFIG.minimalOperatorFee * 5 * 2)); + expect(await ssvViews.getOperatorEarnings(8)).to.equal((helpers.CONFIG.minimalOperatorFee * 10 * 3) + (helpers.CONFIG.minimalOperatorFee * 5 * 2)); }); }); diff --git a/test/validators/register.ts b/test/validators/register.ts index 08fe6048..4cb4655b 100644 --- a/test/validators/register.ts +++ b/test/validators/register.ts @@ -4,7 +4,7 @@ import * as utils from '../helpers/utils'; import { expect } from 'chai'; import { trackGas, GasGroup } from '../helpers/gas-usage'; -let ssvNetworkContract: any, ssvViews: any, ssvToken: any, minDepositAmount: any, cluster1: any; +let ssvNetworkContract: any, ssvViews: any, ssvToken: any, minDepositAmount: any, cluster1: any, initialClusterState: any; describe('Register Validator Tests', () => { beforeEach(async () => { @@ -14,6 +14,8 @@ describe('Register Validator Tests', () => { ssvToken = metadata.ssvToken; ssvViews = metadata.ssvViews; + initialClusterState = helpers.DB.initialClusterState; + // Register operators await helpers.registerOperators(0, 14, helpers.CONFIG.minimalOperatorFee); @@ -31,13 +33,7 @@ describe('Register Validator Tests', () => { [1, 2, 3, 4], helpers.DataGenerator.shares(6, 1, 4), '1000000000000000', - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true, - }, + initialClusterState, ), ); }); @@ -52,13 +48,7 @@ describe('Register Validator Tests', () => { [1, 2, 3, 4], helpers.DataGenerator.shares(1, 1, 4), minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true, - }, + initialClusterState, ), ).to.emit(ssvNetworkContract, 'ValidatorAdded'); }); @@ -75,13 +65,7 @@ describe('Register Validator Tests', () => { helpers.DataGenerator.cluster.new(), helpers.DataGenerator.shares(1, 1, 4), minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true, - }, + initialClusterState, ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE], ); @@ -101,13 +85,7 @@ describe('Register Validator Tests', () => { [1, 2, 3, 4], helpers.DataGenerator.shares(1, 1, 4), minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true, - }, + initialClusterState, ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE], ); @@ -139,13 +117,7 @@ describe('Register Validator Tests', () => { [1, 2, 3, 4], helpers.DataGenerator.shares(1, 1, 4), minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true, - }, + initialClusterState, ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE], ); @@ -175,13 +147,7 @@ describe('Register Validator Tests', () => { [2, 3, 4, 5], helpers.DataGenerator.shares(2, 4, 4), minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true, - }, + initialClusterState, ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE], ); @@ -199,13 +165,7 @@ describe('Register Validator Tests', () => { [1, 2, 3, 4], helpers.DataGenerator.shares(1, 1, 4), `${minDepositAmount * 2}`, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true, - }, + initialClusterState, ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE], ); @@ -242,42 +202,32 @@ describe('Register Validator Tests', () => { )); const args = eventsByName.ValidatorAdded[0].args; - - const pks = Array.from({ length: 10 }, (_, index) => helpers.DataGenerator.publicKey(index + 1)); - const shares = Array.from({ length: 10 }, (_, index) => helpers.DataGenerator.shares(1, index, 4)); - const depositAmount = minDepositAmount * 10; - - await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, depositAmount); - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).bulkRegisterValidator( - pks, + await helpers.bulkRegisterValidators( + 1, + 10, [1, 2, 3, 4], - shares, - depositAmount, - args.cluster - ), [GasGroup.BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_4]); + minDepositAmount, + args.cluster, + [GasGroup.BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_4], + ); }); it('Bulk register 10 validators with 4 operators new cluster', async () => { - const pks = Array.from({ length: 10 }, (_, index) => helpers.DataGenerator.publicKey(index + 1)); - const operatorIds = [1, 2, 3, 4]; - const shares = Array.from({ length: 10 }, (_, index) => helpers.DataGenerator.shares(1, index, 4)); - - const depositAmount = minDepositAmount * 10; - await helpers.DB.ssvToken.approve(ssvNetworkContract.address, depositAmount); - await trackGas(ssvNetworkContract.bulkRegisterValidator( - pks, - operatorIds, - shares, - depositAmount, + await helpers.bulkRegisterValidators( + 1, + 10, + [1, 2, 3, 4], + minDepositAmount, { validatorCount: 0, networkFeeIndex: 0, index: 0, balance: 0, active: true - } - ), [GasGroup.BULK_REGISTER_10_VALIDATOR_NEW_STATE_4]); + }, + [GasGroup.BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_4], + ); }); // 7 operators @@ -292,13 +242,7 @@ describe('Register Validator Tests', () => { helpers.DataGenerator.cluster.new(7), helpers.DataGenerator.shares(1, 2, 7), minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true, - }, + initialClusterState, ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7], ); @@ -314,13 +258,7 @@ describe('Register Validator Tests', () => { [1, 2, 3, 4, 5, 6, 7], helpers.DataGenerator.shares(1, 1, 7), minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true, - }, + initialClusterState, ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7], ); @@ -352,13 +290,7 @@ describe('Register Validator Tests', () => { [1, 2, 3, 4, 5, 6, 7], helpers.DataGenerator.shares(1, 1, 7), minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true, - }, + initialClusterState, ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7], ); @@ -388,13 +320,7 @@ describe('Register Validator Tests', () => { [2, 3, 4, 5, 6, 7, 8], helpers.DataGenerator.shares(2, 4, 7), minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true, - }, + initialClusterState, ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7], ); @@ -412,13 +338,7 @@ describe('Register Validator Tests', () => { [1, 2, 3, 4, 5, 6, 7], helpers.DataGenerator.shares(1, 1, 7), `${minDepositAmount * 2}`, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true, - }, + initialClusterState, ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7], ); @@ -458,42 +378,31 @@ describe('Register Validator Tests', () => { const args = eventsByName.ValidatorAdded[0].args; - const pks = Array.from({ length: 10 }, (_, index) => helpers.DataGenerator.publicKey(index + 1)); - const shares = Array.from({ length: 10 }, (_, index) => helpers.DataGenerator.shares(1, index, operatorIds.length)); - const depositAmount = minDepositAmount * 10; - - await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, depositAmount); - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).bulkRegisterValidator( - pks, + await helpers.bulkRegisterValidators( + 1, + 10, operatorIds, - shares, - depositAmount, - args.cluster - ), [GasGroup.BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_7]); + minDepositAmount, + args.cluster, + [GasGroup.BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_7], + ); }); it('Bulk register 10 validators with 7 operators new cluster', async () => { - const operatorIds = [1, 2, 3, 4, 5, 6, 7]; - - const pks = Array.from({ length: 10 }, (_, index) => helpers.DataGenerator.publicKey(index + 1)); - const shares = Array.from({ length: 10 }, (_, index) => helpers.DataGenerator.shares(1, index, operatorIds.length)); - const depositAmount = minDepositAmount * 10; - - await helpers.DB.ssvToken.approve(ssvNetworkContract.address, depositAmount); - - await trackGas(ssvNetworkContract.bulkRegisterValidator( - pks, - operatorIds, - shares, - depositAmount, + await helpers.bulkRegisterValidators( + 1, + 10, + [1, 2, 3, 4, 5, 6, 7], + minDepositAmount, { validatorCount: 0, networkFeeIndex: 0, index: 0, balance: 0, active: true - } - ), [GasGroup.BULK_REGISTER_10_VALIDATOR_NEW_STATE_7]); + }, + [GasGroup.BULK_REGISTER_10_VALIDATOR_NEW_STATE_7], + ); }); // 10 operators @@ -508,13 +417,7 @@ describe('Register Validator Tests', () => { helpers.DataGenerator.cluster.new(10), helpers.DataGenerator.shares(1, 1, 10), minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true, - }, + initialClusterState, ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_10], ); @@ -530,13 +433,7 @@ describe('Register Validator Tests', () => { [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], helpers.DataGenerator.shares(1, 1, 10), minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true, - }, + initialClusterState, ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_10], ); @@ -568,13 +465,7 @@ describe('Register Validator Tests', () => { [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], helpers.DataGenerator.shares(1, 1, 10), minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true, - }, + initialClusterState, ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_10], ); @@ -604,13 +495,7 @@ describe('Register Validator Tests', () => { [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], helpers.DataGenerator.shares(2, 4, 10), minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true, - }, + initialClusterState, ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_10], ); @@ -628,13 +513,7 @@ describe('Register Validator Tests', () => { [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], helpers.DataGenerator.shares(1, 1, 10), `${minDepositAmount * 2}`, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true, - }, + initialClusterState, ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_10], ); @@ -674,42 +553,31 @@ describe('Register Validator Tests', () => { const args = eventsByName.ValidatorAdded[0].args; - const pks = Array.from({ length: 10 }, (_, index) => helpers.DataGenerator.publicKey(index + 1)); - const shares = Array.from({ length: 10 }, (_, index) => helpers.DataGenerator.shares(1,index, operatorIds.length)); - const depositAmount = minDepositAmount * 10; - - await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, depositAmount); - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).bulkRegisterValidator( - pks, + await helpers.bulkRegisterValidators( + 1, + 10, operatorIds, - shares, - depositAmount, - args.cluster - ), [GasGroup.BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_10]); + minDepositAmount, + args.cluster, + [GasGroup.BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_10], + ); }); it('Bulk register 10 validators with 10 operators new cluster', async () => { - const operatorIds = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; - - const pks = Array.from({ length: 10 }, (_, index) => helpers.DataGenerator.publicKey(index + 1)); - const shares = Array.from({ length: 10 }, (_, index) => helpers.DataGenerator.shares(1, index, operatorIds.length)); - - const depositAmount = minDepositAmount * 10; - - await helpers.DB.ssvToken.approve(ssvNetworkContract.address, depositAmount); - await trackGas(ssvNetworkContract.bulkRegisterValidator( - pks, - operatorIds, - shares, - depositAmount, + await helpers.bulkRegisterValidators( + 1, + 10, + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + minDepositAmount, { validatorCount: 0, networkFeeIndex: 0, index: 0, balance: 0, active: true - } - ), [GasGroup.BULK_REGISTER_10_VALIDATOR_NEW_STATE_10]); + }, + [GasGroup.BULK_REGISTER_10_VALIDATOR_NEW_STATE_10], + ); }); // 13 operators @@ -724,13 +592,7 @@ describe('Register Validator Tests', () => { helpers.DataGenerator.cluster.new(13), helpers.DataGenerator.shares(1, 1, 13), minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true, - }, + initialClusterState, ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13], ); @@ -746,13 +608,7 @@ describe('Register Validator Tests', () => { [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], helpers.DataGenerator.shares(1, 1, 13), minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true, - }, + initialClusterState, ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13], ); @@ -783,13 +639,7 @@ describe('Register Validator Tests', () => { [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], helpers.DataGenerator.shares(1, 1, 13), minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true, - }, + initialClusterState, ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13], ); @@ -818,13 +668,7 @@ describe('Register Validator Tests', () => { [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], helpers.DataGenerator.shares(2, 4, 13), minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true, - }, + initialClusterState, ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13], ); @@ -842,13 +686,7 @@ describe('Register Validator Tests', () => { [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], helpers.DataGenerator.shares(1, 1, 13), `${minDepositAmount * 2}`, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true, - }, + initialClusterState, ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13], ); @@ -888,42 +726,31 @@ describe('Register Validator Tests', () => { const args = eventsByName.ValidatorAdded[0].args; - const pks = Array.from({ length: 10 }, (_, index) => helpers.DataGenerator.publicKey(index + 1)); - const shares = Array.from({ length: 10 }, (_, index) => helpers.DataGenerator.shares(1, index, operatorIds.length)); - const depositAmount = minDepositAmount * 10; - - await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, depositAmount); - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).bulkRegisterValidator( - pks, + await helpers.bulkRegisterValidators( + 1, + 10, operatorIds, - shares, - depositAmount, - args.cluster - ), [GasGroup.BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_13]); + minDepositAmount, + args.cluster, + [GasGroup.BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_13], + ); }); it('Bulk register 10 validators with 13 operators new cluster', async () => { - const operatorIds = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]; - - const pks = Array.from({ length: 10 }, (_, index) => helpers.DataGenerator.publicKey(index + 1)); - const shares = Array.from({ length: 10 }, (_, index) => helpers.DataGenerator.shares(1, index, operatorIds.length)); - - const depositAmount = minDepositAmount * 10; - - await helpers.DB.ssvToken.approve(ssvNetworkContract.address, depositAmount); - await trackGas(ssvNetworkContract.bulkRegisterValidator( - pks, - operatorIds, - shares, - depositAmount, + await helpers.bulkRegisterValidators( + 1, + 10, + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], + minDepositAmount, { validatorCount: 0, networkFeeIndex: 0, index: 0, balance: 0, active: true - } - ), [GasGroup.BULK_REGISTER_10_VALIDATOR_NEW_STATE_13]); + }, + [GasGroup.BULK_REGISTER_10_VALIDATOR_NEW_STATE_13], + ); }); it('Get cluster burn rate', async () => { @@ -1171,13 +998,7 @@ describe('Register Validator Tests', () => { [1, 2, 3, 4], helpers.DataGenerator.shares(6, 1, 4), minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true, - }, + initialClusterState, ), ).to.be.revertedWithCustomError(ssvNetworkContract, 'ValidatorAlreadyExists'); }); @@ -1194,13 +1015,7 @@ describe('Register Validator Tests', () => { [1, 2, 5, 6], helpers.DataGenerator.shares(6, 1, 4), minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true, - }, + initialClusterState, ), ).to.be.revertedWithCustomError(ssvNetworkContract, 'ValidatorAlreadyExists'); }); @@ -1226,13 +1041,7 @@ describe('Register Validator Tests', () => { [1, 2, 3, operatorId], helpers.DataGenerator.shares(3, 1, 4), minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true, - }, + initialClusterState, ), ).to.emit(ssvNetworkContract, 'ValidatorAdded'); }); diff --git a/test/validators/remove.ts b/test/validators/remove.ts index 92fbadf6..e5b8bf35 100644 --- a/test/validators/remove.ts +++ b/test/validators/remove.ts @@ -27,7 +27,7 @@ describe('Remove Validator Tests', () => { 1, minDepositAmount, [1], - [1, 2, 3, 4], + helpers.DEFAULT_OPERATOR_IDS[4], helpers.getClusterForValidator(0, 0, 0, 0, true), [GasGroup.REGISTER_VALIDATOR_NEW_STATE], ); @@ -43,6 +43,28 @@ describe('Remove Validator Tests', () => { ).to.emit(ssvNetworkContract, 'ValidatorRemoved'); }); + it('Bulk remove validator emits "ValidatorRemoved"', async () => { + const { args, pks } = await helpers.bulkRegisterValidators( + 2, + 10, + helpers.DEFAULT_OPERATOR_IDS[4], + minDepositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true, + }, + ); + + await expect( + ssvNetworkContract + .connect(helpers.DB.owners[2]) + .bulkRemoveValidator(pks, args.operatorIds, args.cluster), + ).to.emit(ssvNetworkContract, 'ValidatorRemoved'); + }); + it('Remove validator after cluster liquidation period emits "ValidatorRemoved"', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation + 10); @@ -62,12 +84,35 @@ describe('Remove Validator Tests', () => { ); }); + it('Bulk remove 10 validator gas limit (4 operators cluster)', async () => { + const { args, pks } = await helpers.bulkRegisterValidators( + 2, + 10, + helpers.DEFAULT_OPERATOR_IDS[4], + minDepositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true, + }, + ); + + await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[2]) + .bulkRemoveValidator(pks, args.operatorIds, args.cluster), + [GasGroup.BULK_REMOVE_10_VALIDATOR_4], + ); + }); + it('Remove validator gas limit (7 operators cluster)', async () => { const cluster = await helpers.registerValidators( 1, (minDepositAmount * 2).toString(), [2], - [1, 2, 3, 4, 5, 6, 7], + helpers.DEFAULT_OPERATOR_IDS[7], helpers.getClusterForValidator(0, 0, 0, 0, true), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7], ); @@ -81,12 +126,35 @@ describe('Remove Validator Tests', () => { ); }); + it('Bulk remove 10 validator gas limit (7 operators cluster)', async () => { + const { args, pks } = await helpers.bulkRegisterValidators( + 2, + 10, + helpers.DEFAULT_OPERATOR_IDS[7], + minDepositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true, + }, + ); + + await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[2]) + .bulkRemoveValidator(pks, args.operatorIds, args.cluster), + [GasGroup.BULK_REMOVE_10_VALIDATOR_7], + ); + }); + it('Remove validator gas limit (10 operators cluster)', async () => { const cluster = await helpers.registerValidators( 1, (minDepositAmount * 3).toString(), [2], - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + helpers.DEFAULT_OPERATOR_IDS[10], helpers.getClusterForValidator(0, 0, 0, 0, true), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_10], ); @@ -100,6 +168,29 @@ describe('Remove Validator Tests', () => { ); }); + it('Bulk remove 10 validator gas limit (10 operators cluster)', async () => { + const { args, pks } = await helpers.bulkRegisterValidators( + 2, + 10, + helpers.DEFAULT_OPERATOR_IDS[10], + minDepositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true, + }, + ); + + await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[2]) + .bulkRemoveValidator(pks, args.operatorIds, args.cluster), + [GasGroup.BULK_REMOVE_10_VALIDATOR_10], + ); + }); + it('Remove validator gas limit (13 operators cluster)', async () => { const cluster = await helpers.registerValidators( 1, @@ -119,6 +210,29 @@ describe('Remove Validator Tests', () => { ); }); + it('Bulk remove 10 validator gas limit (13 operators cluster)', async () => { + const { args, pks } = await helpers.bulkRegisterValidators( + 2, + 10, + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], + minDepositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true, + }, + ); + + await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[2]) + .bulkRemoveValidator(pks, args.operatorIds, args.cluster), + [GasGroup.BULK_REMOVE_10_VALIDATOR_13], + ); + }); + it('Remove validator with a removed operator in the cluster', async () => { await trackGas(ssvNetworkContract.removeOperator(1), [GasGroup.REMOVE_OPERATOR_WITH_WITHDRAW]); await trackGas( From 5483446f03c1e3c3e3979857ba692ed7c1b5d5e9 Mon Sep 17 00:00:00 2001 From: Marco Tabasco Date: Tue, 16 Jan 2024 01:03:34 +0100 Subject: [PATCH 21/38] upgrade goerli prod --- .openzeppelin/goerli.json | 109 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) diff --git a/.openzeppelin/goerli.json b/.openzeppelin/goerli.json index 443c72ad..70cc80c4 100644 --- a/.openzeppelin/goerli.json +++ b/.openzeppelin/goerli.json @@ -7581,6 +7581,115 @@ } } } + }, + "e311afb1f25419f9f90569ca2bf47a87990372364d587ec21789bb9aa6e83966": { + "address": "0xc25ad8Ebf84E08797b3076bb861C35056D3728e9", + "txHash": "0x7c1551d856363b706c688ef21bb39ab5cf30154806d2198d9a3666af45e40b7c", + "layout": { + "solcVersion": "0.8.18", + "storage": [ + { + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_uint8", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:63", + "retypedFrom": "bool" + }, + { + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:68" + }, + { + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)50_storage", + "contract": "ERC1967UpgradeUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol:169" + }, + { + "label": "__gap", + "offset": 0, + "slot": "51", + "type": "t_array(t_uint256)50_storage", + "contract": "UUPSUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol:111" + }, + { + "label": "__gap", + "offset": 0, + "slot": "101", + "type": "t_array(t_uint256)50_storage", + "contract": "ContextUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" + }, + { + "label": "_owner", + "offset": 0, + "slot": "151", + "type": "t_address", + "contract": "OwnableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" + }, + { + "label": "__gap", + "offset": 0, + "slot": "152", + "type": "t_array(t_uint256)49_storage", + "contract": "OwnableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:94" + }, + { + "label": "_pendingOwner", + "offset": 0, + "slot": "201", + "type": "t_address", + "contract": "Ownable2StepUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol:27" + }, + { + "label": "__gap", + "offset": 0, + "slot": "202", + "type": "t_array(t_uint256)49_storage", + "contract": "Ownable2StepUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol:70" + } + ], + "types": { + "t_address": { + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_uint256)49_storage": { + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_array(t_uint256)50_storage": { + "label": "uint256[50]", + "numberOfBytes": "1600" + }, + "t_bool": { + "label": "bool", + "numberOfBytes": "1" + }, + "t_uint256": { + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint8": { + "label": "uint8", + "numberOfBytes": "1" + } + }, + "namespaces": {} + } } } } From 2af125ae62be5cce549f196af90fe6f9ec372a64 Mon Sep 17 00:00:00 2001 From: Marco Tabasco Date: Tue, 16 Jan 2024 02:17:43 +0100 Subject: [PATCH 22/38] bulk exit validator --- abis/SSVNetwork.json | 68 +++++++++++++++ contracts/SSVNetwork.sol | 4 + contracts/interfaces/ISSVClusters.sol | 5 ++ contracts/modules/SSVClusters.sol | 15 ++-- contracts/test/SSVNetworkUpgrade.sol | 7 ++ test/helpers/gas-usage.ts | 20 +++-- test/validators/others.ts | 115 ++++++++++++++++++++++++++ 7 files changed, 223 insertions(+), 11 deletions(-) diff --git a/abis/SSVNetwork.json b/abis/SSVNetwork.json index 5526f48b..ef9681e3 100644 --- a/abis/SSVNetwork.json +++ b/abis/SSVNetwork.json @@ -937,6 +937,24 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "bytes[]", + "name": "publicKeys", + "type": "bytes[]" + }, + { + "internalType": "uint64[]", + "name": "operatorIds", + "type": "uint64[]" + } + ], + "name": "bulkExitValidator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -997,6 +1015,56 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "bytes[]", + "name": "publicKeys", + "type": "bytes[]" + }, + { + "internalType": "uint64[]", + "name": "operatorIds", + "type": "uint64[]" + }, + { + "components": [ + { + "internalType": "uint32", + "name": "validatorCount", + "type": "uint32" + }, + { + "internalType": "uint64", + "name": "networkFeeIndex", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "index", + "type": "uint64" + }, + { + "internalType": "bool", + "name": "active", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + } + ], + "internalType": "struct ISSVNetworkCore.Cluster", + "name": "cluster", + "type": "tuple" + } + ], + "name": "bulkRemoveValidator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index adbe0ac8..fdf3c5c0 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -238,6 +238,10 @@ contract SSVNetwork is _delegate(SSVStorage.load().ssvContracts[SSVModules.SSV_CLUSTERS]); } + function bulkExitValidator(bytes[] calldata publicKeys, uint64[] calldata operatorIds) external override { + _delegate(SSVStorage.load().ssvContracts[SSVModules.SSV_CLUSTERS]); + } + function updateNetworkFee(uint256 fee) external override onlyOwner { _delegate(SSVStorage.load().ssvContracts[SSVModules.SSV_DAO]); } diff --git a/contracts/interfaces/ISSVClusters.sol b/contracts/interfaces/ISSVClusters.sol index 21b993de..acb32847 100644 --- a/contracts/interfaces/ISSVClusters.sol +++ b/contracts/interfaces/ISSVClusters.sol @@ -86,6 +86,11 @@ interface ISSVClusters is ISSVNetworkCore { /// @param operatorIds Array of IDs of operators managing the validator function exitValidator(bytes calldata publicKey, uint64[] calldata operatorIds) external; + /// @notice Fires the exit event for a set of validators + /// @param publicKeys The public keys of the validators to be exited + /// @param operatorIds Array of IDs of operators managing the validators + function bulkExitValidator(bytes[] calldata publicKeys, uint64[] calldata operatorIds) external; + /** * @dev Emitted when the validator has been added. * @param publicKey The public key of a validator. diff --git a/contracts/modules/SSVClusters.sol b/contracts/modules/SSVClusters.sol index dba001f6..c81edaa3 100644 --- a/contracts/modules/SSVClusters.sol +++ b/contracts/modules/SSVClusters.sol @@ -70,14 +70,11 @@ contract SSVClusters is ISSVClusters { CoreLib.deposit(amount); } - for (uint i; i < validatorsLength; ) { + for (uint i; i < validatorsLength; ++i) { bytes memory pk = publicKeys[i]; bytes memory sh = sharesData[i]; - emit ValidatorAdded(msg.sender, operatorIds, pk, sh, cluster); - unchecked { - ++i; - } + emit ValidatorAdded(msg.sender, operatorIds, pk, sh, cluster); } } @@ -326,4 +323,12 @@ contract SSVClusters is ISSVClusters { emit ValidatorExited(msg.sender, operatorIds, publicKey); } + + function bulkExitValidator(bytes[] calldata publicKeys, uint64[] calldata operatorIds) external override { + ValidatorLib.validateStates(publicKeys, operatorIds, SSVStorage.load()); + + for (uint i; i < publicKeys.length; ++i) { + emit ValidatorExited(msg.sender, operatorIds, publicKeys[i]); + } + } } diff --git a/contracts/test/SSVNetworkUpgrade.sol b/contracts/test/SSVNetworkUpgrade.sol index 9731270d..c92edfd3 100644 --- a/contracts/test/SSVNetworkUpgrade.sol +++ b/contracts/test/SSVNetworkUpgrade.sol @@ -329,6 +329,13 @@ contract SSVNetworkUpgrade is ); } + function bulkExitValidator(bytes[] calldata publicKeys, uint64[] calldata operatorIds) external override { + _delegateCall( + SSVStorage.load().ssvContracts[SSVModules.SSV_CLUSTERS], + abi.encodeWithSignature("bulkExitValidator(bytes[],uint64[]))", publicKeys, operatorIds) + ); + } + function updateNetworkFee(uint256 fee) external override onlyOwner { _delegateCall( SSVStorage.load().ssvContracts[SSVModules.SSV_DAO], diff --git a/test/helpers/gas-usage.ts b/test/helpers/gas-usage.ts index e40ad15f..53aa046d 100644 --- a/test/helpers/gas-usage.ts +++ b/test/helpers/gas-usage.ts @@ -51,6 +51,10 @@ export enum GasGroup { WITHDRAW_CLUSTER_BALANCE, WITHDRAW_OPERATOR_BALANCE, VALIDATOR_EXIT, + BULK_EXIT_10_VALIDATOR_4, + BULK_EXIT_10_VALIDATOR_7, + BULK_EXIT_10_VALIDATOR_10, + BULK_EXIT_10_VALIDATOR_13, LIQUIDATE_CLUSTER_4, LIQUIDATE_CLUSTER_7, @@ -92,22 +96,22 @@ const MAX_GAS_PER_GROUP: any = { [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]: 289000, [GasGroup.REGISTER_VALIDATOR_WITHOUT_DEPOSIT_7]: 251600, - [GasGroup.BULK_REGISTER_10_VALIDATOR_NEW_STATE_7]: 1085000, - [GasGroup.BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_7]: 1068000, + [GasGroup.BULK_REGISTER_10_VALIDATOR_NEW_STATE_7]: 1085500, + [GasGroup.BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_7]: 1068500, [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER_10]: 342700, [GasGroup.REGISTER_VALIDATOR_NEW_STATE_10]: 359500, [GasGroup.REGISTER_VALIDATOR_WITHOUT_DEPOSIT_10]: 322200, - [GasGroup.BULK_REGISTER_10_VALIDATOR_NEW_STATE_10]: 1364500, - [GasGroup.BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_10]: 1348000, + [GasGroup.BULK_REGISTER_10_VALIDATOR_NEW_STATE_10]: 1365000, + [GasGroup.BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_10]: 1348200, [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER_13]: 413700, [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]: 430500, [GasGroup.REGISTER_VALIDATOR_WITHOUT_DEPOSIT_13]: 393200, - [GasGroup.BULK_REGISTER_10_VALIDATOR_NEW_STATE_13]: 1649600, - [GasGroup.BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_13]: 1633000, + [GasGroup.BULK_REGISTER_10_VALIDATOR_NEW_STATE_13]: 1650200, + [GasGroup.BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_13]: 1633500, [GasGroup.REMOVE_VALIDATOR]: 115000, [GasGroup.BULK_REMOVE_10_VALIDATOR_4]: 196000, @@ -125,6 +129,10 @@ const MAX_GAS_PER_GROUP: any = { [GasGroup.WITHDRAW_CLUSTER_BALANCE]: 94500, [GasGroup.WITHDRAW_OPERATOR_BALANCE]: 64900, [GasGroup.VALIDATOR_EXIT]: 43000, + [GasGroup.BULK_EXIT_10_VALIDATOR_4]: 126200, + [GasGroup.BULK_EXIT_10_VALIDATOR_7]: 139500, + [GasGroup.BULK_EXIT_10_VALIDATOR_10]: 152500, + [GasGroup.BULK_EXIT_10_VALIDATOR_13]: 165500, [GasGroup.LIQUIDATE_CLUSTER_4]: 129300, [GasGroup.LIQUIDATE_CLUSTER_7]: 170500, diff --git a/test/validators/others.ts b/test/validators/others.ts index 3c7f5c5b..6d751866 100644 --- a/test/validators/others.ts +++ b/test/validators/others.ts @@ -169,4 +169,119 @@ describe('Other Validator Tests', () => { ssvNetworkContract.connect(helpers.DB.owners[1]).exitValidator(helpers.DataGenerator.publicKey(1), [1, 2, 3, 5]), ).to.be.revertedWithCustomError(ssvNetworkContract, 'IncorrectValidatorState'); }); + + it('Bulk exiting a validator emits "ValidatorExited"', async () => { + const { args, pks } = await helpers.bulkRegisterValidators( + 2, + 10, + helpers.DEFAULT_OPERATOR_IDS[4], + minDepositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true, + }, + ); + + await expect( + ssvNetworkContract + .connect(helpers.DB.owners[2]) + .bulkExitValidator(pks, args.operatorIds), + ) + .to.emit(ssvNetworkContract, 'ValidatorExited'); + }); + + it('Bulk exiting 10 validator (4 operators cluster) gas limit', async () => { + const { args, pks } = await helpers.bulkRegisterValidators( + 2, + 10, + helpers.DEFAULT_OPERATOR_IDS[4], + minDepositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true, + }, + ); + + await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[2]) + .bulkExitValidator(pks, args.operatorIds), + [GasGroup.BULK_EXIT_10_VALIDATOR_4], + ); + }); + + it('Bulk exiting 10 validator (7 operators cluster) gas limit', async () => { + const { args, pks } = await helpers.bulkRegisterValidators( + 2, + 10, + helpers.DEFAULT_OPERATOR_IDS[7], + minDepositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true, + }, + ); + + await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[2]) + .bulkExitValidator(pks, args.operatorIds), + [GasGroup.BULK_EXIT_10_VALIDATOR_7], + ); + }); + + it('Bulk exiting 10 validator (10 operators cluster) gas limit', async () => { + const { args, pks } = await helpers.bulkRegisterValidators( + 2, + 10, + helpers.DEFAULT_OPERATOR_IDS[10], + minDepositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true, + }, + ); + + await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[2]) + .bulkExitValidator(pks, args.operatorIds), + [GasGroup.BULK_EXIT_10_VALIDATOR_10], + ); + }); + + it('Bulk exiting 10 validator (13 operators cluster) gas limit', async () => { + const { args, pks } = await helpers.bulkRegisterValidators( + 2, + 10, + helpers.DEFAULT_OPERATOR_IDS[13], + minDepositAmount, + { + validatorCount: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + active: true, + }, + ); + + await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[2]) + .bulkExitValidator(pks, args.operatorIds), + [GasGroup.BULK_EXIT_10_VALIDATOR_13], + ); + }); }); From 49ba157f7249d806fe99f7e4fbe90aa68a39afd2 Mon Sep 17 00:00:00 2001 From: Marco Tabasco Date: Tue, 16 Jan 2024 02:25:33 +0100 Subject: [PATCH 23/38] hlsky dev metadata --- .openzeppelin/unknown-17000.json | 109 +++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) diff --git a/.openzeppelin/unknown-17000.json b/.openzeppelin/unknown-17000.json index fef1b41c..b7d411c4 100644 --- a/.openzeppelin/unknown-17000.json +++ b/.openzeppelin/unknown-17000.json @@ -830,6 +830,115 @@ }, "namespaces": {} } + }, + "ea22005a44aa654c8170296ef0052ed50bdb1eb52b46b0b5a9aefc6275bf48c0": { + "address": "0x990B226E8D74B42414F1296CCf2d8BA454879621", + "txHash": "0xfdde435768aa2ea9fe64206e700dfb6eac13345e5d733beca1a723e59a578683", + "layout": { + "solcVersion": "0.8.18", + "storage": [ + { + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_uint8", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:63", + "retypedFrom": "bool" + }, + { + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:68" + }, + { + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)50_storage", + "contract": "ERC1967UpgradeUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol:169" + }, + { + "label": "__gap", + "offset": 0, + "slot": "51", + "type": "t_array(t_uint256)50_storage", + "contract": "UUPSUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol:111" + }, + { + "label": "__gap", + "offset": 0, + "slot": "101", + "type": "t_array(t_uint256)50_storage", + "contract": "ContextUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" + }, + { + "label": "_owner", + "offset": 0, + "slot": "151", + "type": "t_address", + "contract": "OwnableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" + }, + { + "label": "__gap", + "offset": 0, + "slot": "152", + "type": "t_array(t_uint256)49_storage", + "contract": "OwnableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:94" + }, + { + "label": "_pendingOwner", + "offset": 0, + "slot": "201", + "type": "t_address", + "contract": "Ownable2StepUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol:27" + }, + { + "label": "__gap", + "offset": 0, + "slot": "202", + "type": "t_array(t_uint256)49_storage", + "contract": "Ownable2StepUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol:70" + } + ], + "types": { + "t_address": { + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_uint256)49_storage": { + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_array(t_uint256)50_storage": { + "label": "uint256[50]", + "numberOfBytes": "1600" + }, + "t_bool": { + "label": "bool", + "numberOfBytes": "1" + }, + "t_uint256": { + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint8": { + "label": "uint8", + "numberOfBytes": "1" + } + }, + "namespaces": {} + } } } } From c80dc3b5ccf8d3e2d770bdebb0d5cf6bfb0086a5 Mon Sep 17 00:00:00 2001 From: Marco Tabasco Date: Tue, 16 Jan 2024 15:45:45 +0100 Subject: [PATCH 24/38] add exit validator tests --- contracts/libraries/ValidatorLib.sol | 6 +- contracts/modules/SSVClusters.sol | 8 +- test/sanity/balances.ts | 51 +++++++- test/validators/{others.ts => exit.ts} | 139 ++++++++++++++------ test/validators/remove.ts | 169 ++++++++++++++++++------- 5 files changed, 279 insertions(+), 94 deletions(-) rename test/validators/{others.ts => exit.ts} (72%) diff --git a/contracts/libraries/ValidatorLib.sol b/contracts/libraries/ValidatorLib.sol index ae12e02f..ff85ee90 100644 --- a/contracts/libraries/ValidatorLib.sol +++ b/contracts/libraries/ValidatorLib.sol @@ -56,6 +56,9 @@ library ValidatorLib { uint64[] calldata operatorIds, StorageData storage s ) internal view returns (bytes32[] memory hashedValidator) { + if (publicKeys.length == 0) { + revert ISSVNetworkCore.ValidatorDoesNotExist(); + } hashedValidator = new bytes32[](publicKeys.length); bytes32 hashedOperatorIds = hashOperatorIds(operatorIds); @@ -76,7 +79,8 @@ library ValidatorLib { revert ISSVNetworkCore.ValidatorDoesNotExist(); } - if ((validatorData & ~bytes32(uint256(1))) != hashedOperatorIds) { // All bits set to 1 except LSB + if ((validatorData & ~bytes32(uint256(1))) != hashedOperatorIds) { + // All bits set to 1 except LSB // Clear LSB of stored validator data and compare revert ISSVNetworkCore.IncorrectValidatorState(); } diff --git a/contracts/modules/SSVClusters.sol b/contracts/modules/SSVClusters.sol index c81edaa3..49e0b097 100644 --- a/contracts/modules/SSVClusters.sol +++ b/contracts/modules/SSVClusters.sol @@ -85,11 +85,10 @@ contract SSVClusters is ISSVClusters { ) external override { StorageData storage s = SSVStorage.load(); + bytes32 hashedCluster = cluster.validateHashedCluster(msg.sender, operatorIds, s); bytes32 hashedOperatorIds = ValidatorLib.hashOperatorIds(operatorIds); bytes32 hashedValidator = ValidatorLib.validateState(publicKey, hashedOperatorIds, s); - bytes32 hashedCluster = cluster.validateHashedCluster(msg.sender, operatorIds, s); - if (cluster.active) { StorageProtocol storage sp = SSVStorageProtocol.load(); (uint64 clusterIndex, ) = OperatorLib.updateClusterOperators(operatorIds, false, false, 1, s, sp); @@ -116,7 +115,6 @@ contract SSVClusters is ISSVClusters { StorageData storage s = SSVStorage.load(); bytes32 hashedCluster = cluster.validateHashedCluster(msg.sender, operatorIds, s); - bytes32[] memory hashedValidators = ValidatorLib.validateStates(publicKeys, operatorIds, s); uint32 validatorsLength = uint32(publicKeys.length); @@ -137,12 +135,12 @@ contract SSVClusters is ISSVClusters { sp.updateDAO(false, validatorsLength); } + cluster.validatorCount -= validatorsLength; + for (uint i; i < validatorsLength; ++i) { delete s.validatorPKs[hashedValidators[i]]; } - cluster.validatorCount -= validatorsLength; - s.clusters[hashedCluster] = cluster.hashClusterData(); for (uint i; i < validatorsLength; ++i) { diff --git a/test/sanity/balances.ts b/test/sanity/balances.ts index e19da092..bb4401ce 100644 --- a/test/sanity/balances.ts +++ b/test/sanity/balances.ts @@ -430,13 +430,7 @@ describe('Balance Tests', () => { 10, [5, 6, 7, 8], minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true, - }, + helpers.DB.initialClusterState, ); await utils.progressBlocks(2); @@ -474,4 +468,47 @@ describe('Balance Tests', () => { expect(await ssvViews.getOperatorEarnings(7)).to.equal((helpers.CONFIG.minimalOperatorFee * 10 * 3) + (helpers.CONFIG.minimalOperatorFee * 5 * 2)); expect(await ssvViews.getOperatorEarnings(8)).to.equal((helpers.CONFIG.minimalOperatorFee * 10 * 3) + (helpers.CONFIG.minimalOperatorFee * 5 * 2)); }); + + it('Remove validators from a liquidated cluster', async () => { + const clusterDeposit = minDepositAmount * 10; + // 3 operators cluster burnPerBlock + const newBurnPerBlock = helpers.CONFIG.minimalOperatorFee * 3 + networkFee; + + // register 10 validators + const { args, pks } = await helpers.bulkRegisterValidators( + 2, + 10, + [5, 6, 7, 8], + minDepositAmount, + helpers.DB.initialClusterState, + ); + + await utils.progressBlocks(2); + + // remove one operator + await ssvNetworkContract.connect(helpers.DB.owners[0]).removeOperator(8); + + await utils.progressBlocks(2); + + // bulk remove 10 validators + const result = await trackGas(ssvNetworkContract + .connect(helpers.DB.owners[2]) + .bulkRemoveValidator(pks, args.operatorIds, args.cluster) + ); + const removed = result.eventsByName.ValidatorRemoved[0].args; + + await utils.progressBlocks(2); + + // check operators' balances + expect(await ssvViews.getOperatorEarnings(5)).to.equal((helpers.CONFIG.minimalOperatorFee * 10 * 6)); + expect(await ssvViews.getOperatorEarnings(6)).to.equal((helpers.CONFIG.minimalOperatorFee * 10 * 6)); + expect(await ssvViews.getOperatorEarnings(7)).to.equal((helpers.CONFIG.minimalOperatorFee * 10 * 6)); + expect(await ssvViews.getOperatorEarnings(8)).to.equal(0); + + // check cluster balance + expect( + await ssvViews.getBalance(helpers.DB.owners[2].address, removed.operatorIds, removed.cluster), + ).to.equal(clusterDeposit - (burnPerBlock * 10 * 3) - (newBurnPerBlock * 10 * 3)); + + }); }); diff --git a/test/validators/others.ts b/test/validators/exit.ts similarity index 72% rename from test/validators/others.ts rename to test/validators/exit.ts index 6d751866..dd5eff6a 100644 --- a/test/validators/others.ts +++ b/test/validators/exit.ts @@ -6,7 +6,7 @@ import { trackGas, GasGroup } from '../helpers/gas-usage'; // Declare globals let ssvNetworkContract: any, minDepositAmount: any, firstCluster: any; -describe('Other Validator Tests', () => { +describe('Exit Validator Tests', () => { beforeEach(async () => { // Initialize contract const metadata = await helpers.initializeContract(); @@ -176,13 +176,7 @@ describe('Other Validator Tests', () => { 10, helpers.DEFAULT_OPERATOR_IDS[4], minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true, - }, + helpers.DB.initialClusterState, ); await expect( @@ -199,13 +193,7 @@ describe('Other Validator Tests', () => { 10, helpers.DEFAULT_OPERATOR_IDS[4], minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true, - }, + helpers.DB.initialClusterState, ); await trackGas( @@ -222,13 +210,7 @@ describe('Other Validator Tests', () => { 10, helpers.DEFAULT_OPERATOR_IDS[7], minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true, - }, + helpers.DB.initialClusterState, ); await trackGas( @@ -245,13 +227,7 @@ describe('Other Validator Tests', () => { 10, helpers.DEFAULT_OPERATOR_IDS[10], minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true, - }, + helpers.DB.initialClusterState, ); await trackGas( @@ -268,13 +244,7 @@ describe('Other Validator Tests', () => { 10, helpers.DEFAULT_OPERATOR_IDS[13], minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true, - }, + helpers.DB.initialClusterState, ); await trackGas( @@ -284,4 +254,101 @@ describe('Other Validator Tests', () => { [GasGroup.BULK_EXIT_10_VALIDATOR_13], ); }); + + it('Bulk exiting removed validators reverts "ValidatorDoesNotExist"', async () => { + const { args, pks } = await helpers.bulkRegisterValidators( + 2, + 10, + helpers.DEFAULT_OPERATOR_IDS[4], + minDepositAmount, + helpers.DB.initialClusterState, + ); + + await trackGas(ssvNetworkContract + .connect(helpers.DB.owners[2]) + .bulkRemoveValidator(pks.slice(0, 5), args.operatorIds, args.cluster) + ); + + await expect( + ssvNetworkContract + .connect(helpers.DB.owners[2]) + .bulkExitValidator(pks.slice(0, 5), args.operatorIds), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'ValidatorDoesNotExist'); + }); + + it('Bulk exiting non-existing validators reverts "ValidatorDoesNotExist"', async () => { + const { args, pks } = await helpers.bulkRegisterValidators( + 2, + 10, + helpers.DEFAULT_OPERATOR_IDS[4], + minDepositAmount, + helpers.DB.initialClusterState, + ); + + pks[4] = "0xabcd1234"; + + await expect( + ssvNetworkContract + .connect(helpers.DB.owners[2]) + .bulkExitValidator(pks, args.operatorIds), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'ValidatorDoesNotExist'); + }); + + it('Bulk exiting validators with empty operator list reverts "IncorrectValidatorState"', async () => { + const { args, pks } = await helpers.bulkRegisterValidators( + 2, + 10, + helpers.DEFAULT_OPERATOR_IDS[4], + minDepositAmount, + helpers.DB.initialClusterState, + ); + + await expect( + ssvNetworkContract.connect(helpers.DB.owners[2]).bulkExitValidator(pks, []), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'IncorrectValidatorState'); + }); + + it('Bulk exiting validators with empty public key reverts "ValidatorDoesNotExist', async () => { + const { args } = await helpers.bulkRegisterValidators( + 2, + 10, + helpers.DEFAULT_OPERATOR_IDS[4], + minDepositAmount, + helpers.DB.initialClusterState, + ); + + await expect( + ssvNetworkContract.connect(helpers.DB.owners[2]).bulkExitValidator([], args.operatorIds), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'ValidatorDoesNotExist'); + }); + + it('Bulk exiting validators using the wrong account reverts "ValidatorDoesNotExist"', async () => { + const { args, pks } = await helpers.bulkRegisterValidators( + 2, + 10, + helpers.DEFAULT_OPERATOR_IDS[4], + minDepositAmount, + helpers.DB.initialClusterState, + ); + + await expect( + ssvNetworkContract + .connect(helpers.DB.owners[3]) + .bulkExitValidator(pks, args.operatorIds), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'ValidatorDoesNotExist'); + }); + + it('Bulk exiting validators with incorrect operators (unsorted list) reverts with "IncorrectValidatorState"', async () => { + const { args, pks } = await helpers.bulkRegisterValidators( + 2, + 10, + helpers.DEFAULT_OPERATOR_IDS[4], + minDepositAmount, + helpers.DB.initialClusterState, + ); + + await expect( + ssvNetworkContract.connect(helpers.DB.owners[1]).bulkExitValidator(pks, [4, 3, 2, 1]), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'IncorrectValidatorState'); + }); }); diff --git a/test/validators/remove.ts b/test/validators/remove.ts index e5b8bf35..ecbdc3bd 100644 --- a/test/validators/remove.ts +++ b/test/validators/remove.ts @@ -49,13 +49,7 @@ describe('Remove Validator Tests', () => { 10, helpers.DEFAULT_OPERATOR_IDS[4], minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true, - }, + helpers.DB.initialClusterState, ); await expect( @@ -68,10 +62,9 @@ describe('Remove Validator Tests', () => { it('Remove validator after cluster liquidation period emits "ValidatorRemoved"', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation + 10); - await expect( - ssvNetworkContract - .connect(helpers.DB.owners[1]) - .removeValidator(helpers.DataGenerator.publicKey(1), firstCluster.operatorIds, firstCluster.cluster), + await expect(ssvNetworkContract + .connect(helpers.DB.owners[1]) + .removeValidator(helpers.DataGenerator.publicKey(1), firstCluster.operatorIds, firstCluster.cluster), ).to.emit(ssvNetworkContract, 'ValidatorRemoved'); }); @@ -90,13 +83,7 @@ describe('Remove Validator Tests', () => { 10, helpers.DEFAULT_OPERATOR_IDS[4], minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true, - }, + helpers.DB.initialClusterState, ); await trackGas( @@ -132,13 +119,7 @@ describe('Remove Validator Tests', () => { 10, helpers.DEFAULT_OPERATOR_IDS[7], minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true, - }, + helpers.DB.initialClusterState, ); await trackGas( @@ -174,13 +155,7 @@ describe('Remove Validator Tests', () => { 10, helpers.DEFAULT_OPERATOR_IDS[10], minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true, - }, + helpers.DB.initialClusterState, ); await trackGas( @@ -196,7 +171,7 @@ describe('Remove Validator Tests', () => { 1, (minDepositAmount * 4).toString(), [2], - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], + helpers.DEFAULT_OPERATOR_IDS[13], helpers.getClusterForValidator(0, 0, 0, 0, true), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13], ); @@ -214,15 +189,9 @@ describe('Remove Validator Tests', () => { const { args, pks } = await helpers.bulkRegisterValidators( 2, 10, - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], + helpers.DEFAULT_OPERATOR_IDS[13], minDepositAmount, - { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true, - }, + helpers.DB.initialClusterState, ); await trackGas( @@ -297,23 +266,42 @@ describe('Remove Validator Tests', () => { ); }); - it('Remove validator with an invalid owner reverts "ValidatorDoesNotExist"', async () => { + it('Remove validator with an invalid owner reverts "ClusterDoesNotExists"', async () => { await expect( ssvNetworkContract .connect(helpers.DB.owners[2]) .removeValidator(helpers.DataGenerator.publicKey(1), firstCluster.operatorIds, firstCluster.cluster), - ).to.be.revertedWithCustomError(ssvNetworkContract, 'ValidatorDoesNotExist'); + ).to.be.revertedWithCustomError(ssvNetworkContract, 'ClusterDoesNotExists'); }); - it('Remove validator with an invalid operator setup reverts "IncorrectValidatorState"', async () => { + it('Remove validator with an invalid operator setup reverts "ClusterDoesNotExists"', async () => { await expect( ssvNetworkContract .connect(helpers.DB.owners[1]) .removeValidator(helpers.DataGenerator.publicKey(1), [1, 2, 3, 5], firstCluster.cluster), - ).to.be.revertedWithCustomError(ssvNetworkContract, 'IncorrectValidatorState'); + ).to.be.revertedWithCustomError(ssvNetworkContract, 'ClusterDoesNotExists'); }); it('Remove the same validator twice reverts "ValidatorDoesNotExist"', async () => { + // Remove validator + const result = await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .removeValidator(helpers.DataGenerator.publicKey(1), firstCluster.operatorIds, firstCluster.cluster), + [GasGroup.REMOVE_VALIDATOR], + ); + + const removed = result.eventsByName.ValidatorRemoved[0].args; + + // Remove validator again + await expect( + ssvNetworkContract + .connect(helpers.DB.owners[1]) + .removeValidator(helpers.DataGenerator.publicKey(1), removed.operatorIds, removed.cluster), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'ValidatorDoesNotExist'); + }); + + it('Remove the same validator with wrong input parameters reverts "IncorrectClusterState"', async () => { // Remove validator await trackGas( ssvNetworkContract @@ -327,6 +315,97 @@ describe('Remove Validator Tests', () => { ssvNetworkContract .connect(helpers.DB.owners[1]) .removeValidator(helpers.DataGenerator.publicKey(1), firstCluster.operatorIds, firstCluster.cluster), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'IncorrectClusterState'); + }); + + it('Bulk Remove validator that does not exist in a valid cluster reverts "ValidatorDoesNotExist"', async () => { + const { args, pks } = await helpers.bulkRegisterValidators( + 2, + 10, + helpers.DEFAULT_OPERATOR_IDS[4], + minDepositAmount, + helpers.DB.initialClusterState, + ); + + pks[2] = "0xabcd1234"; + + await expect( + ssvNetworkContract + .connect(helpers.DB.owners[2]) + .bulkRemoveValidator(pks, args.operatorIds, args.cluster), ).to.be.revertedWithCustomError(ssvNetworkContract, 'ValidatorDoesNotExist'); }); + + it('Bulk remove validator with an invalid operator setup reverts "ClusterDoesNotExists"', async () => { + const { args, pks } = await helpers.bulkRegisterValidators( + 2, + 10, + helpers.DEFAULT_OPERATOR_IDS[4], + minDepositAmount, + helpers.DB.initialClusterState, + ); + + await expect( + ssvNetworkContract + .connect(helpers.DB.owners[2]) + .bulkRemoveValidator(pks, [1, 2, 3, 5], args.cluster), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'ClusterDoesNotExists'); + }); + + it('Bulk Remove the same validator twice reverts "ValidatorDoesNotExist"', async () => { + const { args, pks } = await helpers.bulkRegisterValidators( + 2, + 10, + helpers.DEFAULT_OPERATOR_IDS[4], + minDepositAmount, + helpers.DB.initialClusterState, + ); + + const result = await trackGas( + ssvNetworkContract + .connect(helpers.DB.owners[2]) + .bulkRemoveValidator(pks, args.operatorIds, args.cluster) + ); + + const removed = result.eventsByName.ValidatorRemoved[0].args; + + // Remove validator again + await expect( + ssvNetworkContract + .connect(helpers.DB.owners[2]) + .bulkRemoveValidator(pks, removed.operatorIds, removed.cluster), + ).to.be.revertedWithCustomError(ssvNetworkContract, 'ValidatorDoesNotExist'); + }); + + it('Remove validators from a liquidated cluster', async () => { + const { args, pks } = await helpers.bulkRegisterValidators( + 2, + 10, + helpers.DEFAULT_OPERATOR_IDS[4], + minDepositAmount, + helpers.DB.initialClusterState, + ); + + await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation - 2); + + let result = await trackGas(ssvNetworkContract + .connect(helpers.DB.owners[1]) + .liquidate(args.owner, args.operatorIds, args.cluster) + ); + + const liquidated = result.eventsByName.ClusterLiquidated[0].args; + + result = await trackGas(ssvNetworkContract + .connect(helpers.DB.owners[2]) + .bulkRemoveValidator(pks.slice(0, 5), liquidated.operatorIds, liquidated.cluster) + ); + + const removed = result.eventsByName.ValidatorRemoved[0].args; + + expect(removed.cluster.validatorCount).to.equal(5); + expect(removed.cluster.networkFeeIndex.toNumber()).to.equal(0); + expect(removed.cluster.index.toNumber()).to.equal(0); + expect(removed.cluster.active).to.equal(false); + expect(removed.cluster.balance.toNumber()).to.equal(0); + }); }); From a8f814d80681af3258092ffed3656c636c3f995d Mon Sep 17 00:00:00 2001 From: Marco Tabasco Date: Tue, 16 Jan 2024 16:11:40 +0100 Subject: [PATCH 25/38] update CHANGELOG --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a96f4d6b..f2b3d1cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,9 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ## [Unreleased] ### [v1.1.0] 2024-01-08 -- [9c609cd](https://github.com/bloxapp/ssv-network/commit/9c609cd) - Bulk registration of validators. +- [c80dc3b](https://github.com/bloxapp/ssv-network/commit/c80dc3b) - [Feature] Bulk exit of validators. +- [6431a00](https://github.com/bloxapp/ssv-network/commit/6431a00) - [Feature] Bulk removal of validators. +- [9c609cd](https://github.com/bloxapp/ssv-network/commit/9c609cd) - [Feature] Bulk registration of validators. - [c9a90b1](https://github.com/bloxapp/ssv-network/commit/c9a90b1) - [Update] Added triggers for compilation in a few tasks (upgrading / updating). - [4471f05](https://github.com/bloxapp/ssv-network/commit/4471f05) - [Update] Deployment tests and update task and documentation. - [7564dfe](https://github.com/bloxapp/ssv-network/commit/7564dfe) - [Feature] Integration ssv-keys in ssv-network for generating keyshares. From 7ce944046c9baf37a9e49df5619df174547f667e Mon Sep 17 00:00:00 2001 From: Marco Tabasco Date: Tue, 16 Jan 2024 18:28:07 +0100 Subject: [PATCH 26/38] update gas usage --- test/helpers/gas-usage.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/helpers/gas-usage.ts b/test/helpers/gas-usage.ts index 53aa046d..367c6a8a 100644 --- a/test/helpers/gas-usage.ts +++ b/test/helpers/gas-usage.ts @@ -108,7 +108,7 @@ const MAX_GAS_PER_GROUP: any = { [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER_13]: 413700, [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]: 430500, - [GasGroup.REGISTER_VALIDATOR_WITHOUT_DEPOSIT_13]: 393200, + [GasGroup.REGISTER_VALIDATOR_WITHOUT_DEPOSIT_13]: 393300, [GasGroup.BULK_REGISTER_10_VALIDATOR_NEW_STATE_13]: 1650200, [GasGroup.BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_13]: 1633500, From af99def4d4f87dfda1f5035b7bbef9e51e773361 Mon Sep 17 00:00:00 2001 From: Marco Tabasco Date: Wed, 17 Jan 2024 11:38:50 +0100 Subject: [PATCH 27/38] update roles doc --- docs/roles.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/roles.md b/docs/roles.md index b227a8b7..07adf84d 100644 --- a/docs/roles.md +++ b/docs/roles.md @@ -20,6 +20,7 @@ The contract owner can perform operational actions over the contract and protoco - `SSVNetwork.updateExecuteOperatorFeePeriod()` - Updates the period for executing operator fees - `SSVNetwork.updateLiquidationThresholdPeriod()` - Updates the liquidation threshold period - `SSVNetwork.updateMinimumLiquidationCollateral()` - Updates the minimum collateral required to prevent liquidation +- `SSVNetwork.updateMaximumOperatorFee()` - Updates the maximum fee an operator can set ## Operator owner @@ -39,6 +40,10 @@ Only the owner of an operator can execute these functions: Only the owner of a cluster can execute these functions: - `SSVNetwork.registerValidator` - Registers a new validator on the SSV Network +- `SSVNetwork.bulkRegisterValidator` - Registers a set of validators in the same cluster on the SSV Network - `SSVNetwork.removeValidator` - Removes an existing validator from the SSV Network +- `SSVNetwork.bulkRemoveValidator` - Bulk removes an set of existing validators in the same cluster from the SSV Network - `SSVNetwork.reactivate` - Reactivates a cluster - `SSVNetwork.withdraw` - Withdraws tokens from a cluster +- `SSVNetwork.exitValidator` - Starts the exit protocol for an exisiting validator +- `SSVNetwork.bulkExitValidator` - Starts the exit protocol for a set of existing validators From 56d11846e69785b617a974521fd25ecf031c9989 Mon Sep 17 00:00:00 2001 From: Marco Tabasco Date: Fri, 19 Jan 2024 13:50:07 +0100 Subject: [PATCH 28/38] minor improvements --- contracts/SSVNetwork.sol | 2 +- contracts/interfaces/ISSVClusters.sol | 4 +- docs/roles.md | 2 +- test/helpers/contract-helpers.ts | 9 +---- test/sanity/balances.ts | 4 +- test/validators/exit.ts | 22 +++++------ test/validators/register.ts | 54 +++++++++++++-------------- test/validators/remove.ts | 18 ++++----- 8 files changed, 53 insertions(+), 62 deletions(-) diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index fdf3c5c0..58d82556 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -168,7 +168,7 @@ contract SSVNetwork is function registerValidator( bytes calldata publicKey, uint64[] memory operatorIds, - bytes calldata shares, + bytes calldata sharesData, uint256 amount, ISSVNetworkCore.Cluster memory cluster ) external override { diff --git a/contracts/interfaces/ISSVClusters.sol b/contracts/interfaces/ISSVClusters.sol index acb32847..1cc93925 100644 --- a/contracts/interfaces/ISSVClusters.sol +++ b/contracts/interfaces/ISSVClusters.sol @@ -32,13 +32,13 @@ interface ISSVClusters is ISSVNetworkCore { Cluster memory cluster ) external; - /// @notice Removes an existing validator from the SSV Network + /// @notice Bulk removes an set of existing validators in the same cluster from the SSV Network /// @param publicKey The public key of the validator to be removed /// @param operatorIds Array of IDs of operators managing the validator /// @param cluster Cluster associated with the validator function removeValidator(bytes calldata publicKey, uint64[] memory operatorIds, Cluster memory cluster) external; - /// @notice Removes an existing validator from the SSV Network + /// @notice Removes an existing validator set from the SSV Network /// @param publicKeys The public keys of the validators to be removed /// @param operatorIds Array of IDs of operators managing the validator /// @param cluster Cluster associated with the validator diff --git a/docs/roles.md b/docs/roles.md index 07adf84d..88364363 100644 --- a/docs/roles.md +++ b/docs/roles.md @@ -42,7 +42,7 @@ Only the owner of a cluster can execute these functions: - `SSVNetwork.registerValidator` - Registers a new validator on the SSV Network - `SSVNetwork.bulkRegisterValidator` - Registers a set of validators in the same cluster on the SSV Network - `SSVNetwork.removeValidator` - Removes an existing validator from the SSV Network -- `SSVNetwork.bulkRemoveValidator` - Bulk removes an set of existing validators in the same cluster from the SSV Network +- `SSVNetwork.bulkRemoveValidator` - Bulk removes a set of existing validators in the same cluster from the SSV Network - `SSVNetwork.reactivate` - Reactivates a cluster - `SSVNetwork.withdraw` - Withdraws tokens from a cluster - `SSVNetwork.exitValidator` - Starts the exit protocol for an exisiting validator diff --git a/test/helpers/contract-helpers.ts b/test/helpers/contract-helpers.ts index 80148605..28cb8adb 100644 --- a/test/helpers/contract-helpers.ts +++ b/test/helpers/contract-helpers.ts @@ -134,14 +134,7 @@ export const initializeContract = async () => { ssvClustersMod: {}, ssvDAOMod: {}, ssvViewsMod: {}, - ownerNonce: 0, - initialClusterState: { - validatorCount: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - active: true - } + ownerNonce: 0 }; SSV_MODULES = { diff --git a/test/sanity/balances.ts b/test/sanity/balances.ts index bb4401ce..1fcd9f3f 100644 --- a/test/sanity/balances.ts +++ b/test/sanity/balances.ts @@ -430,7 +430,7 @@ describe('Balance Tests', () => { 10, [5, 6, 7, 8], minDepositAmount, - helpers.DB.initialClusterState, + helpers.getClusterForValidator(0, 0, 0, 0, true), ); await utils.progressBlocks(2); @@ -480,7 +480,7 @@ describe('Balance Tests', () => { 10, [5, 6, 7, 8], minDepositAmount, - helpers.DB.initialClusterState, + helpers.getClusterForValidator(0, 0, 0, 0, true), ); await utils.progressBlocks(2); diff --git a/test/validators/exit.ts b/test/validators/exit.ts index dd5eff6a..2a1a0681 100644 --- a/test/validators/exit.ts +++ b/test/validators/exit.ts @@ -176,7 +176,7 @@ describe('Exit Validator Tests', () => { 10, helpers.DEFAULT_OPERATOR_IDS[4], minDepositAmount, - helpers.DB.initialClusterState, + helpers.getClusterForValidator(0, 0, 0, 0, true), ); await expect( @@ -193,7 +193,7 @@ describe('Exit Validator Tests', () => { 10, helpers.DEFAULT_OPERATOR_IDS[4], minDepositAmount, - helpers.DB.initialClusterState, + helpers.getClusterForValidator(0, 0, 0, 0, true), ); await trackGas( @@ -210,7 +210,7 @@ describe('Exit Validator Tests', () => { 10, helpers.DEFAULT_OPERATOR_IDS[7], minDepositAmount, - helpers.DB.initialClusterState, + helpers.getClusterForValidator(0, 0, 0, 0, true), ); await trackGas( @@ -227,7 +227,7 @@ describe('Exit Validator Tests', () => { 10, helpers.DEFAULT_OPERATOR_IDS[10], minDepositAmount, - helpers.DB.initialClusterState, + helpers.getClusterForValidator(0, 0, 0, 0, true), ); await trackGas( @@ -244,7 +244,7 @@ describe('Exit Validator Tests', () => { 10, helpers.DEFAULT_OPERATOR_IDS[13], minDepositAmount, - helpers.DB.initialClusterState, + helpers.getClusterForValidator(0, 0, 0, 0, true), ); await trackGas( @@ -261,7 +261,7 @@ describe('Exit Validator Tests', () => { 10, helpers.DEFAULT_OPERATOR_IDS[4], minDepositAmount, - helpers.DB.initialClusterState, + helpers.getClusterForValidator(0, 0, 0, 0, true), ); await trackGas(ssvNetworkContract @@ -282,7 +282,7 @@ describe('Exit Validator Tests', () => { 10, helpers.DEFAULT_OPERATOR_IDS[4], minDepositAmount, - helpers.DB.initialClusterState, + helpers.getClusterForValidator(0, 0, 0, 0, true), ); pks[4] = "0xabcd1234"; @@ -300,7 +300,7 @@ describe('Exit Validator Tests', () => { 10, helpers.DEFAULT_OPERATOR_IDS[4], minDepositAmount, - helpers.DB.initialClusterState, + helpers.getClusterForValidator(0, 0, 0, 0, true), ); await expect( @@ -314,7 +314,7 @@ describe('Exit Validator Tests', () => { 10, helpers.DEFAULT_OPERATOR_IDS[4], minDepositAmount, - helpers.DB.initialClusterState, + helpers.getClusterForValidator(0, 0, 0, 0, true), ); await expect( @@ -328,7 +328,7 @@ describe('Exit Validator Tests', () => { 10, helpers.DEFAULT_OPERATOR_IDS[4], minDepositAmount, - helpers.DB.initialClusterState, + helpers.getClusterForValidator(0, 0, 0, 0, true), ); await expect( @@ -344,7 +344,7 @@ describe('Exit Validator Tests', () => { 10, helpers.DEFAULT_OPERATOR_IDS[4], minDepositAmount, - helpers.DB.initialClusterState, + helpers.getClusterForValidator(0, 0, 0, 0, true), ); await expect( diff --git a/test/validators/register.ts b/test/validators/register.ts index 7b76a8e0..f56b1bb8 100644 --- a/test/validators/register.ts +++ b/test/validators/register.ts @@ -4,7 +4,7 @@ import * as utils from '../helpers/utils'; import { expect } from 'chai'; import { trackGas, GasGroup } from '../helpers/gas-usage'; -let ssvNetworkContract: any, ssvViews: any, ssvToken: any, minDepositAmount: any, cluster1: any, initialClusterState: any; +let ssvNetworkContract: any, ssvViews: any, ssvToken: any, minDepositAmount: any, cluster1: any; describe('Register Validator Tests', () => { beforeEach(async () => { @@ -14,8 +14,6 @@ describe('Register Validator Tests', () => { ssvToken = metadata.ssvToken; ssvViews = metadata.ssvViews; - initialClusterState = helpers.DB.initialClusterState; - // Register operators await helpers.registerOperators(0, 14, helpers.CONFIG.minimalOperatorFee); @@ -33,7 +31,7 @@ describe('Register Validator Tests', () => { [1, 2, 3, 4], helpers.DataGenerator.shares(6, 1, 4), '1000000000000000', - initialClusterState, + helpers.getClusterForValidator(0, 0, 0, 0, true), ), ); }); @@ -48,7 +46,7 @@ describe('Register Validator Tests', () => { [1, 2, 3, 4], helpers.DataGenerator.shares(1, 1, 4), minDepositAmount, - initialClusterState, + helpers.getClusterForValidator(0, 0, 0, 0, true), ), ).to.emit(ssvNetworkContract, 'ValidatorAdded'); }); @@ -65,7 +63,7 @@ describe('Register Validator Tests', () => { helpers.DataGenerator.cluster.new(), helpers.DataGenerator.shares(1, 1, 4), minDepositAmount, - initialClusterState, + helpers.getClusterForValidator(0, 0, 0, 0, true), ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE], ); @@ -85,7 +83,7 @@ describe('Register Validator Tests', () => { [1, 2, 3, 4], helpers.DataGenerator.shares(1, 1, 4), minDepositAmount, - initialClusterState, + helpers.getClusterForValidator(0, 0, 0, 0, true), ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE], ); @@ -117,7 +115,7 @@ describe('Register Validator Tests', () => { [1, 2, 3, 4], helpers.DataGenerator.shares(1, 1, 4), minDepositAmount, - initialClusterState, + helpers.getClusterForValidator(0, 0, 0, 0, true), ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE], ); @@ -147,7 +145,7 @@ describe('Register Validator Tests', () => { [2, 3, 4, 5], helpers.DataGenerator.shares(2, 4, 4), minDepositAmount, - initialClusterState, + helpers.getClusterForValidator(0, 0, 0, 0, true), ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE], ); @@ -165,7 +163,7 @@ describe('Register Validator Tests', () => { [1, 2, 3, 4], helpers.DataGenerator.shares(1, 1, 4), `${minDepositAmount * 2}`, - initialClusterState, + helpers.getClusterForValidator(0, 0, 0, 0, true), ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE], ); @@ -246,7 +244,7 @@ describe('Register Validator Tests', () => { helpers.DataGenerator.cluster.new(7), helpers.DataGenerator.shares(1, 2, 7), minDepositAmount, - initialClusterState, + helpers.getClusterForValidator(0, 0, 0, 0, true), ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7], ); @@ -262,7 +260,7 @@ describe('Register Validator Tests', () => { [1, 2, 3, 4, 5, 6, 7], helpers.DataGenerator.shares(1, 1, 7), minDepositAmount, - initialClusterState, + helpers.getClusterForValidator(0, 0, 0, 0, true), ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7], ); @@ -294,7 +292,7 @@ describe('Register Validator Tests', () => { [1, 2, 3, 4, 5, 6, 7], helpers.DataGenerator.shares(1, 1, 7), minDepositAmount, - initialClusterState, + helpers.getClusterForValidator(0, 0, 0, 0, true), ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7], ); @@ -324,7 +322,7 @@ describe('Register Validator Tests', () => { [2, 3, 4, 5, 6, 7, 8], helpers.DataGenerator.shares(2, 4, 7), minDepositAmount, - initialClusterState, + helpers.getClusterForValidator(0, 0, 0, 0, true), ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7], ); @@ -342,7 +340,7 @@ describe('Register Validator Tests', () => { [1, 2, 3, 4, 5, 6, 7], helpers.DataGenerator.shares(1, 1, 7), `${minDepositAmount * 2}`, - initialClusterState, + helpers.getClusterForValidator(0, 0, 0, 0, true), ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7], ); @@ -423,7 +421,7 @@ describe('Register Validator Tests', () => { helpers.DataGenerator.cluster.new(10), helpers.DataGenerator.shares(1, 1, 10), minDepositAmount, - initialClusterState, + helpers.getClusterForValidator(0, 0, 0, 0, true), ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_10], ); @@ -439,7 +437,7 @@ describe('Register Validator Tests', () => { [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], helpers.DataGenerator.shares(1, 1, 10), minDepositAmount, - initialClusterState, + helpers.getClusterForValidator(0, 0, 0, 0, true), ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_10], ); @@ -471,7 +469,7 @@ describe('Register Validator Tests', () => { [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], helpers.DataGenerator.shares(1, 1, 10), minDepositAmount, - initialClusterState, + helpers.getClusterForValidator(0, 0, 0, 0, true), ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_10], ); @@ -501,7 +499,7 @@ describe('Register Validator Tests', () => { [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], helpers.DataGenerator.shares(2, 4, 10), minDepositAmount, - initialClusterState, + helpers.getClusterForValidator(0, 0, 0, 0, true), ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_10], ); @@ -519,7 +517,7 @@ describe('Register Validator Tests', () => { [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], helpers.DataGenerator.shares(1, 1, 10), `${minDepositAmount * 2}`, - initialClusterState, + helpers.getClusterForValidator(0, 0, 0, 0, true), ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_10], ); @@ -602,7 +600,7 @@ describe('Register Validator Tests', () => { helpers.DataGenerator.cluster.new(13), helpers.DataGenerator.shares(1, 1, 13), minDepositAmount, - initialClusterState, + helpers.getClusterForValidator(0, 0, 0, 0, true), ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13], ); @@ -618,7 +616,7 @@ describe('Register Validator Tests', () => { [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], helpers.DataGenerator.shares(1, 1, 13), minDepositAmount, - initialClusterState, + helpers.getClusterForValidator(0, 0, 0, 0, true), ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13], ); @@ -649,7 +647,7 @@ describe('Register Validator Tests', () => { [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], helpers.DataGenerator.shares(1, 1, 13), minDepositAmount, - initialClusterState, + helpers.getClusterForValidator(0, 0, 0, 0, true), ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13], ); @@ -678,7 +676,7 @@ describe('Register Validator Tests', () => { [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], helpers.DataGenerator.shares(2, 4, 13), minDepositAmount, - initialClusterState, + helpers.getClusterForValidator(0, 0, 0, 0, true), ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13], ); @@ -696,7 +694,7 @@ describe('Register Validator Tests', () => { [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], helpers.DataGenerator.shares(1, 1, 13), `${minDepositAmount * 2}`, - initialClusterState, + helpers.getClusterForValidator(0, 0, 0, 0, true), ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13], ); @@ -1012,7 +1010,7 @@ describe('Register Validator Tests', () => { [1, 2, 3, 4], helpers.DataGenerator.shares(6, 1, 4), minDepositAmount, - initialClusterState, + helpers.getClusterForValidator(0, 0, 0, 0, true), ), ).to.be.revertedWithCustomError(ssvNetworkContract, 'ValidatorAlreadyExists'); }); @@ -1029,7 +1027,7 @@ describe('Register Validator Tests', () => { [1, 2, 5, 6], helpers.DataGenerator.shares(6, 1, 4), minDepositAmount, - initialClusterState, + helpers.getClusterForValidator(0, 0, 0, 0, true), ), ).to.be.revertedWithCustomError(ssvNetworkContract, 'ValidatorAlreadyExists'); }); @@ -1055,7 +1053,7 @@ describe('Register Validator Tests', () => { [1, 2, 3, operatorId], helpers.DataGenerator.shares(3, 1, 4), minDepositAmount, - initialClusterState, + helpers.getClusterForValidator(0, 0, 0, 0, true), ), ).to.emit(ssvNetworkContract, 'ValidatorAdded'); }); diff --git a/test/validators/remove.ts b/test/validators/remove.ts index ecbdc3bd..58a439d9 100644 --- a/test/validators/remove.ts +++ b/test/validators/remove.ts @@ -49,7 +49,7 @@ describe('Remove Validator Tests', () => { 10, helpers.DEFAULT_OPERATOR_IDS[4], minDepositAmount, - helpers.DB.initialClusterState, + helpers.getClusterForValidator(0, 0, 0, 0, true), ); await expect( @@ -83,7 +83,7 @@ describe('Remove Validator Tests', () => { 10, helpers.DEFAULT_OPERATOR_IDS[4], minDepositAmount, - helpers.DB.initialClusterState, + helpers.getClusterForValidator(0, 0, 0, 0, true), ); await trackGas( @@ -119,7 +119,7 @@ describe('Remove Validator Tests', () => { 10, helpers.DEFAULT_OPERATOR_IDS[7], minDepositAmount, - helpers.DB.initialClusterState, + helpers.getClusterForValidator(0, 0, 0, 0, true), ); await trackGas( @@ -155,7 +155,7 @@ describe('Remove Validator Tests', () => { 10, helpers.DEFAULT_OPERATOR_IDS[10], minDepositAmount, - helpers.DB.initialClusterState, + helpers.getClusterForValidator(0, 0, 0, 0, true), ); await trackGas( @@ -191,7 +191,7 @@ describe('Remove Validator Tests', () => { 10, helpers.DEFAULT_OPERATOR_IDS[13], minDepositAmount, - helpers.DB.initialClusterState, + helpers.getClusterForValidator(0, 0, 0, 0, true), ); await trackGas( @@ -324,7 +324,7 @@ describe('Remove Validator Tests', () => { 10, helpers.DEFAULT_OPERATOR_IDS[4], minDepositAmount, - helpers.DB.initialClusterState, + helpers.getClusterForValidator(0, 0, 0, 0, true), ); pks[2] = "0xabcd1234"; @@ -342,7 +342,7 @@ describe('Remove Validator Tests', () => { 10, helpers.DEFAULT_OPERATOR_IDS[4], minDepositAmount, - helpers.DB.initialClusterState, + helpers.getClusterForValidator(0, 0, 0, 0, true), ); await expect( @@ -358,7 +358,7 @@ describe('Remove Validator Tests', () => { 10, helpers.DEFAULT_OPERATOR_IDS[4], minDepositAmount, - helpers.DB.initialClusterState, + helpers.getClusterForValidator(0, 0, 0, 0, true), ); const result = await trackGas( @@ -383,7 +383,7 @@ describe('Remove Validator Tests', () => { 10, helpers.DEFAULT_OPERATOR_IDS[4], minDepositAmount, - helpers.DB.initialClusterState, + helpers.getClusterForValidator(0, 0, 0, 0, true), ); await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation - 2); From 584b2cb0562ed8d430b903420c29089663be3cba Mon Sep 17 00:00:00 2001 From: Marco Tabasco Date: Mon, 22 Jan 2024 13:11:04 +0100 Subject: [PATCH 29/38] v1.1.0 goerli_prod metadata --- .openzeppelin/goerli.json | 109 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) diff --git a/.openzeppelin/goerli.json b/.openzeppelin/goerli.json index 70cc80c4..6b208828 100644 --- a/.openzeppelin/goerli.json +++ b/.openzeppelin/goerli.json @@ -7690,6 +7690,115 @@ }, "namespaces": {} } + }, + "ea22005a44aa654c8170296ef0052ed50bdb1eb52b46b0b5a9aefc6275bf48c0": { + "address": "0x5888116f5863CA1A311F51ab79a03fBd34Ac6487", + "txHash": "0x1754042f1c35ae05c7ea6c1090e2af0bd38dcf99ce86374720222ed1c66b8fba", + "layout": { + "solcVersion": "0.8.18", + "storage": [ + { + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_uint8", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:63", + "retypedFrom": "bool" + }, + { + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:68" + }, + { + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)50_storage", + "contract": "ERC1967UpgradeUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol:169" + }, + { + "label": "__gap", + "offset": 0, + "slot": "51", + "type": "t_array(t_uint256)50_storage", + "contract": "UUPSUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol:111" + }, + { + "label": "__gap", + "offset": 0, + "slot": "101", + "type": "t_array(t_uint256)50_storage", + "contract": "ContextUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" + }, + { + "label": "_owner", + "offset": 0, + "slot": "151", + "type": "t_address", + "contract": "OwnableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" + }, + { + "label": "__gap", + "offset": 0, + "slot": "152", + "type": "t_array(t_uint256)49_storage", + "contract": "OwnableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:94" + }, + { + "label": "_pendingOwner", + "offset": 0, + "slot": "201", + "type": "t_address", + "contract": "Ownable2StepUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol:27" + }, + { + "label": "__gap", + "offset": 0, + "slot": "202", + "type": "t_array(t_uint256)49_storage", + "contract": "Ownable2StepUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol:70" + } + ], + "types": { + "t_address": { + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_uint256)49_storage": { + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_array(t_uint256)50_storage": { + "label": "uint256[50]", + "numberOfBytes": "1600" + }, + "t_bool": { + "label": "bool", + "numberOfBytes": "1" + }, + "t_uint256": { + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint8": { + "label": "uint8", + "numberOfBytes": "1" + } + }, + "namespaces": {} + } } } } From 31389e1e48da6ceeb4c6711adcf66116055d6341 Mon Sep 17 00:00:00 2001 From: Marco Tabasco Date: Sun, 28 Jan 2024 01:18:29 +0100 Subject: [PATCH 30/38] remove abis from git --- .gitignore | 2 +- abis/SSVNetwork.json | 1850 ------------------------------------- abis/SSVNetworkViews.json | 880 ------------------ 3 files changed, 1 insertion(+), 2731 deletions(-) delete mode 100644 abis/SSVNetwork.json delete mode 100644 abis/SSVNetworkViews.json diff --git a/.gitignore b/.gitignore index 88003748..ac70bba5 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,7 @@ node_modules .env .env.prod .env.stage -#Hardhat files +abis cache coverage coverage.json diff --git a/abis/SSVNetwork.json b/abis/SSVNetwork.json deleted file mode 100644 index ef9681e3..00000000 --- a/abis/SSVNetwork.json +++ /dev/null @@ -1,1850 +0,0 @@ -[ - { - "inputs": [], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [], - "name": "ApprovalNotWithinTimeframe", - "type": "error" - }, - { - "inputs": [], - "name": "CallerNotOwner", - "type": "error" - }, - { - "inputs": [], - "name": "CallerNotWhitelisted", - "type": "error" - }, - { - "inputs": [], - "name": "ClusterAlreadyEnabled", - "type": "error" - }, - { - "inputs": [], - "name": "ClusterDoesNotExists", - "type": "error" - }, - { - "inputs": [], - "name": "ClusterIsLiquidated", - "type": "error" - }, - { - "inputs": [], - "name": "ClusterNotLiquidatable", - "type": "error" - }, - { - "inputs": [], - "name": "ExceedValidatorLimit", - "type": "error" - }, - { - "inputs": [], - "name": "FeeExceedsIncreaseLimit", - "type": "error" - }, - { - "inputs": [], - "name": "FeeIncreaseNotAllowed", - "type": "error" - }, - { - "inputs": [], - "name": "FeeTooHigh", - "type": "error" - }, - { - "inputs": [], - "name": "FeeTooLow", - "type": "error" - }, - { - "inputs": [], - "name": "IncorrectClusterState", - "type": "error" - }, - { - "inputs": [], - "name": "IncorrectValidatorState", - "type": "error" - }, - { - "inputs": [], - "name": "InsufficientBalance", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidOperatorIdsLength", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidPublicKeyLength", - "type": "error" - }, - { - "inputs": [], - "name": "MaxValueExceeded", - "type": "error" - }, - { - "inputs": [], - "name": "NewBlockPeriodIsBelowMinimum", - "type": "error" - }, - { - "inputs": [], - "name": "NoFeeDeclared", - "type": "error" - }, - { - "inputs": [], - "name": "NotAuthorized", - "type": "error" - }, - { - "inputs": [], - "name": "OperatorAlreadyExists", - "type": "error" - }, - { - "inputs": [], - "name": "OperatorDoesNotExist", - "type": "error" - }, - { - "inputs": [], - "name": "OperatorsListNotUnique", - "type": "error" - }, - { - "inputs": [], - "name": "PublicKeysSharesLengthMismatch", - "type": "error" - }, - { - "inputs": [], - "name": "SameFeeChangeNotAllowed", - "type": "error" - }, - { - "inputs": [], - "name": "TargetModuleDoesNotExist", - "type": "error" - }, - { - "inputs": [], - "name": "TokenTransferFailed", - "type": "error" - }, - { - "inputs": [], - "name": "UnsortedOperatorsList", - "type": "error" - }, - { - "inputs": [], - "name": "ValidatorAlreadyExists", - "type": "error" - }, - { - "inputs": [], - "name": "ValidatorDoesNotExist", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" - } - ], - "name": "AdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "beacon", - "type": "address" - } - ], - "name": "BeaconUpgraded", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint64[]", - "name": "operatorIds", - "type": "uint64[]" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "value", - "type": "uint256" - }, - { - "components": [ - { - "internalType": "uint32", - "name": "validatorCount", - "type": "uint32" - }, - { - "internalType": "uint64", - "name": "networkFeeIndex", - "type": "uint64" - }, - { - "internalType": "uint64", - "name": "index", - "type": "uint64" - }, - { - "internalType": "bool", - "name": "active", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "balance", - "type": "uint256" - } - ], - "indexed": false, - "internalType": "struct ISSVNetworkCore.Cluster", - "name": "cluster", - "type": "tuple" - } - ], - "name": "ClusterDeposited", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint64[]", - "name": "operatorIds", - "type": "uint64[]" - }, - { - "components": [ - { - "internalType": "uint32", - "name": "validatorCount", - "type": "uint32" - }, - { - "internalType": "uint64", - "name": "networkFeeIndex", - "type": "uint64" - }, - { - "internalType": "uint64", - "name": "index", - "type": "uint64" - }, - { - "internalType": "bool", - "name": "active", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "balance", - "type": "uint256" - } - ], - "indexed": false, - "internalType": "struct ISSVNetworkCore.Cluster", - "name": "cluster", - "type": "tuple" - } - ], - "name": "ClusterLiquidated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint64[]", - "name": "operatorIds", - "type": "uint64[]" - }, - { - "components": [ - { - "internalType": "uint32", - "name": "validatorCount", - "type": "uint32" - }, - { - "internalType": "uint64", - "name": "networkFeeIndex", - "type": "uint64" - }, - { - "internalType": "uint64", - "name": "index", - "type": "uint64" - }, - { - "internalType": "bool", - "name": "active", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "balance", - "type": "uint256" - } - ], - "indexed": false, - "internalType": "struct ISSVNetworkCore.Cluster", - "name": "cluster", - "type": "tuple" - } - ], - "name": "ClusterReactivated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint64[]", - "name": "operatorIds", - "type": "uint64[]" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "value", - "type": "uint256" - }, - { - "components": [ - { - "internalType": "uint32", - "name": "validatorCount", - "type": "uint32" - }, - { - "internalType": "uint64", - "name": "networkFeeIndex", - "type": "uint64" - }, - { - "internalType": "uint64", - "name": "index", - "type": "uint64" - }, - { - "internalType": "bool", - "name": "active", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "balance", - "type": "uint256" - } - ], - "indexed": false, - "internalType": "struct ISSVNetworkCore.Cluster", - "name": "cluster", - "type": "tuple" - } - ], - "name": "ClusterWithdrawn", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint64", - "name": "value", - "type": "uint64" - } - ], - "name": "DeclareOperatorFeePeriodUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint64", - "name": "value", - "type": "uint64" - } - ], - "name": "ExecuteOperatorFeePeriodUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "recipientAddress", - "type": "address" - } - ], - "name": "FeeRecipientAddressUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint8", - "name": "version", - "type": "uint8" - } - ], - "name": "Initialized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint64", - "name": "value", - "type": "uint64" - } - ], - "name": "LiquidationThresholdPeriodUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "MinimumLiquidationCollateralUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "value", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "address", - "name": "recipient", - "type": "address" - } - ], - "name": "NetworkEarningsWithdrawn", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "oldFee", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "newFee", - "type": "uint256" - } - ], - "name": "NetworkFeeUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint64", - "name": "operatorId", - "type": "uint64" - }, - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "publicKey", - "type": "bytes" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "fee", - "type": "uint256" - } - ], - "name": "OperatorAdded", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint64", - "name": "operatorId", - "type": "uint64" - } - ], - "name": "OperatorFeeDeclarationCancelled", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint64", - "name": "operatorId", - "type": "uint64" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "blockNumber", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "fee", - "type": "uint256" - } - ], - "name": "OperatorFeeDeclared", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint64", - "name": "operatorId", - "type": "uint64" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "blockNumber", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "fee", - "type": "uint256" - } - ], - "name": "OperatorFeeExecuted", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint64", - "name": "value", - "type": "uint64" - } - ], - "name": "OperatorFeeIncreaseLimitUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint64", - "name": "maxFee", - "type": "uint64" - } - ], - "name": "OperatorMaximumFeeUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint64", - "name": "operatorId", - "type": "uint64" - } - ], - "name": "OperatorRemoved", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint64", - "name": "operatorId", - "type": "uint64" - }, - { - "indexed": false, - "internalType": "address", - "name": "whitelisted", - "type": "address" - } - ], - "name": "OperatorWhitelistUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint64", - "name": "operatorId", - "type": "uint64" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "OperatorWithdrawn", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "previousOwner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "OwnershipTransferStarted", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "previousOwner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "OwnershipTransferred", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" - } - ], - "name": "Upgraded", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint64[]", - "name": "operatorIds", - "type": "uint64[]" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "publicKey", - "type": "bytes" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "shares", - "type": "bytes" - }, - { - "components": [ - { - "internalType": "uint32", - "name": "validatorCount", - "type": "uint32" - }, - { - "internalType": "uint64", - "name": "networkFeeIndex", - "type": "uint64" - }, - { - "internalType": "uint64", - "name": "index", - "type": "uint64" - }, - { - "internalType": "bool", - "name": "active", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "balance", - "type": "uint256" - } - ], - "indexed": false, - "internalType": "struct ISSVNetworkCore.Cluster", - "name": "cluster", - "type": "tuple" - } - ], - "name": "ValidatorAdded", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint64[]", - "name": "operatorIds", - "type": "uint64[]" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "publicKey", - "type": "bytes" - } - ], - "name": "ValidatorExited", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint64[]", - "name": "operatorIds", - "type": "uint64[]" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "publicKey", - "type": "bytes" - }, - { - "components": [ - { - "internalType": "uint32", - "name": "validatorCount", - "type": "uint32" - }, - { - "internalType": "uint64", - "name": "networkFeeIndex", - "type": "uint64" - }, - { - "internalType": "uint64", - "name": "index", - "type": "uint64" - }, - { - "internalType": "bool", - "name": "active", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "balance", - "type": "uint256" - } - ], - "indexed": false, - "internalType": "struct ISSVNetworkCore.Cluster", - "name": "cluster", - "type": "tuple" - } - ], - "name": "ValidatorRemoved", - "type": "event" - }, - { - "stateMutability": "nonpayable", - "type": "fallback" - }, - { - "inputs": [], - "name": "acceptOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes[]", - "name": "publicKeys", - "type": "bytes[]" - }, - { - "internalType": "uint64[]", - "name": "operatorIds", - "type": "uint64[]" - } - ], - "name": "bulkExitValidator", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes[]", - "name": "publicKeys", - "type": "bytes[]" - }, - { - "internalType": "uint64[]", - "name": "operatorIds", - "type": "uint64[]" - }, - { - "internalType": "bytes[]", - "name": "sharesData", - "type": "bytes[]" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "components": [ - { - "internalType": "uint32", - "name": "validatorCount", - "type": "uint32" - }, - { - "internalType": "uint64", - "name": "networkFeeIndex", - "type": "uint64" - }, - { - "internalType": "uint64", - "name": "index", - "type": "uint64" - }, - { - "internalType": "bool", - "name": "active", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "balance", - "type": "uint256" - } - ], - "internalType": "struct ISSVNetworkCore.Cluster", - "name": "cluster", - "type": "tuple" - } - ], - "name": "bulkRegisterValidator", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes[]", - "name": "publicKeys", - "type": "bytes[]" - }, - { - "internalType": "uint64[]", - "name": "operatorIds", - "type": "uint64[]" - }, - { - "components": [ - { - "internalType": "uint32", - "name": "validatorCount", - "type": "uint32" - }, - { - "internalType": "uint64", - "name": "networkFeeIndex", - "type": "uint64" - }, - { - "internalType": "uint64", - "name": "index", - "type": "uint64" - }, - { - "internalType": "bool", - "name": "active", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "balance", - "type": "uint256" - } - ], - "internalType": "struct ISSVNetworkCore.Cluster", - "name": "cluster", - "type": "tuple" - } - ], - "name": "bulkRemoveValidator", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint64", - "name": "operatorId", - "type": "uint64" - } - ], - "name": "cancelDeclaredOperatorFee", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint64", - "name": "operatorId", - "type": "uint64" - }, - { - "internalType": "uint256", - "name": "fee", - "type": "uint256" - } - ], - "name": "declareOperatorFee", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "clusterOwner", - "type": "address" - }, - { - "internalType": "uint64[]", - "name": "operatorIds", - "type": "uint64[]" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "components": [ - { - "internalType": "uint32", - "name": "validatorCount", - "type": "uint32" - }, - { - "internalType": "uint64", - "name": "networkFeeIndex", - "type": "uint64" - }, - { - "internalType": "uint64", - "name": "index", - "type": "uint64" - }, - { - "internalType": "bool", - "name": "active", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "balance", - "type": "uint256" - } - ], - "internalType": "struct ISSVNetworkCore.Cluster", - "name": "cluster", - "type": "tuple" - } - ], - "name": "deposit", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint64", - "name": "operatorId", - "type": "uint64" - } - ], - "name": "executeOperatorFee", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes", - "name": "publicKey", - "type": "bytes" - }, - { - "internalType": "uint64[]", - "name": "operatorIds", - "type": "uint64[]" - } - ], - "name": "exitValidator", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "getVersion", - "outputs": [ - { - "internalType": "string", - "name": "version", - "type": "string" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract IERC20", - "name": "token_", - "type": "address" - }, - { - "internalType": "contract ISSVOperators", - "name": "ssvOperators_", - "type": "address" - }, - { - "internalType": "contract ISSVClusters", - "name": "ssvClusters_", - "type": "address" - }, - { - "internalType": "contract ISSVDAO", - "name": "ssvDAO_", - "type": "address" - }, - { - "internalType": "contract ISSVViews", - "name": "ssvViews_", - "type": "address" - }, - { - "internalType": "uint64", - "name": "minimumBlocksBeforeLiquidation_", - "type": "uint64" - }, - { - "internalType": "uint256", - "name": "minimumLiquidationCollateral_", - "type": "uint256" - }, - { - "internalType": "uint32", - "name": "validatorsPerOperatorLimit_", - "type": "uint32" - }, - { - "internalType": "uint64", - "name": "declareOperatorFeePeriod_", - "type": "uint64" - }, - { - "internalType": "uint64", - "name": "executeOperatorFeePeriod_", - "type": "uint64" - }, - { - "internalType": "uint64", - "name": "operatorMaxFeeIncrease_", - "type": "uint64" - } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "clusterOwner", - "type": "address" - }, - { - "internalType": "uint64[]", - "name": "operatorIds", - "type": "uint64[]" - }, - { - "components": [ - { - "internalType": "uint32", - "name": "validatorCount", - "type": "uint32" - }, - { - "internalType": "uint64", - "name": "networkFeeIndex", - "type": "uint64" - }, - { - "internalType": "uint64", - "name": "index", - "type": "uint64" - }, - { - "internalType": "bool", - "name": "active", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "balance", - "type": "uint256" - } - ], - "internalType": "struct ISSVNetworkCore.Cluster", - "name": "cluster", - "type": "tuple" - } - ], - "name": "liquidate", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "pendingOwner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "proxiableUUID", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint64[]", - "name": "operatorIds", - "type": "uint64[]" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "components": [ - { - "internalType": "uint32", - "name": "validatorCount", - "type": "uint32" - }, - { - "internalType": "uint64", - "name": "networkFeeIndex", - "type": "uint64" - }, - { - "internalType": "uint64", - "name": "index", - "type": "uint64" - }, - { - "internalType": "bool", - "name": "active", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "balance", - "type": "uint256" - } - ], - "internalType": "struct ISSVNetworkCore.Cluster", - "name": "cluster", - "type": "tuple" - } - ], - "name": "reactivate", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint64", - "name": "operatorId", - "type": "uint64" - }, - { - "internalType": "uint256", - "name": "fee", - "type": "uint256" - } - ], - "name": "reduceOperatorFee", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes", - "name": "publicKey", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "fee", - "type": "uint256" - } - ], - "name": "registerOperator", - "outputs": [ - { - "internalType": "uint64", - "name": "id", - "type": "uint64" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes", - "name": "publicKey", - "type": "bytes" - }, - { - "internalType": "uint64[]", - "name": "operatorIds", - "type": "uint64[]" - }, - { - "internalType": "bytes", - "name": "shares", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "components": [ - { - "internalType": "uint32", - "name": "validatorCount", - "type": "uint32" - }, - { - "internalType": "uint64", - "name": "networkFeeIndex", - "type": "uint64" - }, - { - "internalType": "uint64", - "name": "index", - "type": "uint64" - }, - { - "internalType": "bool", - "name": "active", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "balance", - "type": "uint256" - } - ], - "internalType": "struct ISSVNetworkCore.Cluster", - "name": "cluster", - "type": "tuple" - } - ], - "name": "registerValidator", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint64", - "name": "operatorId", - "type": "uint64" - } - ], - "name": "removeOperator", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes", - "name": "publicKey", - "type": "bytes" - }, - { - "internalType": "uint64[]", - "name": "operatorIds", - "type": "uint64[]" - }, - { - "components": [ - { - "internalType": "uint32", - "name": "validatorCount", - "type": "uint32" - }, - { - "internalType": "uint64", - "name": "networkFeeIndex", - "type": "uint64" - }, - { - "internalType": "uint64", - "name": "index", - "type": "uint64" - }, - { - "internalType": "bool", - "name": "active", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "balance", - "type": "uint256" - } - ], - "internalType": "struct ISSVNetworkCore.Cluster", - "name": "cluster", - "type": "tuple" - } - ], - "name": "removeValidator", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "renounceOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "recipientAddress", - "type": "address" - } - ], - "name": "setFeeRecipientAddress", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint64", - "name": "operatorId", - "type": "uint64" - }, - { - "internalType": "address", - "name": "whitelisted", - "type": "address" - } - ], - "name": "setOperatorWhitelist", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "transferOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint64", - "name": "timeInSeconds", - "type": "uint64" - } - ], - "name": "updateDeclareOperatorFeePeriod", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint64", - "name": "timeInSeconds", - "type": "uint64" - } - ], - "name": "updateExecuteOperatorFeePeriod", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint64", - "name": "blocks", - "type": "uint64" - } - ], - "name": "updateLiquidationThresholdPeriod", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint64", - "name": "maxFee", - "type": "uint64" - } - ], - "name": "updateMaximumOperatorFee", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "updateMinimumLiquidationCollateral", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "enum SSVModules", - "name": "moduleId", - "type": "uint8" - }, - { - "internalType": "address", - "name": "moduleAddress", - "type": "address" - } - ], - "name": "updateModule", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "fee", - "type": "uint256" - } - ], - "name": "updateNetworkFee", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint64", - "name": "percentage", - "type": "uint64" - } - ], - "name": "updateOperatorFeeIncreaseLimit", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newImplementation", - "type": "address" - } - ], - "name": "upgradeTo", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newImplementation", - "type": "address" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "upgradeToAndCall", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint64[]", - "name": "operatorIds", - "type": "uint64[]" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "components": [ - { - "internalType": "uint32", - "name": "validatorCount", - "type": "uint32" - }, - { - "internalType": "uint64", - "name": "networkFeeIndex", - "type": "uint64" - }, - { - "internalType": "uint64", - "name": "index", - "type": "uint64" - }, - { - "internalType": "bool", - "name": "active", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "balance", - "type": "uint256" - } - ], - "internalType": "struct ISSVNetworkCore.Cluster", - "name": "cluster", - "type": "tuple" - } - ], - "name": "withdraw", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint64", - "name": "operatorId", - "type": "uint64" - } - ], - "name": "withdrawAllOperatorEarnings", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "withdrawNetworkEarnings", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint64", - "name": "operatorId", - "type": "uint64" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "withdrawOperatorEarnings", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - } -] diff --git a/abis/SSVNetworkViews.json b/abis/SSVNetworkViews.json deleted file mode 100644 index 2ae195d5..00000000 --- a/abis/SSVNetworkViews.json +++ /dev/null @@ -1,880 +0,0 @@ -[ - { - "inputs": [], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [], - "name": "ApprovalNotWithinTimeframe", - "type": "error" - }, - { - "inputs": [], - "name": "CallerNotOwner", - "type": "error" - }, - { - "inputs": [], - "name": "CallerNotWhitelisted", - "type": "error" - }, - { - "inputs": [], - "name": "ClusterAlreadyEnabled", - "type": "error" - }, - { - "inputs": [], - "name": "ClusterDoesNotExists", - "type": "error" - }, - { - "inputs": [], - "name": "ClusterIsLiquidated", - "type": "error" - }, - { - "inputs": [], - "name": "ClusterNotLiquidatable", - "type": "error" - }, - { - "inputs": [], - "name": "ExceedValidatorLimit", - "type": "error" - }, - { - "inputs": [], - "name": "FeeExceedsIncreaseLimit", - "type": "error" - }, - { - "inputs": [], - "name": "FeeIncreaseNotAllowed", - "type": "error" - }, - { - "inputs": [], - "name": "FeeTooHigh", - "type": "error" - }, - { - "inputs": [], - "name": "FeeTooLow", - "type": "error" - }, - { - "inputs": [], - "name": "IncorrectClusterState", - "type": "error" - }, - { - "inputs": [], - "name": "IncorrectValidatorState", - "type": "error" - }, - { - "inputs": [], - "name": "InsufficientBalance", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidOperatorIdsLength", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidPublicKeyLength", - "type": "error" - }, - { - "inputs": [], - "name": "MaxValueExceeded", - "type": "error" - }, - { - "inputs": [], - "name": "NewBlockPeriodIsBelowMinimum", - "type": "error" - }, - { - "inputs": [], - "name": "NoFeeDeclared", - "type": "error" - }, - { - "inputs": [], - "name": "NotAuthorized", - "type": "error" - }, - { - "inputs": [], - "name": "OperatorAlreadyExists", - "type": "error" - }, - { - "inputs": [], - "name": "OperatorDoesNotExist", - "type": "error" - }, - { - "inputs": [], - "name": "OperatorsListNotUnique", - "type": "error" - }, - { - "inputs": [], - "name": "PublicKeysSharesLengthMismatch", - "type": "error" - }, - { - "inputs": [], - "name": "SameFeeChangeNotAllowed", - "type": "error" - }, - { - "inputs": [], - "name": "TargetModuleDoesNotExist", - "type": "error" - }, - { - "inputs": [], - "name": "TokenTransferFailed", - "type": "error" - }, - { - "inputs": [], - "name": "UnsortedOperatorsList", - "type": "error" - }, - { - "inputs": [], - "name": "ValidatorAlreadyExists", - "type": "error" - }, - { - "inputs": [], - "name": "ValidatorDoesNotExist", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" - } - ], - "name": "AdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "beacon", - "type": "address" - } - ], - "name": "BeaconUpgraded", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint8", - "name": "version", - "type": "uint8" - } - ], - "name": "Initialized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "previousOwner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "OwnershipTransferStarted", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "previousOwner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "OwnershipTransferred", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" - } - ], - "name": "Upgraded", - "type": "event" - }, - { - "inputs": [], - "name": "acceptOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "clusterOwner", - "type": "address" - }, - { - "internalType": "uint64[]", - "name": "operatorIds", - "type": "uint64[]" - }, - { - "components": [ - { - "internalType": "uint32", - "name": "validatorCount", - "type": "uint32" - }, - { - "internalType": "uint64", - "name": "networkFeeIndex", - "type": "uint64" - }, - { - "internalType": "uint64", - "name": "index", - "type": "uint64" - }, - { - "internalType": "bool", - "name": "active", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "balance", - "type": "uint256" - } - ], - "internalType": "struct ISSVNetworkCore.Cluster", - "name": "cluster", - "type": "tuple" - } - ], - "name": "getBalance", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "clusterOwner", - "type": "address" - }, - { - "internalType": "uint64[]", - "name": "operatorIds", - "type": "uint64[]" - }, - { - "components": [ - { - "internalType": "uint32", - "name": "validatorCount", - "type": "uint32" - }, - { - "internalType": "uint64", - "name": "networkFeeIndex", - "type": "uint64" - }, - { - "internalType": "uint64", - "name": "index", - "type": "uint64" - }, - { - "internalType": "bool", - "name": "active", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "balance", - "type": "uint256" - } - ], - "internalType": "struct ISSVNetworkCore.Cluster", - "name": "cluster", - "type": "tuple" - } - ], - "name": "getBurnRate", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getLiquidationThresholdPeriod", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getMaximumOperatorFee", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getMinimumLiquidationCollateral", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getNetworkEarnings", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getNetworkFee", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getNetworkValidatorsCount", - "outputs": [ - { - "internalType": "uint32", - "name": "", - "type": "uint32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint64", - "name": "operatorId", - "type": "uint64" - } - ], - "name": "getOperatorById", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - }, - { - "internalType": "uint32", - "name": "", - "type": "uint32" - }, - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "bool", - "name": "", - "type": "bool" - }, - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint64", - "name": "operatorId", - "type": "uint64" - } - ], - "name": "getOperatorDeclaredFee", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - }, - { - "internalType": "uint64", - "name": "", - "type": "uint64" - }, - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint64", - "name": "id", - "type": "uint64" - } - ], - "name": "getOperatorEarnings", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint64", - "name": "operatorId", - "type": "uint64" - } - ], - "name": "getOperatorFee", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getOperatorFeeIncreaseLimit", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getOperatorFeePeriods", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - }, - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "clusterOwner", - "type": "address" - }, - { - "internalType": "bytes", - "name": "publicKey", - "type": "bytes" - } - ], - "name": "getValidator", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getValidatorsPerOperatorLimit", - "outputs": [ - { - "internalType": "uint32", - "name": "", - "type": "uint32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getVersion", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract ISSVViews", - "name": "ssvNetwork_", - "type": "address" - } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "clusterOwner", - "type": "address" - }, - { - "internalType": "uint64[]", - "name": "operatorIds", - "type": "uint64[]" - }, - { - "components": [ - { - "internalType": "uint32", - "name": "validatorCount", - "type": "uint32" - }, - { - "internalType": "uint64", - "name": "networkFeeIndex", - "type": "uint64" - }, - { - "internalType": "uint64", - "name": "index", - "type": "uint64" - }, - { - "internalType": "bool", - "name": "active", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "balance", - "type": "uint256" - } - ], - "internalType": "struct ISSVNetworkCore.Cluster", - "name": "cluster", - "type": "tuple" - } - ], - "name": "isLiquidatable", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "clusterOwner", - "type": "address" - }, - { - "internalType": "uint64[]", - "name": "operatorIds", - "type": "uint64[]" - }, - { - "components": [ - { - "internalType": "uint32", - "name": "validatorCount", - "type": "uint32" - }, - { - "internalType": "uint64", - "name": "networkFeeIndex", - "type": "uint64" - }, - { - "internalType": "uint64", - "name": "index", - "type": "uint64" - }, - { - "internalType": "bool", - "name": "active", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "balance", - "type": "uint256" - } - ], - "internalType": "struct ISSVNetworkCore.Cluster", - "name": "cluster", - "type": "tuple" - } - ], - "name": "isLiquidated", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "pendingOwner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "proxiableUUID", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "renounceOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "ssvNetwork", - "outputs": [ - { - "internalType": "contract ISSVViews", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "transferOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newImplementation", - "type": "address" - } - ], - "name": "upgradeTo", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newImplementation", - "type": "address" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "upgradeToAndCall", - "outputs": [], - "stateMutability": "payable", - "type": "function" - } -] From f51d071841d68f2fc1ac1a6ac7a8073116a944dc Mon Sep 17 00:00:00 2001 From: Marco Tabasco Date: Sun, 28 Jan 2024 02:00:58 +0100 Subject: [PATCH 31/38] remove liquidation check (duplicate) --- contracts/libraries/ClusterLib.sol | 28 ++++++++++++---------------- test/validators/exit.ts | 6 ++++++ test/validators/remove.ts | 6 ++++++ 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/contracts/libraries/ClusterLib.sol b/contracts/libraries/ClusterLib.sol index b839501d..81648a53 100644 --- a/contracts/libraries/ClusterLib.sol +++ b/contracts/libraries/ClusterLib.sol @@ -118,22 +118,18 @@ library ClusterLib { StorageData storage s, StorageProtocol storage sp ) internal { - uint64 burnRate; - - if (cluster.active) { - (uint64 clusterIndex, uint64 burnRate) = OperatorLib.updateClusterOperators( - operatorIds, - true, - true, - validatorCountDelta, - s, - sp - ); - - updateClusterData(cluster, clusterIndex, sp.currentNetworkFeeIndex()); - - sp.updateDAO(true, validatorCountDelta); - } + (uint64 clusterIndex, uint64 burnRate) = OperatorLib.updateClusterOperators( + operatorIds, + true, + true, + validatorCountDelta, + s, + sp + ); + + updateClusterData(cluster, clusterIndex, sp.currentNetworkFeeIndex()); + + sp.updateDAO(true, validatorCountDelta); cluster.validatorCount += validatorCountDelta; diff --git a/test/validators/exit.ts b/test/validators/exit.ts index 2a1a0681..31470980 100644 --- a/test/validators/exit.ts +++ b/test/validators/exit.ts @@ -205,6 +205,8 @@ describe('Exit Validator Tests', () => { }); it('Bulk exiting 10 validator (7 operators cluster) gas limit', async () => { + minDepositAmount = (helpers.CONFIG.minimalBlocksBeforeLiquidation + 10) * helpers.CONFIG.minimalOperatorFee * 7; + const { args, pks } = await helpers.bulkRegisterValidators( 2, 10, @@ -222,6 +224,8 @@ describe('Exit Validator Tests', () => { }); it('Bulk exiting 10 validator (10 operators cluster) gas limit', async () => { + minDepositAmount = (helpers.CONFIG.minimalBlocksBeforeLiquidation + 10) * helpers.CONFIG.minimalOperatorFee * 10; + const { args, pks } = await helpers.bulkRegisterValidators( 2, 10, @@ -239,6 +243,8 @@ describe('Exit Validator Tests', () => { }); it('Bulk exiting 10 validator (13 operators cluster) gas limit', async () => { + minDepositAmount = (helpers.CONFIG.minimalBlocksBeforeLiquidation + 10) * helpers.CONFIG.minimalOperatorFee * 13; + const { args, pks } = await helpers.bulkRegisterValidators( 2, 10, diff --git a/test/validators/remove.ts b/test/validators/remove.ts index 58a439d9..e6b6da94 100644 --- a/test/validators/remove.ts +++ b/test/validators/remove.ts @@ -114,6 +114,8 @@ describe('Remove Validator Tests', () => { }); it('Bulk remove 10 validator gas limit (7 operators cluster)', async () => { + minDepositAmount = (helpers.CONFIG.minimalBlocksBeforeLiquidation + 10) * helpers.CONFIG.minimalOperatorFee * 7; + const { args, pks } = await helpers.bulkRegisterValidators( 2, 10, @@ -150,6 +152,8 @@ describe('Remove Validator Tests', () => { }); it('Bulk remove 10 validator gas limit (10 operators cluster)', async () => { + minDepositAmount = (helpers.CONFIG.minimalBlocksBeforeLiquidation + 10) * helpers.CONFIG.minimalOperatorFee * 10; + const { args, pks } = await helpers.bulkRegisterValidators( 2, 10, @@ -186,6 +190,8 @@ describe('Remove Validator Tests', () => { }); it('Bulk remove 10 validator gas limit (13 operators cluster)', async () => { + minDepositAmount = (helpers.CONFIG.minimalBlocksBeforeLiquidation + 10) * helpers.CONFIG.minimalOperatorFee * 13; + const { args, pks } = await helpers.bulkRegisterValidators( 2, 10, From 1156139f937948e95ca6946f151dd3ad8f47dca5 Mon Sep 17 00:00:00 2001 From: Mohsen-T Date: Mon, 5 Feb 2024 09:38:53 +0100 Subject: [PATCH 32/38] Fix: updated the test coverage Enhanced test coverage by incorporating additional test cases to address previously overlooked scenarios --- contracts/mocks/SSVTokenMock.sol | 23 --- contracts/token/SSVToken.sol | 3 +- test/deployment/deploy.ts | 232 +++++++++++++++++-------------- test/helpers/contract-helpers.ts | 27 ++-- 4 files changed, 140 insertions(+), 145 deletions(-) delete mode 100644 contracts/mocks/SSVTokenMock.sol diff --git a/contracts/mocks/SSVTokenMock.sol b/contracts/mocks/SSVTokenMock.sol deleted file mode 100644 index d37ad827..00000000 --- a/contracts/mocks/SSVTokenMock.sol +++ /dev/null @@ -1,23 +0,0 @@ -//SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity 0.8.18; -import "@openzeppelin/contracts/access/Ownable.sol"; -import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; - -/** - * @title SSV Token - */ -contract SSVTokenMock is Ownable, ERC20 { - constructor() ERC20("SSV Token", "SSV") { - _mint(msg.sender, 1000000000000000000000); - } - - /** - * @dev Mint tokens - * @param to The target address - * @param amount The amount of token to mint - */ - // solhint-disable-next-line comprehensive-interface - function mint(address to, uint256 amount) external onlyOwner { - _mint(to, amount); - } -} diff --git a/contracts/token/SSVToken.sol b/contracts/token/SSVToken.sol index df3588d8..48165768 100644 --- a/contracts/token/SSVToken.sol +++ b/contracts/token/SSVToken.sol @@ -10,6 +10,7 @@ import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol"; */ contract SSVToken is Ownable, ERC20, ERC20Burnable { constructor() ERC20("SSV Token", "SSV") { + _mint(msg.sender, 1000000000000000000000); } /** @@ -20,4 +21,4 @@ contract SSVToken is Ownable, ERC20, ERC20Burnable { function mint(address to, uint256 amount) external onlyOwner { _mint(to, amount); } -} \ No newline at end of file +} diff --git a/test/deployment/deploy.ts b/test/deployment/deploy.ts index e4392f80..fb83d23a 100644 --- a/test/deployment/deploy.ts +++ b/test/deployment/deploy.ts @@ -5,137 +5,153 @@ import { ethers, upgrades } from 'hardhat'; import { expect } from 'chai'; describe('Deployment tests', () => { - let ssvNetworkContract: any, ssvNetworkViews: any, ssvToken: any; - - beforeEach(async () => { - const metadata = await initializeContract(); - ssvNetworkContract = metadata.contract; - ssvNetworkViews = metadata.ssvViews; - ssvToken = metadata.ssvToken; - }); - - it('Check default values after deploying', async () => { - expect((await ssvNetworkViews.getNetworkValidatorsCount())).to.equal(0); - expect((await ssvNetworkViews.getNetworkEarnings())).to.equal(0); - expect((await ssvNetworkViews.getOperatorFeeIncreaseLimit())).to.equal(CONFIG.operatorMaxFeeIncrease); - expect((await ssvNetworkViews.getOperatorFeePeriods())).to.deep.equal([CONFIG.declareOperatorFeePeriod, CONFIG.executeOperatorFeePeriod]); - expect((await ssvNetworkViews.getLiquidationThresholdPeriod())).to.equal(CONFIG.minimalBlocksBeforeLiquidation); - expect((await ssvNetworkViews.getMinimumLiquidationCollateral())).to.equal(CONFIG.minimumLiquidationCollateral); - expect((await ssvNetworkViews.getValidatorsPerOperatorLimit())).to.equal(CONFIG.validatorsPerOperatorLimit); - expect((await ssvNetworkViews.getOperatorFeeIncreaseLimit())).to.equal(CONFIG.operatorMaxFeeIncrease); + let ssvNetworkContract: any, ssvNetworkViews: any, ssvToken: any; + + beforeEach(async () => { + const metadata = await initializeContract(); + ssvNetworkContract = metadata.contract; + ssvNetworkViews = metadata.ssvViews; + ssvToken = metadata.ssvToken; + }); + + it('Check default values after deploying', async () => { + expect(await ssvNetworkViews.getNetworkValidatorsCount()).to.equal(0); + expect(await ssvNetworkViews.getNetworkEarnings()).to.equal(0); + expect(await ssvNetworkViews.getOperatorFeeIncreaseLimit()).to.equal(CONFIG.operatorMaxFeeIncrease); + expect(await ssvNetworkViews.getOperatorFeePeriods()).to.deep.equal([ + CONFIG.declareOperatorFeePeriod, + CONFIG.executeOperatorFeePeriod, + ]); + expect(await ssvNetworkViews.getLiquidationThresholdPeriod()).to.equal(CONFIG.minimalBlocksBeforeLiquidation); + expect(await ssvNetworkViews.getMinimumLiquidationCollateral()).to.equal(CONFIG.minimumLiquidationCollateral); + expect(await ssvNetworkViews.getValidatorsPerOperatorLimit()).to.equal(CONFIG.validatorsPerOperatorLimit); + expect(await ssvNetworkViews.getOperatorFeeIncreaseLimit()).to.equal(CONFIG.operatorMaxFeeIncrease); + }); + + it('Upgrade SSVNetwork contract. Check new function execution', async () => { + await ssvNetworkContract + .connect(DB.owners[1]) + .registerOperator(DataGenerator.publicKey(0), CONFIG.minimalOperatorFee); + + const BasicUpgrade = await ethers.getContractFactory('SSVNetworkBasicUpgrade'); + const ssvNetworkUpgrade = await upgrades.upgradeProxy(ssvNetworkContract.address, BasicUpgrade, { + kind: 'uups', + unsafeAllow: ['delegatecall'], }); + await ssvNetworkUpgrade.deployed(); - it('Upgrade SSVNetwork contract. Check new function execution', async () => { - await ssvNetworkContract.connect(DB.owners[1]).registerOperator( - DataGenerator.publicKey(0), - CONFIG.minimalOperatorFee); - - const BasicUpgrade = await ethers.getContractFactory("SSVNetworkBasicUpgrade"); - const ssvNetworkUpgrade = await upgrades.upgradeProxy(ssvNetworkContract.address, BasicUpgrade, { - kind: 'uups', - unsafeAllow: ['delegatecall'] - }); - await ssvNetworkUpgrade.deployed(); - - await ssvNetworkUpgrade.resetNetworkFee(10000000); - expect((await ssvNetworkViews.getNetworkFee())).to.equal(10000000); - }); + await ssvNetworkUpgrade.resetNetworkFee(10000000); + expect(await ssvNetworkViews.getNetworkFee()).to.equal(10000000); + }); - it('Upgrade SSVNetwork contract. Deploy implemetation manually', async () => { - const SSVNetwork = await ethers.getContractFactory("SSVNetwork"); - const BasicUpgrade = await ethers.getContractFactory("SSVNetworkBasicUpgrade"); + it('Upgrade SSVNetwork contract. Deploy implemetation manually', async () => { + const SSVNetwork = await ethers.getContractFactory('SSVNetwork'); + const BasicUpgrade = await ethers.getContractFactory('SSVNetworkBasicUpgrade'); - // Get current SSVNetwork proxy - const ssvNetwork = SSVNetwork.attach(ssvNetworkContract.address); + // Get current SSVNetwork proxy + const ssvNetwork = SSVNetwork.attach(ssvNetworkContract.address); - // Deploy a new implementation with another account - const contractImpl = await BasicUpgrade.connect(DB.owners[1]).deploy(); - await contractImpl.deployed(); + // Deploy a new implementation with another account + const contractImpl = await BasicUpgrade.connect(DB.owners[1]).deploy(); + await contractImpl.deployed(); - const newNetworkFee = ethers.utils.parseUnits("10000000", "wei"); - const calldata = contractImpl.interface.encodeFunctionData('resetNetworkFee', [newNetworkFee]); + const newNetworkFee = ethers.utils.parseUnits('10000000', 'wei'); + const calldata = contractImpl.interface.encodeFunctionData('resetNetworkFee', [newNetworkFee]); - // The owner of SSVNetwork contract peforms the upgrade - await ssvNetwork.upgradeToAndCall(contractImpl.address, calldata); + // The owner of SSVNetwork contract peforms the upgrade + await ssvNetwork.upgradeToAndCall(contractImpl.address, calldata); - expect((await ssvNetworkViews.getNetworkFee())).to.equal(10000000); + expect(await ssvNetworkViews.getNetworkFee()).to.equal(10000000); + }); + it('Upgrade SSVNetwork contract. Check base contract is not re-initialized', async () => { + const BasicUpgrade = await ethers.getContractFactory('SSVNetworkBasicUpgrade'); + const ssvNetworkUpgrade = await upgrades.upgradeProxy(ssvNetworkContract.address, BasicUpgrade, { + kind: 'uups', + unsafeAllow: ['delegatecall'], }); - - it('Upgrade SSVNetwork contract. Check base contract is not re-initialized', async () => { - const BasicUpgrade = await ethers.getContractFactory("SSVNetworkBasicUpgrade"); - const ssvNetworkUpgrade = await upgrades.upgradeProxy(ssvNetworkContract.address, BasicUpgrade, { - kind: 'uups', - unsafeAllow: ['delegatecall'] - }); - await ssvNetworkUpgrade.deployed(); - - const address = await upgrades.erc1967.getImplementationAddress(ssvNetworkUpgrade.address); - const instance = await ssvNetworkUpgrade.attach(address); - - await expect(instance.connect(DB.owners[1]).initialize( - '0x6471F70b932390f527c6403773D082A0Db8e8A9F', - '0x6471F70b932390f527c6403773D082A0Db8e8A9F', - '0x6471F70b932390f527c6403773D082A0Db8e8A9F', - '0x6471F70b932390f527c6403773D082A0Db8e8A9F', - '0x6471F70b932390f527c6403773D082A0Db8e8A9F', - 2000000, - 2000000, - 2000000, - 2000000, - 2000000, - 2000)).to.be.revertedWith('Initializable: contract is already initialized'); + await ssvNetworkUpgrade.deployed(); + + const address = await upgrades.erc1967.getImplementationAddress(ssvNetworkUpgrade.address); + const instance = await ssvNetworkUpgrade.attach(address); + + await expect( + instance + .connect(DB.owners[1]) + .initialize( + '0x6471F70b932390f527c6403773D082A0Db8e8A9F', + '0x6471F70b932390f527c6403773D082A0Db8e8A9F', + '0x6471F70b932390f527c6403773D082A0Db8e8A9F', + '0x6471F70b932390f527c6403773D082A0Db8e8A9F', + '0x6471F70b932390f527c6403773D082A0Db8e8A9F', + 2000000, + 2000000, + 2000000, + 2000000, + 2000000, + 2000, + ), + ).to.be.revertedWith('Initializable: contract is already initialized'); + }); + + it('Upgrade SSVNetwork contract. Check state is only changed from proxy contract', async () => { + const BasicUpgrade = await ethers.getContractFactory('SSVNetworkBasicUpgrade'); + const ssvNetworkUpgrade = await upgrades.upgradeProxy(ssvNetworkContract.address, BasicUpgrade, { + kind: 'uups', + unsafeAllow: ['delegatecall'], }); + await ssvNetworkUpgrade.deployed(); - it('Upgrade SSVNetwork contract. Check state is only changed from proxy contract', async () => { - const BasicUpgrade = await ethers.getContractFactory("SSVNetworkBasicUpgrade"); - const ssvNetworkUpgrade = await upgrades.upgradeProxy(ssvNetworkContract.address, BasicUpgrade, { - kind: 'uups', - unsafeAllow: ['delegatecall'] - }); - await ssvNetworkUpgrade.deployed(); + const address = await upgrades.erc1967.getImplementationAddress(ssvNetworkUpgrade.address); + const instance = await ssvNetworkUpgrade.attach(address); - const address = await upgrades.erc1967.getImplementationAddress(ssvNetworkUpgrade.address); - const instance = await ssvNetworkUpgrade.attach(address); + await trackGas(instance.connect(DB.owners[1]).resetNetworkFee(100000000000)); - await trackGas( - instance.connect(DB.owners[1]).resetNetworkFee(100000000000) - ); + expect(await ssvNetworkViews.getNetworkFee()).to.be.equals(0); + }); - expect(await ssvNetworkViews.getNetworkFee()).to.be.equals(0); - }); + it('Update a module (SSVOperators)', async () => { + const ssvNetworkFactory = await ethers.getContractFactory('SSVNetwork'); + const ssvNetwork = await ssvNetworkFactory.attach(ssvNetworkContract.address); - it('Update a module (SSVOperators)', async () => { - const ssvNetworkFactory = await ethers.getContractFactory('SSVNetwork'); - const ssvNetwork = await ssvNetworkFactory.attach(ssvNetworkContract.address); + const ssvOperatorsFactory = await ethers.getContractFactory('SSVOperatorsUpdate'); - const ssvOperatorsFactory = await ethers.getContractFactory('SSVOperatorsUpdate'); + const operatorsImpl = await ssvOperatorsFactory.connect(DB.owners[1]).deploy(); + await operatorsImpl.deployed(); - const operatorsImpl = await ssvOperatorsFactory.connect(DB.owners[1]).deploy(); - await operatorsImpl.deployed(); + await expect(ssvNetwork.updateModule(0, ethers.constants.AddressZero)).to.be.revertedWithCustomError( + ssvNetworkContract, + 'TargetModuleDoesNotExist', + ); - await ssvNetwork.updateModule(0, operatorsImpl.address); + await ssvNetwork.updateModule(0, operatorsImpl.address); - await expect(ssvNetworkContract.declareOperatorFee(0, 0)) - .to.be.revertedWithCustomError(ssvNetworkContract, 'NoFeeDeclared'); - }); + await expect(ssvNetworkContract.declareOperatorFee(0, 0)).to.be.revertedWithCustomError( + ssvNetworkContract, + 'NoFeeDeclared', + ); + }); - it('ETH can not be transferred to SSVNetwork / SSVNetwork views', async () => { - const amount = ethers.utils.parseUnits("10000000", "wei"); + it('ETH can not be transferred to SSVNetwork / SSVNetwork views', async () => { + const amount = ethers.utils.parseUnits('10000000', 'wei'); - const sender = ethers.provider.getSigner(0); + const sender = ethers.provider.getSigner(0); - await expect(sender.sendTransaction({ - to: ssvNetworkContract.address, - value: amount - })).to.be.reverted; + await expect( + sender.sendTransaction({ + to: ssvNetworkContract.address, + value: amount, + }), + ).to.be.reverted; - await expect(sender.sendTransaction({ - to: ssvNetworkViews.address, - value: amount - })).to.be.reverted; + await expect( + sender.sendTransaction({ + to: ssvNetworkViews.address, + value: amount, + }), + ).to.be.reverted; - expect(await ethers.provider.getBalance(ssvNetworkContract.address)).to.be.equal(0); - expect(await ethers.provider.getBalance(ssvNetworkViews.address)).to.be.equal(0); - }); + expect(await ethers.provider.getBalance(ssvNetworkContract.address)).to.be.equal(0); + expect(await ethers.provider.getBalance(ssvNetworkViews.address)).to.be.equal(0); + }); }); diff --git a/test/helpers/contract-helpers.ts b/test/helpers/contract-helpers.ts index 28cb8adb..bf4516a6 100644 --- a/test/helpers/contract-helpers.ts +++ b/test/helpers/contract-helpers.ts @@ -14,7 +14,7 @@ export const DEFAULT_OPERATOR_IDS = { 4: [1, 2, 3, 4], 7: [1, 2, 3, 4, 5, 6, 7], 10: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], - 13: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13] + 13: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], }; const getSecretSharedPayload = async (validator: Validator, operatorIds: number[], ownerId: number) => { @@ -134,7 +134,7 @@ export const initializeContract = async () => { ssvClustersMod: {}, ssvDAOMod: {}, ssvViewsMod: {}, - ownerNonce: 0 + ownerNonce: 0, }; SSV_MODULES = { @@ -158,7 +158,7 @@ export const initializeContract = async () => { const ssvViews = await ethers.getContractFactory('SSVNetworkViews'); const ssvViewsMod = await ethers.getContractFactory('contracts/modules/SSVViews.sol:SSVViews'); - const ssvToken = await ethers.getContractFactory('SSVTokenMock'); + const ssvToken = await ethers.getContractFactory('SSVToken'); const ssvOperatorsMod = await ethers.getContractFactory('SSVOperators'); const ssvClustersMod = await ethers.getContractFactory('SSVClusters'); const ssvDAOMod = await ethers.getContractFactory('SSVDAO'); @@ -317,25 +317,26 @@ export const bulkRegisterValidators = async ( operatorIds: number[], minDepositAmount: any, cluster: any, - gasGroups?: GasGroup[] + gasGroups?: GasGroup[], ) => { const pks = Array.from({ length: numberOfValidators }, (_, index) => DataGenerator.publicKey(index + 1)); - const shares = Array.from({ length: numberOfValidators }, (_, index) => DataGenerator.shares(1, index, operatorIds.length)); + const shares = Array.from({ length: numberOfValidators }, (_, index) => + DataGenerator.shares(1, index, operatorIds.length), + ); const depositAmount = minDepositAmount * numberOfValidators; await DB.ssvToken.connect(DB.owners[ownerId]).approve(DB.ssvNetwork.contract.address, depositAmount); - const result = await trackGas(DB.ssvNetwork.contract.connect(DB.owners[ownerId]).bulkRegisterValidator( - pks, - operatorIds, - shares, - depositAmount, - cluster - ), gasGroups); + const result = await trackGas( + DB.ssvNetwork.contract + .connect(DB.owners[ownerId]) + .bulkRegisterValidator(pks, operatorIds, shares, depositAmount, cluster), + gasGroups, + ); return { args: result.eventsByName.ValidatorAdded[0].args, - pks + pks, }; }; From a58162e83a3713ecb5db7293719283ab67ecdc96 Mon Sep 17 00:00:00 2001 From: Marco Tabasco Date: Wed, 7 Feb 2024 11:22:45 +0100 Subject: [PATCH 33/38] fix: bulkRemoveValidators reduce validator counter --- contracts/SSVNetwork.sol | 4 +- contracts/interfaces/ISSVNetworkCore.sol | 6 +- contracts/libraries/ValidatorLib.sol | 49 ++----------- contracts/modules/SSVClusters.sol | 87 +++++++++++++++++------- test/helpers/gas-usage.ts | 4 +- test/validators/remove.ts | 21 ++++++ 6 files changed, 96 insertions(+), 75 deletions(-) diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index 58d82556..d570c199 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -167,7 +167,7 @@ contract SSVNetwork is function registerValidator( bytes calldata publicKey, - uint64[] memory operatorIds, + uint64[] calldata operatorIds, bytes calldata sharesData, uint256 amount, ISSVNetworkCore.Cluster memory cluster @@ -177,7 +177,7 @@ contract SSVNetwork is function bulkRegisterValidator( bytes[] calldata publicKeys, - uint64[] memory operatorIds, + uint64[] calldata operatorIds, bytes[] calldata sharesData, uint256 amount, ISSVNetworkCore.Cluster memory cluster diff --git a/contracts/interfaces/ISSVNetworkCore.sol b/contracts/interfaces/ISSVNetworkCore.sol index c577e402..785b77e9 100644 --- a/contracts/interfaces/ISSVNetworkCore.sol +++ b/contracts/interfaces/ISSVNetworkCore.sol @@ -41,7 +41,7 @@ interface ISSVNetworkCore { } /// @notice Represents a cluster of validators - struct Cluster { + struct Cluster { /// @dev The number of validators in the cluster uint32 validatorCount; /// @dev The index of network fees related to this cluster @@ -66,9 +66,7 @@ interface ISSVNetworkCore { error ApprovalNotWithinTimeframe(); // 0x97e4b518 error OperatorDoesNotExist(); // 0x961e3e8c error InsufficientBalance(); // 0xf4d678b8 - error ValidatorAlreadyExists(); // 0x8d09a73e error ValidatorDoesNotExist(); // 0xe51315d2 - error IncorrectValidatorState(); // 0x2feda3c1 error ClusterNotLiquidatable(); // 0x60300a8d error InvalidPublicKeyLength(); // 0x637297a4 error InvalidOperatorIdsLength(); // 0x38186224 @@ -89,4 +87,6 @@ interface ISSVNetworkCore { error MaxValueExceeded(); // 0x91aa3017 error FeeTooHigh(); // 0xcd4e6167 error PublicKeysSharesLengthMismatch(); // 0x9ad467b8 + error IncorrectValidatorStateWithData(bytes publicKey); // 0x89307938 + error ValidatorAlreadyExistsWithData(bytes publicKey); // 0x388e7999 } diff --git a/contracts/libraries/ValidatorLib.sol b/contracts/libraries/ValidatorLib.sol index ff85ee90..5539719c 100644 --- a/contracts/libraries/ValidatorLib.sol +++ b/contracts/libraries/ValidatorLib.sol @@ -22,17 +22,7 @@ library ValidatorLib { } } - function registerPublicKeys( - bytes[] calldata publicKeys, - uint64[] memory operatorIds, - StorageData storage s - ) internal { - for (uint i; i < publicKeys.length; ++i) { - resgisterPublicKey(publicKeys[i], operatorIds, s); - } - } - - function resgisterPublicKey(bytes memory publicKey, uint64[] memory operatorIds, StorageData storage s) internal { + function registerPublicKey(bytes memory publicKey, uint64[] memory operatorIds, StorageData storage s) internal { if (publicKey.length != PUBLIC_KEY_LENGTH) { revert ISSVNetworkCore.InvalidPublicKeyLength(); } @@ -40,49 +30,20 @@ library ValidatorLib { bytes32 hashedPk = keccak256(abi.encodePacked(publicKey, msg.sender)); if (s.validatorPKs[hashedPk] != bytes32(0)) { - revert ISSVNetworkCore.ValidatorAlreadyExists(); + revert ISSVNetworkCore.ValidatorAlreadyExistsWithData(publicKey); } s.validatorPKs[hashedPk] = bytes32(uint256(keccak256(abi.encodePacked(operatorIds))) | uint256(0x01)); // set LSB to 1 } - function hashOperatorIds(uint64[] calldata operatorIds) internal pure returns (bytes32) { + function hashOperatorIds(uint64[] memory operatorIds) internal pure returns (bytes32) { bytes32 mask = ~bytes32(uint256(1)); // All bits set to 1 except LSB return keccak256(abi.encodePacked(operatorIds)) & mask; // Clear LSB of provided operator ids } - function validateStates( - bytes[] calldata publicKeys, - uint64[] calldata operatorIds, - StorageData storage s - ) internal view returns (bytes32[] memory hashedValidator) { - if (publicKeys.length == 0) { - revert ISSVNetworkCore.ValidatorDoesNotExist(); - } - hashedValidator = new bytes32[](publicKeys.length); - bytes32 hashedOperatorIds = hashOperatorIds(operatorIds); - - for (uint i; i < publicKeys.length; ++i) { - hashedValidator[i] = validateState(publicKeys[i], hashedOperatorIds, s); - } - } - - function validateState( - bytes calldata publicKey, - bytes32 hashedOperatorIds, - StorageData storage s - ) internal view returns (bytes32 hashedValidator) { - hashedValidator = keccak256(abi.encodePacked(publicKey, msg.sender)); - bytes32 validatorData = s.validatorPKs[hashedValidator]; - - if (validatorData == bytes32(0)) { - revert ISSVNetworkCore.ValidatorDoesNotExist(); - } - - if ((validatorData & ~bytes32(uint256(1))) != hashedOperatorIds) { + function validateCorrectState(bytes32 validatorData, bytes32 hashedOperatorIds) internal pure returns (bool) { // All bits set to 1 except LSB // Clear LSB of stored validator data and compare - revert ISSVNetworkCore.IncorrectValidatorState(); - } + return (validatorData & ~bytes32(uint256(1))) == hashedOperatorIds; } } diff --git a/contracts/modules/SSVClusters.sol b/contracts/modules/SSVClusters.sol index 49e0b097..1599c4a0 100644 --- a/contracts/modules/SSVClusters.sol +++ b/contracts/modules/SSVClusters.sol @@ -16,7 +16,7 @@ contract SSVClusters is ISSVClusters { using ProtocolLib for StorageProtocol; function registerValidator( - bytes calldata publicKey, + bytes memory publicKey, uint64[] memory operatorIds, bytes calldata sharesData, uint256 amount, @@ -27,7 +27,7 @@ contract SSVClusters is ISSVClusters { ValidatorLib.validateOperatorsLength(operatorIds); - ValidatorLib.resgisterPublicKey(publicKey, operatorIds, s); + ValidatorLib.registerPublicKey(publicKey, operatorIds, s); bytes32 hashedCluster = cluster.validateClusterOnRegistration(operatorIds, s); @@ -43,7 +43,7 @@ contract SSVClusters is ISSVClusters { } function bulkRegisterValidator( - bytes[] calldata publicKeys, + bytes[] memory publicKeys, uint64[] memory operatorIds, bytes[] calldata sharesData, uint256 amount, @@ -54,17 +54,18 @@ contract SSVClusters is ISSVClusters { StorageData storage s = SSVStorage.load(); StorageProtocol storage sp = SSVStorageProtocol.load(); - uint32 validatorsLength = uint32(publicKeys.length); + uint256 validatorsLength = publicKeys.length; ValidatorLib.validateOperatorsLength(operatorIds); - ValidatorLib.registerPublicKeys(publicKeys, operatorIds, s); - + for (uint i; i < validatorsLength; ++i) { + ValidatorLib.registerPublicKey(publicKeys[i], operatorIds, s); +} bytes32 hashedCluster = cluster.validateClusterOnRegistration(operatorIds, s); cluster.balance += amount; - cluster.updateClusterOnRegistration(operatorIds, hashedCluster, validatorsLength, s, sp); + cluster.updateClusterOnRegistration(operatorIds, hashedCluster, uint32(validatorsLength), s, sp); if (amount != 0) { CoreLib.deposit(amount); @@ -87,7 +88,18 @@ contract SSVClusters is ISSVClusters { bytes32 hashedCluster = cluster.validateHashedCluster(msg.sender, operatorIds, s); bytes32 hashedOperatorIds = ValidatorLib.hashOperatorIds(operatorIds); - bytes32 hashedValidator = ValidatorLib.validateState(publicKey, hashedOperatorIds, s); + + bytes32 hashedValidator = keccak256(abi.encodePacked(publicKey, msg.sender)); + bytes32 validatorData = s.validatorPKs[hashedValidator]; + + if (validatorData == bytes32(0)) { + revert ISSVNetworkCore.ValidatorDoesNotExist(); + } + + if (!ValidatorLib.validateCorrectState(validatorData, hashedOperatorIds)) + revert ISSVNetworkCore.IncorrectValidatorStateWithData(publicKey); + + delete s.validatorPKs[hashedValidator]; if (cluster.active) { StorageProtocol storage sp = SSVStorageProtocol.load(); @@ -100,24 +112,41 @@ contract SSVClusters is ISSVClusters { --cluster.validatorCount; - delete s.validatorPKs[hashedValidator]; - s.clusters[hashedCluster] = cluster.hashClusterData(); emit ValidatorRemoved(msg.sender, operatorIds, publicKey, cluster); } function bulkRemoveValidator( - bytes[] calldata publicKeys, - uint64[] calldata operatorIds, + bytes[] memory publicKeys, + uint64[] memory operatorIds, Cluster memory cluster ) external override { +uint256 validatorsLength = publicKeys.length; + + if (validatorsLength == 0) { + revert ISSVNetworkCore.ValidatorDoesNotExist(); + } StorageData storage s = SSVStorage.load(); bytes32 hashedCluster = cluster.validateHashedCluster(msg.sender, operatorIds, s); - bytes32[] memory hashedValidators = ValidatorLib.validateStates(publicKeys, operatorIds, s); + bytes32 hashedOperatorIds = ValidatorLib.hashOperatorIds(operatorIds); - uint32 validatorsLength = uint32(publicKeys.length); + bytes32 hashedValidator; + bytes32 validatorData; + + uint32 validatorsRemoved; + + for (uint i; i < validatorsLength; ++i) { + hashedValidator = keccak256(abi.encodePacked(publicKeys[i], msg.sender)); + validatorData = s.validatorPKs[hashedValidator]; + + if (!ValidatorLib.validateCorrectState(validatorData, hashedOperatorIds)) + revert ISSVNetworkCore.IncorrectValidatorStateWithData(publicKeys[i]); + + delete s.validatorPKs[hashedValidator]; + validatorsRemoved++; + } if (cluster.active) { StorageProtocol storage sp = SSVStorageProtocol.load(); @@ -125,21 +154,17 @@ contract SSVClusters is ISSVClusters { operatorIds, false, false, - validatorsLength, + validatorsRemoved, s, sp ); cluster.updateClusterData(clusterIndex, sp.currentNetworkFeeIndex()); - sp.updateDAO(false, validatorsLength); + sp.updateDAO(false, validatorsRemoved); } - cluster.validatorCount -= validatorsLength; - - for (uint i; i < validatorsLength; ++i) { - delete s.validatorPKs[hashedValidators[i]]; - } + cluster.validatorCount -= validatorsRemoved; s.clusters[hashedCluster] = cluster.hashClusterData(); @@ -316,16 +341,30 @@ contract SSVClusters is ISSVClusters { } function exitValidator(bytes calldata publicKey, uint64[] calldata operatorIds) external override { - bytes32 hashedOperatorIds = ValidatorLib.hashOperatorIds(operatorIds); - ValidatorLib.validateState(publicKey, hashedOperatorIds, SSVStorage.load()); + if ( + !ValidatorLib.validateCorrectState( + SSVStorage.load().validatorPKs[keccak256(abi.encodePacked(publicKey, msg.sender))], + ValidatorLib.hashOperatorIds(operatorIds) + ) + ) revert ISSVNetworkCore.IncorrectValidatorStateWithData(publicKey); emit ValidatorExited(msg.sender, operatorIds, publicKey); } function bulkExitValidator(bytes[] calldata publicKeys, uint64[] calldata operatorIds) external override { - ValidatorLib.validateStates(publicKeys, operatorIds, SSVStorage.load()); + if (publicKeys.length == 0) { + revert ISSVNetworkCore.ValidatorDoesNotExist(); + } + bytes32 hashedOperatorIds = ValidatorLib.hashOperatorIds(operatorIds); for (uint i; i < publicKeys.length; ++i) { +if ( + !ValidatorLib.validateCorrectState( + SSVStorage.load().validatorPKs[keccak256(abi.encodePacked(publicKeys[i], msg.sender))], + hashedOperatorIds + ) + ) revert ISSVNetworkCore.IncorrectValidatorStateWithData(publicKeys[i]); + emit ValidatorExited(msg.sender, operatorIds, publicKeys[i]); } } diff --git a/test/helpers/gas-usage.ts b/test/helpers/gas-usage.ts index 367c6a8a..da2c7ffa 100644 --- a/test/helpers/gas-usage.ts +++ b/test/helpers/gas-usage.ts @@ -111,7 +111,7 @@ const MAX_GAS_PER_GROUP: any = { [GasGroup.REGISTER_VALIDATOR_WITHOUT_DEPOSIT_13]: 393300, [GasGroup.BULK_REGISTER_10_VALIDATOR_NEW_STATE_13]: 1650200, - [GasGroup.BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_13]: 1633500, + [GasGroup.BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_13]: 1629000, [GasGroup.REMOVE_VALIDATOR]: 115000, [GasGroup.BULK_REMOVE_10_VALIDATOR_4]: 196000, @@ -123,7 +123,7 @@ const MAX_GAS_PER_GROUP: any = { [GasGroup.BULK_REMOVE_10_VALIDATOR_10]: 301000, [GasGroup.REMOVE_VALIDATOR_13]: 239000, - [GasGroup.BULK_REMOVE_10_VALIDATOR_13]: 353200, + [GasGroup.BULK_REMOVE_10_VALIDATOR_13]: 348500, [GasGroup.DEPOSIT]: 77500, [GasGroup.WITHDRAW_CLUSTER_BALANCE]: 94500, diff --git a/test/validators/remove.ts b/test/validators/remove.ts index e6b6da94..b0d39269 100644 --- a/test/validators/remove.ts +++ b/test/validators/remove.ts @@ -414,4 +414,25 @@ describe('Remove Validator Tests', () => { expect(removed.cluster.active).to.equal(false); expect(removed.cluster.balance.toNumber()).to.equal(0); }); + + it('Bulk remove 10 validator, non unique keys', async () => { + minDepositAmount = (helpers.CONFIG.minimalBlocksBeforeLiquidation + 10) * helpers.CONFIG.minimalOperatorFee * 13; + + const { args, pks } = await helpers.bulkRegisterValidators( + 2, + 10, + helpers.DEFAULT_OPERATOR_IDS[4], + minDepositAmount, + helpers.getClusterForValidator(0, 0, 0, 0, true), + ); + + const keys = [pks[0], pks[1], pks[2], pks[3], pks[2], pks[5], pks[2], pks[7], pks[2], pks[8]]; + + + await expect(ssvNetworkContract + .connect(helpers.DB.owners[2]) + .bulkRemoveValidator(keys, args.operatorIds, args.cluster) + ).to.be.revertedWithCustomError(ssvNetworkContract, 'IncorrectValidatorStateWithData') + .withArgs(pks[2]); + }); }); From 9508cf398405c192989bd3e245944e28afec70b9 Mon Sep 17 00:00:00 2001 From: Marco Tabasco Date: Thu, 8 Feb 2024 01:25:28 +0100 Subject: [PATCH 34/38] fix: bulkRemoveValidator all tests passed --- contracts/interfaces/ISSVNetworkCore.sol | 4 ++ contracts/libraries/ClusterLib.sol | 6 +-- contracts/modules/SSVClusters.sol | 14 +++--- test/helpers/gas-usage.ts | 38 +++++++-------- test/validators/exit.ts | 62 ++++++++++++++---------- test/validators/register.ts | 10 ++-- test/validators/remove.ts | 19 ++++++-- 7 files changed, 89 insertions(+), 64 deletions(-) diff --git a/contracts/interfaces/ISSVNetworkCore.sol b/contracts/interfaces/ISSVNetworkCore.sol index 785b77e9..70990e72 100644 --- a/contracts/interfaces/ISSVNetworkCore.sol +++ b/contracts/interfaces/ISSVNetworkCore.sol @@ -89,4 +89,8 @@ interface ISSVNetworkCore { error PublicKeysSharesLengthMismatch(); // 0x9ad467b8 error IncorrectValidatorStateWithData(bytes publicKey); // 0x89307938 error ValidatorAlreadyExistsWithData(bytes publicKey); // 0x388e7999 + + // legacy errors + error ValidatorAlreadyExists(); // 0x8d09a73e + error IncorrectValidatorState(); // 0x2feda3c1 } diff --git a/contracts/libraries/ClusterLib.sol b/contracts/libraries/ClusterLib.sol index 81648a53..7fe492f6 100644 --- a/contracts/libraries/ClusterLib.sol +++ b/contracts/libraries/ClusterLib.sol @@ -48,8 +48,8 @@ library ClusterLib { address owner, uint64[] memory operatorIds, StorageData storage s - ) internal view returns (bytes32) { - bytes32 hashedCluster = keccak256(abi.encodePacked(owner, operatorIds)); + ) internal view returns (bytes32 hashedCluster) { + hashedCluster = keccak256(abi.encodePacked(owner, operatorIds)); bytes32 hashedClusterData = hashClusterData(cluster); bytes32 clusterData = s.clusters[hashedCluster]; @@ -58,8 +58,6 @@ library ClusterLib { } else if (clusterData != hashedClusterData) { revert ISSVNetworkCore.IncorrectClusterState(); } - - return hashedCluster; } function updateClusterData( diff --git a/contracts/modules/SSVClusters.sol b/contracts/modules/SSVClusters.sol index 1599c4a0..f4b6fd4f 100644 --- a/contracts/modules/SSVClusters.sol +++ b/contracts/modules/SSVClusters.sol @@ -16,7 +16,7 @@ contract SSVClusters is ISSVClusters { using ProtocolLib for StorageProtocol; function registerValidator( - bytes memory publicKey, + bytes calldata publicKey, uint64[] memory operatorIds, bytes calldata sharesData, uint256 amount, @@ -60,7 +60,7 @@ contract SSVClusters is ISSVClusters { for (uint i; i < validatorsLength; ++i) { ValidatorLib.registerPublicKey(publicKeys[i], operatorIds, s); -} + } bytes32 hashedCluster = cluster.validateClusterOnRegistration(operatorIds, s); cluster.balance += amount; @@ -81,14 +81,14 @@ contract SSVClusters is ISSVClusters { function removeValidator( bytes calldata publicKey, - uint64[] calldata operatorIds, + uint64[] memory operatorIds, Cluster memory cluster ) external override { StorageData storage s = SSVStorage.load(); bytes32 hashedCluster = cluster.validateHashedCluster(msg.sender, operatorIds, s); bytes32 hashedOperatorIds = ValidatorLib.hashOperatorIds(operatorIds); - + bytes32 hashedValidator = keccak256(abi.encodePacked(publicKey, msg.sender)); bytes32 validatorData = s.validatorPKs[hashedValidator]; @@ -118,11 +118,11 @@ contract SSVClusters is ISSVClusters { } function bulkRemoveValidator( - bytes[] memory publicKeys, + bytes[] calldata publicKeys, uint64[] memory operatorIds, Cluster memory cluster ) external override { -uint256 validatorsLength = publicKeys.length; + uint256 validatorsLength = publicKeys.length; if (validatorsLength == 0) { revert ISSVNetworkCore.ValidatorDoesNotExist(); @@ -358,7 +358,7 @@ uint256 validatorsLength = publicKeys.length; bytes32 hashedOperatorIds = ValidatorLib.hashOperatorIds(operatorIds); for (uint i; i < publicKeys.length; ++i) { -if ( + if ( !ValidatorLib.validateCorrectState( SSVStorage.load().validatorPKs[keccak256(abi.encodePacked(publicKeys[i], msg.sender))], hashedOperatorIds diff --git a/test/helpers/gas-usage.ts b/test/helpers/gas-usage.ts index da2c7ffa..68d22b0f 100644 --- a/test/helpers/gas-usage.ts +++ b/test/helpers/gas-usage.ts @@ -76,8 +76,8 @@ export enum GasGroup { const MAX_GAS_PER_GROUP: any = { /* REAL GAS LIMITS */ [GasGroup.REGISTER_OPERATOR]: 134500, - [GasGroup.REMOVE_OPERATOR]: 70200, - [GasGroup.REMOVE_OPERATOR_WITH_WITHDRAW]: 70200, + [GasGroup.REMOVE_OPERATOR]: 70500, + [GasGroup.REMOVE_OPERATOR_WITH_WITHDRAW]: 70300, [GasGroup.SET_OPERATOR_WHITELIST]: 84300, [GasGroup.DECLARE_OPERATOR_FEE]: 70000, @@ -85,8 +85,8 @@ const MAX_GAS_PER_GROUP: any = { [GasGroup.EXECUTE_OPERATOR_FEE]: 52000, [GasGroup.REDUCE_OPERATOR_FEE]: 51900, - [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]: 201200, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE]: 235000, + [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]: 202000, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE]: 235500, [GasGroup.REGISTER_VALIDATOR_WITHOUT_DEPOSIT]: 180600, [GasGroup.BULK_REGISTER_10_VALIDATOR_NEW_STATE_4]: 889900, @@ -111,22 +111,22 @@ const MAX_GAS_PER_GROUP: any = { [GasGroup.REGISTER_VALIDATOR_WITHOUT_DEPOSIT_13]: 393300, [GasGroup.BULK_REGISTER_10_VALIDATOR_NEW_STATE_13]: 1650200, - [GasGroup.BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_13]: 1629000, + [GasGroup.BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_13]: 1630200, - [GasGroup.REMOVE_VALIDATOR]: 115000, - [GasGroup.BULK_REMOVE_10_VALIDATOR_4]: 196000, + [GasGroup.REMOVE_VALIDATOR]: 114000, + [GasGroup.BULK_REMOVE_10_VALIDATOR_4]: 191500, - [GasGroup.REMOVE_VALIDATOR_7]: 156000, - [GasGroup.BULK_REMOVE_10_VALIDATOR_7]: 248500, + [GasGroup.REMOVE_VALIDATOR_7]: 155500, + [GasGroup.BULK_REMOVE_10_VALIDATOR_7]: 241700, - [GasGroup.REMOVE_VALIDATOR_10]: 197500, - [GasGroup.BULK_REMOVE_10_VALIDATOR_10]: 301000, + [GasGroup.REMOVE_VALIDATOR_10]: 197000, + [GasGroup.BULK_REMOVE_10_VALIDATOR_10]: 292500, - [GasGroup.REMOVE_VALIDATOR_13]: 239000, - [GasGroup.BULK_REMOVE_10_VALIDATOR_13]: 348500, + [GasGroup.REMOVE_VALIDATOR_13]: 238500, + [GasGroup.BULK_REMOVE_10_VALIDATOR_13]: 343000, [GasGroup.DEPOSIT]: 77500, - [GasGroup.WITHDRAW_CLUSTER_BALANCE]: 94500, + [GasGroup.WITHDRAW_CLUSTER_BALANCE]: 95000, [GasGroup.WITHDRAW_OPERATOR_BALANCE]: 64900, [GasGroup.VALIDATOR_EXIT]: 43000, [GasGroup.BULK_EXIT_10_VALIDATOR_4]: 126200, @@ -134,14 +134,14 @@ const MAX_GAS_PER_GROUP: any = { [GasGroup.BULK_EXIT_10_VALIDATOR_10]: 152500, [GasGroup.BULK_EXIT_10_VALIDATOR_13]: 165500, - [GasGroup.LIQUIDATE_CLUSTER_4]: 129300, - [GasGroup.LIQUIDATE_CLUSTER_7]: 170500, - [GasGroup.LIQUIDATE_CLUSTER_10]: 211600, + [GasGroup.LIQUIDATE_CLUSTER_4]: 130500, + [GasGroup.LIQUIDATE_CLUSTER_7]: 171000, + [GasGroup.LIQUIDATE_CLUSTER_10]: 212000, [GasGroup.LIQUIDATE_CLUSTER_13]: 252800, - [GasGroup.REACTIVATE_CLUSTER]: 120600, + [GasGroup.REACTIVATE_CLUSTER]: 121500, [GasGroup.NETWORK_FEE_CHANGE]: 45800, - [GasGroup.WITHDRAW_NETWORK_EARNINGS]: 62200, + [GasGroup.WITHDRAW_NETWORK_EARNINGS]: 62500, [GasGroup.DAO_UPDATE_OPERATOR_FEE_INCREASE_LIMIT]: 38200, [GasGroup.DAO_UPDATE_DECLARE_OPERATOR_FEE_PERIOD]: 40900, [GasGroup.DAO_UPDATE_EXECUTE_OPERATOR_FEE_PERIOD]: 41000, diff --git a/test/validators/exit.ts b/test/validators/exit.ts index 31470980..03b41d95 100644 --- a/test/validators/exit.ts +++ b/test/validators/exit.ts @@ -86,7 +86,7 @@ describe('Exit Validator Tests', () => { .withArgs(helpers.DB.owners[1].address, firstCluster.operatorIds, helpers.DataGenerator.publicKey(2)); }); - it('Exiting a removed validator reverts "ValidatorDoesNotExist"', async () => { + it('Exiting a removed validator reverts "IncorrectValidatorStateWithData"', async () => { await ssvNetworkContract .connect(helpers.DB.owners[1]) .removeValidator(helpers.DataGenerator.publicKey(1), firstCluster.operatorIds, firstCluster.cluster); @@ -95,41 +95,47 @@ describe('Exit Validator Tests', () => { ssvNetworkContract .connect(helpers.DB.owners[1]) .exitValidator(helpers.DataGenerator.publicKey(1), firstCluster.operatorIds), - ).to.be.revertedWithCustomError(ssvNetworkContract, 'ValidatorDoesNotExist'); + ).to.be.revertedWithCustomError(ssvNetworkContract, 'IncorrectValidatorStateWithData') + .withArgs(helpers.DataGenerator.publicKey(1)); }); - it('Exiting a non-existing validator reverts "ValidatorDoesNotExist"', async () => { + it('Exiting a non-existing validator reverts "IncorrectValidatorStateWithData"', async () => { await expect( ssvNetworkContract .connect(helpers.DB.owners[1]) .exitValidator(helpers.DataGenerator.publicKey(12), firstCluster.operatorIds), - ).to.be.revertedWithCustomError(ssvNetworkContract, 'ValidatorDoesNotExist'); + ).to.be.revertedWithCustomError(ssvNetworkContract, 'IncorrectValidatorStateWithData') + .withArgs(helpers.DataGenerator.publicKey(12)); }); - it('Exiting a validator with empty operator list reverts "IncorrectValidatorState"', async () => { + it('Exiting a validator with empty operator list reverts "IncorrectValidatorStateWithData"', async () => { await expect( ssvNetworkContract.connect(helpers.DB.owners[1]).exitValidator(helpers.DataGenerator.publicKey(1), []), - ).to.be.revertedWithCustomError(ssvNetworkContract, 'IncorrectValidatorState'); + ).to.be.revertedWithCustomError(ssvNetworkContract, 'IncorrectValidatorStateWithData') + .withArgs(helpers.DataGenerator.publicKey(1)); }); - it('Exiting a validator with empty public key reverts "ValidatorDoesNotExist"', async () => { + it('Exiting a validator with empty public key reverts "IncorrectValidatorStateWithData"', async () => { await expect( ssvNetworkContract.connect(helpers.DB.owners[1]).exitValidator('0x', firstCluster.operatorIds), - ).to.be.revertedWithCustomError(ssvNetworkContract, 'ValidatorDoesNotExist'); + ).to.be.revertedWithCustomError(ssvNetworkContract, 'IncorrectValidatorStateWithData') + .withArgs('0x'); }); - it('Exiting a validator using the wrong account reverts "ValidatorDoesNotExist"', async () => { + it('Exiting a validator using the wrong account reverts "IncorrectValidatorStateWithData"', async () => { await expect( ssvNetworkContract .connect(helpers.DB.owners[2]) .exitValidator(helpers.DataGenerator.publicKey(1), firstCluster.operatorIds), - ).to.be.revertedWithCustomError(ssvNetworkContract, 'ValidatorDoesNotExist'); + ).to.be.revertedWithCustomError(ssvNetworkContract, 'IncorrectValidatorStateWithData') + .withArgs(helpers.DataGenerator.publicKey(1)); }); - it('Exiting a validator with incorrect operators (unsorted list) reverts with "IncorrectValidatorState"', async () => { + it('Exiting a validator with incorrect operators (unsorted list) reverts with "IncorrectValidatorStateWithData"', async () => { await expect( ssvNetworkContract.connect(helpers.DB.owners[1]).exitValidator(helpers.DataGenerator.publicKey(1), [4, 3, 2, 1]), - ).to.be.revertedWithCustomError(ssvNetworkContract, 'IncorrectValidatorState'); + ).to.be.revertedWithCustomError(ssvNetworkContract, 'IncorrectValidatorStateWithData') + .withArgs(helpers.DataGenerator.publicKey(1)); }); it('Exiting a validator with incorrect operators (too many operators) reverts with "IncorrectValidatorState"', async () => { @@ -164,10 +170,11 @@ describe('Exit Validator Tests', () => { .withArgs(helpers.DB.owners[2].address, secondCluster.operatorIds, helpers.DataGenerator.publicKey(2)); }); - it('Exiting a validator with incorrect operators reverts with "IncorrectValidatorState"', async () => { + it('Exiting a validator with incorrect operators reverts with "IncorrectValidatorStateWithData"', async () => { await expect( ssvNetworkContract.connect(helpers.DB.owners[1]).exitValidator(helpers.DataGenerator.publicKey(1), [1, 2, 3, 5]), - ).to.be.revertedWithCustomError(ssvNetworkContract, 'IncorrectValidatorState'); + ).to.be.revertedWithCustomError(ssvNetworkContract, 'IncorrectValidatorStateWithData') + .withArgs(helpers.DataGenerator.publicKey(1)); }); it('Bulk exiting a validator emits "ValidatorExited"', async () => { @@ -261,7 +268,7 @@ describe('Exit Validator Tests', () => { ); }); - it('Bulk exiting removed validators reverts "ValidatorDoesNotExist"', async () => { + it('Bulk exiting removed validators reverts "IncorrectValidatorStateWithData"', async () => { const { args, pks } = await helpers.bulkRegisterValidators( 2, 10, @@ -279,10 +286,11 @@ describe('Exit Validator Tests', () => { ssvNetworkContract .connect(helpers.DB.owners[2]) .bulkExitValidator(pks.slice(0, 5), args.operatorIds), - ).to.be.revertedWithCustomError(ssvNetworkContract, 'ValidatorDoesNotExist'); + ).to.be.revertedWithCustomError(ssvNetworkContract, 'IncorrectValidatorStateWithData') + .withArgs(pks[0]); }); - it('Bulk exiting non-existing validators reverts "ValidatorDoesNotExist"', async () => { + it('Bulk exiting non-existing validators reverts "IncorrectValidatorStateWithData"', async () => { const { args, pks } = await helpers.bulkRegisterValidators( 2, 10, @@ -297,10 +305,11 @@ describe('Exit Validator Tests', () => { ssvNetworkContract .connect(helpers.DB.owners[2]) .bulkExitValidator(pks, args.operatorIds), - ).to.be.revertedWithCustomError(ssvNetworkContract, 'ValidatorDoesNotExist'); + ).to.be.revertedWithCustomError(ssvNetworkContract, 'IncorrectValidatorStateWithData') + .withArgs(pks[4]); }); - it('Bulk exiting validators with empty operator list reverts "IncorrectValidatorState"', async () => { + it('Bulk exiting validators with empty operator list reverts "IncorrectValidatorStateWithData"', async () => { const { args, pks } = await helpers.bulkRegisterValidators( 2, 10, @@ -311,10 +320,11 @@ describe('Exit Validator Tests', () => { await expect( ssvNetworkContract.connect(helpers.DB.owners[2]).bulkExitValidator(pks, []), - ).to.be.revertedWithCustomError(ssvNetworkContract, 'IncorrectValidatorState'); + ).to.be.revertedWithCustomError(ssvNetworkContract, 'IncorrectValidatorStateWithData') + .withArgs(pks[0]); }); - it('Bulk exiting validators with empty public key reverts "ValidatorDoesNotExist', async () => { + it('Bulk exiting validators with empty public key reverts "ValidatorDoesNotExist"', async () => { const { args } = await helpers.bulkRegisterValidators( 2, 10, @@ -328,7 +338,7 @@ describe('Exit Validator Tests', () => { ).to.be.revertedWithCustomError(ssvNetworkContract, 'ValidatorDoesNotExist'); }); - it('Bulk exiting validators using the wrong account reverts "ValidatorDoesNotExist"', async () => { + it('Bulk exiting validators using the wrong account reverts "IncorrectValidatorStateWithData"', async () => { const { args, pks } = await helpers.bulkRegisterValidators( 2, 10, @@ -341,10 +351,11 @@ describe('Exit Validator Tests', () => { ssvNetworkContract .connect(helpers.DB.owners[3]) .bulkExitValidator(pks, args.operatorIds), - ).to.be.revertedWithCustomError(ssvNetworkContract, 'ValidatorDoesNotExist'); + ).to.be.revertedWithCustomError(ssvNetworkContract, 'IncorrectValidatorStateWithData') + .withArgs(pks[0]); }); - it('Bulk exiting validators with incorrect operators (unsorted list) reverts with "IncorrectValidatorState"', async () => { + it('Bulk exiting validators with incorrect operators (unsorted list) reverts with "IncorrectValidatorStateWithData"', async () => { const { args, pks } = await helpers.bulkRegisterValidators( 2, 10, @@ -355,6 +366,7 @@ describe('Exit Validator Tests', () => { await expect( ssvNetworkContract.connect(helpers.DB.owners[1]).bulkExitValidator(pks, [4, 3, 2, 1]), - ).to.be.revertedWithCustomError(ssvNetworkContract, 'IncorrectValidatorState'); + ).to.be.revertedWithCustomError(ssvNetworkContract, 'IncorrectValidatorStateWithData') + .withArgs(pks[0]); }); }); diff --git a/test/validators/register.ts b/test/validators/register.ts index f56b1bb8..1f8e95dd 100644 --- a/test/validators/register.ts +++ b/test/validators/register.ts @@ -998,7 +998,7 @@ describe('Register Validator Tests', () => { ).to.be.revertedWithCustomError(ssvNetworkContract, 'InsufficientBalance'); }); - it('Register an existing validator with same operators setup reverts "ValidatorAlreadyExists"', async () => { + it('Register an existing validator with same operators setup reverts "ValidatorAlreadyExistsWithData"', async () => { await helpers.DB.ssvToken .connect(helpers.DB.owners[6]) .approve(ssvNetworkContract.address, helpers.CONFIG.minimalOperatorFee); @@ -1012,10 +1012,11 @@ describe('Register Validator Tests', () => { minDepositAmount, helpers.getClusterForValidator(0, 0, 0, 0, true), ), - ).to.be.revertedWithCustomError(ssvNetworkContract, 'ValidatorAlreadyExists'); + ).to.be.revertedWithCustomError(ssvNetworkContract, 'ValidatorAlreadyExistsWithData') + .withArgs(helpers.DataGenerator.publicKey(1)); }); - it('Register an existing validator with different operators setup reverts "ValidatorAlreadyExists"', async () => { + it('Register an existing validator with different operators setup reverts "ValidatorAlreadyExistsWithData"', async () => { await helpers.DB.ssvToken .connect(helpers.DB.owners[6]) .approve(ssvNetworkContract.address, helpers.CONFIG.minimalOperatorFee); @@ -1029,7 +1030,8 @@ describe('Register Validator Tests', () => { minDepositAmount, helpers.getClusterForValidator(0, 0, 0, 0, true), ), - ).to.be.revertedWithCustomError(ssvNetworkContract, 'ValidatorAlreadyExists'); + ).to.be.revertedWithCustomError(ssvNetworkContract, 'ValidatorAlreadyExistsWithData') + .withArgs(helpers.DataGenerator.publicKey(1)); }); it('Register whitelisted validator in 1 operator with 4 operators emits "ValidatorAdded"', async () => { diff --git a/test/validators/remove.ts b/test/validators/remove.ts index b0d39269..1765e5a7 100644 --- a/test/validators/remove.ts +++ b/test/validators/remove.ts @@ -324,7 +324,7 @@ describe('Remove Validator Tests', () => { ).to.be.revertedWithCustomError(ssvNetworkContract, 'IncorrectClusterState'); }); - it('Bulk Remove validator that does not exist in a valid cluster reverts "ValidatorDoesNotExist"', async () => { + it('Bulk Remove validator that does not exist in a valid cluster reverts "IncorrectValidatorStateWithData"', async () => { const { args, pks } = await helpers.bulkRegisterValidators( 2, 10, @@ -339,7 +339,8 @@ describe('Remove Validator Tests', () => { ssvNetworkContract .connect(helpers.DB.owners[2]) .bulkRemoveValidator(pks, args.operatorIds, args.cluster), - ).to.be.revertedWithCustomError(ssvNetworkContract, 'ValidatorDoesNotExist'); + ).to.be.revertedWithCustomError(ssvNetworkContract, 'IncorrectValidatorStateWithData') + .withArgs(pks[2]); }); it('Bulk remove validator with an invalid operator setup reverts "ClusterDoesNotExists"', async () => { @@ -358,7 +359,7 @@ describe('Remove Validator Tests', () => { ).to.be.revertedWithCustomError(ssvNetworkContract, 'ClusterDoesNotExists'); }); - it('Bulk Remove the same validator twice reverts "ValidatorDoesNotExist"', async () => { + it('Bulk Remove the same validator twice reverts "IncorrectValidatorStateWithData"', async () => { const { args, pks } = await helpers.bulkRegisterValidators( 2, 10, @@ -380,7 +381,8 @@ describe('Remove Validator Tests', () => { ssvNetworkContract .connect(helpers.DB.owners[2]) .bulkRemoveValidator(pks, removed.operatorIds, removed.cluster), - ).to.be.revertedWithCustomError(ssvNetworkContract, 'ValidatorDoesNotExist'); + ).to.be.revertedWithCustomError(ssvNetworkContract, 'IncorrectValidatorStateWithData') + .withArgs(pks[0]); }); it('Remove validators from a liquidated cluster', async () => { @@ -415,7 +417,7 @@ describe('Remove Validator Tests', () => { expect(removed.cluster.balance.toNumber()).to.equal(0); }); - it('Bulk remove 10 validator, non unique keys', async () => { + it('Bulk remove 10 validator with duplicated public keys reverts "IncorrectValidatorStateWithData"', async () => { minDepositAmount = (helpers.CONFIG.minimalBlocksBeforeLiquidation + 10) * helpers.CONFIG.minimalOperatorFee * 13; const { args, pks } = await helpers.bulkRegisterValidators( @@ -435,4 +437,11 @@ describe('Remove Validator Tests', () => { ).to.be.revertedWithCustomError(ssvNetworkContract, 'IncorrectValidatorStateWithData') .withArgs(pks[2]); }); + + it('Bulk remove 10 validator with empty public keys reverts "IncorrectValidatorStateWithData"', async () => { + await expect(ssvNetworkContract + .connect(helpers.DB.owners[2]) + .bulkRemoveValidator([], firstCluster.operatorIds, firstCluster.cluster) + ).to.be.revertedWithCustomError(ssvNetworkContract, 'ValidatorDoesNotExist'); + }); }); From c20aaca4a86a43cc7d6c661d559463c85eb5197a Mon Sep 17 00:00:00 2001 From: Marco Tabasco Date: Thu, 8 Feb 2024 01:43:31 +0100 Subject: [PATCH 35/38] update gas numbers --- test/helpers/gas-usage.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/helpers/gas-usage.ts b/test/helpers/gas-usage.ts index 68d22b0f..95678e9b 100644 --- a/test/helpers/gas-usage.ts +++ b/test/helpers/gas-usage.ts @@ -111,7 +111,7 @@ const MAX_GAS_PER_GROUP: any = { [GasGroup.REGISTER_VALIDATOR_WITHOUT_DEPOSIT_13]: 393300, [GasGroup.BULK_REGISTER_10_VALIDATOR_NEW_STATE_13]: 1650200, - [GasGroup.BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_13]: 1630200, + [GasGroup.BULK_REGISTER_10_VALIDATOR_EXISTING_CLUSTER_13]: 1630500, [GasGroup.REMOVE_VALIDATOR]: 114000, [GasGroup.BULK_REMOVE_10_VALIDATOR_4]: 191500, From 27a6b9993bd4c2140433d5518c77121aa51ff8ab Mon Sep 17 00:00:00 2001 From: Marco Tabasco Date: Fri, 9 Feb 2024 00:44:27 +0100 Subject: [PATCH 36/38] update NatSpec comments --- contracts/interfaces/ISSVClusters.sol | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/contracts/interfaces/ISSVClusters.sol b/contracts/interfaces/ISSVClusters.sol index 1cc93925..3784aa17 100644 --- a/contracts/interfaces/ISSVClusters.sol +++ b/contracts/interfaces/ISSVClusters.sol @@ -32,13 +32,14 @@ interface ISSVClusters is ISSVNetworkCore { Cluster memory cluster ) external; - /// @notice Bulk removes an set of existing validators in the same cluster from the SSV Network + /// @notice Removes an existing validator from the SSV Network /// @param publicKey The public key of the validator to be removed /// @param operatorIds Array of IDs of operators managing the validator /// @param cluster Cluster associated with the validator function removeValidator(bytes calldata publicKey, uint64[] memory operatorIds, Cluster memory cluster) external; - /// @notice Removes an existing validator set from the SSV Network + /// @notice Bulk removes a set of existing validators in the same cluster from the SSV Network + /// @notice Reverts if publicKeys contains duplicates or non-existent validators /// @param publicKeys The public keys of the validators to be removed /// @param operatorIds Array of IDs of operators managing the validator /// @param cluster Cluster associated with the validator From 0d183f563ede2a6e91a46d917a10eea22ae4986a Mon Sep 17 00:00:00 2001 From: Marco Tabasco Date: Thu, 15 Feb 2024 11:40:34 +0100 Subject: [PATCH 37/38] add audit report --- .../audits/2024-15-02_Quantstamp_v1.1.0.pdf | Bin 0 -> 913408 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 contracts/audits/2024-15-02_Quantstamp_v1.1.0.pdf diff --git a/contracts/audits/2024-15-02_Quantstamp_v1.1.0.pdf b/contracts/audits/2024-15-02_Quantstamp_v1.1.0.pdf new file mode 100644 index 0000000000000000000000000000000000000000..71c398e037696adae9591ef30541d331cd4f49b4 GIT binary patch literal 913408 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

    )N`Oy09AI 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

    mn+%jRuBYBrn)60guy2fL^ltIcL(y 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

    9J^?iC@Q57_d%EnUqSk zA0Od(7x5pH7o~pVfP3C@al6%VF>#UHm|XuDZSR)@nUF!Rd%=;s{6q1NC|KTQTh8P~ zS!EFls1$?$gSPLCYwGFN-H3nv>_IhTmS@W#D3rAx5-OH4j zUUDtJNK6>o56B?X`8$+FJ8J5KchE*L$&Dwt6h04^gP9^_gTf_?w;5bwd=*YO9tZNgM3tl1UV z>62E=0x&|l_?{XrFNo*EZtDYdF%?yGhV%HVKT}%*V`a(KgI#AiPY@kC>U37ux(=4H z+;$3c1}UtiPA?74+>IE`8ktFr9KQ-IqhX1)YN$Gfcq zQCKD;OneL1TQA(S`K}%y0=vFh^)Psd9y%t{n@kHvTIT6(B4qT%U$BbrX{%uw|~`wr9C+RKmmVf;F!XJU$}#7uaCjEv9S$CqgmJv|ZXJKFFG zyJFLVNx*IDlx6_g9GH*ka%11oCrH{QDcNRJFI8TK>M_Q=Gv7&|L#gvS-+k&87+?3y ztS0(oR5;>TENKx;77KnX+PXjaQuHS5rcU+N>0+v@G803!*@ z;v}!^Ny2z_>I-{|s4*GthdTdg_PiAJ1L*bdjY3o(uti~yivQ5on+@p&tDfmZZtNm; z1;-aW>&=gn_x7?t-b)kEOm#D!;HL>6FZ>wWu^1=5fe#KzqU4^bgJ){Uf=yz@h9iz3 z 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 o%*CsMgBscX5A?v~+yDRo literal 0 HcmV?d00001 From fe79a26ad9118d3f5d51ea80384d70ab89197af4 Mon Sep 17 00:00:00 2001 From: Marco Tabasco Date: Thu, 15 Feb 2024 12:12:41 +0100 Subject: [PATCH 38/38] holesky deployment metadata --- .openzeppelin/unknown-17000.json | 109 +++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) diff --git a/.openzeppelin/unknown-17000.json b/.openzeppelin/unknown-17000.json index b7d411c4..7d22a840 100644 --- a/.openzeppelin/unknown-17000.json +++ b/.openzeppelin/unknown-17000.json @@ -939,6 +939,115 @@ }, "namespaces": {} } + }, + "cace716c99b7c3331ef14bea41153e9b79ee38508d038ed764ebfa2f3addf8d6": { + "address": "0xEFccE07BeC6418e32e72a28aFf0cdf442AEc14ea", + "txHash": "0x3da46b8992ed89a293c740d4e6a724eb0f24fc7b8fd2257bcd8af434ca1f956c", + "layout": { + "solcVersion": "0.8.18", + "storage": [ + { + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_uint8", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:63", + "retypedFrom": "bool" + }, + { + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:68" + }, + { + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)50_storage", + "contract": "ERC1967UpgradeUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol:169" + }, + { + "label": "__gap", + "offset": 0, + "slot": "51", + "type": "t_array(t_uint256)50_storage", + "contract": "UUPSUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol:111" + }, + { + "label": "__gap", + "offset": 0, + "slot": "101", + "type": "t_array(t_uint256)50_storage", + "contract": "ContextUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" + }, + { + "label": "_owner", + "offset": 0, + "slot": "151", + "type": "t_address", + "contract": "OwnableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" + }, + { + "label": "__gap", + "offset": 0, + "slot": "152", + "type": "t_array(t_uint256)49_storage", + "contract": "OwnableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:94" + }, + { + "label": "_pendingOwner", + "offset": 0, + "slot": "201", + "type": "t_address", + "contract": "Ownable2StepUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol:27" + }, + { + "label": "__gap", + "offset": 0, + "slot": "202", + "type": "t_array(t_uint256)49_storage", + "contract": "Ownable2StepUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol:70" + } + ], + "types": { + "t_address": { + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_uint256)49_storage": { + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_array(t_uint256)50_storage": { + "label": "uint256[50]", + "numberOfBytes": "1600" + }, + "t_bool": { + "label": "bool", + "numberOfBytes": "1" + }, + "t_uint256": { + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint8": { + "label": "uint8", + "numberOfBytes": "1" + } + }, + "namespaces": {} + } } } }