From 786b76689ebabdcc4bb16acd905513584c630ecf Mon Sep 17 00:00:00 2001 From: Vadim Date: Mon, 8 Aug 2022 11:46:24 +0200 Subject: [PATCH 001/149] v3 core experements --- .openzeppelin/goerli.json | 20247 ------------------------ .openzeppelin/mainnet.json | 170 - contracts/ISSVNetwork.sol | 403 - contracts/ISSVRegistry.sol | 171 - contracts/SSVNetwork.sol | 811 - contracts/SSVRegistry.sol | 517 +- contracts/mocks/SSVTokenMock.sol | 22 - contracts/utils/Types.sol | 18 - contracts/utils/Utils.sol | 14 - contracts/utils/VersionedContract.sol | 8 - docs/_config.yml | 1 - hardhat.config.ts | 4 + scripts/ssv-network-deploy.ts | 28 - scripts/ssv-network-upgrade.ts | 19 - scripts/utils.ts | 58 - test/e2e/balances.ts | 94 - test/e2e/deposit.ts | 65 - test/e2e/validator.ts | 80 - test/e2e/withdraw.ts | 69 - test/helpers/asserts.ts | 51 - test/helpers/setup.ts | 351 - test/helpers/utils.ts | 66 - test/unit/burn-rate.ts | 138 - test/unit/liquidation.ts | 207 - test/unit/operator-register.ts | 88 - test/unit/operator-remove.ts | 132 - test/unit/operator-update.ts | 172 - test/unit/ssv-network-balances.ts | 162 - test/unit/ssv-network.ts | 412 - test/unit/ssv-registry.js | 67 + test/unit/ssv-registry.ts | 105 - test/unit/validator-register.ts | 104 - test/unit/validator-remove.ts | 93 - test/unit/validator-update.ts | 106 - 34 files changed, 363 insertions(+), 24690 deletions(-) delete mode 100644 .openzeppelin/goerli.json delete mode 100644 .openzeppelin/mainnet.json delete mode 100644 contracts/ISSVNetwork.sol delete mode 100644 contracts/ISSVRegistry.sol delete mode 100644 contracts/SSVNetwork.sol delete mode 100644 contracts/mocks/SSVTokenMock.sol delete mode 100644 contracts/utils/Types.sol delete mode 100644 contracts/utils/Utils.sol delete mode 100644 contracts/utils/VersionedContract.sol delete mode 100644 docs/_config.yml delete mode 100644 scripts/ssv-network-deploy.ts delete mode 100644 scripts/ssv-network-upgrade.ts delete mode 100644 scripts/utils.ts delete mode 100644 test/e2e/balances.ts delete mode 100644 test/e2e/deposit.ts delete mode 100644 test/e2e/validator.ts delete mode 100644 test/e2e/withdraw.ts delete mode 100644 test/helpers/asserts.ts delete mode 100644 test/helpers/setup.ts delete mode 100644 test/helpers/utils.ts delete mode 100644 test/unit/burn-rate.ts delete mode 100644 test/unit/liquidation.ts delete mode 100644 test/unit/operator-register.ts delete mode 100644 test/unit/operator-remove.ts delete mode 100644 test/unit/operator-update.ts delete mode 100644 test/unit/ssv-network-balances.ts delete mode 100644 test/unit/ssv-network.ts create mode 100644 test/unit/ssv-registry.js delete mode 100644 test/unit/ssv-registry.ts delete mode 100644 test/unit/validator-register.ts delete mode 100644 test/unit/validator-remove.ts delete mode 100644 test/unit/validator-update.ts diff --git a/.openzeppelin/goerli.json b/.openzeppelin/goerli.json deleted file mode 100644 index b1594a7e..00000000 --- a/.openzeppelin/goerli.json +++ /dev/null @@ -1,20247 +0,0 @@ -{ - "manifestVersion": "3.2", - "admin": { - "address": "0x550160B132987DD3197a637Ea5dfc21FE1a4bf1f", - "txHash": "0x0f1f054bd276cc6e54294c35dc784f991402a60eff974c58b24941ef43740ddd" - }, - "proxies": [ - { - "address": "0x07C29d7381cd03d21327CF88B918ef790fb19e67", - "txHash": "0xafe771e2b9e65209e6dc1fafe47780ddc4a01a7f33275fe5481f36dd8e582b44", - "kind": "transparent" - }, - { - "address": "0x6186F08bbb12dA5797852Bb8C3FBEC0623D57d62", - "txHash": "0x1f599ba77123b6dec2a8b2ac5164c2961229b95c91e295b7108f0bab0cc89e43", - "kind": "transparent" - }, - { - "address": "0xe8c9934EBA868BB8f54549376b5157B4bc79F84B", - "txHash": "0x25add42aa25f8679923a60d2997beeed6906864b79de9d83898a6468d69b86e9", - "kind": "transparent" - }, - { - "address": "0xFC561F6CDA1b65423b00B427c13b3b3666cfe668", - "txHash": "0x05eb20754f8461dfba639e9ae77d06b8e52328d90ccb8c595c7afde1dd7091a5", - "kind": "transparent" - }, - { - "address": "0x3F90b99EEcb3F3745428255CecB5c6d54b0a5eaD", - "txHash": "0x26b8de1fa1ef28cc80c4d70769f803377dad6ba28ee1ff4644afaae5884137b8", - "kind": "transparent" - }, - { - "address": "0x1963eeaD9C100FE7375e5F3d4b17A014759cFb04", - "txHash": "0x890336b445669bbdc638de43b5aa4caa680a4217baf66b7028b88f26c947f503", - "kind": "transparent" - }, - { - "address": "0x38D6bc1531EE425F30e6647B21903F7bbA97DD6d", - "txHash": "0x8ece39536fd37708eaee4d7afe752fde3451a21ae9190259d83a92e48a8855fd", - "kind": "transparent" - }, - { - "address": "0x0C5b677E1f662fC28bFFD0cb001c90DF3c20aa0B", - "txHash": "0x5f7e16ee1f4ea77a9c48ac14e8b72f461adf59777cb6ba72efdf08fc43c866b5", - "kind": "transparent" - }, - { - "address": "0x1B5676Af47f954E24c207F0481a0BFd89A0cfc8a", - "txHash": "0x5038901d32c89caf3a9255de31647a0651a1869dcd28717828c14e1ad41a4a64", - "kind": "transparent" - }, - { - "address": "0xfE86B2653F47909C36620eD7B3DbB4C064266475", - "txHash": "0x7ee2a55fe0923a55fa8601f0d1bc904fadc5cca75a83eeef322b5f70eef90e2a", - "kind": "transparent" - }, - { - "address": "0xF1E8f1b98D6B05Dcc27E93B1b501c89e286EEbA9", - "txHash": "0x9253e46eec12dfb5749ee3917b7e7f839fe1e778ac89af38407a071114538b7f", - "kind": "transparent" - }, - { - "address": "0x3a6c1995586D4d6827e8D8dA9F5F89Ba4Ab58a1f", - "txHash": "0x6bf582eb758b7066402efdfc20e1ace5de636812ad7cb41d65ba780dc86128fa", - "kind": "transparent" - }, - { - "address": "0x862afFa4f2D055f7a33E6137d7B94C42b929B20C", - "txHash": "0x0f65d8956703f10cc16f4aa31f3862e4581f508a0512622a873b15829bbcebc7", - "kind": "transparent" - }, - { - "address": "0x79AFd88A8DD393D8F3dCB89323246E9Cd5E2d87a", - "txHash": "0x7e11278c8c9f8507eb396f2a10cf10a8240d48c45753e7667adbe1acadabd578", - "kind": "transparent" - }, - { - "address": "0xF2f7e10F48319fa1BFf8b52920beAc251174B84F", - "txHash": "0x7906e5f39ed7c2c9162b2fd8f1530109b4cd844ca4091b3f39a91b92ef85ec38", - "kind": "transparent" - }, - { - "address": "0x6D8741Ec680f01DAD35355F6c7c8378E90e1cd66", - "txHash": "0x048dc955f725fbb144a6a97c4b6a64eb5a8251ca38f10e97fb72154426511c80", - "kind": "transparent" - }, - { - "address": "0xd594C1ef4845713e86658cb42227A811625A285b", - "txHash": "0xc1f43dbfc796cded2d0ea3748828c569d9841a928d2554d6f1de11637da42586", - "kind": "transparent" - }, - { - "address": "0x9A99b07128899a8772215AEAb70bC57160cccdF1", - "txHash": "0x4221336976bac8a687e0c1c1e132a1ed79c584c0e54cad0ef3cf6ebd004d967d", - "kind": "transparent" - }, - { - "address": "0xf5Bb64CdFA92315Aa8B13Cd2DD7c565C1EB6f077", - "txHash": "0xb69e3ed02a65ffb8595f76e453a779df573385cc1687f0242c9aac3479c8d15f", - "kind": "transparent" - }, - { - "address": "0x8AA6878bfCbF7c784C0C9e20e2dE2A50679FE553", - "txHash": "0xbc46130c5787ef1ba7bcbdc7dce506fb23310279fa686a26cc441e2255469da7", - "kind": "transparent" - }, - { - "address": "0x5e41f6E36B2bDE05eF2eFebF0EcEf6706A79E52D", - "txHash": "0x7dab5347f65a128c5a9bab21d429c050c8f7b4ddad83b6e133e083562c12f041", - "kind": "transparent" - }, - { - "address": "0x158C50eCd05674952Fb8533158885D90d311af22", - "txHash": "0x6679dafafde8b1b17fde9807a96af705b29ebaada0462974065a5d08fed2ad1f", - "kind": "transparent" - }, - { - "address": "0x9042f9D698FEA4A6aD13fBc83D2752D141522C7B", - "txHash": "0x0b6eb5bfa72da67438ef79918adb3af535885ed5b114f8cafcd358b4f290d0d5", - "kind": "transparent" - }, - { - "address": "0xD1fE29018CF54bdDa759a7C99fB85da58026030E", - "txHash": "0x82b0e60d92f5e0c39a03329bf07d69af8b92de5ba5abeceeb418b0303108f821", - "kind": "transparent" - }, - { - "address": "0x76B1c8E85A43c665eBC4aE1f8ea0Aebd2CAdd11e", - "txHash": "0x78af225cf066fa814b4c07fd173d82ce4bc68aec304e39c01f4b56021126a960", - "kind": "transparent" - }, - { - "address": "0xf3c07138d0e526D99333069362526295F4562990", - "txHash": "0xf4039e76202a1cf51904f8576cc24e0d2978793e8e99c1a5cf8edec5f5cf8f62", - "kind": "transparent" - }, - { - "address": "0xAfF9F2CB25841985FDae7811479630b3ef855e36", - "txHash": "0xb7c3ace5b3930ddc6e29d1863162bf0f4c0d8fcad0aa9bcbe14e40d91255bf77", - "kind": "transparent" - }, - { - "address": "0xC71eBc08F6924Bf2b0c3e669Cf82f05F0381E2Bb", - "txHash": "0x060e51692ba639e737ebc3bf2e9831abac6b528a7670db864511d9601538fbaa", - "kind": "transparent" - }, - { - "address": "0xf4F4B10d8c0a775Dd60b9B190234f2df3c8C7962", - "txHash": "0x5b1753737d96aab7a9cf000a0b244fe645f8a0a199b092b8def76b9a88f700c4", - "kind": "transparent" - }, - { - "address": "0xB2114c005fE00dBd9f745cc6296d33a5A8ae9420", - "txHash": "0xe9db44a457a31756bdbce452205a08b778690d948dc12806e9846d99d332277e", - "kind": "transparent" - }, - { - "address": "0x2c27Bca775fE20B01D6F5F39BFCc3fAAA26bC3dd", - "txHash": "0x569e3a4e269965cbf436c4759f06339223b5cb6832f2f6dfd66877b00967afd8", - "kind": "transparent" - }, - { - "address": "0x282937f09BF2D95D7BD899e105c072Aaf7Fb232c", - "txHash": "0x81cec6b5711813c7185c77f012068a444e66a0225076a9ec6765ebef63b6896f", - "kind": "transparent" - }, - { - "address": "0x4caa916f10e2144EDDCC7F8D1Dce579B16505025", - "txHash": "0xc7e32ccf6b4eb64173969ff18802a45ddddef58c0ea30a7a146f5aaa34bf89dc", - "kind": "transparent" - }, - { - "address": "0x04d0497552BEB9Da477DbfF809D8c88010E6357F", - "txHash": "0x67d81a4cee42407d40aacc1abfa7d3b02b7bafe2cf47ee5f8c41d4b5336982d0", - "kind": "transparent" - }, - { - "address": "0x483A0c1b82863758daC4868d6732A0CFFEfB9c93", - "txHash": "0xa9f621f03ff1b8ed5f68ac21eafc32009a10b84bc348cb3d8f31066a92a73b03", - "kind": "transparent" - }, - { - "address": "0x0f8b2d1e053c8D5C4093b8c5b48Fe17eABE0c90B", - "txHash": "0x3a9c9c18fba42f75d44d537f302027da46c1fc67364b49bbe2a0f3a7f6102f87", - "kind": "transparent" - }, - { - "address": "0x1F940D719A37071248A88CCAc69E1d650f65D169", - "txHash": "0xa5d885091e7eefd67873a746710387ecfb7259c213923d93626653301b729fd9", - "kind": "transparent" - }, - { - "address": "0xa2251cAAe81862FF0363FC378e7a1d80CE4004Fd", - "txHash": "0xbea0858d89e96fce7a62754c367834fc31f4a3d98b20ea373bfc930ceb85c23c", - "kind": "transparent" - }, - { - "address": "0x784a721ef9497a3793Ce9Ac5674A658e7360F2AD", - "txHash": "0xa1aaa3dfbf0bb9560685feea15eeb8ba6f6b3c04801d4c08361798d6c9a083a8", - "kind": "transparent" - }, - { - "address": "0x7C53aFc3EDdAC236e5960e2EDaF35482AC74D92c", - "txHash": "0xf1ab95bac0638f96748b0c5049ea320d39dfcdc78cb1228cd0ccb571aa81fbd2", - "kind": "transparent" - }, - { - "address": "0x28a55c072a0E72dcdFcBDe5398028260682Fa069", - "txHash": "0x9f032d6a7e875e6009918ad69174571509357e5887a198993fade39a289b88c8", - "kind": "transparent" - }, - { - "address": "0x4774Eef31369Bcb090183358ADdb01764FF223C4", - "txHash": "0xdd466aebddbe8204749cb8c94318260ac9ef38c2d34a66aa39351122934a7bac", - "kind": "transparent" - }, - { - "address": "0x87F7efc8C4c86cf30983f0793860B18A1fa8F127", - "txHash": "0x3691ecd00eecf94d92357610ed02d42fd86bc0fa573adf3ac991a40fb1750e4e", - "kind": "transparent" - }, - { - "address": "0xDD28b9Dbf202F40ebD916a58517dC76e6bFBE1f4", - "txHash": "0x92088d4f15184aacb033a8ed38d24c0e3c51936fa5f1761ff04ef68b5ce114f1", - "kind": "transparent" - }, - { - "address": "0xb2046ECd2db9219bD5915098A0002e4B5341D6D9", - "txHash": "0x843f7e34458a3ce9f2fa4aa28ad5af3a00198a6f15305923ac6d9dab0d293eda", - "kind": "transparent" - }, - { - "address": "0x116E52F0eACD1Ffa11eFd2c66345F76206B38B37", - "txHash": "0xc3e12aae8852924203b66b8208c7348307afcb30c745f7f555384b7785aada7e", - "kind": "transparent" - }, - { - "address": "0x5b46c3659f12D23049Dca9a4edec5E9B24f8948d", - "txHash": "0x3412648a963d11c8a8439099b5a7ba18d96df1144129958baf1697aad517508e", - "kind": "transparent" - }, - { - "address": "0x8A01D75d169e72F7CcD69ee5405d92ce54d9017D", - "txHash": "0x9ea77ba36d36e4a1f7f1100fdc936fa7d571dbad426ab7e07f87d8a121a9cddf", - "kind": "transparent" - }, - { - "address": "0x8feA36b975933A4ee73C31336cE013c45a11feC7", - "txHash": "0xd33c8a9cf72fcce1e6812499eb75ef3a144fc5ebe5d5a4a65a3dfec9d9a8819c", - "kind": "transparent" - }, - { - "address": "0xbb50039a4ff24570cf828b02bd05F08005044C80", - "txHash": "0xd641b55f9e772fd327a65ff411524ae76ae8f526cb61f0a6c5259b3741ade934", - "kind": "transparent" - }, - { - "address": "0x019487101C7a6b55F080965B3DC16E4919c5bD6f", - "txHash": "0x71eef817aa89a3e1d1038c949514239c127d78a1e2837f27242b198a4918f0f6", - "kind": "transparent" - }, - { - "address": "0xE2e28FDEA8bA1bB59a0056f6A5eABD443d47eC78", - "txHash": "0x4f9037f95617b37f0158e0461043de3997a028f36703c34861c34cd2ce17791e", - "kind": "transparent" - }, - { - "address": "0x5b8103ea67D2260FC8571E4ca4eC7d38d64e68B9", - "txHash": "0xc5eb479b71c67606dbdb42a098e216cfaa8cc31a7454215e05b346ebb1dbae70", - "kind": "transparent" - }, - { - "address": "0xe38256539B8731716EE6724EAa8672770ABE7d0d", - "txHash": "0x2a0bf723e1e484a718bc6102554a6d851486196ad5065a6b5b26d1c3081574fe", - "kind": "transparent" - }, - { - "address": "0x49D395eFcE6233e116C69333F249e6cF128D5992", - "txHash": "0x432f81ac0ae56f61a55e7538aea90af82c24d5a073ece806dd5d9cb279655b25", - "kind": "transparent" - }, - { - "address": "0xb9e155e65B5c4D66df28Da8E9a0957f06F11Bc04", - "txHash": "0x08507798c3dc6ecddc4e5c80cf0b7eb05d35f5738a4ccc74cc56b035ad5659d2", - "kind": "transparent" - } - ], - "impls": { - "baf9cc9d16f9682ee3153164cd1610c561f4a2b4e9bf09bd3b7fc9f175992efc": { - "address": "0xD39dc914acf4aA76D3237cCb620e7a3bB1E14b5B", - "txHash": "0xa8f98dd1cecd1e78647a5187c98829637b5e34e8890443fb6eb745a709188a5a", - "layout": { - "storage": [ - { - "contract": "Initializable", - "label": "_initialized", - "type": "t_bool", - "src": "@openzeppelin/contracts/proxy/utils/Initializable.sol:23" - }, - { - "contract": "Initializable", - "label": "_initializing", - "type": "t_bool", - "src": "@openzeppelin/contracts/proxy/utils/Initializable.sol:28" - }, - { - "contract": "DEX", - "label": "_cdtToken", - "type": "t_contract(IERC20)962", - "src": "contracts/DEX.sol:14" - }, - { - "contract": "DEX", - "label": "_ssvToken", - "type": "t_contract(IERC20)962", - "src": "contracts/DEX.sol:15" - }, - { - "contract": "DEX", - "label": "_rate", - "type": "t_uint256", - "src": "contracts/DEX.sol:16" - } - ], - "types": { - "t_contract(IERC20)962": { - "label": "contract IERC20" - }, - "t_uint256": { - "label": "uint256" - }, - "t_bool": { - "label": "bool" - } - } - } - }, - "333dd45fa99ad81fa59bfa7375d09378a45c2bedcaacef3591b1a8f6e6c73310": { - "address": "0x887AE88Ce4A1a1bCFe416b212b2b56923cF0Dcb1", - "txHash": "0x991a34cddad47c222edeb586da5f8b4405e07c655eb8a1059693b79c997fd2ff", - "layout": { - "storage": [ - { - "contract": "Initializable", - "label": "_initialized", - "type": "t_bool", - "src": "@openzeppelin/contracts/proxy/utils/Initializable.sol:23" - }, - { - "contract": "Initializable", - "label": "_initializing", - "type": "t_bool", - "src": "@openzeppelin/contracts/proxy/utils/Initializable.sol:28" - }, - { - "contract": "ContextUpgradeable", - "label": "__gap", - "type": "t_array(t_uint256)50_storage", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" - }, - { - "contract": "OwnableUpgradeable", - "label": "_owner", - "type": "t_address", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:20" - }, - { - "contract": "OwnableUpgradeable", - "label": "__gap", - "type": "t_array(t_uint256)49_storage", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:74" - }, - { - "contract": "SSVRegistry", - "label": "_operatorCount", - "type": "t_uint256", - "src": "contracts/SSVRegistry.sol:32" - }, - { - "contract": "SSVRegistry", - "label": "_validatorCount", - "type": "t_uint256", - "src": "contracts/SSVRegistry.sol:33" - }, - { - "contract": "SSVRegistry", - "label": "_operators", - "type": "t_mapping(t_bytes_memory_ptr,t_struct(Operator)4604_storage)", - "src": "contracts/SSVRegistry.sol:35" - }, - { - "contract": "SSVRegistry", - "label": "_validators", - "type": "t_mapping(t_bytes_memory_ptr,t_struct(Validator)4617_storage)", - "src": "contracts/SSVRegistry.sol:36" - }, - { - "contract": "SSVRegistry", - "label": "_operatorFees", - "type": "t_mapping(t_bytes_memory_ptr,t_array(t_struct(OperatorFee)4622_storage)dyn_storage)", - "src": "contracts/SSVRegistry.sol:38" - }, - { - "contract": "SSVRegistry", - "label": "_operatorsByOwnerAddress", - "type": "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)", - "src": "contracts/SSVRegistry.sol:40" - }, - { - "contract": "SSVRegistry", - "label": "_validatorsByAddress", - "type": "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)", - "src": "contracts/SSVRegistry.sol:41" - } - ], - "types": { - "t_uint256": { - "label": "uint256" - }, - "t_mapping(t_bytes_memory_ptr,t_struct(Operator)4604_storage)": { - "label": "mapping(bytes => struct SSVRegistry.Operator)" - }, - "t_bytes_storage": { - "label": "bytes" - }, - "t_struct(Operator)4604_storage": { - "label": "struct SSVRegistry.Operator", - "members": [ - { - "label": "name", - "type": "t_string_storage" - }, - { - "label": "ownerAddress", - "type": "t_address" - }, - { - "label": "publicKey", - "type": "t_bytes_storage" - }, - { - "label": "score", - "type": "t_uint256" - }, - { - "label": "active", - "type": "t_bool" - }, - { - "label": "index", - "type": "t_uint256" - } - ] - }, - "t_string_storage": { - "label": "string" - }, - "t_address": { - "label": "address" - }, - "t_bool": { - "label": "bool" - }, - "t_mapping(t_bytes_memory_ptr,t_struct(Validator)4617_storage)": { - "label": "mapping(bytes => struct SSVRegistry.Validator)" - }, - "t_struct(Validator)4617_storage": { - "label": "struct SSVRegistry.Validator", - "members": [ - { - "label": "ownerAddress", - "type": "t_address" - }, - { - "label": "publicKey", - "type": "t_bytes_storage" - }, - { - "label": "oess", - "type": "t_array(t_struct(Oess)2395_storage)dyn_storage" - }, - { - "label": "active", - "type": "t_bool" - }, - { - "label": "index", - "type": "t_uint256" - } - ] - }, - "t_array(t_struct(Oess)2395_storage)dyn_storage": { - "label": "struct ISSVRegistry.Oess[]" - }, - "t_struct(Oess)2395_storage": { - "label": "struct ISSVRegistry.Oess", - "members": [ - { - "label": "operatorPublicKey", - "type": "t_bytes_storage" - }, - { - "label": "sharedPublicKey", - "type": "t_bytes_storage" - }, - { - "label": "encryptedKey", - "type": "t_bytes_storage" - } - ] - }, - "t_mapping(t_bytes_memory_ptr,t_array(t_struct(OperatorFee)4622_storage)dyn_storage)": { - "label": "mapping(bytes => struct SSVRegistry.OperatorFee[])" - }, - "t_array(t_struct(OperatorFee)4622_storage)dyn_storage": { - "label": "struct SSVRegistry.OperatorFee[]" - }, - "t_struct(OperatorFee)4622_storage": { - "label": "struct SSVRegistry.OperatorFee", - "members": [ - { - "label": "blockNumber", - "type": "t_uint256" - }, - { - "label": "fee", - "type": "t_uint256" - } - ] - }, - "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)": { - "label": "mapping(address => bytes[])" - }, - "t_array(t_bytes_storage)dyn_storage": { - "label": "bytes[]" - }, - "t_array(t_uint256)49_storage": { - "label": "uint256[49]" - }, - "t_array(t_uint256)50_storage": { - "label": "uint256[50]" - } - } - } - }, - "71b646644b23e3ace247430ed39deaf5b3665d21b0a59fb2398d1f0e6cf64077": { - "address": "0x6C590319868782aeB14aaBA80949b507Fd43CEdA", - "txHash": "0xfb27f1272cbee5b0fdabcf4a02fc4a30124fb1aff3f7031dcb757f91154cc649", - "layout": { - "storage": [ - { - "contract": "Initializable", - "label": "_initialized", - "type": "t_bool", - "src": "@openzeppelin/contracts/proxy/utils/Initializable.sol:23" - }, - { - "contract": "Initializable", - "label": "_initializing", - "type": "t_bool", - "src": "@openzeppelin/contracts/proxy/utils/Initializable.sol:28" - }, - { - "contract": "ContextUpgradeable", - "label": "__gap", - "type": "t_array(t_uint256)50_storage", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" - }, - { - "contract": "OwnableUpgradeable", - "label": "_owner", - "type": "t_address", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:20" - }, - { - "contract": "OwnableUpgradeable", - "label": "__gap", - "type": "t_array(t_uint256)49_storage", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:74" - }, - { - "contract": "SSVNetwork", - "label": "_ssvRegistryContract", - "type": "t_contract(ISSVRegistry)2686", - "src": "contracts/SSVNetwork.sol:38" - }, - { - "contract": "SSVNetwork", - "label": "_token", - "type": "t_contract(IERC20)962", - "src": "contracts/SSVNetwork.sol:39" - }, - { - "contract": "SSVNetwork", - "label": "_minimumBlocksBeforeLiquidation", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:40" - }, - { - "contract": "SSVNetwork", - "label": "_networkFee", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:42" - }, - { - "contract": "SSVNetwork", - "label": "_networkFeeIndex", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:43" - }, - { - "contract": "SSVNetwork", - "label": "_networkFeeIndexBlockNumber", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:44" - }, - { - "contract": "SSVNetwork", - "label": "_lastUpdateNetworkFeeRun", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:45" - }, - { - "contract": "SSVNetwork", - "label": "_operatorDatas", - "type": "t_mapping(t_bytes_memory_ptr,t_struct(OperatorData)2710_storage)", - "src": "contracts/SSVNetwork.sol:47" - }, - { - "contract": "SSVNetwork", - "label": "_owners", - "type": "t_mapping(t_address,t_struct(OwnerData)2725_storage)", - "src": "contracts/SSVNetwork.sol:48" - }, - { - "contract": "SSVNetwork", - "label": "_operatorsInUseByAddress", - "type": "t_mapping(t_address,t_mapping(t_bytes_memory_ptr,t_struct(OperatorInUse)2736_storage))", - "src": "contracts/SSVNetwork.sol:49" - }, - { - "contract": "SSVNetwork", - "label": "_operatorsInUseList", - "type": "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)", - "src": "contracts/SSVNetwork.sol:50" - }, - { - "contract": "SSVNetwork", - "label": "_lastOperatorUpdateNetworkFeeRun", - "type": "t_mapping(t_bytes_memory_ptr,t_uint256)", - "src": "contracts/SSVNetwork.sol:51" - } - ], - "types": { - "t_contract(ISSVRegistry)2686": { - "label": "contract ISSVRegistry" - }, - "t_contract(IERC20)962": { - "label": "contract IERC20" - }, - "t_uint256": { - "label": "uint256" - }, - "t_mapping(t_bytes_memory_ptr,t_struct(OperatorData)2710_storage)": { - "label": "mapping(bytes => struct SSVNetwork.OperatorData)" - }, - "t_bytes_storage": { - "label": "bytes" - }, - "t_struct(OperatorData)2710_storage": { - "label": "struct SSVNetwork.OperatorData", - "members": [ - { - "label": "blockNumber", - "type": "t_uint256" - }, - { - "label": "validatorCount", - "type": "t_uint256" - }, - { - "label": "balance", - "type": "t_uint256" - }, - { - "label": "index", - "type": "t_uint256" - }, - { - "label": "indexBlockNumber", - "type": "t_uint256" - }, - { - "label": "lastFeeUpdate", - "type": "t_uint256" - } - ] - }, - "t_mapping(t_address,t_struct(OwnerData)2725_storage)": { - "label": "mapping(address => struct SSVNetwork.OwnerData)" - }, - "t_address": { - "label": "address" - }, - "t_struct(OwnerData)2725_storage": { - "label": "struct SSVNetwork.OwnerData", - "members": [ - { - "label": "deposited", - "type": "t_uint256" - }, - { - "label": "withdrawn", - "type": "t_uint256" - }, - { - "label": "earned", - "type": "t_uint256" - }, - { - "label": "used", - "type": "t_uint256" - }, - { - "label": "networkFee", - "type": "t_uint256" - }, - { - "label": "networkFeeIndex", - "type": "t_uint256" - }, - { - "label": "activeValidatorsCount", - "type": "t_uint256" - } - ] - }, - "t_mapping(t_address,t_mapping(t_bytes_memory_ptr,t_struct(OperatorInUse)2736_storage))": { - "label": "mapping(address => mapping(bytes => struct SSVNetwork.OperatorInUse))" - }, - "t_mapping(t_bytes_memory_ptr,t_struct(OperatorInUse)2736_storage)": { - "label": "mapping(bytes => struct SSVNetwork.OperatorInUse)" - }, - "t_struct(OperatorInUse)2736_storage": { - "label": "struct SSVNetwork.OperatorInUse", - "members": [ - { - "label": "index", - "type": "t_uint256" - }, - { - "label": "validatorCount", - "type": "t_uint256" - }, - { - "label": "used", - "type": "t_uint256" - }, - { - "label": "exists", - "type": "t_bool" - }, - { - "label": "indexInArray", - "type": "t_uint256" - } - ] - }, - "t_bool": { - "label": "bool" - }, - "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)": { - "label": "mapping(address => bytes[])" - }, - "t_array(t_bytes_storage)dyn_storage": { - "label": "bytes[]" - }, - "t_mapping(t_bytes_memory_ptr,t_uint256)": { - "label": "mapping(bytes => uint256)" - }, - "t_array(t_uint256)49_storage": { - "label": "uint256[49]" - }, - "t_array(t_uint256)50_storage": { - "label": "uint256[50]" - } - } - } - }, - "f3645556a7937193f4534bd7f6b4f181b1f4bf76abd0bc993c3e2cbf43be9699": { - "address": "0x2287f839D558Ba22e79e96d0467ee7db4aB9d785", - "txHash": "0xfd1b6ce59c303603953c59b38578391a556b8dfd8125d79a1600d09cc7f93823", - "layout": { - "storage": [ - { - "contract": "Initializable", - "label": "_initialized", - "type": "t_bool", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:23" - }, - { - "contract": "Initializable", - "label": "_initializing", - "type": "t_bool", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:28" - }, - { - "contract": "ContextUpgradeable", - "label": "__gap", - "type": "t_array(t_uint256)50_storage", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" - }, - { - "contract": "OwnableUpgradeable", - "label": "_owner", - "type": "t_address", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:20" - }, - { - "contract": "OwnableUpgradeable", - "label": "__gap", - "type": "t_array(t_uint256)49_storage", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:74" - }, - { - "contract": "SSVRegistry", - "label": "_operatorCount", - "type": "t_uint256", - "src": "contracts/SSVRegistry.sol:32" - }, - { - "contract": "SSVRegistry", - "label": "_validatorCount", - "type": "t_uint256", - "src": "contracts/SSVRegistry.sol:33" - }, - { - "contract": "SSVRegistry", - "label": "_activeValidatorCount", - "type": "t_uint256", - "src": "contracts/SSVRegistry.sol:34" - }, - { - "contract": "SSVRegistry", - "label": "_operators", - "type": "t_mapping(t_bytes_memory_ptr,t_struct(Operator)618_storage)", - "src": "contracts/SSVRegistry.sol:36" - }, - { - "contract": "SSVRegistry", - "label": "_validators", - "type": "t_mapping(t_bytes_memory_ptr,t_struct(Validator)631_storage)", - "src": "contracts/SSVRegistry.sol:37" - }, - { - "contract": "SSVRegistry", - "label": "_operatorFees", - "type": "t_mapping(t_bytes_memory_ptr,t_array(t_struct(OperatorFee)636_storage)dyn_storage)", - "src": "contracts/SSVRegistry.sol:39" - }, - { - "contract": "SSVRegistry", - "label": "_operatorsByOwnerAddress", - "type": "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)", - "src": "contracts/SSVRegistry.sol:41" - }, - { - "contract": "SSVRegistry", - "label": "_validatorsByAddress", - "type": "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)", - "src": "contracts/SSVRegistry.sol:42" - } - ], - "types": { - "t_uint256": { - "label": "uint256" - }, - "t_mapping(t_bytes_memory_ptr,t_struct(Operator)618_storage)": { - "label": "mapping(bytes => struct SSVRegistry.Operator)" - }, - "t_bytes_storage": { - "label": "bytes" - }, - "t_struct(Operator)618_storage": { - "label": "struct SSVRegistry.Operator", - "members": [ - { - "label": "name", - "type": "t_string_storage" - }, - { - "label": "ownerAddress", - "type": "t_address" - }, - { - "label": "publicKey", - "type": "t_bytes_storage" - }, - { - "label": "score", - "type": "t_uint256" - }, - { - "label": "active", - "type": "t_bool" - }, - { - "label": "index", - "type": "t_uint256" - } - ] - }, - "t_string_storage": { - "label": "string" - }, - "t_address": { - "label": "address" - }, - "t_bool": { - "label": "bool" - }, - "t_mapping(t_bytes_memory_ptr,t_struct(Validator)631_storage)": { - "label": "mapping(bytes => struct SSVRegistry.Validator)" - }, - "t_struct(Validator)631_storage": { - "label": "struct SSVRegistry.Validator", - "members": [ - { - "label": "ownerAddress", - "type": "t_address" - }, - { - "label": "publicKey", - "type": "t_bytes_storage" - }, - { - "label": "oess", - "type": "t_array(t_struct(Oess)303_storage)dyn_storage" - }, - { - "label": "active", - "type": "t_bool" - }, - { - "label": "index", - "type": "t_uint256" - } - ] - }, - "t_array(t_struct(Oess)303_storage)dyn_storage": { - "label": "struct ISSVRegistry.Oess[]" - }, - "t_struct(Oess)303_storage": { - "label": "struct ISSVRegistry.Oess", - "members": [ - { - "label": "operatorPublicKey", - "type": "t_bytes_storage" - }, - { - "label": "sharedPublicKey", - "type": "t_bytes_storage" - }, - { - "label": "encryptedKey", - "type": "t_bytes_storage" - } - ] - }, - "t_mapping(t_bytes_memory_ptr,t_array(t_struct(OperatorFee)636_storage)dyn_storage)": { - "label": "mapping(bytes => struct SSVRegistry.OperatorFee[])" - }, - "t_array(t_struct(OperatorFee)636_storage)dyn_storage": { - "label": "struct SSVRegistry.OperatorFee[]" - }, - "t_struct(OperatorFee)636_storage": { - "label": "struct SSVRegistry.OperatorFee", - "members": [ - { - "label": "blockNumber", - "type": "t_uint256" - }, - { - "label": "fee", - "type": "t_uint256" - } - ] - }, - "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)": { - "label": "mapping(address => bytes[])" - }, - "t_array(t_bytes_storage)dyn_storage": { - "label": "bytes[]" - }, - "t_array(t_uint256)49_storage": { - "label": "uint256[49]" - }, - "t_array(t_uint256)50_storage": { - "label": "uint256[50]" - } - } - } - }, - "7d122f8d61e975ee287c7c64f459a3a18e9034383dc50617c78817ad7e7b0530": { - "address": "0xd5bCe052dA9A2c7a6EE0B8499626843f4e13bEA7", - "txHash": "0x6d51f5a23fb8217845ab879a2c3755565278369bfbe984c6f0363d184aa6e857", - "layout": { - "storage": [ - { - "contract": "Initializable", - "label": "_initialized", - "type": "t_bool", - "src": "@openzeppelin/contracts/proxy/utils/Initializable.sol:23" - }, - { - "contract": "Initializable", - "label": "_initializing", - "type": "t_bool", - "src": "@openzeppelin/contracts/proxy/utils/Initializable.sol:28" - }, - { - "contract": "ContextUpgradeable", - "label": "__gap", - "type": "t_array(t_uint256)50_storage", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" - }, - { - "contract": "OwnableUpgradeable", - "label": "_owner", - "type": "t_address", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:20" - }, - { - "contract": "OwnableUpgradeable", - "label": "__gap", - "type": "t_array(t_uint256)49_storage", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:74" - }, - { - "contract": "SSVNetwork", - "label": "_ssvRegistryContract", - "type": "t_contract(ISSVRegistry)2734", - "src": "contracts/SSVNetwork.sol:38" - }, - { - "contract": "SSVNetwork", - "label": "_token", - "type": "t_contract(IERC20)962", - "src": "contracts/SSVNetwork.sol:39" - }, - { - "contract": "SSVNetwork", - "label": "_minimumBlocksBeforeLiquidation", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:40" - }, - { - "contract": "SSVNetwork", - "label": "_operatorMaxFeeIncrease", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:41" - }, - { - "contract": "SSVNetwork", - "label": "_networkFee", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:43" - }, - { - "contract": "SSVNetwork", - "label": "_networkFeeIndex", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:44" - }, - { - "contract": "SSVNetwork", - "label": "_networkFeeIndexBlockNumber", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:45" - }, - { - "contract": "SSVNetwork", - "label": "_lastUpdateNetworkFeeRun", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:46" - }, - { - "contract": "SSVNetwork", - "label": "_networkEarnings", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:47" - }, - { - "contract": "SSVNetwork", - "label": "_networkEarningsBlockNumber", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:48" - }, - { - "contract": "SSVNetwork", - "label": "_withdrawnFromTreasury", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:49" - }, - { - "contract": "SSVNetwork", - "label": "_operatorDatas", - "type": "t_mapping(t_bytes_memory_ptr,t_struct(OperatorData)2758_storage)", - "src": "contracts/SSVNetwork.sol:51" - }, - { - "contract": "SSVNetwork", - "label": "_owners", - "type": "t_mapping(t_address,t_struct(OwnerData)2773_storage)", - "src": "contracts/SSVNetwork.sol:52" - }, - { - "contract": "SSVNetwork", - "label": "_operatorsInUseByAddress", - "type": "t_mapping(t_address,t_mapping(t_bytes_memory_ptr,t_struct(OperatorInUse)2784_storage))", - "src": "contracts/SSVNetwork.sol:53" - }, - { - "contract": "SSVNetwork", - "label": "_operatorsInUseList", - "type": "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)", - "src": "contracts/SSVNetwork.sol:54" - }, - { - "contract": "SSVNetwork", - "label": "_lastOperatorUpdateNetworkFeeRun", - "type": "t_mapping(t_bytes_memory_ptr,t_uint256)", - "src": "contracts/SSVNetwork.sol:55" - } - ], - "types": { - "t_contract(ISSVRegistry)2734": { - "label": "contract ISSVRegistry" - }, - "t_contract(IERC20)962": { - "label": "contract IERC20" - }, - "t_uint256": { - "label": "uint256" - }, - "t_mapping(t_bytes_memory_ptr,t_struct(OperatorData)2758_storage)": { - "label": "mapping(bytes => struct SSVNetwork.OperatorData)" - }, - "t_bytes_storage": { - "label": "bytes" - }, - "t_struct(OperatorData)2758_storage": { - "label": "struct SSVNetwork.OperatorData", - "members": [ - { - "label": "blockNumber", - "type": "t_uint256" - }, - { - "label": "validatorCount", - "type": "t_uint256" - }, - { - "label": "earnings", - "type": "t_uint256" - }, - { - "label": "index", - "type": "t_uint256" - }, - { - "label": "indexBlockNumber", - "type": "t_uint256" - }, - { - "label": "lastFeeUpdate", - "type": "t_uint256" - } - ] - }, - "t_mapping(t_address,t_struct(OwnerData)2773_storage)": { - "label": "mapping(address => struct SSVNetwork.OwnerData)" - }, - "t_address": { - "label": "address" - }, - "t_struct(OwnerData)2773_storage": { - "label": "struct SSVNetwork.OwnerData", - "members": [ - { - "label": "deposited", - "type": "t_uint256" - }, - { - "label": "withdrawn", - "type": "t_uint256" - }, - { - "label": "earned", - "type": "t_uint256" - }, - { - "label": "used", - "type": "t_uint256" - }, - { - "label": "networkFee", - "type": "t_uint256" - }, - { - "label": "networkFeeIndex", - "type": "t_uint256" - }, - { - "label": "activeValidatorsCount", - "type": "t_uint256" - } - ] - }, - "t_mapping(t_address,t_mapping(t_bytes_memory_ptr,t_struct(OperatorInUse)2784_storage))": { - "label": "mapping(address => mapping(bytes => struct SSVNetwork.OperatorInUse))" - }, - "t_mapping(t_bytes_memory_ptr,t_struct(OperatorInUse)2784_storage)": { - "label": "mapping(bytes => struct SSVNetwork.OperatorInUse)" - }, - "t_struct(OperatorInUse)2784_storage": { - "label": "struct SSVNetwork.OperatorInUse", - "members": [ - { - "label": "index", - "type": "t_uint256" - }, - { - "label": "validatorCount", - "type": "t_uint256" - }, - { - "label": "used", - "type": "t_uint256" - }, - { - "label": "exists", - "type": "t_bool" - }, - { - "label": "indexInArray", - "type": "t_uint256" - } - ] - }, - "t_bool": { - "label": "bool" - }, - "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)": { - "label": "mapping(address => bytes[])" - }, - "t_array(t_bytes_storage)dyn_storage": { - "label": "bytes[]" - }, - "t_mapping(t_bytes_memory_ptr,t_uint256)": { - "label": "mapping(bytes => uint256)" - }, - "t_array(t_uint256)49_storage": { - "label": "uint256[49]" - }, - "t_array(t_uint256)50_storage": { - "label": "uint256[50]" - } - } - } - }, - "ed45d99b66f5161b8364308273bd0abe58ba080ccf2a3eb9c8ea512caafd3ea5": { - "address": "0xd64b457ddaaDB52e7Af08452ddd36d1c72b9f86b", - "txHash": "0xf8590d5068ee3988d9c435b8305821136fec5f23b9f6d42b2cbb69be9911198c", - "layout": { - "storage": [ - { - "contract": "Initializable", - "label": "_initialized", - "type": "t_bool", - "src": "@openzeppelin/contracts/proxy/utils/Initializable.sol:23" - }, - { - "contract": "Initializable", - "label": "_initializing", - "type": "t_bool", - "src": "@openzeppelin/contracts/proxy/utils/Initializable.sol:28" - }, - { - "contract": "ContextUpgradeable", - "label": "__gap", - "type": "t_array(t_uint256)50_storage", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" - }, - { - "contract": "OwnableUpgradeable", - "label": "_owner", - "type": "t_address", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:20" - }, - { - "contract": "OwnableUpgradeable", - "label": "__gap", - "type": "t_array(t_uint256)49_storage", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:74" - }, - { - "contract": "SSVNetwork", - "label": "_ssvRegistryContract", - "type": "t_contract(ISSVRegistry)2752", - "src": "contracts/SSVNetwork.sol:38" - }, - { - "contract": "SSVNetwork", - "label": "_token", - "type": "t_contract(IERC20)962", - "src": "contracts/SSVNetwork.sol:39" - }, - { - "contract": "SSVNetwork", - "label": "_minimumBlocksBeforeLiquidation", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:40" - }, - { - "contract": "SSVNetwork", - "label": "_operatorMaxFeeIncrease", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:41" - }, - { - "contract": "SSVNetwork", - "label": "_networkFee", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:43" - }, - { - "contract": "SSVNetwork", - "label": "_networkFeeIndex", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:44" - }, - { - "contract": "SSVNetwork", - "label": "_networkFeeIndexBlockNumber", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:45" - }, - { - "contract": "SSVNetwork", - "label": "_lastUpdateNetworkFeeRun", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:46" - }, - { - "contract": "SSVNetwork", - "label": "_networkEarnings", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:47" - }, - { - "contract": "SSVNetwork", - "label": "_networkEarningsBlockNumber", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:48" - }, - { - "contract": "SSVNetwork", - "label": "_withdrawnFromTreasury", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:49" - }, - { - "contract": "SSVNetwork", - "label": "_operatorDatas", - "type": "t_mapping(t_bytes_memory_ptr,t_struct(OperatorData)2776_storage)", - "src": "contracts/SSVNetwork.sol:51" - }, - { - "contract": "SSVNetwork", - "label": "_owners", - "type": "t_mapping(t_address,t_struct(OwnerData)2791_storage)", - "src": "contracts/SSVNetwork.sol:52" - }, - { - "contract": "SSVNetwork", - "label": "_operatorsInUseByAddress", - "type": "t_mapping(t_address,t_mapping(t_bytes_memory_ptr,t_struct(OperatorInUse)2802_storage))", - "src": "contracts/SSVNetwork.sol:53" - }, - { - "contract": "SSVNetwork", - "label": "_operatorsInUseList", - "type": "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)", - "src": "contracts/SSVNetwork.sol:54" - }, - { - "contract": "SSVNetwork", - "label": "_lastOperatorUpdateNetworkFeeRun", - "type": "t_mapping(t_bytes_memory_ptr,t_uint256)", - "src": "contracts/SSVNetwork.sol:55" - } - ], - "types": { - "t_contract(ISSVRegistry)2752": { - "label": "contract ISSVRegistry" - }, - "t_contract(IERC20)962": { - "label": "contract IERC20" - }, - "t_uint256": { - "label": "uint256" - }, - "t_mapping(t_bytes_memory_ptr,t_struct(OperatorData)2776_storage)": { - "label": "mapping(bytes => struct SSVNetwork.OperatorData)" - }, - "t_bytes_storage": { - "label": "bytes" - }, - "t_struct(OperatorData)2776_storage": { - "label": "struct SSVNetwork.OperatorData", - "members": [ - { - "label": "blockNumber", - "type": "t_uint256" - }, - { - "label": "validatorCount", - "type": "t_uint256" - }, - { - "label": "earnings", - "type": "t_uint256" - }, - { - "label": "index", - "type": "t_uint256" - }, - { - "label": "indexBlockNumber", - "type": "t_uint256" - }, - { - "label": "lastFeeUpdate", - "type": "t_uint256" - } - ] - }, - "t_mapping(t_address,t_struct(OwnerData)2791_storage)": { - "label": "mapping(address => struct SSVNetwork.OwnerData)" - }, - "t_address": { - "label": "address" - }, - "t_struct(OwnerData)2791_storage": { - "label": "struct SSVNetwork.OwnerData", - "members": [ - { - "label": "deposited", - "type": "t_uint256" - }, - { - "label": "withdrawn", - "type": "t_uint256" - }, - { - "label": "earned", - "type": "t_uint256" - }, - { - "label": "used", - "type": "t_uint256" - }, - { - "label": "networkFee", - "type": "t_uint256" - }, - { - "label": "networkFeeIndex", - "type": "t_uint256" - }, - { - "label": "activeValidatorsCount", - "type": "t_uint256" - } - ] - }, - "t_mapping(t_address,t_mapping(t_bytes_memory_ptr,t_struct(OperatorInUse)2802_storage))": { - "label": "mapping(address => mapping(bytes => struct SSVNetwork.OperatorInUse))" - }, - "t_mapping(t_bytes_memory_ptr,t_struct(OperatorInUse)2802_storage)": { - "label": "mapping(bytes => struct SSVNetwork.OperatorInUse)" - }, - "t_struct(OperatorInUse)2802_storage": { - "label": "struct SSVNetwork.OperatorInUse", - "members": [ - { - "label": "index", - "type": "t_uint256" - }, - { - "label": "validatorCount", - "type": "t_uint256" - }, - { - "label": "used", - "type": "t_uint256" - }, - { - "label": "exists", - "type": "t_bool" - }, - { - "label": "indexInArray", - "type": "t_uint256" - } - ] - }, - "t_bool": { - "label": "bool" - }, - "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)": { - "label": "mapping(address => bytes[])" - }, - "t_array(t_bytes_storage)dyn_storage": { - "label": "bytes[]" - }, - "t_mapping(t_bytes_memory_ptr,t_uint256)": { - "label": "mapping(bytes => uint256)" - }, - "t_array(t_uint256)49_storage": { - "label": "uint256[49]" - }, - "t_array(t_uint256)50_storage": { - "label": "uint256[50]" - } - } - } - }, - "2afaadc5b4e0290f800288c871dab625759e761ea3a93793efd53aed73ccccff": { - "address": "0xAcfBDE0C026CBC1c941CdcfCB24Fa9c73D77DDB9", - "txHash": "0xc96b6419ed4a2277f656acb52cd167f60a907f25983cc46d95014331ba91fe59", - "layout": { - "storage": [ - { - "contract": "Initializable", - "label": "_initialized", - "type": "t_bool", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:23" - }, - { - "contract": "Initializable", - "label": "_initializing", - "type": "t_bool", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:28" - }, - { - "contract": "ContextUpgradeable", - "label": "__gap", - "type": "t_array(t_uint256)50_storage", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" - }, - { - "contract": "OwnableUpgradeable", - "label": "_owner", - "type": "t_address", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:20" - }, - { - "contract": "OwnableUpgradeable", - "label": "__gap", - "type": "t_array(t_uint256)49_storage", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:74" - }, - { - "contract": "SSVNetwork", - "label": "_ssvRegistryContract", - "type": "t_contract(ISSVRegistry)993", - "src": "contracts/SSVNetwork.sol:38" - }, - { - "contract": "SSVNetwork", - "label": "_token", - "type": "t_contract(IERC20)299", - "src": "contracts/SSVNetwork.sol:39" - }, - { - "contract": "SSVNetwork", - "label": "_minimumBlocksBeforeLiquidation", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:40" - }, - { - "contract": "SSVNetwork", - "label": "_operatorMaxFeeIncrease", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:41" - }, - { - "contract": "SSVNetwork", - "label": "_networkFee", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:43" - }, - { - "contract": "SSVNetwork", - "label": "_networkFeeIndex", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:44" - }, - { - "contract": "SSVNetwork", - "label": "_networkFeeIndexBlockNumber", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:45" - }, - { - "contract": "SSVNetwork", - "label": "_lastUpdateNetworkFeeRun", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:46" - }, - { - "contract": "SSVNetwork", - "label": "_networkEarnings", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:47" - }, - { - "contract": "SSVNetwork", - "label": "_networkEarningsBlockNumber", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:48" - }, - { - "contract": "SSVNetwork", - "label": "_withdrawnFromTreasury", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:49" - }, - { - "contract": "SSVNetwork", - "label": "_operatorDatas", - "type": "t_mapping(t_bytes_memory_ptr,t_struct(OperatorData)1017_storage)", - "src": "contracts/SSVNetwork.sol:51" - }, - { - "contract": "SSVNetwork", - "label": "_owners", - "type": "t_mapping(t_address,t_struct(OwnerData)1032_storage)", - "src": "contracts/SSVNetwork.sol:52" - }, - { - "contract": "SSVNetwork", - "label": "_operatorsInUseByAddress", - "type": "t_mapping(t_address,t_mapping(t_bytes_memory_ptr,t_struct(OperatorInUse)1043_storage))", - "src": "contracts/SSVNetwork.sol:53" - }, - { - "contract": "SSVNetwork", - "label": "_operatorsInUseList", - "type": "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)", - "src": "contracts/SSVNetwork.sol:54" - }, - { - "contract": "SSVNetwork", - "label": "_lastOperatorUpdateNetworkFeeRun", - "type": "t_mapping(t_bytes_memory_ptr,t_uint256)", - "src": "contracts/SSVNetwork.sol:55" - } - ], - "types": { - "t_contract(ISSVRegistry)993": { - "label": "contract ISSVRegistry" - }, - "t_contract(IERC20)299": { - "label": "contract IERC20" - }, - "t_uint256": { - "label": "uint256" - }, - "t_mapping(t_bytes_memory_ptr,t_struct(OperatorData)1017_storage)": { - "label": "mapping(bytes => struct SSVNetwork.OperatorData)" - }, - "t_bytes_storage": { - "label": "bytes" - }, - "t_struct(OperatorData)1017_storage": { - "label": "struct SSVNetwork.OperatorData", - "members": [ - { - "label": "blockNumber", - "type": "t_uint256" - }, - { - "label": "validatorCount", - "type": "t_uint256" - }, - { - "label": "earnings", - "type": "t_uint256" - }, - { - "label": "index", - "type": "t_uint256" - }, - { - "label": "indexBlockNumber", - "type": "t_uint256" - }, - { - "label": "lastFeeUpdate", - "type": "t_uint256" - } - ] - }, - "t_mapping(t_address,t_struct(OwnerData)1032_storage)": { - "label": "mapping(address => struct SSVNetwork.OwnerData)" - }, - "t_address": { - "label": "address" - }, - "t_struct(OwnerData)1032_storage": { - "label": "struct SSVNetwork.OwnerData", - "members": [ - { - "label": "deposited", - "type": "t_uint256" - }, - { - "label": "withdrawn", - "type": "t_uint256" - }, - { - "label": "earned", - "type": "t_uint256" - }, - { - "label": "used", - "type": "t_uint256" - }, - { - "label": "networkFee", - "type": "t_uint256" - }, - { - "label": "networkFeeIndex", - "type": "t_uint256" - }, - { - "label": "activeValidatorsCount", - "type": "t_uint256" - } - ] - }, - "t_mapping(t_address,t_mapping(t_bytes_memory_ptr,t_struct(OperatorInUse)1043_storage))": { - "label": "mapping(address => mapping(bytes => struct SSVNetwork.OperatorInUse))" - }, - "t_mapping(t_bytes_memory_ptr,t_struct(OperatorInUse)1043_storage)": { - "label": "mapping(bytes => struct SSVNetwork.OperatorInUse)" - }, - "t_struct(OperatorInUse)1043_storage": { - "label": "struct SSVNetwork.OperatorInUse", - "members": [ - { - "label": "index", - "type": "t_uint256" - }, - { - "label": "validatorCount", - "type": "t_uint256" - }, - { - "label": "used", - "type": "t_uint256" - }, - { - "label": "exists", - "type": "t_bool" - }, - { - "label": "indexInArray", - "type": "t_uint256" - } - ] - }, - "t_bool": { - "label": "bool" - }, - "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)": { - "label": "mapping(address => bytes[])" - }, - "t_array(t_bytes_storage)dyn_storage": { - "label": "bytes[]" - }, - "t_mapping(t_bytes_memory_ptr,t_uint256)": { - "label": "mapping(bytes => uint256)" - }, - "t_array(t_uint256)49_storage": { - "label": "uint256[49]" - }, - "t_array(t_uint256)50_storage": { - "label": "uint256[50]" - } - } - } - }, - "8e51fa7a56aed55e79d7cf894ed22c545ad08ac930536388b1da871be61ea6b1": { - "address": "0xa815B78a7eb572e1ADAa4c9AFd2FCF9A3BB1c439", - "txHash": "0x7bd8bfb4d14055bc935e4af6ba477bc35552c605099496e508171c768ee9e820", - "layout": { - "storage": [ - { - "contract": "Initializable", - "label": "_initialized", - "type": "t_bool", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:23" - }, - { - "contract": "Initializable", - "label": "_initializing", - "type": "t_bool", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:28" - }, - { - "contract": "ContextUpgradeable", - "label": "__gap", - "type": "t_array(t_uint256)50_storage", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" - }, - { - "contract": "OwnableUpgradeable", - "label": "_owner", - "type": "t_address", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:20" - }, - { - "contract": "OwnableUpgradeable", - "label": "__gap", - "type": "t_array(t_uint256)49_storage", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:74" - }, - { - "contract": "SSVNetwork", - "label": "_ssvRegistryContract", - "type": "t_contract(ISSVRegistry)1002", - "src": "contracts/SSVNetwork.sol:38" - }, - { - "contract": "SSVNetwork", - "label": "_token", - "type": "t_contract(IERC20)299", - "src": "contracts/SSVNetwork.sol:39" - }, - { - "contract": "SSVNetwork", - "label": "_minimumBlocksBeforeLiquidation", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:40" - }, - { - "contract": "SSVNetwork", - "label": "_operatorMaxFeeIncrease", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:41" - }, - { - "contract": "SSVNetwork", - "label": "_networkFee", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:43" - }, - { - "contract": "SSVNetwork", - "label": "_networkFeeIndex", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:44" - }, - { - "contract": "SSVNetwork", - "label": "_networkFeeIndexBlockNumber", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:45" - }, - { - "contract": "SSVNetwork", - "label": "_lastUpdateNetworkFeeRun", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:46" - }, - { - "contract": "SSVNetwork", - "label": "_networkEarnings", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:47" - }, - { - "contract": "SSVNetwork", - "label": "_networkEarningsBlockNumber", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:48" - }, - { - "contract": "SSVNetwork", - "label": "_withdrawnFromTreasury", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:49" - }, - { - "contract": "SSVNetwork", - "label": "_operatorDatas", - "type": "t_mapping(t_bytes_memory_ptr,t_struct(OperatorData)1026_storage)", - "src": "contracts/SSVNetwork.sol:51" - }, - { - "contract": "SSVNetwork", - "label": "_owners", - "type": "t_mapping(t_address,t_struct(OwnerData)1041_storage)", - "src": "contracts/SSVNetwork.sol:52" - }, - { - "contract": "SSVNetwork", - "label": "_operatorsInUseByAddress", - "type": "t_mapping(t_address,t_mapping(t_bytes_memory_ptr,t_struct(OperatorInUse)1052_storage))", - "src": "contracts/SSVNetwork.sol:53" - }, - { - "contract": "SSVNetwork", - "label": "_operatorsInUseList", - "type": "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)", - "src": "contracts/SSVNetwork.sol:54" - }, - { - "contract": "SSVNetwork", - "label": "_lastOperatorUpdateNetworkFeeRun", - "type": "t_mapping(t_bytes_memory_ptr,t_uint256)", - "src": "contracts/SSVNetwork.sol:55" - } - ], - "types": { - "t_contract(ISSVRegistry)1002": { - "label": "contract ISSVRegistry" - }, - "t_contract(IERC20)299": { - "label": "contract IERC20" - }, - "t_uint256": { - "label": "uint256" - }, - "t_mapping(t_bytes_memory_ptr,t_struct(OperatorData)1026_storage)": { - "label": "mapping(bytes => struct SSVNetwork.OperatorData)" - }, - "t_bytes_storage": { - "label": "bytes" - }, - "t_struct(OperatorData)1026_storage": { - "label": "struct SSVNetwork.OperatorData", - "members": [ - { - "label": "blockNumber", - "type": "t_uint256" - }, - { - "label": "validatorCount", - "type": "t_uint256" - }, - { - "label": "earnings", - "type": "t_uint256" - }, - { - "label": "index", - "type": "t_uint256" - }, - { - "label": "indexBlockNumber", - "type": "t_uint256" - }, - { - "label": "lastFeeUpdate", - "type": "t_uint256" - } - ] - }, - "t_mapping(t_address,t_struct(OwnerData)1041_storage)": { - "label": "mapping(address => struct SSVNetwork.OwnerData)" - }, - "t_address": { - "label": "address" - }, - "t_struct(OwnerData)1041_storage": { - "label": "struct SSVNetwork.OwnerData", - "members": [ - { - "label": "deposited", - "type": "t_uint256" - }, - { - "label": "withdrawn", - "type": "t_uint256" - }, - { - "label": "earned", - "type": "t_uint256" - }, - { - "label": "used", - "type": "t_uint256" - }, - { - "label": "networkFee", - "type": "t_uint256" - }, - { - "label": "networkFeeIndex", - "type": "t_uint256" - }, - { - "label": "activeValidatorsCount", - "type": "t_uint256" - } - ] - }, - "t_mapping(t_address,t_mapping(t_bytes_memory_ptr,t_struct(OperatorInUse)1052_storage))": { - "label": "mapping(address => mapping(bytes => struct SSVNetwork.OperatorInUse))" - }, - "t_mapping(t_bytes_memory_ptr,t_struct(OperatorInUse)1052_storage)": { - "label": "mapping(bytes => struct SSVNetwork.OperatorInUse)" - }, - "t_struct(OperatorInUse)1052_storage": { - "label": "struct SSVNetwork.OperatorInUse", - "members": [ - { - "label": "index", - "type": "t_uint256" - }, - { - "label": "validatorCount", - "type": "t_uint256" - }, - { - "label": "used", - "type": "t_uint256" - }, - { - "label": "exists", - "type": "t_bool" - }, - { - "label": "indexInArray", - "type": "t_uint256" - } - ] - }, - "t_bool": { - "label": "bool" - }, - "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)": { - "label": "mapping(address => bytes[])" - }, - "t_array(t_bytes_storage)dyn_storage": { - "label": "bytes[]" - }, - "t_mapping(t_bytes_memory_ptr,t_uint256)": { - "label": "mapping(bytes => uint256)" - }, - "t_array(t_uint256)49_storage": { - "label": "uint256[49]" - }, - "t_array(t_uint256)50_storage": { - "label": "uint256[50]" - } - } - } - }, - "f66337b2c14955b2001a36175d40bb64cd2d94582ad15c67473cb56386a60819": { - "address": "0x66fea9A226A5076f77dD4663CEE7Bde6D581609B", - "txHash": "0x400b65333bcfa24b9f020996ba6d48c9ae4e36bdba06ecba58bdb3e55aef2979", - "layout": { - "storage": [ - { - "contract": "Initializable", - "label": "_initialized", - "type": "t_bool", - "src": "@openzeppelin/contracts/proxy/utils/Initializable.sol:23" - }, - { - "contract": "Initializable", - "label": "_initializing", - "type": "t_bool", - "src": "@openzeppelin/contracts/proxy/utils/Initializable.sol:28" - }, - { - "contract": "ContextUpgradeable", - "label": "__gap", - "type": "t_array(t_uint256)50_storage", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" - }, - { - "contract": "OwnableUpgradeable", - "label": "_owner", - "type": "t_address", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:20" - }, - { - "contract": "OwnableUpgradeable", - "label": "__gap", - "type": "t_array(t_uint256)49_storage", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:74" - }, - { - "contract": "SSVRegistry", - "label": "_operatorCount", - "type": "t_uint256", - "src": "contracts/SSVRegistry.sol:37" - }, - { - "contract": "SSVRegistry", - "label": "_validatorCount", - "type": "t_uint256", - "src": "contracts/SSVRegistry.sol:38" - }, - { - "contract": "SSVRegistry", - "label": "_activeValidatorCount", - "type": "t_uint256", - "src": "contracts/SSVRegistry.sol:39" - }, - { - "contract": "SSVRegistry", - "label": "_operators", - "type": "t_mapping(t_bytes_memory_ptr,t_struct(Operator)5714_storage)", - "src": "contracts/SSVRegistry.sol:41" - }, - { - "contract": "SSVRegistry", - "label": "_validators", - "type": "t_mapping(t_bytes_memory_ptr,t_struct(Validator)5727_storage)", - "src": "contracts/SSVRegistry.sol:42" - }, - { - "contract": "SSVRegistry", - "label": "_operatorFees", - "type": "t_mapping(t_bytes_memory_ptr,t_array(t_struct(OperatorFee)5732_storage)dyn_storage)", - "src": "contracts/SSVRegistry.sol:44" - }, - { - "contract": "SSVRegistry", - "label": "_operatorsByOwnerAddress", - "type": "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)", - "src": "contracts/SSVRegistry.sol:46" - }, - { - "contract": "SSVRegistry", - "label": "_validatorsByAddress", - "type": "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)", - "src": "contracts/SSVRegistry.sol:47" - }, - { - "contract": "SSVRegistry", - "label": "_owners", - "type": "t_mapping(t_address,t_struct(OwnerData)5737_storage)", - "src": "contracts/SSVRegistry.sol:48" - } - ], - "types": { - "t_uint256": { - "label": "uint256" - }, - "t_mapping(t_bytes_memory_ptr,t_struct(Operator)5714_storage)": { - "label": "mapping(bytes => struct SSVRegistry.Operator)" - }, - "t_bytes_storage": { - "label": "bytes" - }, - "t_struct(Operator)5714_storage": { - "label": "struct SSVRegistry.Operator", - "members": [ - { - "label": "name", - "type": "t_string_storage" - }, - { - "label": "ownerAddress", - "type": "t_address" - }, - { - "label": "publicKey", - "type": "t_bytes_storage" - }, - { - "label": "score", - "type": "t_uint256" - }, - { - "label": "active", - "type": "t_bool" - }, - { - "label": "index", - "type": "t_uint256" - } - ] - }, - "t_string_storage": { - "label": "string" - }, - "t_address": { - "label": "address" - }, - "t_bool": { - "label": "bool" - }, - "t_mapping(t_bytes_memory_ptr,t_struct(Validator)5727_storage)": { - "label": "mapping(bytes => struct SSVRegistry.Validator)" - }, - "t_struct(Validator)5727_storage": { - "label": "struct SSVRegistry.Validator", - "members": [ - { - "label": "ownerAddress", - "type": "t_address" - }, - { - "label": "publicKey", - "type": "t_bytes_storage" - }, - { - "label": "oess", - "type": "t_array(t_struct(Oess)2605_storage)dyn_storage" - }, - { - "label": "active", - "type": "t_bool" - }, - { - "label": "index", - "type": "t_uint256" - } - ] - }, - "t_array(t_struct(Oess)2605_storage)dyn_storage": { - "label": "struct ISSVRegistry.Oess[]" - }, - "t_struct(Oess)2605_storage": { - "label": "struct ISSVRegistry.Oess", - "members": [ - { - "label": "operatorPublicKey", - "type": "t_bytes_storage" - }, - { - "label": "sharedPublicKey", - "type": "t_bytes_storage" - }, - { - "label": "encryptedKey", - "type": "t_bytes_storage" - } - ] - }, - "t_mapping(t_bytes_memory_ptr,t_array(t_struct(OperatorFee)5732_storage)dyn_storage)": { - "label": "mapping(bytes => struct SSVRegistry.OperatorFee[])" - }, - "t_array(t_struct(OperatorFee)5732_storage)dyn_storage": { - "label": "struct SSVRegistry.OperatorFee[]" - }, - "t_struct(OperatorFee)5732_storage": { - "label": "struct SSVRegistry.OperatorFee", - "members": [ - { - "label": "blockNumber", - "type": "t_uint256" - }, - { - "label": "fee", - "type": "t_uint256" - } - ] - }, - "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)": { - "label": "mapping(address => bytes[])" - }, - "t_array(t_bytes_storage)dyn_storage": { - "label": "bytes[]" - }, - "t_mapping(t_address,t_struct(OwnerData)5737_storage)": { - "label": "mapping(address => struct SSVRegistry.OwnerData)" - }, - "t_struct(OwnerData)5737_storage": { - "label": "struct SSVRegistry.OwnerData", - "members": [ - { - "label": "activeValidatorCount", - "type": "t_uint256" - }, - { - "label": "validatorsDisabled", - "type": "t_bool" - } - ] - }, - "t_array(t_uint256)49_storage": { - "label": "uint256[49]" - }, - "t_array(t_uint256)50_storage": { - "label": "uint256[50]" - } - } - } - }, - "f3ca074e211bfab6f27b634a56e2a4eb7d7ac368910af7d266465034477a2410": { - "address": "0x97bECf9Dc48405c6F5C0CAbD300cB08E0D25cFF1", - "txHash": "0x1d05364076721622a163e361183274fbc766abbf09ed60f4905a67fe71f9e49e", - "layout": { - "storage": [ - { - "contract": "Initializable", - "label": "_initialized", - "type": "t_bool", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:23" - }, - { - "contract": "Initializable", - "label": "_initializing", - "type": "t_bool", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:28" - }, - { - "contract": "ContextUpgradeable", - "label": "__gap", - "type": "t_array(t_uint256)50_storage", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" - }, - { - "contract": "OwnableUpgradeable", - "label": "_owner", - "type": "t_address", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:20" - }, - { - "contract": "OwnableUpgradeable", - "label": "__gap", - "type": "t_array(t_uint256)49_storage", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:74" - }, - { - "contract": "SSVNetwork", - "label": "_ssvRegistryContract", - "type": "t_contract(ISSVRegistry)1070", - "src": "contracts/SSVNetwork.sol:39" - }, - { - "contract": "SSVNetwork", - "label": "_token", - "type": "t_contract(IERC20)299", - "src": "contracts/SSVNetwork.sol:40" - }, - { - "contract": "SSVNetwork", - "label": "_minimumBlocksBeforeLiquidation", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:41" - }, - { - "contract": "SSVNetwork", - "label": "_operatorMaxFeeIncrease", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:42" - }, - { - "contract": "SSVNetwork", - "label": "_networkFee", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:44" - }, - { - "contract": "SSVNetwork", - "label": "_networkFeeIndex", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:45" - }, - { - "contract": "SSVNetwork", - "label": "_networkFeeIndexBlockNumber", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:46" - }, - { - "contract": "SSVNetwork", - "label": "_networkEarnings", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:47" - }, - { - "contract": "SSVNetwork", - "label": "_networkEarningsBlockNumber", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:48" - }, - { - "contract": "SSVNetwork", - "label": "_withdrawnFromTreasury", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:49" - }, - { - "contract": "SSVNetwork", - "label": "_operatorDatas", - "type": "t_mapping(t_bytes_memory_ptr,t_struct(OperatorData)1094_storage)", - "src": "contracts/SSVNetwork.sol:51" - }, - { - "contract": "SSVNetwork", - "label": "_owners", - "type": "t_mapping(t_address,t_struct(OwnerData)1111_storage)", - "src": "contracts/SSVNetwork.sol:52" - }, - { - "contract": "SSVNetwork", - "label": "_operatorsInUseByAddress", - "type": "t_mapping(t_address,t_mapping(t_bytes_memory_ptr,t_struct(OperatorInUse)1122_storage))", - "src": "contracts/SSVNetwork.sol:53" - }, - { - "contract": "SSVNetwork", - "label": "_operatorsInUseList", - "type": "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)", - "src": "contracts/SSVNetwork.sol:54" - }, - { - "contract": "SSVNetwork", - "label": "_lastOperatorUpdateNetworkFeeRun", - "type": "t_mapping(t_bytes_memory_ptr,t_uint256)", - "src": "contracts/SSVNetwork.sol:55" - } - ], - "types": { - "t_contract(ISSVRegistry)1070": { - "label": "contract ISSVRegistry" - }, - "t_contract(IERC20)299": { - "label": "contract IERC20" - }, - "t_uint256": { - "label": "uint256" - }, - "t_mapping(t_bytes_memory_ptr,t_struct(OperatorData)1094_storage)": { - "label": "mapping(bytes => struct SSVNetwork.OperatorData)" - }, - "t_bytes_storage": { - "label": "bytes" - }, - "t_struct(OperatorData)1094_storage": { - "label": "struct SSVNetwork.OperatorData", - "members": [ - { - "label": "blockNumber", - "type": "t_uint256" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256" - }, - { - "label": "earnings", - "type": "t_uint256" - }, - { - "label": "index", - "type": "t_uint256" - }, - { - "label": "indexBlockNumber", - "type": "t_uint256" - }, - { - "label": "lastFeeUpdate", - "type": "t_uint256" - } - ] - }, - "t_mapping(t_address,t_struct(OwnerData)1111_storage)": { - "label": "mapping(address => struct SSVNetwork.OwnerData)" - }, - "t_address": { - "label": "address" - }, - "t_struct(OwnerData)1111_storage": { - "label": "struct SSVNetwork.OwnerData", - "members": [ - { - "label": "deposited", - "type": "t_uint256" - }, - { - "label": "withdrawn", - "type": "t_uint256" - }, - { - "label": "earned", - "type": "t_uint256" - }, - { - "label": "used", - "type": "t_uint256" - }, - { - "label": "networkFee", - "type": "t_uint256" - }, - { - "label": "networkFeeIndex", - "type": "t_uint256" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256" - }, - { - "label": "validatorsDisabled", - "type": "t_bool" - } - ] - }, - "t_bool": { - "label": "bool" - }, - "t_mapping(t_address,t_mapping(t_bytes_memory_ptr,t_struct(OperatorInUse)1122_storage))": { - "label": "mapping(address => mapping(bytes => struct SSVNetwork.OperatorInUse))" - }, - "t_mapping(t_bytes_memory_ptr,t_struct(OperatorInUse)1122_storage)": { - "label": "mapping(bytes => struct SSVNetwork.OperatorInUse)" - }, - "t_struct(OperatorInUse)1122_storage": { - "label": "struct SSVNetwork.OperatorInUse", - "members": [ - { - "label": "index", - "type": "t_uint256" - }, - { - "label": "validatorCount", - "type": "t_uint256" - }, - { - "label": "used", - "type": "t_uint256" - }, - { - "label": "exists", - "type": "t_bool" - }, - { - "label": "indexInArray", - "type": "t_uint256" - } - ] - }, - "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)": { - "label": "mapping(address => bytes[])" - }, - "t_array(t_bytes_storage)dyn_storage": { - "label": "bytes[]" - }, - "t_mapping(t_bytes_memory_ptr,t_uint256)": { - "label": "mapping(bytes => uint256)" - }, - "t_array(t_uint256)49_storage": { - "label": "uint256[49]" - }, - "t_array(t_uint256)50_storage": { - "label": "uint256[50]" - } - } - } - }, - "63c2818eeeb6de1336874be44fb0e9d5ca81fe0c4dffa29cf5a13438b2fa0125": { - "address": "0x7e9B800984fa874e96c93406A0742A8cf8B1DF04", - "txHash": "0x2a13ecda3e6bf2127f0006be0184eada6ec9653c9ecb6f7e80922eb02a67bf03", - "layout": { - "storage": [ - { - "contract": "Initializable", - "label": "_initialized", - "type": "t_bool", - "src": "@openzeppelin/contracts/proxy/utils/Initializable.sol:23" - }, - { - "contract": "Initializable", - "label": "_initializing", - "type": "t_bool", - "src": "@openzeppelin/contracts/proxy/utils/Initializable.sol:28" - }, - { - "contract": "ContextUpgradeable", - "label": "__gap", - "type": "t_array(t_uint256)50_storage", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" - }, - { - "contract": "OwnableUpgradeable", - "label": "_owner", - "type": "t_address", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:20" - }, - { - "contract": "OwnableUpgradeable", - "label": "__gap", - "type": "t_array(t_uint256)49_storage", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:74" - }, - { - "contract": "SSVNetwork", - "label": "_ssvRegistryContract", - "type": "t_contract(ISSVRegistry)2927", - "src": "contracts/SSVNetwork.sol:39" - }, - { - "contract": "SSVNetwork", - "label": "_token", - "type": "t_contract(IERC20)962", - "src": "contracts/SSVNetwork.sol:40" - }, - { - "contract": "SSVNetwork", - "label": "_minimumBlocksBeforeLiquidation", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:41" - }, - { - "contract": "SSVNetwork", - "label": "_operatorMaxFeeIncrease", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:42" - }, - { - "contract": "SSVNetwork", - "label": "_networkFee", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:44" - }, - { - "contract": "SSVNetwork", - "label": "_networkFeeIndex", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:45" - }, - { - "contract": "SSVNetwork", - "label": "_networkFeeIndexBlockNumber", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:46" - }, - { - "contract": "SSVNetwork", - "label": "_networkEarnings", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:47" - }, - { - "contract": "SSVNetwork", - "label": "_networkEarningsBlockNumber", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:48" - }, - { - "contract": "SSVNetwork", - "label": "_withdrawnFromTreasury", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:49" - }, - { - "contract": "SSVNetwork", - "label": "_operatorDatas", - "type": "t_mapping(t_bytes_memory_ptr,t_struct(OperatorData)2951_storage)", - "src": "contracts/SSVNetwork.sol:51" - }, - { - "contract": "SSVNetwork", - "label": "_owners", - "type": "t_mapping(t_address,t_struct(OwnerData)2968_storage)", - "src": "contracts/SSVNetwork.sol:52" - }, - { - "contract": "SSVNetwork", - "label": "_operatorsInUseByAddress", - "type": "t_mapping(t_address,t_mapping(t_bytes_memory_ptr,t_struct(OperatorInUse)2979_storage))", - "src": "contracts/SSVNetwork.sol:53" - }, - { - "contract": "SSVNetwork", - "label": "_operatorsInUseList", - "type": "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)", - "src": "contracts/SSVNetwork.sol:54" - }, - { - "contract": "SSVNetwork", - "label": "_lastOperatorUpdateNetworkFeeRun", - "type": "t_mapping(t_bytes_memory_ptr,t_uint256)", - "src": "contracts/SSVNetwork.sol:55" - } - ], - "types": { - "t_contract(ISSVRegistry)2927": { - "label": "contract ISSVRegistry" - }, - "t_contract(IERC20)962": { - "label": "contract IERC20" - }, - "t_uint256": { - "label": "uint256" - }, - "t_mapping(t_bytes_memory_ptr,t_struct(OperatorData)2951_storage)": { - "label": "mapping(bytes => struct SSVNetwork.OperatorData)" - }, - "t_bytes_storage": { - "label": "bytes" - }, - "t_struct(OperatorData)2951_storage": { - "label": "struct SSVNetwork.OperatorData", - "members": [ - { - "label": "blockNumber", - "type": "t_uint256" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256" - }, - { - "label": "earnings", - "type": "t_uint256" - }, - { - "label": "index", - "type": "t_uint256" - }, - { - "label": "indexBlockNumber", - "type": "t_uint256" - }, - { - "label": "lastFeeUpdate", - "type": "t_uint256" - } - ] - }, - "t_mapping(t_address,t_struct(OwnerData)2968_storage)": { - "label": "mapping(address => struct SSVNetwork.OwnerData)" - }, - "t_address": { - "label": "address" - }, - "t_struct(OwnerData)2968_storage": { - "label": "struct SSVNetwork.OwnerData", - "members": [ - { - "label": "deposited", - "type": "t_uint256" - }, - { - "label": "withdrawn", - "type": "t_uint256" - }, - { - "label": "earned", - "type": "t_uint256" - }, - { - "label": "used", - "type": "t_uint256" - }, - { - "label": "networkFee", - "type": "t_uint256" - }, - { - "label": "networkFeeIndex", - "type": "t_uint256" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256" - }, - { - "label": "validatorsDisabled", - "type": "t_bool" - } - ] - }, - "t_bool": { - "label": "bool" - }, - "t_mapping(t_address,t_mapping(t_bytes_memory_ptr,t_struct(OperatorInUse)2979_storage))": { - "label": "mapping(address => mapping(bytes => struct SSVNetwork.OperatorInUse))" - }, - "t_mapping(t_bytes_memory_ptr,t_struct(OperatorInUse)2979_storage)": { - "label": "mapping(bytes => struct SSVNetwork.OperatorInUse)" - }, - "t_struct(OperatorInUse)2979_storage": { - "label": "struct SSVNetwork.OperatorInUse", - "members": [ - { - "label": "index", - "type": "t_uint256" - }, - { - "label": "validatorCount", - "type": "t_uint256" - }, - { - "label": "used", - "type": "t_uint256" - }, - { - "label": "exists", - "type": "t_bool" - }, - { - "label": "indexInArray", - "type": "t_uint256" - } - ] - }, - "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)": { - "label": "mapping(address => bytes[])" - }, - "t_array(t_bytes_storage)dyn_storage": { - "label": "bytes[]" - }, - "t_mapping(t_bytes_memory_ptr,t_uint256)": { - "label": "mapping(bytes => uint256)" - }, - "t_array(t_uint256)49_storage": { - "label": "uint256[49]" - }, - "t_array(t_uint256)50_storage": { - "label": "uint256[50]" - } - } - } - }, - "39be4898e477410a3ad816f254675839281b5b9fe13703c1764a53720c4fb2d7": { - "address": "0x3a21966e34ac0B031621C3c3F8063200A35E0FFd", - "txHash": "0x9b0940c255f370f6b3d0e29fb47b796bf18bd0edb3a9b871ffc8d570515ad2b6", - "layout": { - "storage": [ - { - "contract": "Initializable", - "label": "_initialized", - "type": "t_bool", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:23" - }, - { - "contract": "Initializable", - "label": "_initializing", - "type": "t_bool", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:28" - }, - { - "contract": "ContextUpgradeable", - "label": "__gap", - "type": "t_array(t_uint256)50_storage", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" - }, - { - "contract": "OwnableUpgradeable", - "label": "_owner", - "type": "t_address", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:20" - }, - { - "contract": "OwnableUpgradeable", - "label": "__gap", - "type": "t_array(t_uint256)49_storage", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:74" - }, - { - "contract": "SSVNetwork", - "label": "_ssvRegistryContract", - "type": "t_contract(ISSVRegistry)1070", - "src": "contracts/SSVNetwork.sol:39" - }, - { - "contract": "SSVNetwork", - "label": "_token", - "type": "t_contract(IERC20)299", - "src": "contracts/SSVNetwork.sol:40" - }, - { - "contract": "SSVNetwork", - "label": "_minimumBlocksBeforeLiquidation", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:41" - }, - { - "contract": "SSVNetwork", - "label": "_operatorMaxFeeIncrease", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:42" - }, - { - "contract": "SSVNetwork", - "label": "_networkFee", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:44" - }, - { - "contract": "SSVNetwork", - "label": "_networkFeeIndex", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:45" - }, - { - "contract": "SSVNetwork", - "label": "_networkFeeIndexBlockNumber", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:46" - }, - { - "contract": "SSVNetwork", - "label": "_networkEarnings", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:47" - }, - { - "contract": "SSVNetwork", - "label": "_networkEarningsBlockNumber", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:48" - }, - { - "contract": "SSVNetwork", - "label": "_withdrawnFromTreasury", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:49" - }, - { - "contract": "SSVNetwork", - "label": "_operatorDatas", - "type": "t_mapping(t_bytes_memory_ptr,t_struct(OperatorData)1094_storage)", - "src": "contracts/SSVNetwork.sol:51" - }, - { - "contract": "SSVNetwork", - "label": "_owners", - "type": "t_mapping(t_address,t_struct(OwnerData)1111_storage)", - "src": "contracts/SSVNetwork.sol:52" - }, - { - "contract": "SSVNetwork", - "label": "_operatorsInUseByAddress", - "type": "t_mapping(t_address,t_mapping(t_bytes_memory_ptr,t_struct(OperatorInUse)1122_storage))", - "src": "contracts/SSVNetwork.sol:53" - }, - { - "contract": "SSVNetwork", - "label": "_operatorsInUseList", - "type": "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)", - "src": "contracts/SSVNetwork.sol:54" - }, - { - "contract": "SSVNetwork", - "label": "_lastOperatorUpdateNetworkFeeRun", - "type": "t_mapping(t_bytes_memory_ptr,t_uint256)", - "src": "contracts/SSVNetwork.sol:55" - } - ], - "types": { - "t_contract(ISSVRegistry)1070": { - "label": "contract ISSVRegistry" - }, - "t_contract(IERC20)299": { - "label": "contract IERC20" - }, - "t_uint256": { - "label": "uint256" - }, - "t_mapping(t_bytes_memory_ptr,t_struct(OperatorData)1094_storage)": { - "label": "mapping(bytes => struct SSVNetwork.OperatorData)" - }, - "t_bytes_storage": { - "label": "bytes" - }, - "t_struct(OperatorData)1094_storage": { - "label": "struct SSVNetwork.OperatorData", - "members": [ - { - "label": "blockNumber", - "type": "t_uint256" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256" - }, - { - "label": "earnings", - "type": "t_uint256" - }, - { - "label": "index", - "type": "t_uint256" - }, - { - "label": "indexBlockNumber", - "type": "t_uint256" - }, - { - "label": "lastFeeUpdate", - "type": "t_uint256" - } - ] - }, - "t_mapping(t_address,t_struct(OwnerData)1111_storage)": { - "label": "mapping(address => struct SSVNetwork.OwnerData)" - }, - "t_address": { - "label": "address" - }, - "t_struct(OwnerData)1111_storage": { - "label": "struct SSVNetwork.OwnerData", - "members": [ - { - "label": "deposited", - "type": "t_uint256" - }, - { - "label": "withdrawn", - "type": "t_uint256" - }, - { - "label": "earned", - "type": "t_uint256" - }, - { - "label": "used", - "type": "t_uint256" - }, - { - "label": "networkFee", - "type": "t_uint256" - }, - { - "label": "networkFeeIndex", - "type": "t_uint256" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256" - }, - { - "label": "validatorsDisabled", - "type": "t_bool" - } - ] - }, - "t_bool": { - "label": "bool" - }, - "t_mapping(t_address,t_mapping(t_bytes_memory_ptr,t_struct(OperatorInUse)1122_storage))": { - "label": "mapping(address => mapping(bytes => struct SSVNetwork.OperatorInUse))" - }, - "t_mapping(t_bytes_memory_ptr,t_struct(OperatorInUse)1122_storage)": { - "label": "mapping(bytes => struct SSVNetwork.OperatorInUse)" - }, - "t_struct(OperatorInUse)1122_storage": { - "label": "struct SSVNetwork.OperatorInUse", - "members": [ - { - "label": "index", - "type": "t_uint256" - }, - { - "label": "validatorCount", - "type": "t_uint256" - }, - { - "label": "used", - "type": "t_uint256" - }, - { - "label": "exists", - "type": "t_bool" - }, - { - "label": "indexInArray", - "type": "t_uint256" - } - ] - }, - "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)": { - "label": "mapping(address => bytes[])" - }, - "t_array(t_bytes_storage)dyn_storage": { - "label": "bytes[]" - }, - "t_mapping(t_bytes_memory_ptr,t_uint256)": { - "label": "mapping(bytes => uint256)" - }, - "t_array(t_uint256)49_storage": { - "label": "uint256[49]" - }, - "t_array(t_uint256)50_storage": { - "label": "uint256[50]" - } - } - } - }, - "16ce6205801704c716fb7e4f210622bc3492167e4c83208cea879ae381eef3bc": { - "address": "0x27cC1891D439845231904F71dF365523C76A19C7", - "txHash": "0x712be24c9b03ac00a2c22daf6563669b61e07ebe50b7e26754bf957ebfaf6914", - "layout": { - "storage": [ - { - "contract": "Initializable", - "label": "_initialized", - "type": "t_bool", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:23" - }, - { - "contract": "Initializable", - "label": "_initializing", - "type": "t_bool", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:28" - }, - { - "contract": "ContextUpgradeable", - "label": "__gap", - "type": "t_array(t_uint256)50_storage", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" - }, - { - "contract": "OwnableUpgradeable", - "label": "_owner", - "type": "t_address", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:20" - }, - { - "contract": "OwnableUpgradeable", - "label": "__gap", - "type": "t_array(t_uint256)49_storage", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:74" - }, - { - "contract": "SSVRegistry", - "label": "_operatorCount", - "type": "t_uint256", - "src": "contracts/SSVRegistry.sol:37" - }, - { - "contract": "SSVRegistry", - "label": "_validatorCount", - "type": "t_uint256", - "src": "contracts/SSVRegistry.sol:38" - }, - { - "contract": "SSVRegistry", - "label": "_activeValidatorCount", - "type": "t_uint256", - "src": "contracts/SSVRegistry.sol:39" - }, - { - "contract": "SSVRegistry", - "label": "_operators", - "type": "t_mapping(t_bytes_memory_ptr,t_struct(Operator)623_storage)", - "src": "contracts/SSVRegistry.sol:41" - }, - { - "contract": "SSVRegistry", - "label": "_validators", - "type": "t_mapping(t_bytes_memory_ptr,t_struct(Validator)636_storage)", - "src": "contracts/SSVRegistry.sol:42" - }, - { - "contract": "SSVRegistry", - "label": "_operatorFees", - "type": "t_mapping(t_bytes_memory_ptr,t_array(t_struct(OperatorFee)641_storage)dyn_storage)", - "src": "contracts/SSVRegistry.sol:44" - }, - { - "contract": "SSVRegistry", - "label": "_operatorsByOwnerAddress", - "type": "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)", - "src": "contracts/SSVRegistry.sol:46" - }, - { - "contract": "SSVRegistry", - "label": "_validatorsByAddress", - "type": "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)", - "src": "contracts/SSVRegistry.sol:47" - }, - { - "contract": "SSVRegistry", - "label": "_owners", - "type": "t_mapping(t_address,t_struct(OwnerData)646_storage)", - "src": "contracts/SSVRegistry.sol:48" - } - ], - "types": { - "t_uint256": { - "label": "uint256" - }, - "t_mapping(t_bytes_memory_ptr,t_struct(Operator)623_storage)": { - "label": "mapping(bytes => struct SSVRegistry.Operator)" - }, - "t_bytes_storage": { - "label": "bytes" - }, - "t_struct(Operator)623_storage": { - "label": "struct SSVRegistry.Operator", - "members": [ - { - "label": "name", - "type": "t_string_storage" - }, - { - "label": "ownerAddress", - "type": "t_address" - }, - { - "label": "publicKey", - "type": "t_bytes_storage" - }, - { - "label": "score", - "type": "t_uint256" - }, - { - "label": "active", - "type": "t_bool" - }, - { - "label": "index", - "type": "t_uint256" - } - ] - }, - "t_string_storage": { - "label": "string" - }, - "t_address": { - "label": "address" - }, - "t_bool": { - "label": "bool" - }, - "t_mapping(t_bytes_memory_ptr,t_struct(Validator)636_storage)": { - "label": "mapping(bytes => struct SSVRegistry.Validator)" - }, - "t_struct(Validator)636_storage": { - "label": "struct SSVRegistry.Validator", - "members": [ - { - "label": "ownerAddress", - "type": "t_address" - }, - { - "label": "publicKey", - "type": "t_bytes_storage" - }, - { - "label": "oess", - "type": "t_array(t_struct(Oess)303_storage)dyn_storage" - }, - { - "label": "active", - "type": "t_bool" - }, - { - "label": "index", - "type": "t_uint256" - } - ] - }, - "t_array(t_struct(Oess)303_storage)dyn_storage": { - "label": "struct ISSVRegistry.Oess[]" - }, - "t_struct(Oess)303_storage": { - "label": "struct ISSVRegistry.Oess", - "members": [ - { - "label": "operatorPublicKey", - "type": "t_bytes_storage" - }, - { - "label": "sharedPublicKey", - "type": "t_bytes_storage" - }, - { - "label": "encryptedKey", - "type": "t_bytes_storage" - } - ] - }, - "t_mapping(t_bytes_memory_ptr,t_array(t_struct(OperatorFee)641_storage)dyn_storage)": { - "label": "mapping(bytes => struct SSVRegistry.OperatorFee[])" - }, - "t_array(t_struct(OperatorFee)641_storage)dyn_storage": { - "label": "struct SSVRegistry.OperatorFee[]" - }, - "t_struct(OperatorFee)641_storage": { - "label": "struct SSVRegistry.OperatorFee", - "members": [ - { - "label": "blockNumber", - "type": "t_uint256" - }, - { - "label": "fee", - "type": "t_uint256" - } - ] - }, - "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)": { - "label": "mapping(address => bytes[])" - }, - "t_array(t_bytes_storage)dyn_storage": { - "label": "bytes[]" - }, - "t_mapping(t_address,t_struct(OwnerData)646_storage)": { - "label": "mapping(address => struct SSVRegistry.OwnerData)" - }, - "t_struct(OwnerData)646_storage": { - "label": "struct SSVRegistry.OwnerData", - "members": [ - { - "label": "activeValidatorCount", - "type": "t_uint256" - }, - { - "label": "validatorsDisabled", - "type": "t_bool" - } - ] - }, - "t_array(t_uint256)49_storage": { - "label": "uint256[49]" - }, - "t_array(t_uint256)50_storage": { - "label": "uint256[50]" - } - } - } - }, - "446e8b352eb2db74b9635d90579d222f983ecf9979b9aeb6e851209469ea2763": { - "address": "0x6E034CC5dfA0B68fDe9881681ad32C3179952501", - "txHash": "0xb4abaf6b54c40ea8d9eeb0711c0ba6c0986861fc356625ba410fa0193f6f68c2", - "layout": { - "storage": [ - { - "contract": "Initializable", - "label": "_initialized", - "type": "t_bool", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:23" - }, - { - "contract": "Initializable", - "label": "_initializing", - "type": "t_bool", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:28" - }, - { - "contract": "ContextUpgradeable", - "label": "__gap", - "type": "t_array(t_uint256)50_storage", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" - }, - { - "contract": "OwnableUpgradeable", - "label": "_owner", - "type": "t_address", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:20" - }, - { - "contract": "OwnableUpgradeable", - "label": "__gap", - "type": "t_array(t_uint256)49_storage", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:74" - }, - { - "contract": "SSVNetwork", - "label": "_ssvRegistryContract", - "type": "t_contract(ISSVRegistry)1026", - "src": "contracts/SSVNetwork.sol:39" - }, - { - "contract": "SSVNetwork", - "label": "_token", - "type": "t_contract(IERC20)299", - "src": "contracts/SSVNetwork.sol:40" - }, - { - "contract": "SSVNetwork", - "label": "_minimumBlocksBeforeLiquidation", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:41" - }, - { - "contract": "SSVNetwork", - "label": "_operatorMaxFeeIncrease", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:42" - }, - { - "contract": "SSVNetwork", - "label": "_networkFee", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:44" - }, - { - "contract": "SSVNetwork", - "label": "_networkFeeIndex", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:45" - }, - { - "contract": "SSVNetwork", - "label": "_networkFeeIndexBlockNumber", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:46" - }, - { - "contract": "SSVNetwork", - "label": "_networkEarnings", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:47" - }, - { - "contract": "SSVNetwork", - "label": "_networkEarningsBlockNumber", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:48" - }, - { - "contract": "SSVNetwork", - "label": "_withdrawnFromTreasury", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:49" - }, - { - "contract": "SSVNetwork", - "label": "_operatorDatas", - "type": "t_mapping(t_bytes_memory_ptr,t_struct(OperatorData)1050_storage)", - "src": "contracts/SSVNetwork.sol:51" - }, - { - "contract": "SSVNetwork", - "label": "_owners", - "type": "t_mapping(t_address,t_struct(OwnerData)1067_storage)", - "src": "contracts/SSVNetwork.sol:52" - }, - { - "contract": "SSVNetwork", - "label": "_operatorsInUseByAddress", - "type": "t_mapping(t_address,t_mapping(t_bytes_memory_ptr,t_struct(OperatorInUse)1078_storage))", - "src": "contracts/SSVNetwork.sol:53" - }, - { - "contract": "SSVNetwork", - "label": "_operatorsInUseList", - "type": "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)", - "src": "contracts/SSVNetwork.sol:54" - }, - { - "contract": "SSVNetwork", - "label": "_lastOperatorUpdateNetworkFeeRun", - "type": "t_mapping(t_bytes_memory_ptr,t_uint256)", - "src": "contracts/SSVNetwork.sol:55" - } - ], - "types": { - "t_contract(ISSVRegistry)1026": { - "label": "contract ISSVRegistry" - }, - "t_contract(IERC20)299": { - "label": "contract IERC20" - }, - "t_uint256": { - "label": "uint256" - }, - "t_mapping(t_bytes_memory_ptr,t_struct(OperatorData)1050_storage)": { - "label": "mapping(bytes => struct SSVNetwork.OperatorData)" - }, - "t_bytes_storage": { - "label": "bytes" - }, - "t_struct(OperatorData)1050_storage": { - "label": "struct SSVNetwork.OperatorData", - "members": [ - { - "label": "blockNumber", - "type": "t_uint256" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256" - }, - { - "label": "earnings", - "type": "t_uint256" - }, - { - "label": "index", - "type": "t_uint256" - }, - { - "label": "indexBlockNumber", - "type": "t_uint256" - }, - { - "label": "lastFeeUpdate", - "type": "t_uint256" - } - ] - }, - "t_mapping(t_address,t_struct(OwnerData)1067_storage)": { - "label": "mapping(address => struct SSVNetwork.OwnerData)" - }, - "t_address": { - "label": "address" - }, - "t_struct(OwnerData)1067_storage": { - "label": "struct SSVNetwork.OwnerData", - "members": [ - { - "label": "deposited", - "type": "t_uint256" - }, - { - "label": "withdrawn", - "type": "t_uint256" - }, - { - "label": "earned", - "type": "t_uint256" - }, - { - "label": "used", - "type": "t_uint256" - }, - { - "label": "networkFee", - "type": "t_uint256" - }, - { - "label": "networkFeeIndex", - "type": "t_uint256" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256" - }, - { - "label": "validatorsDisabled", - "type": "t_bool" - } - ] - }, - "t_bool": { - "label": "bool" - }, - "t_mapping(t_address,t_mapping(t_bytes_memory_ptr,t_struct(OperatorInUse)1078_storage))": { - "label": "mapping(address => mapping(bytes => struct SSVNetwork.OperatorInUse))" - }, - "t_mapping(t_bytes_memory_ptr,t_struct(OperatorInUse)1078_storage)": { - "label": "mapping(bytes => struct SSVNetwork.OperatorInUse)" - }, - "t_struct(OperatorInUse)1078_storage": { - "label": "struct SSVNetwork.OperatorInUse", - "members": [ - { - "label": "index", - "type": "t_uint256" - }, - { - "label": "validatorCount", - "type": "t_uint256" - }, - { - "label": "used", - "type": "t_uint256" - }, - { - "label": "exists", - "type": "t_bool" - }, - { - "label": "indexInArray", - "type": "t_uint256" - } - ] - }, - "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)": { - "label": "mapping(address => bytes[])" - }, - "t_array(t_bytes_storage)dyn_storage": { - "label": "bytes[]" - }, - "t_mapping(t_bytes_memory_ptr,t_uint256)": { - "label": "mapping(bytes => uint256)" - }, - "t_array(t_uint256)49_storage": { - "label": "uint256[49]" - }, - "t_array(t_uint256)50_storage": { - "label": "uint256[50]" - } - } - } - }, - "184305b80710a84a34b0bf97223857fa67941e7a63d04aa451576469dfc0f380": { - "address": "0x1DAa34A47ab0952e59f5Aa1B8200dc48D1FE310a", - "txHash": "0x0862b360ad04472372df6e7ecade75fc45c14fe0b3c9cf52ae043803c98f640d", - "layout": { - "storage": [ - { - "contract": "Initializable", - "label": "_initialized", - "type": "t_bool", - "src": "@openzeppelin/contracts/proxy/utils/Initializable.sol:23" - }, - { - "contract": "Initializable", - "label": "_initializing", - "type": "t_bool", - "src": "@openzeppelin/contracts/proxy/utils/Initializable.sol:28" - }, - { - "contract": "ContextUpgradeable", - "label": "__gap", - "type": "t_array(t_uint256)50_storage", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" - }, - { - "contract": "OwnableUpgradeable", - "label": "_owner", - "type": "t_address", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:20" - }, - { - "contract": "OwnableUpgradeable", - "label": "__gap", - "type": "t_array(t_uint256)49_storage", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:74" - }, - { - "contract": "SSVNetwork", - "label": "_ssvRegistryContract", - "type": "t_contract(ISSVRegistry)2878", - "src": "contracts/SSVNetwork.sol:39" - }, - { - "contract": "SSVNetwork", - "label": "_token", - "type": "t_contract(IERC20)962", - "src": "contracts/SSVNetwork.sol:40" - }, - { - "contract": "SSVNetwork", - "label": "_minimumBlocksBeforeLiquidation", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:41" - }, - { - "contract": "SSVNetwork", - "label": "_operatorMaxFeeIncrease", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:42" - }, - { - "contract": "SSVNetwork", - "label": "_networkFee", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:44" - }, - { - "contract": "SSVNetwork", - "label": "_networkFeeIndex", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:45" - }, - { - "contract": "SSVNetwork", - "label": "_networkFeeIndexBlockNumber", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:46" - }, - { - "contract": "SSVNetwork", - "label": "_networkEarnings", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:47" - }, - { - "contract": "SSVNetwork", - "label": "_networkEarningsBlockNumber", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:48" - }, - { - "contract": "SSVNetwork", - "label": "_withdrawnFromTreasury", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:49" - }, - { - "contract": "SSVNetwork", - "label": "_operatorDatas", - "type": "t_mapping(t_bytes_memory_ptr,t_struct(OperatorData)2902_storage)", - "src": "contracts/SSVNetwork.sol:51" - }, - { - "contract": "SSVNetwork", - "label": "_owners", - "type": "t_mapping(t_address,t_struct(OwnerData)2919_storage)", - "src": "contracts/SSVNetwork.sol:52" - }, - { - "contract": "SSVNetwork", - "label": "_operatorsInUseByAddress", - "type": "t_mapping(t_address,t_mapping(t_bytes_memory_ptr,t_struct(OperatorInUse)2930_storage))", - "src": "contracts/SSVNetwork.sol:53" - }, - { - "contract": "SSVNetwork", - "label": "_operatorsInUseList", - "type": "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)", - "src": "contracts/SSVNetwork.sol:54" - }, - { - "contract": "SSVNetwork", - "label": "_lastOperatorUpdateNetworkFeeRun", - "type": "t_mapping(t_bytes_memory_ptr,t_uint256)", - "src": "contracts/SSVNetwork.sol:55" - } - ], - "types": { - "t_contract(ISSVRegistry)2878": { - "label": "contract ISSVRegistry" - }, - "t_contract(IERC20)962": { - "label": "contract IERC20" - }, - "t_uint256": { - "label": "uint256" - }, - "t_mapping(t_bytes_memory_ptr,t_struct(OperatorData)2902_storage)": { - "label": "mapping(bytes => struct SSVNetwork.OperatorData)" - }, - "t_bytes_storage": { - "label": "bytes" - }, - "t_struct(OperatorData)2902_storage": { - "label": "struct SSVNetwork.OperatorData", - "members": [ - { - "label": "blockNumber", - "type": "t_uint256" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256" - }, - { - "label": "earnings", - "type": "t_uint256" - }, - { - "label": "index", - "type": "t_uint256" - }, - { - "label": "indexBlockNumber", - "type": "t_uint256" - }, - { - "label": "lastFeeUpdate", - "type": "t_uint256" - } - ] - }, - "t_mapping(t_address,t_struct(OwnerData)2919_storage)": { - "label": "mapping(address => struct SSVNetwork.OwnerData)" - }, - "t_address": { - "label": "address" - }, - "t_struct(OwnerData)2919_storage": { - "label": "struct SSVNetwork.OwnerData", - "members": [ - { - "label": "deposited", - "type": "t_uint256" - }, - { - "label": "withdrawn", - "type": "t_uint256" - }, - { - "label": "earned", - "type": "t_uint256" - }, - { - "label": "used", - "type": "t_uint256" - }, - { - "label": "networkFee", - "type": "t_uint256" - }, - { - "label": "networkFeeIndex", - "type": "t_uint256" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256" - }, - { - "label": "validatorsDisabled", - "type": "t_bool" - } - ] - }, - "t_bool": { - "label": "bool" - }, - "t_mapping(t_address,t_mapping(t_bytes_memory_ptr,t_struct(OperatorInUse)2930_storage))": { - "label": "mapping(address => mapping(bytes => struct SSVNetwork.OperatorInUse))" - }, - "t_mapping(t_bytes_memory_ptr,t_struct(OperatorInUse)2930_storage)": { - "label": "mapping(bytes => struct SSVNetwork.OperatorInUse)" - }, - "t_struct(OperatorInUse)2930_storage": { - "label": "struct SSVNetwork.OperatorInUse", - "members": [ - { - "label": "index", - "type": "t_uint256" - }, - { - "label": "validatorCount", - "type": "t_uint256" - }, - { - "label": "used", - "type": "t_uint256" - }, - { - "label": "exists", - "type": "t_bool" - }, - { - "label": "indexInArray", - "type": "t_uint256" - } - ] - }, - "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)": { - "label": "mapping(address => bytes[])" - }, - "t_array(t_bytes_storage)dyn_storage": { - "label": "bytes[]" - }, - "t_mapping(t_bytes_memory_ptr,t_uint256)": { - "label": "mapping(bytes => uint256)" - }, - "t_array(t_uint256)49_storage": { - "label": "uint256[49]" - }, - "t_array(t_uint256)50_storage": { - "label": "uint256[50]" - } - } - } - }, - "41d11ce4d91e5e3782985451ee40d696f72c9485ceca77fbfd11cc02b4af1de0": { - "address": "0xdb6Dca54b0fDEA4e3fE6Fc9598F93943194a6e51", - "txHash": "0xa05f3e34265c099315dcb6ec201472a03ba10a1635c8d37f24f3cef55e0dc75e", - "layout": { - "storage": [ - { - "contract": "Initializable", - "label": "_initialized", - "type": "t_bool", - "src": "@openzeppelin/contracts/proxy/utils/Initializable.sol:23" - }, - { - "contract": "Initializable", - "label": "_initializing", - "type": "t_bool", - "src": "@openzeppelin/contracts/proxy/utils/Initializable.sol:28" - }, - { - "contract": "ContextUpgradeable", - "label": "__gap", - "type": "t_array(t_uint256)50_storage", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" - }, - { - "contract": "OwnableUpgradeable", - "label": "_owner", - "type": "t_address", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:20" - }, - { - "contract": "OwnableUpgradeable", - "label": "__gap", - "type": "t_array(t_uint256)49_storage", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:74" - }, - { - "contract": "SSVRegistry", - "label": "_operatorCount", - "type": "t_uint256", - "src": "contracts/SSVRegistry.sol:37" - }, - { - "contract": "SSVRegistry", - "label": "_validatorCount", - "type": "t_uint256", - "src": "contracts/SSVRegistry.sol:38" - }, - { - "contract": "SSVRegistry", - "label": "_activeValidatorCount", - "type": "t_uint256", - "src": "contracts/SSVRegistry.sol:39" - }, - { - "contract": "SSVRegistry", - "label": "_operators", - "type": "t_mapping(t_bytes_memory_ptr,t_struct(Operator)5325_storage)", - "src": "contracts/SSVRegistry.sol:41" - }, - { - "contract": "SSVRegistry", - "label": "_validators", - "type": "t_mapping(t_bytes_memory_ptr,t_struct(Validator)5338_storage)", - "src": "contracts/SSVRegistry.sol:42" - }, - { - "contract": "SSVRegistry", - "label": "_operatorFees", - "type": "t_mapping(t_bytes_memory_ptr,t_array(t_struct(OperatorFee)5343_storage)dyn_storage)", - "src": "contracts/SSVRegistry.sol:44" - }, - { - "contract": "SSVRegistry", - "label": "_operatorsByOwnerAddress", - "type": "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)", - "src": "contracts/SSVRegistry.sol:46" - }, - { - "contract": "SSVRegistry", - "label": "_validatorsByAddress", - "type": "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)", - "src": "contracts/SSVRegistry.sol:47" - }, - { - "contract": "SSVRegistry", - "label": "_owners", - "type": "t_mapping(t_address,t_struct(OwnerData)5348_storage)", - "src": "contracts/SSVRegistry.sol:48" - } - ], - "types": { - "t_uint256": { - "label": "uint256" - }, - "t_mapping(t_bytes_memory_ptr,t_struct(Operator)5325_storage)": { - "label": "mapping(bytes => struct SSVRegistry.Operator)" - }, - "t_bytes_storage": { - "label": "bytes" - }, - "t_struct(Operator)5325_storage": { - "label": "struct SSVRegistry.Operator", - "members": [ - { - "label": "name", - "type": "t_string_storage" - }, - { - "label": "ownerAddress", - "type": "t_address" - }, - { - "label": "publicKey", - "type": "t_bytes_storage" - }, - { - "label": "score", - "type": "t_uint256" - }, - { - "label": "active", - "type": "t_bool" - }, - { - "label": "index", - "type": "t_uint256" - } - ] - }, - "t_string_storage": { - "label": "string" - }, - "t_address": { - "label": "address" - }, - "t_bool": { - "label": "bool" - }, - "t_mapping(t_bytes_memory_ptr,t_struct(Validator)5338_storage)": { - "label": "mapping(bytes => struct SSVRegistry.Validator)" - }, - "t_struct(Validator)5338_storage": { - "label": "struct SSVRegistry.Validator", - "members": [ - { - "label": "ownerAddress", - "type": "t_address" - }, - { - "label": "publicKey", - "type": "t_bytes_storage" - }, - { - "label": "oess", - "type": "t_array(t_struct(Oess)2582_storage)dyn_storage" - }, - { - "label": "active", - "type": "t_bool" - }, - { - "label": "index", - "type": "t_uint256" - } - ] - }, - "t_array(t_struct(Oess)2582_storage)dyn_storage": { - "label": "struct ISSVRegistry.Oess[]" - }, - "t_struct(Oess)2582_storage": { - "label": "struct ISSVRegistry.Oess", - "members": [ - { - "label": "operatorPublicKey", - "type": "t_bytes_storage" - }, - { - "label": "sharedPublicKey", - "type": "t_bytes_storage" - }, - { - "label": "encryptedKey", - "type": "t_bytes_storage" - } - ] - }, - "t_mapping(t_bytes_memory_ptr,t_array(t_struct(OperatorFee)5343_storage)dyn_storage)": { - "label": "mapping(bytes => struct SSVRegistry.OperatorFee[])" - }, - "t_array(t_struct(OperatorFee)5343_storage)dyn_storage": { - "label": "struct SSVRegistry.OperatorFee[]" - }, - "t_struct(OperatorFee)5343_storage": { - "label": "struct SSVRegistry.OperatorFee", - "members": [ - { - "label": "blockNumber", - "type": "t_uint256" - }, - { - "label": "fee", - "type": "t_uint256" - } - ] - }, - "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)": { - "label": "mapping(address => bytes[])" - }, - "t_array(t_bytes_storage)dyn_storage": { - "label": "bytes[]" - }, - "t_mapping(t_address,t_struct(OwnerData)5348_storage)": { - "label": "mapping(address => struct SSVRegistry.OwnerData)" - }, - "t_struct(OwnerData)5348_storage": { - "label": "struct SSVRegistry.OwnerData", - "members": [ - { - "label": "activeValidatorCount", - "type": "t_uint256" - }, - { - "label": "validatorsDisabled", - "type": "t_bool" - } - ] - }, - "t_array(t_uint256)49_storage": { - "label": "uint256[49]" - }, - "t_array(t_uint256)50_storage": { - "label": "uint256[50]" - } - } - } - }, - "43289e51990930f55e76f182fd7330669892b15e3c11389be9981a7c728b842a": { - "address": "0xAEC49a01880f493d737254b8aA015B254eb1EA56", - "txHash": "0x0f0319b7c244f5e7a7e0f4c56508f964fa9539d5303b66acddebeca9d808113b", - "layout": { - "storage": [ - { - "contract": "Initializable", - "label": "_initialized", - "type": "t_bool", - "src": "@openzeppelin/contracts/proxy/utils/Initializable.sol:23" - }, - { - "contract": "Initializable", - "label": "_initializing", - "type": "t_bool", - "src": "@openzeppelin/contracts/proxy/utils/Initializable.sol:28" - }, - { - "contract": "ContextUpgradeable", - "label": "__gap", - "type": "t_array(t_uint256)50_storage", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" - }, - { - "contract": "OwnableUpgradeable", - "label": "_owner", - "type": "t_address", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:20" - }, - { - "contract": "OwnableUpgradeable", - "label": "__gap", - "type": "t_array(t_uint256)49_storage", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:74" - }, - { - "contract": "SSVNetwork", - "label": "_ssvRegistryContract", - "type": "t_contract(ISSVRegistry)2947", - "src": "contracts/SSVNetwork.sol:47" - }, - { - "contract": "SSVNetwork", - "label": "_token", - "type": "t_contract(IERC20)962", - "src": "contracts/SSVNetwork.sol:48" - }, - { - "contract": "SSVNetwork", - "label": "_minimumBlocksBeforeLiquidation", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:49" - }, - { - "contract": "SSVNetwork", - "label": "_operatorMaxFeeIncrease", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:50" - }, - { - "contract": "SSVNetwork", - "label": "_networkFee", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:52" - }, - { - "contract": "SSVNetwork", - "label": "_networkFeeIndex", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:53" - }, - { - "contract": "SSVNetwork", - "label": "_networkFeeIndexBlockNumber", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:54" - }, - { - "contract": "SSVNetwork", - "label": "_networkEarnings", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:55" - }, - { - "contract": "SSVNetwork", - "label": "_networkEarningsBlockNumber", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:56" - }, - { - "contract": "SSVNetwork", - "label": "_withdrawnFromTreasury", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:57" - }, - { - "contract": "SSVNetwork", - "label": "_operatorDatas", - "type": "t_mapping(t_bytes_memory_ptr,t_struct(OperatorData)2972_storage)", - "src": "contracts/SSVNetwork.sol:59" - }, - { - "contract": "SSVNetwork", - "label": "_owners", - "type": "t_mapping(t_address,t_struct(OwnerData)2989_storage)", - "src": "contracts/SSVNetwork.sol:60" - }, - { - "contract": "SSVNetwork", - "label": "_operatorsInUseByAddress", - "type": "t_mapping(t_address,t_mapping(t_bytes_memory_ptr,t_struct(OperatorInUse)3000_storage))", - "src": "contracts/SSVNetwork.sol:61" - }, - { - "contract": "SSVNetwork", - "label": "_operatorsInUseList", - "type": "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)", - "src": "contracts/SSVNetwork.sol:62" - }, - { - "contract": "SSVNetwork", - "label": "_lastOperatorUpdateNetworkFeeRun", - "type": "t_mapping(t_bytes_memory_ptr,t_uint256)", - "src": "contracts/SSVNetwork.sol:63" - }, - { - "contract": "SSVNetwork", - "label": "_setOperatorFeePeriod", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:65" - }, - { - "contract": "SSVNetwork", - "label": "_approveOperatorFeePeriod", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:66" - }, - { - "contract": "SSVNetwork", - "label": "_feeChangeRequests", - "type": "t_mapping(t_bytes_memory_ptr,t_struct(FeeChangeRequest)3007_storage)", - "src": "contracts/SSVNetwork.sol:67" - } - ], - "types": { - "t_contract(ISSVRegistry)2947": { - "label": "contract ISSVRegistry" - }, - "t_contract(IERC20)962": { - "label": "contract IERC20" - }, - "t_uint256": { - "label": "uint256" - }, - "t_mapping(t_bytes_memory_ptr,t_struct(OperatorData)2972_storage)": { - "label": "mapping(bytes => struct SSVNetwork.OperatorData)" - }, - "t_bytes_storage": { - "label": "bytes" - }, - "t_struct(OperatorData)2972_storage": { - "label": "struct SSVNetwork.OperatorData", - "members": [ - { - "label": "blockNumber", - "type": "t_uint256" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256" - }, - { - "label": "earnings", - "type": "t_uint256" - }, - { - "label": "index", - "type": "t_uint256" - }, - { - "label": "indexBlockNumber", - "type": "t_uint256" - }, - { - "label": "previousFee", - "type": "t_uint256" - } - ] - }, - "t_mapping(t_address,t_struct(OwnerData)2989_storage)": { - "label": "mapping(address => struct SSVNetwork.OwnerData)" - }, - "t_address": { - "label": "address" - }, - "t_struct(OwnerData)2989_storage": { - "label": "struct SSVNetwork.OwnerData", - "members": [ - { - "label": "deposited", - "type": "t_uint256" - }, - { - "label": "withdrawn", - "type": "t_uint256" - }, - { - "label": "earned", - "type": "t_uint256" - }, - { - "label": "used", - "type": "t_uint256" - }, - { - "label": "networkFee", - "type": "t_uint256" - }, - { - "label": "networkFeeIndex", - "type": "t_uint256" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256" - }, - { - "label": "validatorsDisabled", - "type": "t_bool" - } - ] - }, - "t_bool": { - "label": "bool" - }, - "t_mapping(t_address,t_mapping(t_bytes_memory_ptr,t_struct(OperatorInUse)3000_storage))": { - "label": "mapping(address => mapping(bytes => struct SSVNetwork.OperatorInUse))" - }, - "t_mapping(t_bytes_memory_ptr,t_struct(OperatorInUse)3000_storage)": { - "label": "mapping(bytes => struct SSVNetwork.OperatorInUse)" - }, - "t_struct(OperatorInUse)3000_storage": { - "label": "struct SSVNetwork.OperatorInUse", - "members": [ - { - "label": "index", - "type": "t_uint256" - }, - { - "label": "validatorCount", - "type": "t_uint256" - }, - { - "label": "used", - "type": "t_uint256" - }, - { - "label": "exists", - "type": "t_bool" - }, - { - "label": "indexInArray", - "type": "t_uint256" - } - ] - }, - "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)": { - "label": "mapping(address => bytes[])" - }, - "t_array(t_bytes_storage)dyn_storage": { - "label": "bytes[]" - }, - "t_mapping(t_bytes_memory_ptr,t_uint256)": { - "label": "mapping(bytes => uint256)" - }, - "t_mapping(t_bytes_memory_ptr,t_struct(FeeChangeRequest)3007_storage)": { - "label": "mapping(bytes => struct SSVNetwork.FeeChangeRequest)" - }, - "t_struct(FeeChangeRequest)3007_storage": { - "label": "struct SSVNetwork.FeeChangeRequest", - "members": [ - { - "label": "fee", - "type": "t_uint256" - }, - { - "label": "approvalBeginTime", - "type": "t_uint256" - }, - { - "label": "approvalEndTime", - "type": "t_uint256" - } - ] - }, - "t_array(t_uint256)49_storage": { - "label": "uint256[49]" - }, - "t_array(t_uint256)50_storage": { - "label": "uint256[50]" - } - } - } - }, - "c63bf4bc1baa499980de2e288597db420f603f58bbb626a614d63b145179ed1c": { - "address": "0x8750104499ffFcc16Af6B5c230BDd93aDc9E08CD", - "txHash": "0x202fc6072d8b366d6c15d00db8744e7a989afa7cca3a7be393e011e833389d9f", - "layout": { - "storage": [ - { - "contract": "Initializable", - "label": "_initialized", - "type": "t_bool", - "src": "@openzeppelin/contracts/proxy/utils/Initializable.sol:23" - }, - { - "contract": "Initializable", - "label": "_initializing", - "type": "t_bool", - "src": "@openzeppelin/contracts/proxy/utils/Initializable.sol:28" - }, - { - "contract": "ContextUpgradeable", - "label": "__gap", - "type": "t_array(t_uint256)50_storage", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" - }, - { - "contract": "OwnableUpgradeable", - "label": "_owner", - "type": "t_address", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:20" - }, - { - "contract": "OwnableUpgradeable", - "label": "__gap", - "type": "t_array(t_uint256)49_storage", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:74" - }, - { - "contract": "SSVRegistry", - "label": "_activeValidatorCount", - "type": "t_uint256", - "src": "contracts/SSVRegistry.sol:38" - }, - { - "contract": "SSVRegistry", - "label": "_lastOperatorId", - "type": "t_struct(Counter)1597_storage", - "src": "contracts/SSVRegistry.sol:40" - }, - { - "contract": "SSVRegistry", - "label": "_operators", - "type": "t_mapping(t_uint256,t_struct(Operator)5521_storage)", - "src": "contracts/SSVRegistry.sol:42" - }, - { - "contract": "SSVRegistry", - "label": "_validators", - "type": "t_mapping(t_bytes_memory_ptr,t_struct(Validator)5531_storage)", - "src": "contracts/SSVRegistry.sol:43" - }, - { - "contract": "SSVRegistry", - "label": "_operatorFees", - "type": "t_mapping(t_uint256,t_array(t_struct(OperatorFee)5536_storage)dyn_storage)", - "src": "contracts/SSVRegistry.sol:44" - }, - { - "contract": "SSVRegistry", - "label": "_operatorsByOwnerAddress", - "type": "t_mapping(t_address,t_array(t_uint256)dyn_storage)", - "src": "contracts/SSVRegistry.sol:46" - }, - { - "contract": "SSVRegistry", - "label": "_validatorsByOwnerAddress", - "type": "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)", - "src": "contracts/SSVRegistry.sol:47" - }, - { - "contract": "SSVRegistry", - "label": "_owners", - "type": "t_mapping(t_address,t_struct(OwnerData)5541_storage)", - "src": "contracts/SSVRegistry.sol:48" - }, - { - "contract": "SSVRegistry", - "label": "_operatorPublicKeyToId", - "type": "t_mapping(t_bytes_memory_ptr,t_uint256)", - "src": "contracts/SSVRegistry.sol:50" - } - ], - "types": { - "t_uint256": { - "label": "uint256" - }, - "t_struct(Counter)1597_storage": { - "label": "struct Counters.Counter", - "members": [ - { - "label": "_value", - "type": "t_uint256" - } - ] - }, - "t_mapping(t_uint256,t_struct(Operator)5521_storage)": { - "label": "mapping(uint256 => struct SSVRegistry.Operator)" - }, - "t_struct(Operator)5521_storage": { - "label": "struct SSVRegistry.Operator", - "members": [ - { - "label": "name", - "type": "t_string_storage" - }, - { - "label": "ownerAddress", - "type": "t_address" - }, - { - "label": "publicKey", - "type": "t_bytes_storage" - }, - { - "label": "score", - "type": "t_uint256" - }, - { - "label": "active", - "type": "t_bool" - }, - { - "label": "indexInOwner", - "type": "t_uint256" - } - ] - }, - "t_string_storage": { - "label": "string" - }, - "t_address": { - "label": "address" - }, - "t_bytes_storage": { - "label": "bytes" - }, - "t_bool": { - "label": "bool" - }, - "t_mapping(t_bytes_memory_ptr,t_struct(Validator)5531_storage)": { - "label": "mapping(bytes => struct SSVRegistry.Validator)" - }, - "t_struct(Validator)5531_storage": { - "label": "struct SSVRegistry.Validator", - "members": [ - { - "label": "ownerAddress", - "type": "t_address" - }, - { - "label": "operatorIds", - "type": "t_array(t_uint256)dyn_storage" - }, - { - "label": "active", - "type": "t_bool" - }, - { - "label": "indexInOwner", - "type": "t_uint256" - } - ] - }, - "t_array(t_uint256)dyn_storage": { - "label": "uint256[]" - }, - "t_mapping(t_uint256,t_array(t_struct(OperatorFee)5536_storage)dyn_storage)": { - "label": "mapping(uint256 => struct SSVRegistry.OperatorFee[])" - }, - "t_array(t_struct(OperatorFee)5536_storage)dyn_storage": { - "label": "struct SSVRegistry.OperatorFee[]" - }, - "t_struct(OperatorFee)5536_storage": { - "label": "struct SSVRegistry.OperatorFee", - "members": [ - { - "label": "blockNumber", - "type": "t_uint256" - }, - { - "label": "fee", - "type": "t_uint256" - } - ] - }, - "t_mapping(t_address,t_array(t_uint256)dyn_storage)": { - "label": "mapping(address => uint256[])" - }, - "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)": { - "label": "mapping(address => bytes[])" - }, - "t_array(t_bytes_storage)dyn_storage": { - "label": "bytes[]" - }, - "t_mapping(t_address,t_struct(OwnerData)5541_storage)": { - "label": "mapping(address => struct SSVRegistry.OwnerData)" - }, - "t_struct(OwnerData)5541_storage": { - "label": "struct SSVRegistry.OwnerData", - "members": [ - { - "label": "activeValidatorCount", - "type": "t_uint256" - }, - { - "label": "validatorsDisabled", - "type": "t_bool" - } - ] - }, - "t_mapping(t_bytes_memory_ptr,t_uint256)": { - "label": "mapping(bytes => uint256)" - }, - "t_array(t_uint256)49_storage": { - "label": "uint256[49]" - }, - "t_array(t_uint256)50_storage": { - "label": "uint256[50]" - } - } - } - }, - "8231eb1b6b1076f1610847d8f0bdb5b67e111aa452c6e10c52039dd930da4666": { - "address": "0x4aB14200aF78DE3172112e204cB28aE319ff8d12", - "txHash": "0x893b7ca00e014616385194792b777dd0ded27753432ff4456e61ce8e6f04df52", - "layout": { - "storage": [ - { - "contract": "Initializable", - "label": "_initialized", - "type": "t_bool", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:23" - }, - { - "contract": "Initializable", - "label": "_initializing", - "type": "t_bool", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:28" - }, - { - "contract": "ContextUpgradeable", - "label": "__gap", - "type": "t_array(t_uint256)50_storage", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" - }, - { - "contract": "OwnableUpgradeable", - "label": "_owner", - "type": "t_address", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:20" - }, - { - "contract": "OwnableUpgradeable", - "label": "__gap", - "type": "t_array(t_uint256)49_storage", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:74" - }, - { - "contract": "SSVNetwork", - "label": "_ssvRegistryContract", - "type": "t_contract(ISSVRegistry)1100", - "src": "contracts/SSVNetwork.sol:45" - }, - { - "contract": "SSVNetwork", - "label": "_token", - "type": "t_contract(IERC20)299", - "src": "contracts/SSVNetwork.sol:46" - }, - { - "contract": "SSVNetwork", - "label": "_minimumBlocksBeforeLiquidation", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:47" - }, - { - "contract": "SSVNetwork", - "label": "_operatorMaxFeeIncrease", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:48" - }, - { - "contract": "SSVNetwork", - "label": "_networkFee", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:50" - }, - { - "contract": "SSVNetwork", - "label": "_networkFeeIndex", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:51" - }, - { - "contract": "SSVNetwork", - "label": "_networkFeeIndexBlockNumber", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:52" - }, - { - "contract": "SSVNetwork", - "label": "_networkEarnings", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:53" - }, - { - "contract": "SSVNetwork", - "label": "_networkEarningsBlockNumber", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:54" - }, - { - "contract": "SSVNetwork", - "label": "_withdrawnFromTreasury", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:55" - }, - { - "contract": "SSVNetwork", - "label": "_operatorDatas", - "type": "t_mapping(t_uint256,t_struct(OperatorData)1124_storage)", - "src": "contracts/SSVNetwork.sol:57" - }, - { - "contract": "SSVNetwork", - "label": "_owners", - "type": "t_mapping(t_address,t_struct(OwnerData)1141_storage)", - "src": "contracts/SSVNetwork.sol:58" - }, - { - "contract": "SSVNetwork", - "label": "_operatorsInUseByAddress", - "type": "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)1152_storage))", - "src": "contracts/SSVNetwork.sol:59" - }, - { - "contract": "SSVNetwork", - "label": "_operatorsInUseList", - "type": "t_mapping(t_address,t_array(t_uint256)dyn_storage)", - "src": "contracts/SSVNetwork.sol:60" - }, - { - "contract": "SSVNetwork", - "label": "_lastOperatorUpdateNetworkFeeRun", - "type": "t_mapping(t_uint256,t_uint256)", - "src": "contracts/SSVNetwork.sol:61" - }, - { - "contract": "SSVNetwork", - "label": "_setOperatorFeePeriod", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:63" - }, - { - "contract": "SSVNetwork", - "label": "_approveOperatorFeePeriod", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:64" - }, - { - "contract": "SSVNetwork", - "label": "_feeChangeRequests", - "type": "t_mapping(t_uint256,t_struct(FeeChangeRequest)1159_storage)", - "src": "contracts/SSVNetwork.sol:65" - } - ], - "types": { - "t_contract(ISSVRegistry)1100": { - "label": "contract ISSVRegistry" - }, - "t_contract(IERC20)299": { - "label": "contract IERC20" - }, - "t_uint256": { - "label": "uint256" - }, - "t_mapping(t_uint256,t_struct(OperatorData)1124_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorData)" - }, - "t_struct(OperatorData)1124_storage": { - "label": "struct SSVNetwork.OperatorData", - "members": [ - { - "label": "blockNumber", - "type": "t_uint256" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256" - }, - { - "label": "earnings", - "type": "t_uint256" - }, - { - "label": "index", - "type": "t_uint256" - }, - { - "label": "indexBlockNumber", - "type": "t_uint256" - }, - { - "label": "previousFee", - "type": "t_uint256" - } - ] - }, - "t_mapping(t_address,t_struct(OwnerData)1141_storage)": { - "label": "mapping(address => struct SSVNetwork.OwnerData)" - }, - "t_address": { - "label": "address" - }, - "t_struct(OwnerData)1141_storage": { - "label": "struct SSVNetwork.OwnerData", - "members": [ - { - "label": "deposited", - "type": "t_uint256" - }, - { - "label": "withdrawn", - "type": "t_uint256" - }, - { - "label": "earned", - "type": "t_uint256" - }, - { - "label": "used", - "type": "t_uint256" - }, - { - "label": "networkFee", - "type": "t_uint256" - }, - { - "label": "networkFeeIndex", - "type": "t_uint256" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256" - }, - { - "label": "validatorsDisabled", - "type": "t_bool" - } - ] - }, - "t_bool": { - "label": "bool" - }, - "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)1152_storage))": { - "label": "mapping(address => mapping(uint256 => struct SSVNetwork.OperatorInUse))" - }, - "t_mapping(t_uint256,t_struct(OperatorInUse)1152_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorInUse)" - }, - "t_struct(OperatorInUse)1152_storage": { - "label": "struct SSVNetwork.OperatorInUse", - "members": [ - { - "label": "index", - "type": "t_uint256" - }, - { - "label": "validatorCount", - "type": "t_uint256" - }, - { - "label": "used", - "type": "t_uint256" - }, - { - "label": "exists", - "type": "t_bool" - }, - { - "label": "indexInArray", - "type": "t_uint256" - } - ] - }, - "t_mapping(t_address,t_array(t_uint256)dyn_storage)": { - "label": "mapping(address => uint256[])" - }, - "t_array(t_uint256)dyn_storage": { - "label": "uint256[]" - }, - "t_mapping(t_uint256,t_uint256)": { - "label": "mapping(uint256 => uint256)" - }, - "t_mapping(t_uint256,t_struct(FeeChangeRequest)1159_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.FeeChangeRequest)" - }, - "t_struct(FeeChangeRequest)1159_storage": { - "label": "struct SSVNetwork.FeeChangeRequest", - "members": [ - { - "label": "fee", - "type": "t_uint256" - }, - { - "label": "approvalBeginTime", - "type": "t_uint256" - }, - { - "label": "approvalEndTime", - "type": "t_uint256" - } - ] - }, - "t_array(t_uint256)49_storage": { - "label": "uint256[49]" - }, - "t_array(t_uint256)50_storage": { - "label": "uint256[50]" - } - } - } - }, - "6da42368d480c8d8b98536a3c1e80a736ff4145896375e0005dd2c17fb15ccae": { - "address": "0x4317Ad05B4535c64034Ae9d920D34c3f2a8d107e", - "txHash": "0x8c614ab6634ea308b623c1801cc26bc2fce58b246469fb2385b6ac31744e6c89", - "layout": { - "storage": [ - { - "contract": "Initializable", - "label": "_initialized", - "type": "t_bool", - "src": "@openzeppelin/contracts/proxy/utils/Initializable.sol:23" - }, - { - "contract": "Initializable", - "label": "_initializing", - "type": "t_bool", - "src": "@openzeppelin/contracts/proxy/utils/Initializable.sol:28" - }, - { - "contract": "ContextUpgradeable", - "label": "__gap", - "type": "t_array(t_uint256)50_storage", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" - }, - { - "contract": "OwnableUpgradeable", - "label": "_owner", - "type": "t_address", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:20" - }, - { - "contract": "OwnableUpgradeable", - "label": "__gap", - "type": "t_array(t_uint256)49_storage", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:74" - }, - { - "contract": "SSVNetwork", - "label": "_ssvRegistryContract", - "type": "t_contract(ISSVRegistry)2945", - "src": "contracts/SSVNetwork.sol:45" - }, - { - "contract": "SSVNetwork", - "label": "_token", - "type": "t_contract(IERC20)962", - "src": "contracts/SSVNetwork.sol:46" - }, - { - "contract": "SSVNetwork", - "label": "_minimumBlocksBeforeLiquidation", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:47" - }, - { - "contract": "SSVNetwork", - "label": "_operatorMaxFeeIncrease", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:48" - }, - { - "contract": "SSVNetwork", - "label": "_networkFee", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:50" - }, - { - "contract": "SSVNetwork", - "label": "_networkFeeIndex", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:51" - }, - { - "contract": "SSVNetwork", - "label": "_networkFeeIndexBlockNumber", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:52" - }, - { - "contract": "SSVNetwork", - "label": "_networkEarnings", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:53" - }, - { - "contract": "SSVNetwork", - "label": "_networkEarningsBlockNumber", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:54" - }, - { - "contract": "SSVNetwork", - "label": "_withdrawnFromTreasury", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:55" - }, - { - "contract": "SSVNetwork", - "label": "_operatorDatas", - "type": "t_mapping(t_uint256,t_struct(OperatorData)2969_storage)", - "src": "contracts/SSVNetwork.sol:57" - }, - { - "contract": "SSVNetwork", - "label": "_owners", - "type": "t_mapping(t_address,t_struct(OwnerData)2986_storage)", - "src": "contracts/SSVNetwork.sol:58" - }, - { - "contract": "SSVNetwork", - "label": "_operatorsInUseByAddress", - "type": "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)2997_storage))", - "src": "contracts/SSVNetwork.sol:59" - }, - { - "contract": "SSVNetwork", - "label": "_operatorsInUseList", - "type": "t_mapping(t_address,t_array(t_uint256)dyn_storage)", - "src": "contracts/SSVNetwork.sol:60" - }, - { - "contract": "SSVNetwork", - "label": "_lastOperatorUpdateNetworkFeeRun", - "type": "t_mapping(t_uint256,t_uint256)", - "src": "contracts/SSVNetwork.sol:61" - }, - { - "contract": "SSVNetwork", - "label": "_setOperatorFeePeriod", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:63" - }, - { - "contract": "SSVNetwork", - "label": "_approveOperatorFeePeriod", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:64" - }, - { - "contract": "SSVNetwork", - "label": "_feeChangeRequests", - "type": "t_mapping(t_uint256,t_struct(FeeChangeRequest)3004_storage)", - "src": "contracts/SSVNetwork.sol:65" - } - ], - "types": { - "t_contract(ISSVRegistry)2945": { - "label": "contract ISSVRegistry" - }, - "t_contract(IERC20)962": { - "label": "contract IERC20" - }, - "t_uint256": { - "label": "uint256" - }, - "t_mapping(t_uint256,t_struct(OperatorData)2969_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorData)" - }, - "t_struct(OperatorData)2969_storage": { - "label": "struct SSVNetwork.OperatorData", - "members": [ - { - "label": "blockNumber", - "type": "t_uint256" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256" - }, - { - "label": "earnings", - "type": "t_uint256" - }, - { - "label": "index", - "type": "t_uint256" - }, - { - "label": "indexBlockNumber", - "type": "t_uint256" - }, - { - "label": "previousFee", - "type": "t_uint256" - } - ] - }, - "t_mapping(t_address,t_struct(OwnerData)2986_storage)": { - "label": "mapping(address => struct SSVNetwork.OwnerData)" - }, - "t_address": { - "label": "address" - }, - "t_struct(OwnerData)2986_storage": { - "label": "struct SSVNetwork.OwnerData", - "members": [ - { - "label": "deposited", - "type": "t_uint256" - }, - { - "label": "withdrawn", - "type": "t_uint256" - }, - { - "label": "earned", - "type": "t_uint256" - }, - { - "label": "used", - "type": "t_uint256" - }, - { - "label": "networkFee", - "type": "t_uint256" - }, - { - "label": "networkFeeIndex", - "type": "t_uint256" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256" - }, - { - "label": "validatorsDisabled", - "type": "t_bool" - } - ] - }, - "t_bool": { - "label": "bool" - }, - "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)2997_storage))": { - "label": "mapping(address => mapping(uint256 => struct SSVNetwork.OperatorInUse))" - }, - "t_mapping(t_uint256,t_struct(OperatorInUse)2997_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorInUse)" - }, - "t_struct(OperatorInUse)2997_storage": { - "label": "struct SSVNetwork.OperatorInUse", - "members": [ - { - "label": "index", - "type": "t_uint256" - }, - { - "label": "validatorCount", - "type": "t_uint256" - }, - { - "label": "used", - "type": "t_uint256" - }, - { - "label": "exists", - "type": "t_bool" - }, - { - "label": "indexInArray", - "type": "t_uint256" - } - ] - }, - "t_mapping(t_address,t_array(t_uint256)dyn_storage)": { - "label": "mapping(address => uint256[])" - }, - "t_array(t_uint256)dyn_storage": { - "label": "uint256[]" - }, - "t_mapping(t_uint256,t_uint256)": { - "label": "mapping(uint256 => uint256)" - }, - "t_mapping(t_uint256,t_struct(FeeChangeRequest)3004_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.FeeChangeRequest)" - }, - "t_struct(FeeChangeRequest)3004_storage": { - "label": "struct SSVNetwork.FeeChangeRequest", - "members": [ - { - "label": "fee", - "type": "t_uint256" - }, - { - "label": "approvalBeginTime", - "type": "t_uint256" - }, - { - "label": "approvalEndTime", - "type": "t_uint256" - } - ] - }, - "t_array(t_uint256)49_storage": { - "label": "uint256[49]" - }, - "t_array(t_uint256)50_storage": { - "label": "uint256[50]" - } - } - } - }, - "440af0e34738528eb879d029e9fa150dd9cdae00e35fc93e552962c3f3865242": { - "address": "0x17f9b1643E02bf1c6D90d8442F4ac5194c993E3A", - "txHash": "0x98ef48dab27b1f3225362e86f432344d8fd4ea7ae62b90c850c0a47b12ba21f5", - "layout": { - "storage": [ - { - "contract": "Initializable", - "label": "_initialized", - "type": "t_bool", - "src": "@openzeppelin/contracts/proxy/utils/Initializable.sol:23" - }, - { - "contract": "Initializable", - "label": "_initializing", - "type": "t_bool", - "src": "@openzeppelin/contracts/proxy/utils/Initializable.sol:28" - }, - { - "contract": "ContextUpgradeable", - "label": "__gap", - "type": "t_array(t_uint256)50_storage", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" - }, - { - "contract": "OwnableUpgradeable", - "label": "_owner", - "type": "t_address", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:20" - }, - { - "contract": "OwnableUpgradeable", - "label": "__gap", - "type": "t_array(t_uint256)49_storage", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:74" - }, - { - "contract": "SSVNetwork", - "label": "_ssvRegistryContract", - "type": "t_contract(ISSVRegistry)2945", - "src": "contracts/SSVNetwork.sol:45" - }, - { - "contract": "SSVNetwork", - "label": "_token", - "type": "t_contract(IERC20)962", - "src": "contracts/SSVNetwork.sol:46" - }, - { - "contract": "SSVNetwork", - "label": "_minimumBlocksBeforeLiquidation", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:47" - }, - { - "contract": "SSVNetwork", - "label": "_operatorMaxFeeIncrease", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:48" - }, - { - "contract": "SSVNetwork", - "label": "_networkFee", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:50" - }, - { - "contract": "SSVNetwork", - "label": "_networkFeeIndex", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:51" - }, - { - "contract": "SSVNetwork", - "label": "_networkFeeIndexBlockNumber", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:52" - }, - { - "contract": "SSVNetwork", - "label": "_networkEarnings", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:53" - }, - { - "contract": "SSVNetwork", - "label": "_networkEarningsBlockNumber", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:54" - }, - { - "contract": "SSVNetwork", - "label": "_withdrawnFromTreasury", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:55" - }, - { - "contract": "SSVNetwork", - "label": "_operatorDatas", - "type": "t_mapping(t_uint256,t_struct(OperatorData)2969_storage)", - "src": "contracts/SSVNetwork.sol:57" - }, - { - "contract": "SSVNetwork", - "label": "_owners", - "type": "t_mapping(t_address,t_struct(OwnerData)2986_storage)", - "src": "contracts/SSVNetwork.sol:58" - }, - { - "contract": "SSVNetwork", - "label": "_operatorsInUseByAddress", - "type": "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)2997_storage))", - "src": "contracts/SSVNetwork.sol:59" - }, - { - "contract": "SSVNetwork", - "label": "_operatorsInUseList", - "type": "t_mapping(t_address,t_array(t_uint256)dyn_storage)", - "src": "contracts/SSVNetwork.sol:60" - }, - { - "contract": "SSVNetwork", - "label": "_lastOperatorUpdateNetworkFeeRun", - "type": "t_mapping(t_uint256,t_uint256)", - "src": "contracts/SSVNetwork.sol:61" - }, - { - "contract": "SSVNetwork", - "label": "_setOperatorFeePeriod", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:63" - }, - { - "contract": "SSVNetwork", - "label": "_approveOperatorFeePeriod", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:64" - }, - { - "contract": "SSVNetwork", - "label": "_feeChangeRequests", - "type": "t_mapping(t_uint256,t_struct(FeeChangeRequest)3004_storage)", - "src": "contracts/SSVNetwork.sol:65" - } - ], - "types": { - "t_contract(ISSVRegistry)2945": { - "label": "contract ISSVRegistry" - }, - "t_contract(IERC20)962": { - "label": "contract IERC20" - }, - "t_uint256": { - "label": "uint256" - }, - "t_mapping(t_uint256,t_struct(OperatorData)2969_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorData)" - }, - "t_struct(OperatorData)2969_storage": { - "label": "struct SSVNetwork.OperatorData", - "members": [ - { - "label": "blockNumber", - "type": "t_uint256" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256" - }, - { - "label": "earnings", - "type": "t_uint256" - }, - { - "label": "index", - "type": "t_uint256" - }, - { - "label": "indexBlockNumber", - "type": "t_uint256" - }, - { - "label": "previousFee", - "type": "t_uint256" - } - ] - }, - "t_mapping(t_address,t_struct(OwnerData)2986_storage)": { - "label": "mapping(address => struct SSVNetwork.OwnerData)" - }, - "t_address": { - "label": "address" - }, - "t_struct(OwnerData)2986_storage": { - "label": "struct SSVNetwork.OwnerData", - "members": [ - { - "label": "deposited", - "type": "t_uint256" - }, - { - "label": "withdrawn", - "type": "t_uint256" - }, - { - "label": "earned", - "type": "t_uint256" - }, - { - "label": "used", - "type": "t_uint256" - }, - { - "label": "networkFee", - "type": "t_uint256" - }, - { - "label": "networkFeeIndex", - "type": "t_uint256" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256" - }, - { - "label": "validatorsDisabled", - "type": "t_bool" - } - ] - }, - "t_bool": { - "label": "bool" - }, - "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)2997_storage))": { - "label": "mapping(address => mapping(uint256 => struct SSVNetwork.OperatorInUse))" - }, - "t_mapping(t_uint256,t_struct(OperatorInUse)2997_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorInUse)" - }, - "t_struct(OperatorInUse)2997_storage": { - "label": "struct SSVNetwork.OperatorInUse", - "members": [ - { - "label": "index", - "type": "t_uint256" - }, - { - "label": "validatorCount", - "type": "t_uint256" - }, - { - "label": "used", - "type": "t_uint256" - }, - { - "label": "exists", - "type": "t_bool" - }, - { - "label": "indexInArray", - "type": "t_uint256" - } - ] - }, - "t_mapping(t_address,t_array(t_uint256)dyn_storage)": { - "label": "mapping(address => uint256[])" - }, - "t_array(t_uint256)dyn_storage": { - "label": "uint256[]" - }, - "t_mapping(t_uint256,t_uint256)": { - "label": "mapping(uint256 => uint256)" - }, - "t_mapping(t_uint256,t_struct(FeeChangeRequest)3004_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.FeeChangeRequest)" - }, - "t_struct(FeeChangeRequest)3004_storage": { - "label": "struct SSVNetwork.FeeChangeRequest", - "members": [ - { - "label": "fee", - "type": "t_uint256" - }, - { - "label": "approvalBeginTime", - "type": "t_uint256" - }, - { - "label": "approvalEndTime", - "type": "t_uint256" - } - ] - }, - "t_array(t_uint256)49_storage": { - "label": "uint256[49]" - }, - "t_array(t_uint256)50_storage": { - "label": "uint256[50]" - } - } - } - }, - "301e08c313b7fc56f51923557c5b0e56d80c4b51c88007eadc098879334de9bf": { - "address": "0xEB17aB1F557Bc5f26C797c56A98114D69954A294", - "txHash": "0xa7ab99d0629820ad07bc1325e89afb98e2a40dac5abdd66443ba0c6751e0bfb8", - "layout": { - "storage": [ - { - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:23" - }, - { - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:28" - }, - { - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage", - "contract": "ContextUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" - }, - { - "label": "_owner", - "offset": 0, - "slot": "51", - "type": "t_address", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:20" - }, - { - "label": "__gap", - "offset": 0, - "slot": "52", - "type": "t_array(t_uint256)49_storage", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:74" - }, - { - "label": "_activeValidatorCount", - "offset": 0, - "slot": "101", - "type": "t_uint256", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:38" - }, - { - "label": "_lastOperatorId", - "offset": 0, - "slot": "102", - "type": "t_struct(Counter)1003_storage", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:40" - }, - { - "label": "_operators", - "offset": 0, - "slot": "103", - "type": "t_mapping(t_uint256,t_struct(Operator)4594_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:42" - }, - { - "label": "_validators", - "offset": 0, - "slot": "104", - "type": "t_mapping(t_bytes_memory_ptr,t_struct(Validator)4604_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:43" - }, - { - "label": "_operatorFees", - "offset": 0, - "slot": "105", - "type": "t_mapping(t_uint256,t_array(t_struct(OperatorFee)4609_storage)dyn_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:44" - }, - { - "label": "_operatorsByOwnerAddress", - "offset": 0, - "slot": "106", - "type": "t_mapping(t_address,t_array(t_uint256)dyn_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:46" - }, - { - "label": "_validatorsByOwnerAddress", - "offset": 0, - "slot": "107", - "type": "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:47" - }, - { - "label": "_owners", - "offset": 0, - "slot": "108", - "type": "t_mapping(t_address,t_struct(OwnerData)4614_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:48" - }, - { - "label": "validatorsPerOperator", - "offset": 0, - "slot": "109", - "type": "t_mapping(t_uint256,t_uint256)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:50" - }, - { - "label": "validatorsPerOperatorLimit", - "offset": 0, - "slot": "110", - "type": "t_uint256", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:51" - }, - { - "label": "_operatorPublicKeyToId", - "offset": 0, - "slot": "111", - "type": "t_mapping(t_bytes_memory_ptr,t_uint256)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:52" - } - ], - "types": { - "t_address": { - "label": "address", - "numberOfBytes": "20" - }, - "t_array(t_bytes_storage)dyn_storage": { - "label": "bytes[]", - "numberOfBytes": "32" - }, - "t_array(t_struct(OperatorFee)4609_storage)dyn_storage": { - "label": "struct SSVRegistry.OperatorFee[]", - "numberOfBytes": "32" - }, - "t_array(t_uint256)49_storage": { - "label": "uint256[49]", - "numberOfBytes": "1568" - }, - "t_array(t_uint256)50_storage": { - "label": "uint256[50]", - "numberOfBytes": "1600" - }, - "t_array(t_uint256)dyn_storage": { - "label": "uint256[]", - "numberOfBytes": "32" - }, - "t_bool": { - "label": "bool", - "numberOfBytes": "1" - }, - "t_bytes_memory_ptr": { - "label": "bytes", - "numberOfBytes": "32" - }, - "t_bytes_storage": { - "label": "bytes", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)": { - "label": "mapping(address => bytes[])", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_array(t_uint256)dyn_storage)": { - "label": "mapping(address => uint256[])", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_struct(OwnerData)4614_storage)": { - "label": "mapping(address => struct SSVRegistry.OwnerData)", - "numberOfBytes": "32" - }, - "t_mapping(t_bytes_memory_ptr,t_struct(Validator)4604_storage)": { - "label": "mapping(bytes => struct SSVRegistry.Validator)", - "numberOfBytes": "32" - }, - "t_mapping(t_bytes_memory_ptr,t_uint256)": { - "label": "mapping(bytes => uint256)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_array(t_struct(OperatorFee)4609_storage)dyn_storage)": { - "label": "mapping(uint256 => struct SSVRegistry.OperatorFee[])", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(Operator)4594_storage)": { - "label": "mapping(uint256 => struct SSVRegistry.Operator)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_uint256)": { - "label": "mapping(uint256 => uint256)", - "numberOfBytes": "32" - }, - "t_string_storage": { - "label": "string", - "numberOfBytes": "32" - }, - "t_struct(Counter)1003_storage": { - "label": "struct Counters.Counter", - "members": [ - { - "label": "_value", - "type": "t_uint256", - "offset": 0, - "slot": "0" - } - ], - "numberOfBytes": "32" - }, - "t_struct(Operator)4594_storage": { - "label": "struct SSVRegistry.Operator", - "members": [ - { - "label": "name", - "type": "t_string_storage", - "offset": 0, - "slot": "0" - }, - { - "label": "ownerAddress", - "type": "t_address", - "offset": 0, - "slot": "1" - }, - { - "label": "publicKey", - "type": "t_bytes_storage", - "offset": 0, - "slot": "2" - }, - { - "label": "score", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "active", - "type": "t_bool", - "offset": 0, - "slot": "4" - }, - { - "label": "indexInOwner", - "type": "t_uint256", - "offset": 0, - "slot": "5" - } - ], - "numberOfBytes": "192" - }, - "t_struct(OperatorFee)4609_storage": { - "label": "struct SSVRegistry.OperatorFee", - "members": [ - { - "label": "blockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "fee", - "type": "t_uint256", - "offset": 0, - "slot": "1" - } - ], - "numberOfBytes": "64" - }, - "t_struct(OwnerData)4614_storage": { - "label": "struct SSVRegistry.OwnerData", - "members": [ - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "validatorsDisabled", - "type": "t_bool", - "offset": 0, - "slot": "1" - } - ], - "numberOfBytes": "64" - }, - "t_struct(Validator)4604_storage": { - "label": "struct SSVRegistry.Validator", - "members": [ - { - "label": "ownerAddress", - "type": "t_address", - "offset": 0, - "slot": "0" - }, - { - "label": "operatorIds", - "type": "t_array(t_uint256)dyn_storage", - "offset": 0, - "slot": "1" - }, - { - "label": "active", - "type": "t_bool", - "offset": 0, - "slot": "2" - }, - { - "label": "indexInOwner", - "type": "t_uint256", - "offset": 0, - "slot": "3" - } - ], - "numberOfBytes": "128" - }, - "t_uint256": { - "label": "uint256", - "numberOfBytes": "32" - } - } - } - }, - "1be681dbffb8ab244cf79a9cbc97c88af0b9a85596f58ef57f1f0eec19c1a706": { - "address": "0x000Db5194a12C6A6bDd0B4eDc6C661B006324195", - "txHash": "0xcefff356b2d58c3324934da1972a243a209207fc857e61763cbb8324cb9c660a", - "layout": { - "storage": [ - { - "contract": "Initializable", - "label": "_initialized", - "type": "t_bool", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:23" - }, - { - "contract": "Initializable", - "label": "_initializing", - "type": "t_bool", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:28" - }, - { - "contract": "ContextUpgradeable", - "label": "__gap", - "type": "t_array(t_uint256)50_storage", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" - }, - { - "contract": "OwnableUpgradeable", - "label": "_owner", - "type": "t_address", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:20" - }, - { - "contract": "OwnableUpgradeable", - "label": "__gap", - "type": "t_array(t_uint256)49_storage", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:74" - }, - { - "contract": "SSVNetwork", - "label": "_ssvRegistryContract", - "type": "t_contract(ISSVRegistry)1850", - "src": "contracts/SSVNetwork.sol:45" - }, - { - "contract": "SSVNetwork", - "label": "_token", - "type": "t_contract(IERC20)916", - "src": "contracts/SSVNetwork.sol:46" - }, - { - "contract": "SSVNetwork", - "label": "_minimumBlocksBeforeLiquidation", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:47" - }, - { - "contract": "SSVNetwork", - "label": "_operatorMaxFeeIncrease", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:48" - }, - { - "contract": "SSVNetwork", - "label": "_networkFee", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:50" - }, - { - "contract": "SSVNetwork", - "label": "_networkFeeIndex", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:51" - }, - { - "contract": "SSVNetwork", - "label": "_networkFeeIndexBlockNumber", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:52" - }, - { - "contract": "SSVNetwork", - "label": "_networkEarnings", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:53" - }, - { - "contract": "SSVNetwork", - "label": "_networkEarningsBlockNumber", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:54" - }, - { - "contract": "SSVNetwork", - "label": "_withdrawnFromTreasury", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:55" - }, - { - "contract": "SSVNetwork", - "label": "_operatorDatas", - "type": "t_mapping(t_uint256,t_struct(OperatorData)1874_storage)", - "src": "contracts/SSVNetwork.sol:57" - }, - { - "contract": "SSVNetwork", - "label": "_owners", - "type": "t_mapping(t_address,t_struct(OwnerData)1891_storage)", - "src": "contracts/SSVNetwork.sol:58" - }, - { - "contract": "SSVNetwork", - "label": "_operatorsInUseByAddress", - "type": "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)1902_storage))", - "src": "contracts/SSVNetwork.sol:59" - }, - { - "contract": "SSVNetwork", - "label": "_operatorsInUseList", - "type": "t_mapping(t_address,t_array(t_uint256)dyn_storage)", - "src": "contracts/SSVNetwork.sol:60" - }, - { - "contract": "SSVNetwork", - "label": "_lastOperatorUpdateNetworkFeeRun", - "type": "t_mapping(t_uint256,t_uint256)", - "src": "contracts/SSVNetwork.sol:61" - }, - { - "contract": "SSVNetwork", - "label": "_setOperatorFeePeriod", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:63" - }, - { - "contract": "SSVNetwork", - "label": "_approveOperatorFeePeriod", - "type": "t_uint256", - "src": "contracts/SSVNetwork.sol:64" - }, - { - "contract": "SSVNetwork", - "label": "_feeChangeRequests", - "type": "t_mapping(t_uint256,t_struct(FeeChangeRequest)1909_storage)", - "src": "contracts/SSVNetwork.sol:65" - } - ], - "types": { - "t_contract(ISSVRegistry)1850": { - "label": "contract ISSVRegistry" - }, - "t_contract(IERC20)916": { - "label": "contract IERC20" - }, - "t_uint256": { - "label": "uint256" - }, - "t_mapping(t_uint256,t_struct(OperatorData)1874_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorData)" - }, - "t_struct(OperatorData)1874_storage": { - "label": "struct SSVNetwork.OperatorData", - "members": [ - { - "label": "blockNumber", - "type": "t_uint256" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256" - }, - { - "label": "earnings", - "type": "t_uint256" - }, - { - "label": "index", - "type": "t_uint256" - }, - { - "label": "indexBlockNumber", - "type": "t_uint256" - }, - { - "label": "previousFee", - "type": "t_uint256" - } - ] - }, - "t_mapping(t_address,t_struct(OwnerData)1891_storage)": { - "label": "mapping(address => struct SSVNetwork.OwnerData)" - }, - "t_address": { - "label": "address" - }, - "t_struct(OwnerData)1891_storage": { - "label": "struct SSVNetwork.OwnerData", - "members": [ - { - "label": "deposited", - "type": "t_uint256" - }, - { - "label": "withdrawn", - "type": "t_uint256" - }, - { - "label": "earned", - "type": "t_uint256" - }, - { - "label": "used", - "type": "t_uint256" - }, - { - "label": "networkFee", - "type": "t_uint256" - }, - { - "label": "networkFeeIndex", - "type": "t_uint256" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256" - }, - { - "label": "validatorsDisabled", - "type": "t_bool" - } - ] - }, - "t_bool": { - "label": "bool" - }, - "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)1902_storage))": { - "label": "mapping(address => mapping(uint256 => struct SSVNetwork.OperatorInUse))" - }, - "t_mapping(t_uint256,t_struct(OperatorInUse)1902_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorInUse)" - }, - "t_struct(OperatorInUse)1902_storage": { - "label": "struct SSVNetwork.OperatorInUse", - "members": [ - { - "label": "index", - "type": "t_uint256" - }, - { - "label": "validatorCount", - "type": "t_uint256" - }, - { - "label": "used", - "type": "t_uint256" - }, - { - "label": "exists", - "type": "t_bool" - }, - { - "label": "indexInArray", - "type": "t_uint256" - } - ] - }, - "t_mapping(t_address,t_array(t_uint256)dyn_storage)": { - "label": "mapping(address => uint256[])" - }, - "t_array(t_uint256)dyn_storage": { - "label": "uint256[]" - }, - "t_mapping(t_uint256,t_uint256)": { - "label": "mapping(uint256 => uint256)" - }, - "t_mapping(t_uint256,t_struct(FeeChangeRequest)1909_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.FeeChangeRequest)" - }, - "t_struct(FeeChangeRequest)1909_storage": { - "label": "struct SSVNetwork.FeeChangeRequest", - "members": [ - { - "label": "fee", - "type": "t_uint256" - }, - { - "label": "approvalBeginTime", - "type": "t_uint256" - }, - { - "label": "approvalEndTime", - "type": "t_uint256" - } - ] - }, - "t_array(t_uint256)49_storage": { - "label": "uint256[49]" - }, - "t_array(t_uint256)50_storage": { - "label": "uint256[50]" - } - } - } - }, - "c9468aea4c9907b6748ca3e46567d61e600eef08082523fd7cf3c5de1a45c5c8": { - "address": "0x2b5691bDb2f68092e9375E7a2A8eb81C128A3451", - "txHash": "0xd3cfd2f6ff90dcbe7227007b8719110e8f7e1dd65ee406844b81ddf11620fab3", - "layout": { - "storage": [ - { - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:23" - }, - { - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:28" - }, - { - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage", - "contract": "ContextUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" - }, - { - "label": "_owner", - "offset": 0, - "slot": "51", - "type": "t_address", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:20" - }, - { - "label": "__gap", - "offset": 0, - "slot": "52", - "type": "t_array(t_uint256)49_storage", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:74" - }, - { - "label": "_ssvRegistryContract", - "offset": 0, - "slot": "101", - "type": "t_contract(ISSVRegistry)1896", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:45" - }, - { - "label": "_token", - "offset": 0, - "slot": "102", - "type": "t_contract(IERC20)950", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:46" - }, - { - "label": "_minimumBlocksBeforeLiquidation", - "offset": 0, - "slot": "103", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:47" - }, - { - "label": "_operatorMaxFeeIncrease", - "offset": 0, - "slot": "104", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:48" - }, - { - "label": "_networkFee", - "offset": 0, - "slot": "105", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:50" - }, - { - "label": "_networkFeeIndex", - "offset": 0, - "slot": "106", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:51" - }, - { - "label": "_networkFeeIndexBlockNumber", - "offset": 0, - "slot": "107", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:52" - }, - { - "label": "_networkEarnings", - "offset": 0, - "slot": "108", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:53" - }, - { - "label": "_networkEarningsBlockNumber", - "offset": 0, - "slot": "109", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:54" - }, - { - "label": "_withdrawnFromTreasury", - "offset": 0, - "slot": "110", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:55" - }, - { - "label": "_operatorDatas", - "offset": 0, - "slot": "111", - "type": "t_mapping(t_uint256,t_struct(OperatorData)1920_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:57" - }, - { - "label": "_owners", - "offset": 0, - "slot": "112", - "type": "t_mapping(t_address,t_struct(OwnerData)1937_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:58" - }, - { - "label": "_operatorsInUseByAddress", - "offset": 0, - "slot": "113", - "type": "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)1948_storage))", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:59" - }, - { - "label": "_operatorsInUseList", - "offset": 0, - "slot": "114", - "type": "t_mapping(t_address,t_array(t_uint256)dyn_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:60" - }, - { - "label": "_lastOperatorUpdateNetworkFeeRun", - "offset": 0, - "slot": "115", - "type": "t_mapping(t_uint256,t_uint256)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:61" - }, - { - "label": "_setOperatorFeePeriod", - "offset": 0, - "slot": "116", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:63" - }, - { - "label": "_approveOperatorFeePeriod", - "offset": 0, - "slot": "117", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:64" - }, - { - "label": "_feeChangeRequests", - "offset": 0, - "slot": "118", - "type": "t_mapping(t_uint256,t_struct(FeeChangeRequest)1955_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:65" - } - ], - "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_array(t_uint256)dyn_storage": { - "label": "uint256[]", - "numberOfBytes": "32" - }, - "t_bool": { - "label": "bool", - "numberOfBytes": "1" - }, - "t_contract(IERC20)950": { - "label": "contract IERC20", - "numberOfBytes": "20" - }, - "t_contract(ISSVRegistry)1896": { - "label": "contract ISSVRegistry", - "numberOfBytes": "20" - }, - "t_mapping(t_address,t_array(t_uint256)dyn_storage)": { - "label": "mapping(address => uint256[])", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)1948_storage))": { - "label": "mapping(address => mapping(uint256 => struct SSVNetwork.OperatorInUse))", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_struct(OwnerData)1937_storage)": { - "label": "mapping(address => struct SSVNetwork.OwnerData)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(FeeChangeRequest)1955_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.FeeChangeRequest)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(OperatorData)1920_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorData)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(OperatorInUse)1948_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorInUse)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_uint256)": { - "label": "mapping(uint256 => uint256)", - "numberOfBytes": "32" - }, - "t_struct(FeeChangeRequest)1955_storage": { - "label": "struct SSVNetwork.FeeChangeRequest", - "members": [ - { - "label": "fee", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "approvalBeginTime", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "approvalEndTime", - "type": "t_uint256", - "offset": 0, - "slot": "2" - } - ], - "numberOfBytes": "96" - }, - "t_struct(OperatorData)1920_storage": { - "label": "struct SSVNetwork.OperatorData", - "members": [ - { - "label": "blockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "earnings", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "index", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "indexBlockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "4" - }, - { - "label": "previousFee", - "type": "t_uint256", - "offset": 0, - "slot": "5" - } - ], - "numberOfBytes": "192" - }, - "t_struct(OperatorInUse)1948_storage": { - "label": "struct SSVNetwork.OperatorInUse", - "members": [ - { - "label": "index", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "validatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "used", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "exists", - "type": "t_bool", - "offset": 0, - "slot": "3" - }, - { - "label": "indexInArray", - "type": "t_uint256", - "offset": 0, - "slot": "4" - } - ], - "numberOfBytes": "160" - }, - "t_struct(OwnerData)1937_storage": { - "label": "struct SSVNetwork.OwnerData", - "members": [ - { - "label": "deposited", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "withdrawn", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "earned", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "used", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "networkFee", - "type": "t_uint256", - "offset": 0, - "slot": "4" - }, - { - "label": "networkFeeIndex", - "type": "t_uint256", - "offset": 0, - "slot": "5" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "6" - }, - { - "label": "validatorsDisabled", - "type": "t_bool", - "offset": 0, - "slot": "7" - } - ], - "numberOfBytes": "256" - }, - "t_uint256": { - "label": "uint256", - "numberOfBytes": "32" - } - } - } - }, - "3c50819bcb4b236876a1a4636028a3bd32a2bcf3df314fc5b00351f137f389e0": { - "address": "0xa7D38C6093d633196Fd8025307cB1fB45448b5E8", - "txHash": "0xc82d28babe79152a1477fd7dd6de171ddd93a5c1f7ff12661e6c0d11b5ff7192", - "layout": { - "storage": [ - { - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:39" - }, - { - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:44" - }, - { - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage", - "contract": "ContextUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" - }, - { - "label": "_owner", - "offset": 0, - "slot": "51", - "type": "t_address", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" - }, - { - "label": "__gap", - "offset": 0, - "slot": "52", - "type": "t_array(t_uint256)49_storage", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:87" - }, - { - "label": "_activeValidatorCount", - "offset": 0, - "slot": "101", - "type": "t_uint256", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:38" - }, - { - "label": "_lastOperatorId", - "offset": 0, - "slot": "102", - "type": "t_struct(Counter)1306_storage", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:40" - }, - { - "label": "_operators", - "offset": 0, - "slot": "103", - "type": "t_mapping(t_uint256,t_struct(Operator)4896_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:42" - }, - { - "label": "_validators", - "offset": 0, - "slot": "104", - "type": "t_mapping(t_bytes_memory_ptr,t_struct(Validator)4906_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:43" - }, - { - "label": "_operatorFees", - "offset": 0, - "slot": "105", - "type": "t_mapping(t_uint256,t_array(t_struct(OperatorFee)4911_storage)dyn_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:44" - }, - { - "label": "_operatorsByOwnerAddress", - "offset": 0, - "slot": "106", - "type": "t_mapping(t_address,t_array(t_uint256)dyn_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:46" - }, - { - "label": "_validatorsByOwnerAddress", - "offset": 0, - "slot": "107", - "type": "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:47" - }, - { - "label": "_owners", - "offset": 0, - "slot": "108", - "type": "t_mapping(t_address,t_struct(OwnerData)4916_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:48" - }, - { - "label": "validatorsPerOperator", - "offset": 0, - "slot": "109", - "type": "t_mapping(t_uint256,t_uint256)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:50" - }, - { - "label": "validatorsPerOperatorLimit", - "offset": 0, - "slot": "110", - "type": "t_uint256", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:51" - }, - { - "label": "_operatorPublicKeyToId", - "offset": 0, - "slot": "111", - "type": "t_mapping(t_bytes_memory_ptr,t_uint256)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:52" - } - ], - "types": { - "t_address": { - "label": "address", - "numberOfBytes": "20" - }, - "t_array(t_bytes_storage)dyn_storage": { - "label": "bytes[]", - "numberOfBytes": "32" - }, - "t_array(t_struct(OperatorFee)4911_storage)dyn_storage": { - "label": "struct SSVRegistry.OperatorFee[]", - "numberOfBytes": "32" - }, - "t_array(t_uint256)49_storage": { - "label": "uint256[49]", - "numberOfBytes": "1568" - }, - "t_array(t_uint256)50_storage": { - "label": "uint256[50]", - "numberOfBytes": "1600" - }, - "t_array(t_uint256)dyn_storage": { - "label": "uint256[]", - "numberOfBytes": "32" - }, - "t_bool": { - "label": "bool", - "numberOfBytes": "1" - }, - "t_bytes_memory_ptr": { - "label": "bytes", - "numberOfBytes": "32" - }, - "t_bytes_storage": { - "label": "bytes", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)": { - "label": "mapping(address => bytes[])", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_array(t_uint256)dyn_storage)": { - "label": "mapping(address => uint256[])", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_struct(OwnerData)4916_storage)": { - "label": "mapping(address => struct SSVRegistry.OwnerData)", - "numberOfBytes": "32" - }, - "t_mapping(t_bytes_memory_ptr,t_struct(Validator)4906_storage)": { - "label": "mapping(bytes => struct SSVRegistry.Validator)", - "numberOfBytes": "32" - }, - "t_mapping(t_bytes_memory_ptr,t_uint256)": { - "label": "mapping(bytes => uint256)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_array(t_struct(OperatorFee)4911_storage)dyn_storage)": { - "label": "mapping(uint256 => struct SSVRegistry.OperatorFee[])", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(Operator)4896_storage)": { - "label": "mapping(uint256 => struct SSVRegistry.Operator)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_uint256)": { - "label": "mapping(uint256 => uint256)", - "numberOfBytes": "32" - }, - "t_string_storage": { - "label": "string", - "numberOfBytes": "32" - }, - "t_struct(Counter)1306_storage": { - "label": "struct Counters.Counter", - "members": [ - { - "label": "_value", - "type": "t_uint256", - "offset": 0, - "slot": "0" - } - ], - "numberOfBytes": "32" - }, - "t_struct(Operator)4896_storage": { - "label": "struct SSVRegistry.Operator", - "members": [ - { - "label": "name", - "type": "t_string_storage", - "offset": 0, - "slot": "0" - }, - { - "label": "ownerAddress", - "type": "t_address", - "offset": 0, - "slot": "1" - }, - { - "label": "publicKey", - "type": "t_bytes_storage", - "offset": 0, - "slot": "2" - }, - { - "label": "score", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "active", - "type": "t_bool", - "offset": 0, - "slot": "4" - }, - { - "label": "indexInOwner", - "type": "t_uint256", - "offset": 0, - "slot": "5" - } - ], - "numberOfBytes": "192" - }, - "t_struct(OperatorFee)4911_storage": { - "label": "struct SSVRegistry.OperatorFee", - "members": [ - { - "label": "blockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "fee", - "type": "t_uint256", - "offset": 0, - "slot": "1" - } - ], - "numberOfBytes": "64" - }, - "t_struct(OwnerData)4916_storage": { - "label": "struct SSVRegistry.OwnerData", - "members": [ - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "validatorsDisabled", - "type": "t_bool", - "offset": 0, - "slot": "1" - } - ], - "numberOfBytes": "64" - }, - "t_struct(Validator)4906_storage": { - "label": "struct SSVRegistry.Validator", - "members": [ - { - "label": "ownerAddress", - "type": "t_address", - "offset": 0, - "slot": "0" - }, - { - "label": "operatorIds", - "type": "t_array(t_uint256)dyn_storage", - "offset": 0, - "slot": "1" - }, - { - "label": "active", - "type": "t_bool", - "offset": 0, - "slot": "2" - }, - { - "label": "indexInOwner", - "type": "t_uint256", - "offset": 0, - "slot": "3" - } - ], - "numberOfBytes": "128" - }, - "t_uint256": { - "label": "uint256", - "numberOfBytes": "32" - } - } - } - }, - "1c5afd88adfce109b40e7a53ca0e08405d9b74fc33ae32f5a970e3983f7d4fda": { - "address": "0xe30FDD6fb008A0a8f30bd9B18c7e6671839448B3", - "txHash": "0x1bafc5df98b06c209d457fae459ec519dd708456ccb3bb9d4a4e013d8d5571d7", - "layout": { - "storage": [ - { - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:23" - }, - { - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:28" - }, - { - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage", - "contract": "ContextUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" - }, - { - "label": "_owner", - "offset": 0, - "slot": "51", - "type": "t_address", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:20" - }, - { - "label": "__gap", - "offset": 0, - "slot": "52", - "type": "t_array(t_uint256)49_storage", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:74" - }, - { - "label": "_ssvRegistryContract", - "offset": 0, - "slot": "101", - "type": "t_contract(ISSVRegistry)1898", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:45" - }, - { - "label": "_token", - "offset": 0, - "slot": "102", - "type": "t_contract(IERC20)950", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:46" - }, - { - "label": "_minimumBlocksBeforeLiquidation", - "offset": 0, - "slot": "103", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:47" - }, - { - "label": "_operatorMaxFeeIncrease", - "offset": 0, - "slot": "104", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:48" - }, - { - "label": "_networkFee", - "offset": 0, - "slot": "105", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:50" - }, - { - "label": "_networkFeeIndex", - "offset": 0, - "slot": "106", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:51" - }, - { - "label": "_networkFeeIndexBlockNumber", - "offset": 0, - "slot": "107", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:52" - }, - { - "label": "_networkEarnings", - "offset": 0, - "slot": "108", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:53" - }, - { - "label": "_networkEarningsBlockNumber", - "offset": 0, - "slot": "109", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:54" - }, - { - "label": "_withdrawnFromTreasury", - "offset": 0, - "slot": "110", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:55" - }, - { - "label": "_operatorDatas", - "offset": 0, - "slot": "111", - "type": "t_mapping(t_uint256,t_struct(OperatorData)1922_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:57" - }, - { - "label": "_owners", - "offset": 0, - "slot": "112", - "type": "t_mapping(t_address,t_struct(OwnerData)1939_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:58" - }, - { - "label": "_operatorsInUseByAddress", - "offset": 0, - "slot": "113", - "type": "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)1950_storage))", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:59" - }, - { - "label": "_operatorsInUseList", - "offset": 0, - "slot": "114", - "type": "t_mapping(t_address,t_array(t_uint256)dyn_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:60" - }, - { - "label": "_lastOperatorUpdateNetworkFeeRun", - "offset": 0, - "slot": "115", - "type": "t_mapping(t_uint256,t_uint256)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:61" - }, - { - "label": "_setOperatorFeePeriod", - "offset": 0, - "slot": "116", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:63" - }, - { - "label": "_approveOperatorFeePeriod", - "offset": 0, - "slot": "117", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:64" - }, - { - "label": "_feeChangeRequests", - "offset": 0, - "slot": "118", - "type": "t_mapping(t_uint256,t_struct(FeeChangeRequest)1957_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:65" - } - ], - "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_array(t_uint256)dyn_storage": { - "label": "uint256[]", - "numberOfBytes": "32" - }, - "t_bool": { - "label": "bool", - "numberOfBytes": "1" - }, - "t_contract(IERC20)950": { - "label": "contract IERC20", - "numberOfBytes": "20" - }, - "t_contract(ISSVRegistry)1898": { - "label": "contract ISSVRegistry", - "numberOfBytes": "20" - }, - "t_mapping(t_address,t_array(t_uint256)dyn_storage)": { - "label": "mapping(address => uint256[])", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)1950_storage))": { - "label": "mapping(address => mapping(uint256 => struct SSVNetwork.OperatorInUse))", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_struct(OwnerData)1939_storage)": { - "label": "mapping(address => struct SSVNetwork.OwnerData)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(FeeChangeRequest)1957_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.FeeChangeRequest)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(OperatorData)1922_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorData)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(OperatorInUse)1950_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorInUse)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_uint256)": { - "label": "mapping(uint256 => uint256)", - "numberOfBytes": "32" - }, - "t_struct(FeeChangeRequest)1957_storage": { - "label": "struct SSVNetwork.FeeChangeRequest", - "members": [ - { - "label": "fee", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "approvalBeginTime", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "approvalEndTime", - "type": "t_uint256", - "offset": 0, - "slot": "2" - } - ], - "numberOfBytes": "96" - }, - "t_struct(OperatorData)1922_storage": { - "label": "struct SSVNetwork.OperatorData", - "members": [ - { - "label": "blockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "earnings", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "index", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "indexBlockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "4" - }, - { - "label": "previousFee", - "type": "t_uint256", - "offset": 0, - "slot": "5" - } - ], - "numberOfBytes": "192" - }, - "t_struct(OperatorInUse)1950_storage": { - "label": "struct SSVNetwork.OperatorInUse", - "members": [ - { - "label": "index", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "validatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "used", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "exists", - "type": "t_bool", - "offset": 0, - "slot": "3" - }, - { - "label": "indexInArray", - "type": "t_uint256", - "offset": 0, - "slot": "4" - } - ], - "numberOfBytes": "160" - }, - "t_struct(OwnerData)1939_storage": { - "label": "struct SSVNetwork.OwnerData", - "members": [ - { - "label": "deposited", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "withdrawn", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "earned", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "used", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "networkFee", - "type": "t_uint256", - "offset": 0, - "slot": "4" - }, - { - "label": "networkFeeIndex", - "type": "t_uint256", - "offset": 0, - "slot": "5" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "6" - }, - { - "label": "validatorsDisabled", - "type": "t_bool", - "offset": 0, - "slot": "7" - } - ], - "numberOfBytes": "256" - }, - "t_uint256": { - "label": "uint256", - "numberOfBytes": "32" - } - } - } - }, - "49f5b5339a1066d44b991641b5201895dd65a4af4c292c552bc44f9757f4a717": { - "address": "0x101449ddB2A9Bce92e949b921fE86fe027bE0f6b", - "txHash": "0x1f95b75014d7c9d9ea0fc66bb00ae50f194aa3005801c5d610f92eb4e026bc5c", - "layout": { - "storage": [ - { - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:23" - }, - { - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:28" - }, - { - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage", - "contract": "ContextUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" - }, - { - "label": "_owner", - "offset": 0, - "slot": "51", - "type": "t_address", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:20" - }, - { - "label": "__gap", - "offset": 0, - "slot": "52", - "type": "t_array(t_uint256)49_storage", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:74" - }, - { - "label": "_ssvRegistryContract", - "offset": 0, - "slot": "101", - "type": "t_contract(ISSVRegistry)1126", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:45" - }, - { - "label": "_token", - "offset": 0, - "slot": "102", - "type": "t_contract(IERC20)299", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:46" - }, - { - "label": "_minimumBlocksBeforeLiquidation", - "offset": 0, - "slot": "103", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:47" - }, - { - "label": "_operatorMaxFeeIncrease", - "offset": 0, - "slot": "104", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:48" - }, - { - "label": "_networkFee", - "offset": 0, - "slot": "105", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:50" - }, - { - "label": "_networkFeeIndex", - "offset": 0, - "slot": "106", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:51" - }, - { - "label": "_networkFeeIndexBlockNumber", - "offset": 0, - "slot": "107", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:52" - }, - { - "label": "_networkEarnings", - "offset": 0, - "slot": "108", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:53" - }, - { - "label": "_networkEarningsBlockNumber", - "offset": 0, - "slot": "109", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:54" - }, - { - "label": "_withdrawnFromTreasury", - "offset": 0, - "slot": "110", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:55" - }, - { - "label": "_operatorDatas", - "offset": 0, - "slot": "111", - "type": "t_mapping(t_uint256,t_struct(OperatorData)1150_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:57" - }, - { - "label": "_owners", - "offset": 0, - "slot": "112", - "type": "t_mapping(t_address,t_struct(OwnerData)1167_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:58" - }, - { - "label": "_operatorsInUseByAddress", - "offset": 0, - "slot": "113", - "type": "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)1178_storage))", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:59" - }, - { - "label": "_operatorsInUseList", - "offset": 0, - "slot": "114", - "type": "t_mapping(t_address,t_array(t_uint256)dyn_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:60" - }, - { - "label": "_lastOperatorUpdateNetworkFeeRun", - "offset": 0, - "slot": "115", - "type": "t_mapping(t_uint256,t_uint256)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:61" - }, - { - "label": "_setOperatorFeePeriod", - "offset": 0, - "slot": "116", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:63" - }, - { - "label": "_approveOperatorFeePeriod", - "offset": 0, - "slot": "117", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:64" - }, - { - "label": "_feeChangeRequests", - "offset": 0, - "slot": "118", - "type": "t_mapping(t_uint256,t_struct(FeeChangeRequest)1185_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:65" - } - ], - "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_array(t_uint256)dyn_storage": { - "label": "uint256[]", - "numberOfBytes": "32" - }, - "t_bool": { - "label": "bool", - "numberOfBytes": "1" - }, - "t_contract(IERC20)299": { - "label": "contract IERC20", - "numberOfBytes": "20" - }, - "t_contract(ISSVRegistry)1126": { - "label": "contract ISSVRegistry", - "numberOfBytes": "20" - }, - "t_mapping(t_address,t_array(t_uint256)dyn_storage)": { - "label": "mapping(address => uint256[])", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)1178_storage))": { - "label": "mapping(address => mapping(uint256 => struct SSVNetwork.OperatorInUse))", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_struct(OwnerData)1167_storage)": { - "label": "mapping(address => struct SSVNetwork.OwnerData)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(FeeChangeRequest)1185_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.FeeChangeRequest)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(OperatorData)1150_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorData)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(OperatorInUse)1178_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorInUse)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_uint256)": { - "label": "mapping(uint256 => uint256)", - "numberOfBytes": "32" - }, - "t_struct(FeeChangeRequest)1185_storage": { - "label": "struct SSVNetwork.FeeChangeRequest", - "members": [ - { - "label": "fee", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "approvalBeginTime", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "approvalEndTime", - "type": "t_uint256", - "offset": 0, - "slot": "2" - } - ], - "numberOfBytes": "96" - }, - "t_struct(OperatorData)1150_storage": { - "label": "struct SSVNetwork.OperatorData", - "members": [ - { - "label": "blockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "earnings", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "index", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "indexBlockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "4" - }, - { - "label": "previousFee", - "type": "t_uint256", - "offset": 0, - "slot": "5" - } - ], - "numberOfBytes": "192" - }, - "t_struct(OperatorInUse)1178_storage": { - "label": "struct SSVNetwork.OperatorInUse", - "members": [ - { - "label": "index", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "validatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "used", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "exists", - "type": "t_bool", - "offset": 0, - "slot": "3" - }, - { - "label": "indexInArray", - "type": "t_uint256", - "offset": 0, - "slot": "4" - } - ], - "numberOfBytes": "160" - }, - "t_struct(OwnerData)1167_storage": { - "label": "struct SSVNetwork.OwnerData", - "members": [ - { - "label": "deposited", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "withdrawn", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "earned", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "used", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "networkFee", - "type": "t_uint256", - "offset": 0, - "slot": "4" - }, - { - "label": "networkFeeIndex", - "type": "t_uint256", - "offset": 0, - "slot": "5" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "6" - }, - { - "label": "validatorsDisabled", - "type": "t_bool", - "offset": 0, - "slot": "7" - } - ], - "numberOfBytes": "256" - }, - "t_uint256": { - "label": "uint256", - "numberOfBytes": "32" - } - } - } - }, - "7d1a9368cc5dcd817b543e1fc63d509f51bdefb72d14cdebbed9f4e8e030f8f6": { - "address": "0x8a6Ee175dF8E56c1f0D1c00020e389FDb3Fd4f79", - "txHash": "0xd4213cfceaacdda3336bd4a76d214df98a16ba41c2dcb0407afd43951b3f1869", - "layout": { - "storage": [ - { - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:23" - }, - { - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:28" - }, - { - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage", - "contract": "ContextUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" - }, - { - "label": "_owner", - "offset": 0, - "slot": "51", - "type": "t_address", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:20" - }, - { - "label": "__gap", - "offset": 0, - "slot": "52", - "type": "t_array(t_uint256)49_storage", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:74" - }, - { - "label": "_ssvRegistryContract", - "offset": 0, - "slot": "101", - "type": "t_contract(ISSVRegistry)1126", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:45" - }, - { - "label": "_token", - "offset": 0, - "slot": "102", - "type": "t_contract(IERC20)299", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:46" - }, - { - "label": "_minimumBlocksBeforeLiquidation", - "offset": 0, - "slot": "103", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:47" - }, - { - "label": "_operatorMaxFeeIncrease", - "offset": 0, - "slot": "104", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:48" - }, - { - "label": "_networkFee", - "offset": 0, - "slot": "105", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:50" - }, - { - "label": "_networkFeeIndex", - "offset": 0, - "slot": "106", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:51" - }, - { - "label": "_networkFeeIndexBlockNumber", - "offset": 0, - "slot": "107", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:52" - }, - { - "label": "_networkEarnings", - "offset": 0, - "slot": "108", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:53" - }, - { - "label": "_networkEarningsBlockNumber", - "offset": 0, - "slot": "109", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:54" - }, - { - "label": "_withdrawnFromTreasury", - "offset": 0, - "slot": "110", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:55" - }, - { - "label": "_operatorDatas", - "offset": 0, - "slot": "111", - "type": "t_mapping(t_uint256,t_struct(OperatorData)1150_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:57" - }, - { - "label": "_owners", - "offset": 0, - "slot": "112", - "type": "t_mapping(t_address,t_struct(OwnerData)1167_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:58" - }, - { - "label": "_operatorsInUseByAddress", - "offset": 0, - "slot": "113", - "type": "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)1178_storage))", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:59" - }, - { - "label": "_operatorsInUseList", - "offset": 0, - "slot": "114", - "type": "t_mapping(t_address,t_array(t_uint256)dyn_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:60" - }, - { - "label": "_lastOperatorUpdateNetworkFeeRun", - "offset": 0, - "slot": "115", - "type": "t_mapping(t_uint256,t_uint256)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:61" - }, - { - "label": "_setOperatorFeePeriod", - "offset": 0, - "slot": "116", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:63" - }, - { - "label": "_approveOperatorFeePeriod", - "offset": 0, - "slot": "117", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:64" - }, - { - "label": "_feeChangeRequests", - "offset": 0, - "slot": "118", - "type": "t_mapping(t_uint256,t_struct(FeeChangeRequest)1185_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:65" - } - ], - "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_array(t_uint256)dyn_storage": { - "label": "uint256[]", - "numberOfBytes": "32" - }, - "t_bool": { - "label": "bool", - "numberOfBytes": "1" - }, - "t_contract(IERC20)299": { - "label": "contract IERC20", - "numberOfBytes": "20" - }, - "t_contract(ISSVRegistry)1126": { - "label": "contract ISSVRegistry", - "numberOfBytes": "20" - }, - "t_mapping(t_address,t_array(t_uint256)dyn_storage)": { - "label": "mapping(address => uint256[])", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)1178_storage))": { - "label": "mapping(address => mapping(uint256 => struct SSVNetwork.OperatorInUse))", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_struct(OwnerData)1167_storage)": { - "label": "mapping(address => struct SSVNetwork.OwnerData)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(FeeChangeRequest)1185_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.FeeChangeRequest)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(OperatorData)1150_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorData)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(OperatorInUse)1178_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorInUse)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_uint256)": { - "label": "mapping(uint256 => uint256)", - "numberOfBytes": "32" - }, - "t_struct(FeeChangeRequest)1185_storage": { - "label": "struct SSVNetwork.FeeChangeRequest", - "members": [ - { - "label": "fee", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "approvalBeginTime", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "approvalEndTime", - "type": "t_uint256", - "offset": 0, - "slot": "2" - } - ], - "numberOfBytes": "96" - }, - "t_struct(OperatorData)1150_storage": { - "label": "struct SSVNetwork.OperatorData", - "members": [ - { - "label": "blockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "earnings", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "index", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "indexBlockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "4" - }, - { - "label": "previousFee", - "type": "t_uint256", - "offset": 0, - "slot": "5" - } - ], - "numberOfBytes": "192" - }, - "t_struct(OperatorInUse)1178_storage": { - "label": "struct SSVNetwork.OperatorInUse", - "members": [ - { - "label": "index", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "validatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "used", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "exists", - "type": "t_bool", - "offset": 0, - "slot": "3" - }, - { - "label": "indexInArray", - "type": "t_uint256", - "offset": 0, - "slot": "4" - } - ], - "numberOfBytes": "160" - }, - "t_struct(OwnerData)1167_storage": { - "label": "struct SSVNetwork.OwnerData", - "members": [ - { - "label": "deposited", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "withdrawn", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "earned", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "used", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "networkFee", - "type": "t_uint256", - "offset": 0, - "slot": "4" - }, - { - "label": "networkFeeIndex", - "type": "t_uint256", - "offset": 0, - "slot": "5" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "6" - }, - { - "label": "validatorsDisabled", - "type": "t_bool", - "offset": 0, - "slot": "7" - } - ], - "numberOfBytes": "256" - }, - "t_uint256": { - "label": "uint256", - "numberOfBytes": "32" - } - } - } - }, - "4e10568edeb06c4e775550a6e1cd2c99741ab55bbc066fa01cf302570382e5d2": { - "address": "0xf3A44208173fdd619a1562797aAEa501F77f1406", - "txHash": "0x35afd4a6e30b80a691d95d2212406002f2194a3a37e2081f7505469099965286", - "layout": { - "storage": [ - { - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:23" - }, - { - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:28" - }, - { - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage", - "contract": "ContextUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" - }, - { - "label": "_owner", - "offset": 0, - "slot": "51", - "type": "t_address", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:20" - }, - { - "label": "__gap", - "offset": 0, - "slot": "52", - "type": "t_array(t_uint256)49_storage", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:74" - }, - { - "label": "_ssvRegistryContract", - "offset": 0, - "slot": "101", - "type": "t_contract(ISSVRegistry)1126", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:45" - }, - { - "label": "_token", - "offset": 0, - "slot": "102", - "type": "t_contract(IERC20)299", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:46" - }, - { - "label": "_minimumBlocksBeforeLiquidation", - "offset": 0, - "slot": "103", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:47" - }, - { - "label": "_operatorMaxFeeIncrease", - "offset": 0, - "slot": "104", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:48" - }, - { - "label": "_networkFee", - "offset": 0, - "slot": "105", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:50" - }, - { - "label": "_networkFeeIndex", - "offset": 0, - "slot": "106", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:51" - }, - { - "label": "_networkFeeIndexBlockNumber", - "offset": 0, - "slot": "107", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:52" - }, - { - "label": "_networkEarnings", - "offset": 0, - "slot": "108", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:53" - }, - { - "label": "_networkEarningsBlockNumber", - "offset": 0, - "slot": "109", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:54" - }, - { - "label": "_withdrawnFromTreasury", - "offset": 0, - "slot": "110", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:55" - }, - { - "label": "_operatorDatas", - "offset": 0, - "slot": "111", - "type": "t_mapping(t_uint256,t_struct(OperatorData)1150_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:57" - }, - { - "label": "_owners", - "offset": 0, - "slot": "112", - "type": "t_mapping(t_address,t_struct(OwnerData)1167_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:58" - }, - { - "label": "_operatorsInUseByAddress", - "offset": 0, - "slot": "113", - "type": "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)1178_storage))", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:59" - }, - { - "label": "_operatorsInUseList", - "offset": 0, - "slot": "114", - "type": "t_mapping(t_address,t_array(t_uint256)dyn_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:60" - }, - { - "label": "_lastOperatorUpdateNetworkFeeRun", - "offset": 0, - "slot": "115", - "type": "t_mapping(t_uint256,t_uint256)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:61" - }, - { - "label": "_setOperatorFeePeriod", - "offset": 0, - "slot": "116", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:63" - }, - { - "label": "_approveOperatorFeePeriod", - "offset": 0, - "slot": "117", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:64" - }, - { - "label": "_feeChangeRequests", - "offset": 0, - "slot": "118", - "type": "t_mapping(t_uint256,t_struct(FeeChangeRequest)1185_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:65" - } - ], - "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_array(t_uint256)dyn_storage": { - "label": "uint256[]", - "numberOfBytes": "32" - }, - "t_bool": { - "label": "bool", - "numberOfBytes": "1" - }, - "t_contract(IERC20)299": { - "label": "contract IERC20", - "numberOfBytes": "20" - }, - "t_contract(ISSVRegistry)1126": { - "label": "contract ISSVRegistry", - "numberOfBytes": "20" - }, - "t_mapping(t_address,t_array(t_uint256)dyn_storage)": { - "label": "mapping(address => uint256[])", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)1178_storage))": { - "label": "mapping(address => mapping(uint256 => struct SSVNetwork.OperatorInUse))", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_struct(OwnerData)1167_storage)": { - "label": "mapping(address => struct SSVNetwork.OwnerData)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(FeeChangeRequest)1185_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.FeeChangeRequest)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(OperatorData)1150_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorData)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(OperatorInUse)1178_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorInUse)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_uint256)": { - "label": "mapping(uint256 => uint256)", - "numberOfBytes": "32" - }, - "t_struct(FeeChangeRequest)1185_storage": { - "label": "struct SSVNetwork.FeeChangeRequest", - "members": [ - { - "label": "fee", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "approvalBeginTime", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "approvalEndTime", - "type": "t_uint256", - "offset": 0, - "slot": "2" - } - ], - "numberOfBytes": "96" - }, - "t_struct(OperatorData)1150_storage": { - "label": "struct SSVNetwork.OperatorData", - "members": [ - { - "label": "blockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "earnings", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "index", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "indexBlockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "4" - }, - { - "label": "previousFee", - "type": "t_uint256", - "offset": 0, - "slot": "5" - } - ], - "numberOfBytes": "192" - }, - "t_struct(OperatorInUse)1178_storage": { - "label": "struct SSVNetwork.OperatorInUse", - "members": [ - { - "label": "index", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "validatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "used", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "exists", - "type": "t_bool", - "offset": 0, - "slot": "3" - }, - { - "label": "indexInArray", - "type": "t_uint256", - "offset": 0, - "slot": "4" - } - ], - "numberOfBytes": "160" - }, - "t_struct(OwnerData)1167_storage": { - "label": "struct SSVNetwork.OwnerData", - "members": [ - { - "label": "deposited", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "withdrawn", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "earned", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "used", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "networkFee", - "type": "t_uint256", - "offset": 0, - "slot": "4" - }, - { - "label": "networkFeeIndex", - "type": "t_uint256", - "offset": 0, - "slot": "5" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "6" - }, - { - "label": "validatorsDisabled", - "type": "t_bool", - "offset": 0, - "slot": "7" - } - ], - "numberOfBytes": "256" - }, - "t_uint256": { - "label": "uint256", - "numberOfBytes": "32" - } - } - } - }, - "3c778a272794844b8c2622153b831ab8ba9bb34a7159048b1c91221e187085b9": { - "address": "0xb3Ce54B832acDE442349d6D4F9A80b0671e5759F", - "txHash": "0xc592ecfc5aab8b5da23f211dc5c3fee483866e918d5b0aee098c777ca2872a29", - "layout": { - "storage": [ - { - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:23" - }, - { - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:28" - }, - { - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage", - "contract": "ContextUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" - }, - { - "label": "_owner", - "offset": 0, - "slot": "51", - "type": "t_address", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:20" - }, - { - "label": "__gap", - "offset": 0, - "slot": "52", - "type": "t_array(t_uint256)49_storage", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:74" - }, - { - "label": "_activeValidatorCount", - "offset": 0, - "slot": "101", - "type": "t_uint256", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:38" - }, - { - "label": "_lastOperatorId", - "offset": 0, - "slot": "102", - "type": "t_struct(Counter)1003_storage", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:40" - }, - { - "label": "_operators", - "offset": 0, - "slot": "103", - "type": "t_mapping(t_uint256,t_struct(Operator)4704_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:42" - }, - { - "label": "_validators", - "offset": 0, - "slot": "104", - "type": "t_mapping(t_bytes_memory_ptr,t_struct(Validator)4714_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:43" - }, - { - "label": "_operatorFees", - "offset": 0, - "slot": "105", - "type": "t_mapping(t_uint256,t_array(t_struct(OperatorFee)4719_storage)dyn_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:44" - }, - { - "label": "_operatorsByOwnerAddress", - "offset": 0, - "slot": "106", - "type": "t_mapping(t_address,t_array(t_uint256)dyn_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:46" - }, - { - "label": "_validatorsByOwnerAddress", - "offset": 0, - "slot": "107", - "type": "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:47" - }, - { - "label": "_owners", - "offset": 0, - "slot": "108", - "type": "t_mapping(t_address,t_struct(OwnerData)4724_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:48" - }, - { - "label": "validatorsPerOperator", - "offset": 0, - "slot": "109", - "type": "t_mapping(t_uint256,t_uint256)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:50" - }, - { - "label": "validatorsPerOperatorLimit", - "offset": 0, - "slot": "110", - "type": "t_uint256", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:51" - }, - { - "label": "_operatorPublicKeyToId", - "offset": 0, - "slot": "111", - "type": "t_mapping(t_bytes_memory_ptr,t_uint256)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:52" - } - ], - "types": { - "t_address": { - "label": "address", - "numberOfBytes": "20" - }, - "t_array(t_bytes_storage)dyn_storage": { - "label": "bytes[]", - "numberOfBytes": "32" - }, - "t_array(t_struct(OperatorFee)4719_storage)dyn_storage": { - "label": "struct SSVRegistry.OperatorFee[]", - "numberOfBytes": "32" - }, - "t_array(t_uint256)49_storage": { - "label": "uint256[49]", - "numberOfBytes": "1568" - }, - "t_array(t_uint256)50_storage": { - "label": "uint256[50]", - "numberOfBytes": "1600" - }, - "t_array(t_uint256)dyn_storage": { - "label": "uint256[]", - "numberOfBytes": "32" - }, - "t_bool": { - "label": "bool", - "numberOfBytes": "1" - }, - "t_bytes_memory_ptr": { - "label": "bytes", - "numberOfBytes": "32" - }, - "t_bytes_storage": { - "label": "bytes", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)": { - "label": "mapping(address => bytes[])", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_array(t_uint256)dyn_storage)": { - "label": "mapping(address => uint256[])", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_struct(OwnerData)4724_storage)": { - "label": "mapping(address => struct SSVRegistry.OwnerData)", - "numberOfBytes": "32" - }, - "t_mapping(t_bytes_memory_ptr,t_struct(Validator)4714_storage)": { - "label": "mapping(bytes => struct SSVRegistry.Validator)", - "numberOfBytes": "32" - }, - "t_mapping(t_bytes_memory_ptr,t_uint256)": { - "label": "mapping(bytes => uint256)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_array(t_struct(OperatorFee)4719_storage)dyn_storage)": { - "label": "mapping(uint256 => struct SSVRegistry.OperatorFee[])", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(Operator)4704_storage)": { - "label": "mapping(uint256 => struct SSVRegistry.Operator)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_uint256)": { - "label": "mapping(uint256 => uint256)", - "numberOfBytes": "32" - }, - "t_string_storage": { - "label": "string", - "numberOfBytes": "32" - }, - "t_struct(Counter)1003_storage": { - "label": "struct Counters.Counter", - "members": [ - { - "label": "_value", - "type": "t_uint256", - "offset": 0, - "slot": "0" - } - ], - "numberOfBytes": "32" - }, - "t_struct(Operator)4704_storage": { - "label": "struct SSVRegistry.Operator", - "members": [ - { - "label": "name", - "type": "t_string_storage", - "offset": 0, - "slot": "0" - }, - { - "label": "ownerAddress", - "type": "t_address", - "offset": 0, - "slot": "1" - }, - { - "label": "publicKey", - "type": "t_bytes_storage", - "offset": 0, - "slot": "2" - }, - { - "label": "score", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "active", - "type": "t_bool", - "offset": 0, - "slot": "4" - }, - { - "label": "indexInOwner", - "type": "t_uint256", - "offset": 0, - "slot": "5" - } - ], - "numberOfBytes": "192" - }, - "t_struct(OperatorFee)4719_storage": { - "label": "struct SSVRegistry.OperatorFee", - "members": [ - { - "label": "blockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "fee", - "type": "t_uint256", - "offset": 0, - "slot": "1" - } - ], - "numberOfBytes": "64" - }, - "t_struct(OwnerData)4724_storage": { - "label": "struct SSVRegistry.OwnerData", - "members": [ - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "validatorsDisabled", - "type": "t_bool", - "offset": 0, - "slot": "1" - } - ], - "numberOfBytes": "64" - }, - "t_struct(Validator)4714_storage": { - "label": "struct SSVRegistry.Validator", - "members": [ - { - "label": "ownerAddress", - "type": "t_address", - "offset": 0, - "slot": "0" - }, - { - "label": "operatorIds", - "type": "t_array(t_uint256)dyn_storage", - "offset": 0, - "slot": "1" - }, - { - "label": "active", - "type": "t_bool", - "offset": 0, - "slot": "2" - }, - { - "label": "indexInOwner", - "type": "t_uint256", - "offset": 0, - "slot": "3" - } - ], - "numberOfBytes": "128" - }, - "t_uint256": { - "label": "uint256", - "numberOfBytes": "32" - } - } - } - }, - "d4b4ef97a578fb99837166abcb29522ddbeb7da64c3d557e6a32652e3e47021a": { - "address": "0x16f1fEd6b86Ef0546ba787f8798441E27EFDC131", - "txHash": "0x41a6715bd438d181c38a96e141dc3f5622588826e145de2d2a74e25d2e587468", - "layout": { - "storage": [ - { - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:23" - }, - { - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:28" - }, - { - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage", - "contract": "ContextUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" - }, - { - "label": "_owner", - "offset": 0, - "slot": "51", - "type": "t_address", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:20" - }, - { - "label": "__gap", - "offset": 0, - "slot": "52", - "type": "t_array(t_uint256)49_storage", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:74" - }, - { - "label": "_ssvRegistryContract", - "offset": 0, - "slot": "101", - "type": "t_contract(ISSVRegistry)1930", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:45" - }, - { - "label": "_token", - "offset": 0, - "slot": "102", - "type": "t_contract(IERC20)950", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:46" - }, - { - "label": "_minimumBlocksBeforeLiquidation", - "offset": 0, - "slot": "103", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:47" - }, - { - "label": "_operatorMaxFeeIncrease", - "offset": 0, - "slot": "104", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:48" - }, - { - "label": "_networkFee", - "offset": 0, - "slot": "105", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:50" - }, - { - "label": "_networkFeeIndex", - "offset": 0, - "slot": "106", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:51" - }, - { - "label": "_networkFeeIndexBlockNumber", - "offset": 0, - "slot": "107", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:52" - }, - { - "label": "_networkEarnings", - "offset": 0, - "slot": "108", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:53" - }, - { - "label": "_networkEarningsBlockNumber", - "offset": 0, - "slot": "109", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:54" - }, - { - "label": "_withdrawnFromTreasury", - "offset": 0, - "slot": "110", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:55" - }, - { - "label": "_operatorDatas", - "offset": 0, - "slot": "111", - "type": "t_mapping(t_uint256,t_struct(OperatorData)1954_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:57" - }, - { - "label": "_owners", - "offset": 0, - "slot": "112", - "type": "t_mapping(t_address,t_struct(OwnerData)1971_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:58" - }, - { - "label": "_operatorsInUseByAddress", - "offset": 0, - "slot": "113", - "type": "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)1982_storage))", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:59" - }, - { - "label": "_operatorsInUseList", - "offset": 0, - "slot": "114", - "type": "t_mapping(t_address,t_array(t_uint256)dyn_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:60" - }, - { - "label": "_lastOperatorUpdateNetworkFeeRun", - "offset": 0, - "slot": "115", - "type": "t_mapping(t_uint256,t_uint256)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:61" - }, - { - "label": "_setOperatorFeePeriod", - "offset": 0, - "slot": "116", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:63" - }, - { - "label": "_approveOperatorFeePeriod", - "offset": 0, - "slot": "117", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:64" - }, - { - "label": "_feeChangeRequests", - "offset": 0, - "slot": "118", - "type": "t_mapping(t_uint256,t_struct(FeeChangeRequest)1989_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:65" - } - ], - "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_array(t_uint256)dyn_storage": { - "label": "uint256[]", - "numberOfBytes": "32" - }, - "t_bool": { - "label": "bool", - "numberOfBytes": "1" - }, - "t_contract(IERC20)950": { - "label": "contract IERC20", - "numberOfBytes": "20" - }, - "t_contract(ISSVRegistry)1930": { - "label": "contract ISSVRegistry", - "numberOfBytes": "20" - }, - "t_mapping(t_address,t_array(t_uint256)dyn_storage)": { - "label": "mapping(address => uint256[])", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)1982_storage))": { - "label": "mapping(address => mapping(uint256 => struct SSVNetwork.OperatorInUse))", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_struct(OwnerData)1971_storage)": { - "label": "mapping(address => struct SSVNetwork.OwnerData)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(FeeChangeRequest)1989_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.FeeChangeRequest)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(OperatorData)1954_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorData)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(OperatorInUse)1982_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorInUse)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_uint256)": { - "label": "mapping(uint256 => uint256)", - "numberOfBytes": "32" - }, - "t_struct(FeeChangeRequest)1989_storage": { - "label": "struct SSVNetwork.FeeChangeRequest", - "members": [ - { - "label": "fee", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "approvalBeginTime", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "approvalEndTime", - "type": "t_uint256", - "offset": 0, - "slot": "2" - } - ], - "numberOfBytes": "96" - }, - "t_struct(OperatorData)1954_storage": { - "label": "struct SSVNetwork.OperatorData", - "members": [ - { - "label": "blockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "earnings", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "index", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "indexBlockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "4" - }, - { - "label": "previousFee", - "type": "t_uint256", - "offset": 0, - "slot": "5" - } - ], - "numberOfBytes": "192" - }, - "t_struct(OperatorInUse)1982_storage": { - "label": "struct SSVNetwork.OperatorInUse", - "members": [ - { - "label": "index", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "validatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "used", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "exists", - "type": "t_bool", - "offset": 0, - "slot": "3" - }, - { - "label": "indexInArray", - "type": "t_uint256", - "offset": 0, - "slot": "4" - } - ], - "numberOfBytes": "160" - }, - "t_struct(OwnerData)1971_storage": { - "label": "struct SSVNetwork.OwnerData", - "members": [ - { - "label": "deposited", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "withdrawn", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "earned", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "used", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "networkFee", - "type": "t_uint256", - "offset": 0, - "slot": "4" - }, - { - "label": "networkFeeIndex", - "type": "t_uint256", - "offset": 0, - "slot": "5" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "6" - }, - { - "label": "validatorsDisabled", - "type": "t_bool", - "offset": 0, - "slot": "7" - } - ], - "numberOfBytes": "256" - }, - "t_uint256": { - "label": "uint256", - "numberOfBytes": "32" - } - } - } - }, - "2d779870a5a68b62a448777dae896b376aeb98e4402ddef38d046dd512e379f0": { - "address": "0x1E529C5e476Db0C53187BfDcaD17a88b5004e4bd", - "txHash": "0xa28edc8e14da8408acfbcae74e6680c40782c4cd0e91ff0282b96f529506a0ac", - "layout": { - "storage": [ - { - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:23" - }, - { - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:28" - }, - { - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage", - "contract": "ContextUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" - }, - { - "label": "_owner", - "offset": 0, - "slot": "51", - "type": "t_address", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:20" - }, - { - "label": "__gap", - "offset": 0, - "slot": "52", - "type": "t_array(t_uint256)49_storage", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:74" - }, - { - "label": "_ssvRegistryContract", - "offset": 0, - "slot": "101", - "type": "t_contract(ISSVRegistry)1158", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:45" - }, - { - "label": "_token", - "offset": 0, - "slot": "102", - "type": "t_contract(IERC20)299", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:46" - }, - { - "label": "_minimumBlocksBeforeLiquidation", - "offset": 0, - "slot": "103", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:47" - }, - { - "label": "_operatorMaxFeeIncrease", - "offset": 0, - "slot": "104", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:48" - }, - { - "label": "_networkFee", - "offset": 0, - "slot": "105", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:50" - }, - { - "label": "_networkFeeIndex", - "offset": 0, - "slot": "106", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:51" - }, - { - "label": "_networkFeeIndexBlockNumber", - "offset": 0, - "slot": "107", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:52" - }, - { - "label": "_networkEarnings", - "offset": 0, - "slot": "108", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:53" - }, - { - "label": "_networkEarningsBlockNumber", - "offset": 0, - "slot": "109", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:54" - }, - { - "label": "_withdrawnFromTreasury", - "offset": 0, - "slot": "110", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:55" - }, - { - "label": "_operatorDatas", - "offset": 0, - "slot": "111", - "type": "t_mapping(t_uint256,t_struct(OperatorData)1182_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:57" - }, - { - "label": "_owners", - "offset": 0, - "slot": "112", - "type": "t_mapping(t_address,t_struct(OwnerData)1199_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:58" - }, - { - "label": "_operatorsInUseByAddress", - "offset": 0, - "slot": "113", - "type": "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)1210_storage))", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:59" - }, - { - "label": "_operatorsInUseList", - "offset": 0, - "slot": "114", - "type": "t_mapping(t_address,t_array(t_uint256)dyn_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:60" - }, - { - "label": "_lastOperatorUpdateNetworkFeeRun", - "offset": 0, - "slot": "115", - "type": "t_mapping(t_uint256,t_uint256)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:61" - }, - { - "label": "_setOperatorFeePeriod", - "offset": 0, - "slot": "116", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:63" - }, - { - "label": "_approveOperatorFeePeriod", - "offset": 0, - "slot": "117", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:64" - }, - { - "label": "_feeChangeRequests", - "offset": 0, - "slot": "118", - "type": "t_mapping(t_uint256,t_struct(FeeChangeRequest)1217_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:65" - } - ], - "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_array(t_uint256)dyn_storage": { - "label": "uint256[]", - "numberOfBytes": "32" - }, - "t_bool": { - "label": "bool", - "numberOfBytes": "1" - }, - "t_contract(IERC20)299": { - "label": "contract IERC20", - "numberOfBytes": "20" - }, - "t_contract(ISSVRegistry)1158": { - "label": "contract ISSVRegistry", - "numberOfBytes": "20" - }, - "t_mapping(t_address,t_array(t_uint256)dyn_storage)": { - "label": "mapping(address => uint256[])", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)1210_storage))": { - "label": "mapping(address => mapping(uint256 => struct SSVNetwork.OperatorInUse))", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_struct(OwnerData)1199_storage)": { - "label": "mapping(address => struct SSVNetwork.OwnerData)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(FeeChangeRequest)1217_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.FeeChangeRequest)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(OperatorData)1182_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorData)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(OperatorInUse)1210_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorInUse)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_uint256)": { - "label": "mapping(uint256 => uint256)", - "numberOfBytes": "32" - }, - "t_struct(FeeChangeRequest)1217_storage": { - "label": "struct SSVNetwork.FeeChangeRequest", - "members": [ - { - "label": "fee", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "approvalBeginTime", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "approvalEndTime", - "type": "t_uint256", - "offset": 0, - "slot": "2" - } - ], - "numberOfBytes": "96" - }, - "t_struct(OperatorData)1182_storage": { - "label": "struct SSVNetwork.OperatorData", - "members": [ - { - "label": "blockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "earnings", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "index", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "indexBlockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "4" - }, - { - "label": "previousFee", - "type": "t_uint256", - "offset": 0, - "slot": "5" - } - ], - "numberOfBytes": "192" - }, - "t_struct(OperatorInUse)1210_storage": { - "label": "struct SSVNetwork.OperatorInUse", - "members": [ - { - "label": "index", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "validatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "used", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "exists", - "type": "t_bool", - "offset": 0, - "slot": "3" - }, - { - "label": "indexInArray", - "type": "t_uint256", - "offset": 0, - "slot": "4" - } - ], - "numberOfBytes": "160" - }, - "t_struct(OwnerData)1199_storage": { - "label": "struct SSVNetwork.OwnerData", - "members": [ - { - "label": "deposited", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "withdrawn", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "earned", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "used", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "networkFee", - "type": "t_uint256", - "offset": 0, - "slot": "4" - }, - { - "label": "networkFeeIndex", - "type": "t_uint256", - "offset": 0, - "slot": "5" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "6" - }, - { - "label": "validatorsDisabled", - "type": "t_bool", - "offset": 0, - "slot": "7" - } - ], - "numberOfBytes": "256" - }, - "t_uint256": { - "label": "uint256", - "numberOfBytes": "32" - } - } - } - }, - "f557f63bcbc898781de3d29c33c5f1afbfe1361bbdbfbe23ee7a2f269f484925": { - "address": "0xdE11D8AEb1a6cD2B3a9bDcf6Ec696512FAcf6720", - "txHash": "0x22e53cba7c190110ae87455601ea6cf5e5cfc2291d548e34e538a848da0628e3", - "layout": { - "storage": [ - { - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:23" - }, - { - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:28" - }, - { - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage", - "contract": "ContextUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" - }, - { - "label": "_owner", - "offset": 0, - "slot": "51", - "type": "t_address", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:20" - }, - { - "label": "__gap", - "offset": 0, - "slot": "52", - "type": "t_array(t_uint256)49_storage", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:74" - }, - { - "label": "_ssvRegistryContract", - "offset": 0, - "slot": "101", - "type": "t_contract(ISSVRegistry)1166", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:45" - }, - { - "label": "_token", - "offset": 0, - "slot": "102", - "type": "t_contract(IERC20)299", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:46" - }, - { - "label": "_minimumBlocksBeforeLiquidation", - "offset": 0, - "slot": "103", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:47" - }, - { - "label": "_operatorMaxFeeIncrease", - "offset": 0, - "slot": "104", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:48" - }, - { - "label": "_networkFee", - "offset": 0, - "slot": "105", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:50" - }, - { - "label": "_networkFeeIndex", - "offset": 0, - "slot": "106", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:51" - }, - { - "label": "_networkFeeIndexBlockNumber", - "offset": 0, - "slot": "107", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:52" - }, - { - "label": "_networkEarnings", - "offset": 0, - "slot": "108", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:53" - }, - { - "label": "_networkEarningsBlockNumber", - "offset": 0, - "slot": "109", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:54" - }, - { - "label": "_withdrawnFromTreasury", - "offset": 0, - "slot": "110", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:55" - }, - { - "label": "_operatorDatas", - "offset": 0, - "slot": "111", - "type": "t_mapping(t_uint256,t_struct(OperatorData)1190_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:57" - }, - { - "label": "_owners", - "offset": 0, - "slot": "112", - "type": "t_mapping(t_address,t_struct(OwnerData)1207_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:58" - }, - { - "label": "_operatorsInUseByAddress", - "offset": 0, - "slot": "113", - "type": "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)1218_storage))", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:59" - }, - { - "label": "_operatorsInUseList", - "offset": 0, - "slot": "114", - "type": "t_mapping(t_address,t_array(t_uint256)dyn_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:60" - }, - { - "label": "_lastOperatorUpdateNetworkFeeRun", - "offset": 0, - "slot": "115", - "type": "t_mapping(t_uint256,t_uint256)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:61" - }, - { - "label": "_setOperatorFeePeriod", - "offset": 0, - "slot": "116", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:63" - }, - { - "label": "_approveOperatorFeePeriod", - "offset": 0, - "slot": "117", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:64" - }, - { - "label": "_feeChangeRequests", - "offset": 0, - "slot": "118", - "type": "t_mapping(t_uint256,t_struct(FeeChangeRequest)1225_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:65" - } - ], - "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_array(t_uint256)dyn_storage": { - "label": "uint256[]", - "numberOfBytes": "32" - }, - "t_bool": { - "label": "bool", - "numberOfBytes": "1" - }, - "t_contract(IERC20)299": { - "label": "contract IERC20", - "numberOfBytes": "20" - }, - "t_contract(ISSVRegistry)1166": { - "label": "contract ISSVRegistry", - "numberOfBytes": "20" - }, - "t_mapping(t_address,t_array(t_uint256)dyn_storage)": { - "label": "mapping(address => uint256[])", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)1218_storage))": { - "label": "mapping(address => mapping(uint256 => struct SSVNetwork.OperatorInUse))", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_struct(OwnerData)1207_storage)": { - "label": "mapping(address => struct SSVNetwork.OwnerData)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(FeeChangeRequest)1225_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.FeeChangeRequest)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(OperatorData)1190_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorData)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(OperatorInUse)1218_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorInUse)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_uint256)": { - "label": "mapping(uint256 => uint256)", - "numberOfBytes": "32" - }, - "t_struct(FeeChangeRequest)1225_storage": { - "label": "struct SSVNetwork.FeeChangeRequest", - "members": [ - { - "label": "fee", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "approvalBeginTime", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "approvalEndTime", - "type": "t_uint256", - "offset": 0, - "slot": "2" - } - ], - "numberOfBytes": "96" - }, - "t_struct(OperatorData)1190_storage": { - "label": "struct SSVNetwork.OperatorData", - "members": [ - { - "label": "blockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "earnings", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "index", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "indexBlockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "4" - }, - { - "label": "previousFee", - "type": "t_uint256", - "offset": 0, - "slot": "5" - } - ], - "numberOfBytes": "192" - }, - "t_struct(OperatorInUse)1218_storage": { - "label": "struct SSVNetwork.OperatorInUse", - "members": [ - { - "label": "index", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "validatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "used", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "exists", - "type": "t_bool", - "offset": 0, - "slot": "3" - }, - { - "label": "indexInArray", - "type": "t_uint256", - "offset": 0, - "slot": "4" - } - ], - "numberOfBytes": "160" - }, - "t_struct(OwnerData)1207_storage": { - "label": "struct SSVNetwork.OwnerData", - "members": [ - { - "label": "deposited", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "withdrawn", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "earned", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "used", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "networkFee", - "type": "t_uint256", - "offset": 0, - "slot": "4" - }, - { - "label": "networkFeeIndex", - "type": "t_uint256", - "offset": 0, - "slot": "5" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "6" - }, - { - "label": "validatorsDisabled", - "type": "t_bool", - "offset": 0, - "slot": "7" - } - ], - "numberOfBytes": "256" - }, - "t_uint256": { - "label": "uint256", - "numberOfBytes": "32" - } - } - } - }, - "ae5984ead891d2e47210c2ff576be6f5a5f98ca46f06a86a9a6ca9733e061446": { - "address": "0x2634AFF73b6014A62ceC667e809255E6a46624A4", - "txHash": "0x8979f4c4c3e3ce142154070dde554d6f617ed823c498a8363bc64f5822b39a1e", - "layout": { - "storage": [ - { - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:23" - }, - { - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:28" - }, - { - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage", - "contract": "ContextUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" - }, - { - "label": "_owner", - "offset": 0, - "slot": "51", - "type": "t_address", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:20" - }, - { - "label": "__gap", - "offset": 0, - "slot": "52", - "type": "t_array(t_uint256)49_storage", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:74" - }, - { - "label": "_ssvRegistryContract", - "offset": 0, - "slot": "101", - "type": "t_contract(ISSVRegistry)1938", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:45" - }, - { - "label": "_token", - "offset": 0, - "slot": "102", - "type": "t_contract(IERC20)950", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:46" - }, - { - "label": "_minimumBlocksBeforeLiquidation", - "offset": 0, - "slot": "103", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:47" - }, - { - "label": "_operatorMaxFeeIncrease", - "offset": 0, - "slot": "104", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:48" - }, - { - "label": "_networkFee", - "offset": 0, - "slot": "105", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:50" - }, - { - "label": "_networkFeeIndex", - "offset": 0, - "slot": "106", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:51" - }, - { - "label": "_networkFeeIndexBlockNumber", - "offset": 0, - "slot": "107", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:52" - }, - { - "label": "_networkEarnings", - "offset": 0, - "slot": "108", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:53" - }, - { - "label": "_networkEarningsBlockNumber", - "offset": 0, - "slot": "109", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:54" - }, - { - "label": "_withdrawnFromTreasury", - "offset": 0, - "slot": "110", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:55" - }, - { - "label": "_operatorDatas", - "offset": 0, - "slot": "111", - "type": "t_mapping(t_uint256,t_struct(OperatorData)1962_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:57" - }, - { - "label": "_owners", - "offset": 0, - "slot": "112", - "type": "t_mapping(t_address,t_struct(OwnerData)1979_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:58" - }, - { - "label": "_operatorsInUseByAddress", - "offset": 0, - "slot": "113", - "type": "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)1990_storage))", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:59" - }, - { - "label": "_operatorsInUseList", - "offset": 0, - "slot": "114", - "type": "t_mapping(t_address,t_array(t_uint256)dyn_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:60" - }, - { - "label": "_lastOperatorUpdateNetworkFeeRun", - "offset": 0, - "slot": "115", - "type": "t_mapping(t_uint256,t_uint256)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:61" - }, - { - "label": "_setOperatorFeePeriod", - "offset": 0, - "slot": "116", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:63" - }, - { - "label": "_approveOperatorFeePeriod", - "offset": 0, - "slot": "117", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:64" - }, - { - "label": "_feeChangeRequests", - "offset": 0, - "slot": "118", - "type": "t_mapping(t_uint256,t_struct(FeeChangeRequest)1997_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:65" - } - ], - "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_array(t_uint256)dyn_storage": { - "label": "uint256[]", - "numberOfBytes": "32" - }, - "t_bool": { - "label": "bool", - "numberOfBytes": "1" - }, - "t_contract(IERC20)950": { - "label": "contract IERC20", - "numberOfBytes": "20" - }, - "t_contract(ISSVRegistry)1938": { - "label": "contract ISSVRegistry", - "numberOfBytes": "20" - }, - "t_mapping(t_address,t_array(t_uint256)dyn_storage)": { - "label": "mapping(address => uint256[])", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)1990_storage))": { - "label": "mapping(address => mapping(uint256 => struct SSVNetwork.OperatorInUse))", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_struct(OwnerData)1979_storage)": { - "label": "mapping(address => struct SSVNetwork.OwnerData)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(FeeChangeRequest)1997_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.FeeChangeRequest)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(OperatorData)1962_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorData)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(OperatorInUse)1990_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorInUse)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_uint256)": { - "label": "mapping(uint256 => uint256)", - "numberOfBytes": "32" - }, - "t_struct(FeeChangeRequest)1997_storage": { - "label": "struct SSVNetwork.FeeChangeRequest", - "members": [ - { - "label": "fee", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "approvalBeginTime", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "approvalEndTime", - "type": "t_uint256", - "offset": 0, - "slot": "2" - } - ], - "numberOfBytes": "96" - }, - "t_struct(OperatorData)1962_storage": { - "label": "struct SSVNetwork.OperatorData", - "members": [ - { - "label": "blockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "earnings", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "index", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "indexBlockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "4" - }, - { - "label": "previousFee", - "type": "t_uint256", - "offset": 0, - "slot": "5" - } - ], - "numberOfBytes": "192" - }, - "t_struct(OperatorInUse)1990_storage": { - "label": "struct SSVNetwork.OperatorInUse", - "members": [ - { - "label": "index", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "validatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "used", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "exists", - "type": "t_bool", - "offset": 0, - "slot": "3" - }, - { - "label": "indexInArray", - "type": "t_uint256", - "offset": 0, - "slot": "4" - } - ], - "numberOfBytes": "160" - }, - "t_struct(OwnerData)1979_storage": { - "label": "struct SSVNetwork.OwnerData", - "members": [ - { - "label": "deposited", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "withdrawn", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "earned", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "used", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "networkFee", - "type": "t_uint256", - "offset": 0, - "slot": "4" - }, - { - "label": "networkFeeIndex", - "type": "t_uint256", - "offset": 0, - "slot": "5" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "6" - }, - { - "label": "validatorsDisabled", - "type": "t_bool", - "offset": 0, - "slot": "7" - } - ], - "numberOfBytes": "256" - }, - "t_uint256": { - "label": "uint256", - "numberOfBytes": "32" - } - } - } - }, - "7fef33eab0d91be88e51726ebbd6ae0d932b9f362e0a0debd5da2c346d8bab48": { - "address": "0x3C49c1012999585146128997B5bB5B9286cb0fa0", - "txHash": "0x54334f3029071b9b0a9db816fb5f1d8066929b64ced10623c3372add45755e87", - "layout": { - "storage": [ - { - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:23" - }, - { - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:28" - }, - { - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage", - "contract": "ContextUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" - }, - { - "label": "_owner", - "offset": 0, - "slot": "51", - "type": "t_address", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:20" - }, - { - "label": "__gap", - "offset": 0, - "slot": "52", - "type": "t_array(t_uint256)49_storage", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:74" - }, - { - "label": "_ssvRegistryContract", - "offset": 0, - "slot": "101", - "type": "t_contract(ISSVRegistry)1938", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:45" - }, - { - "label": "_token", - "offset": 0, - "slot": "102", - "type": "t_contract(IERC20)950", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:46" - }, - { - "label": "_minimumBlocksBeforeLiquidation", - "offset": 0, - "slot": "103", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:47" - }, - { - "label": "_operatorMaxFeeIncrease", - "offset": 0, - "slot": "104", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:48" - }, - { - "label": "_networkFee", - "offset": 0, - "slot": "105", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:50" - }, - { - "label": "_networkFeeIndex", - "offset": 0, - "slot": "106", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:51" - }, - { - "label": "_networkFeeIndexBlockNumber", - "offset": 0, - "slot": "107", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:52" - }, - { - "label": "_networkEarnings", - "offset": 0, - "slot": "108", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:53" - }, - { - "label": "_networkEarningsBlockNumber", - "offset": 0, - "slot": "109", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:54" - }, - { - "label": "_withdrawnFromTreasury", - "offset": 0, - "slot": "110", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:55" - }, - { - "label": "_operatorDatas", - "offset": 0, - "slot": "111", - "type": "t_mapping(t_uint256,t_struct(OperatorData)1962_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:57" - }, - { - "label": "_owners", - "offset": 0, - "slot": "112", - "type": "t_mapping(t_address,t_struct(OwnerData)1979_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:58" - }, - { - "label": "_operatorsInUseByAddress", - "offset": 0, - "slot": "113", - "type": "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)1990_storage))", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:59" - }, - { - "label": "_operatorsInUseList", - "offset": 0, - "slot": "114", - "type": "t_mapping(t_address,t_array(t_uint256)dyn_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:60" - }, - { - "label": "_lastOperatorUpdateNetworkFeeRun", - "offset": 0, - "slot": "115", - "type": "t_mapping(t_uint256,t_uint256)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:61" - }, - { - "label": "_setOperatorFeePeriod", - "offset": 0, - "slot": "116", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:63" - }, - { - "label": "_approveOperatorFeePeriod", - "offset": 0, - "slot": "117", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:64" - }, - { - "label": "_feeChangeRequests", - "offset": 0, - "slot": "118", - "type": "t_mapping(t_uint256,t_struct(FeeChangeRequest)1997_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:65" - } - ], - "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_array(t_uint256)dyn_storage": { - "label": "uint256[]", - "numberOfBytes": "32" - }, - "t_bool": { - "label": "bool", - "numberOfBytes": "1" - }, - "t_contract(IERC20)950": { - "label": "contract IERC20", - "numberOfBytes": "20" - }, - "t_contract(ISSVRegistry)1938": { - "label": "contract ISSVRegistry", - "numberOfBytes": "20" - }, - "t_mapping(t_address,t_array(t_uint256)dyn_storage)": { - "label": "mapping(address => uint256[])", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)1990_storage))": { - "label": "mapping(address => mapping(uint256 => struct SSVNetwork.OperatorInUse))", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_struct(OwnerData)1979_storage)": { - "label": "mapping(address => struct SSVNetwork.OwnerData)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(FeeChangeRequest)1997_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.FeeChangeRequest)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(OperatorData)1962_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorData)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(OperatorInUse)1990_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorInUse)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_uint256)": { - "label": "mapping(uint256 => uint256)", - "numberOfBytes": "32" - }, - "t_struct(FeeChangeRequest)1997_storage": { - "label": "struct SSVNetwork.FeeChangeRequest", - "members": [ - { - "label": "fee", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "approvalBeginTime", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "approvalEndTime", - "type": "t_uint256", - "offset": 0, - "slot": "2" - } - ], - "numberOfBytes": "96" - }, - "t_struct(OperatorData)1962_storage": { - "label": "struct SSVNetwork.OperatorData", - "members": [ - { - "label": "blockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "earnings", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "index", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "indexBlockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "4" - }, - { - "label": "previousFee", - "type": "t_uint256", - "offset": 0, - "slot": "5" - } - ], - "numberOfBytes": "192" - }, - "t_struct(OperatorInUse)1990_storage": { - "label": "struct SSVNetwork.OperatorInUse", - "members": [ - { - "label": "index", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "validatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "used", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "exists", - "type": "t_bool", - "offset": 0, - "slot": "3" - }, - { - "label": "indexInArray", - "type": "t_uint256", - "offset": 0, - "slot": "4" - } - ], - "numberOfBytes": "160" - }, - "t_struct(OwnerData)1979_storage": { - "label": "struct SSVNetwork.OwnerData", - "members": [ - { - "label": "deposited", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "withdrawn", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "earned", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "used", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "networkFee", - "type": "t_uint256", - "offset": 0, - "slot": "4" - }, - { - "label": "networkFeeIndex", - "type": "t_uint256", - "offset": 0, - "slot": "5" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "6" - }, - { - "label": "validatorsDisabled", - "type": "t_bool", - "offset": 0, - "slot": "7" - } - ], - "numberOfBytes": "256" - }, - "t_uint256": { - "label": "uint256", - "numberOfBytes": "32" - } - } - } - }, - "663fd14399d5bfddd3523019121a39f05b3fd11298546abddae0db8777ec295f": { - "address": "0x168F3BE1cfEf7AA432E0F8C2d157Af7c4EFe592C", - "txHash": "0xe5aa3e1a5b170f5479d22538a5ae1528631e590a9101bea7de6bc7a2564b6f4c", - "layout": { - "storage": [ - { - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:23" - }, - { - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:28" - }, - { - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage", - "contract": "ContextUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" - }, - { - "label": "_owner", - "offset": 0, - "slot": "51", - "type": "t_address", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:20" - }, - { - "label": "__gap", - "offset": 0, - "slot": "52", - "type": "t_array(t_uint256)49_storage", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:74" - }, - { - "label": "_ssvRegistryContract", - "offset": 0, - "slot": "101", - "type": "t_contract(ISSVRegistry)1938", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:45" - }, - { - "label": "_token", - "offset": 0, - "slot": "102", - "type": "t_contract(IERC20)950", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:46" - }, - { - "label": "_minimumBlocksBeforeLiquidation", - "offset": 0, - "slot": "103", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:47" - }, - { - "label": "_operatorMaxFeeIncrease", - "offset": 0, - "slot": "104", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:48" - }, - { - "label": "_networkFee", - "offset": 0, - "slot": "105", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:50" - }, - { - "label": "_networkFeeIndex", - "offset": 0, - "slot": "106", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:51" - }, - { - "label": "_networkFeeIndexBlockNumber", - "offset": 0, - "slot": "107", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:52" - }, - { - "label": "_networkEarnings", - "offset": 0, - "slot": "108", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:53" - }, - { - "label": "_networkEarningsBlockNumber", - "offset": 0, - "slot": "109", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:54" - }, - { - "label": "_withdrawnFromTreasury", - "offset": 0, - "slot": "110", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:55" - }, - { - "label": "_operatorDatas", - "offset": 0, - "slot": "111", - "type": "t_mapping(t_uint256,t_struct(OperatorData)1962_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:57" - }, - { - "label": "_owners", - "offset": 0, - "slot": "112", - "type": "t_mapping(t_address,t_struct(OwnerData)1979_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:58" - }, - { - "label": "_operatorsInUseByAddress", - "offset": 0, - "slot": "113", - "type": "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)1990_storage))", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:59" - }, - { - "label": "_operatorsInUseList", - "offset": 0, - "slot": "114", - "type": "t_mapping(t_address,t_array(t_uint256)dyn_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:60" - }, - { - "label": "_lastOperatorUpdateNetworkFeeRun", - "offset": 0, - "slot": "115", - "type": "t_mapping(t_uint256,t_uint256)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:61" - }, - { - "label": "_setOperatorFeePeriod", - "offset": 0, - "slot": "116", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:63" - }, - { - "label": "_approveOperatorFeePeriod", - "offset": 0, - "slot": "117", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:64" - }, - { - "label": "_feeChangeRequests", - "offset": 0, - "slot": "118", - "type": "t_mapping(t_uint256,t_struct(FeeChangeRequest)1997_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:65" - } - ], - "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_array(t_uint256)dyn_storage": { - "label": "uint256[]", - "numberOfBytes": "32" - }, - "t_bool": { - "label": "bool", - "numberOfBytes": "1" - }, - "t_contract(IERC20)950": { - "label": "contract IERC20", - "numberOfBytes": "20" - }, - "t_contract(ISSVRegistry)1938": { - "label": "contract ISSVRegistry", - "numberOfBytes": "20" - }, - "t_mapping(t_address,t_array(t_uint256)dyn_storage)": { - "label": "mapping(address => uint256[])", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)1990_storage))": { - "label": "mapping(address => mapping(uint256 => struct SSVNetwork.OperatorInUse))", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_struct(OwnerData)1979_storage)": { - "label": "mapping(address => struct SSVNetwork.OwnerData)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(FeeChangeRequest)1997_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.FeeChangeRequest)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(OperatorData)1962_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorData)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(OperatorInUse)1990_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorInUse)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_uint256)": { - "label": "mapping(uint256 => uint256)", - "numberOfBytes": "32" - }, - "t_struct(FeeChangeRequest)1997_storage": { - "label": "struct SSVNetwork.FeeChangeRequest", - "members": [ - { - "label": "fee", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "approvalBeginTime", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "approvalEndTime", - "type": "t_uint256", - "offset": 0, - "slot": "2" - } - ], - "numberOfBytes": "96" - }, - "t_struct(OperatorData)1962_storage": { - "label": "struct SSVNetwork.OperatorData", - "members": [ - { - "label": "blockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "earnings", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "index", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "indexBlockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "4" - }, - { - "label": "previousFee", - "type": "t_uint256", - "offset": 0, - "slot": "5" - } - ], - "numberOfBytes": "192" - }, - "t_struct(OperatorInUse)1990_storage": { - "label": "struct SSVNetwork.OperatorInUse", - "members": [ - { - "label": "index", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "validatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "used", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "exists", - "type": "t_bool", - "offset": 0, - "slot": "3" - }, - { - "label": "indexInArray", - "type": "t_uint256", - "offset": 0, - "slot": "4" - } - ], - "numberOfBytes": "160" - }, - "t_struct(OwnerData)1979_storage": { - "label": "struct SSVNetwork.OwnerData", - "members": [ - { - "label": "deposited", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "withdrawn", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "earned", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "used", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "networkFee", - "type": "t_uint256", - "offset": 0, - "slot": "4" - }, - { - "label": "networkFeeIndex", - "type": "t_uint256", - "offset": 0, - "slot": "5" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "6" - }, - { - "label": "validatorsDisabled", - "type": "t_bool", - "offset": 0, - "slot": "7" - } - ], - "numberOfBytes": "256" - }, - "t_uint256": { - "label": "uint256", - "numberOfBytes": "32" - } - } - } - }, - "2f2200e16fa03b6a2258174c55b3b07ef0719d2c51b74744005de71a718c15d7": { - "address": "0x766785A02c335146085D44c1CA42D74FB5313654", - "txHash": "0x446149846f61bcedbfafef0f5e86be40fd5ae857f843fbd25690ad0d1a6ac1c2", - "layout": { - "storage": [ - { - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:23" - }, - { - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:28" - }, - { - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage", - "contract": "ContextUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" - }, - { - "label": "_owner", - "offset": 0, - "slot": "51", - "type": "t_address", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:20" - }, - { - "label": "__gap", - "offset": 0, - "slot": "52", - "type": "t_array(t_uint256)49_storage", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:74" - }, - { - "label": "_ssvRegistryContract", - "offset": 0, - "slot": "101", - "type": "t_contract(ISSVRegistry)1938", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:45" - }, - { - "label": "_token", - "offset": 0, - "slot": "102", - "type": "t_contract(IERC20)950", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:46" - }, - { - "label": "_minimumBlocksBeforeLiquidation", - "offset": 0, - "slot": "103", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:47" - }, - { - "label": "_operatorMaxFeeIncrease", - "offset": 0, - "slot": "104", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:48" - }, - { - "label": "_networkFee", - "offset": 0, - "slot": "105", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:50" - }, - { - "label": "_networkFeeIndex", - "offset": 0, - "slot": "106", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:51" - }, - { - "label": "_networkFeeIndexBlockNumber", - "offset": 0, - "slot": "107", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:52" - }, - { - "label": "_networkEarnings", - "offset": 0, - "slot": "108", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:53" - }, - { - "label": "_networkEarningsBlockNumber", - "offset": 0, - "slot": "109", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:54" - }, - { - "label": "_withdrawnFromTreasury", - "offset": 0, - "slot": "110", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:55" - }, - { - "label": "_operatorDatas", - "offset": 0, - "slot": "111", - "type": "t_mapping(t_uint256,t_struct(OperatorData)1962_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:57" - }, - { - "label": "_owners", - "offset": 0, - "slot": "112", - "type": "t_mapping(t_address,t_struct(OwnerData)1979_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:58" - }, - { - "label": "_operatorsInUseByAddress", - "offset": 0, - "slot": "113", - "type": "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)1990_storage))", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:59" - }, - { - "label": "_operatorsInUseList", - "offset": 0, - "slot": "114", - "type": "t_mapping(t_address,t_array(t_uint256)dyn_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:60" - }, - { - "label": "_lastOperatorUpdateNetworkFeeRun", - "offset": 0, - "slot": "115", - "type": "t_mapping(t_uint256,t_uint256)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:61" - }, - { - "label": "_setOperatorFeePeriod", - "offset": 0, - "slot": "116", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:63" - }, - { - "label": "_approveOperatorFeePeriod", - "offset": 0, - "slot": "117", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:64" - }, - { - "label": "_feeChangeRequests", - "offset": 0, - "slot": "118", - "type": "t_mapping(t_uint256,t_struct(FeeChangeRequest)1997_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:65" - } - ], - "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_array(t_uint256)dyn_storage": { - "label": "uint256[]", - "numberOfBytes": "32" - }, - "t_bool": { - "label": "bool", - "numberOfBytes": "1" - }, - "t_contract(IERC20)950": { - "label": "contract IERC20", - "numberOfBytes": "20" - }, - "t_contract(ISSVRegistry)1938": { - "label": "contract ISSVRegistry", - "numberOfBytes": "20" - }, - "t_mapping(t_address,t_array(t_uint256)dyn_storage)": { - "label": "mapping(address => uint256[])", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)1990_storage))": { - "label": "mapping(address => mapping(uint256 => struct SSVNetwork.OperatorInUse))", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_struct(OwnerData)1979_storage)": { - "label": "mapping(address => struct SSVNetwork.OwnerData)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(FeeChangeRequest)1997_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.FeeChangeRequest)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(OperatorData)1962_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorData)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(OperatorInUse)1990_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorInUse)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_uint256)": { - "label": "mapping(uint256 => uint256)", - "numberOfBytes": "32" - }, - "t_struct(FeeChangeRequest)1997_storage": { - "label": "struct SSVNetwork.FeeChangeRequest", - "members": [ - { - "label": "fee", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "approvalBeginTime", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "approvalEndTime", - "type": "t_uint256", - "offset": 0, - "slot": "2" - } - ], - "numberOfBytes": "96" - }, - "t_struct(OperatorData)1962_storage": { - "label": "struct SSVNetwork.OperatorData", - "members": [ - { - "label": "blockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "earnings", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "index", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "indexBlockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "4" - }, - { - "label": "previousFee", - "type": "t_uint256", - "offset": 0, - "slot": "5" - } - ], - "numberOfBytes": "192" - }, - "t_struct(OperatorInUse)1990_storage": { - "label": "struct SSVNetwork.OperatorInUse", - "members": [ - { - "label": "index", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "validatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "used", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "exists", - "type": "t_bool", - "offset": 0, - "slot": "3" - }, - { - "label": "indexInArray", - "type": "t_uint256", - "offset": 0, - "slot": "4" - } - ], - "numberOfBytes": "160" - }, - "t_struct(OwnerData)1979_storage": { - "label": "struct SSVNetwork.OwnerData", - "members": [ - { - "label": "deposited", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "withdrawn", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "earned", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "used", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "networkFee", - "type": "t_uint256", - "offset": 0, - "slot": "4" - }, - { - "label": "networkFeeIndex", - "type": "t_uint256", - "offset": 0, - "slot": "5" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "6" - }, - { - "label": "validatorsDisabled", - "type": "t_bool", - "offset": 0, - "slot": "7" - } - ], - "numberOfBytes": "256" - }, - "t_uint256": { - "label": "uint256", - "numberOfBytes": "32" - } - } - } - }, - "3641c20d95a09e5c74f1b824567f683e90937063940d6b87b5788efaa0004462": { - "address": "0x2FD7874d2A45D9c53C5716a2350D36a8B494C09C", - "txHash": "0xe16405dba2da260d2e453fcfbfa6afa7903e5da8bd9286fc1fd6e65b950a1193", - "layout": { - "storage": [ - { - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:23" - }, - { - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:28" - }, - { - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage", - "contract": "ContextUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" - }, - { - "label": "_owner", - "offset": 0, - "slot": "51", - "type": "t_address", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:20" - }, - { - "label": "__gap", - "offset": 0, - "slot": "52", - "type": "t_array(t_uint256)49_storage", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:74" - }, - { - "label": "_activeValidatorCount", - "offset": 0, - "slot": "101", - "type": "t_uint256", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:34" - }, - { - "label": "_lastOperatorId", - "offset": 0, - "slot": "102", - "type": "t_struct(Counter)1003_storage", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:36" - }, - { - "label": "_operators", - "offset": 0, - "slot": "103", - "type": "t_mapping(t_uint256,t_struct(Operator)4515_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:38" - }, - { - "label": "_validators", - "offset": 0, - "slot": "104", - "type": "t_mapping(t_bytes_memory_ptr,t_struct(Validator)4525_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:39" - }, - { - "label": "_operatorsByOwnerAddress", - "offset": 0, - "slot": "105", - "type": "t_mapping(t_address,t_array(t_uint256)dyn_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:41" - }, - { - "label": "_validatorsByOwnerAddress", - "offset": 0, - "slot": "106", - "type": "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:42" - }, - { - "label": "_owners", - "offset": 0, - "slot": "107", - "type": "t_mapping(t_address,t_struct(OwnerData)4530_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:43" - }, - { - "label": "validatorsPerOperator", - "offset": 0, - "slot": "108", - "type": "t_mapping(t_uint256,t_uint256)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:45" - }, - { - "label": "validatorsPerOperatorLimit", - "offset": 0, - "slot": "109", - "type": "t_uint256", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:46" - }, - { - "label": "_operatorPublicKeyToId", - "offset": 0, - "slot": "110", - "type": "t_mapping(t_bytes_memory_ptr,t_uint256)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:47" - } - ], - "types": { - "t_address": { - "label": "address", - "numberOfBytes": "20" - }, - "t_array(t_bytes_storage)dyn_storage": { - "label": "bytes[]", - "numberOfBytes": "32" - }, - "t_array(t_uint256)49_storage": { - "label": "uint256[49]", - "numberOfBytes": "1568" - }, - "t_array(t_uint256)50_storage": { - "label": "uint256[50]", - "numberOfBytes": "1600" - }, - "t_array(t_uint256)dyn_storage": { - "label": "uint256[]", - "numberOfBytes": "32" - }, - "t_bool": { - "label": "bool", - "numberOfBytes": "1" - }, - "t_bytes_memory_ptr": { - "label": "bytes", - "numberOfBytes": "32" - }, - "t_bytes_storage": { - "label": "bytes", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)": { - "label": "mapping(address => bytes[])", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_array(t_uint256)dyn_storage)": { - "label": "mapping(address => uint256[])", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_struct(OwnerData)4530_storage)": { - "label": "mapping(address => struct SSVRegistry.OwnerData)", - "numberOfBytes": "32" - }, - "t_mapping(t_bytes_memory_ptr,t_struct(Validator)4525_storage)": { - "label": "mapping(bytes => struct SSVRegistry.Validator)", - "numberOfBytes": "32" - }, - "t_mapping(t_bytes_memory_ptr,t_uint256)": { - "label": "mapping(bytes => uint256)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(Operator)4515_storage)": { - "label": "mapping(uint256 => struct SSVRegistry.Operator)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_uint256)": { - "label": "mapping(uint256 => uint256)", - "numberOfBytes": "32" - }, - "t_string_storage": { - "label": "string", - "numberOfBytes": "32" - }, - "t_struct(Counter)1003_storage": { - "label": "struct Counters.Counter", - "members": [ - { - "label": "_value", - "type": "t_uint256", - "offset": 0, - "slot": "0" - } - ], - "numberOfBytes": "32" - }, - "t_struct(Operator)4515_storage": { - "label": "struct SSVRegistry.Operator", - "members": [ - { - "label": "name", - "type": "t_string_storage", - "offset": 0, - "slot": "0" - }, - { - "label": "ownerAddress", - "type": "t_address", - "offset": 0, - "slot": "1" - }, - { - "label": "publicKey", - "type": "t_bytes_storage", - "offset": 0, - "slot": "2" - }, - { - "label": "score", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "fee", - "type": "t_uint256", - "offset": 0, - "slot": "4" - }, - { - "label": "active", - "type": "t_bool", - "offset": 0, - "slot": "5" - }, - { - "label": "indexInOwner", - "type": "t_uint256", - "offset": 0, - "slot": "6" - } - ], - "numberOfBytes": "224" - }, - "t_struct(OwnerData)4530_storage": { - "label": "struct SSVRegistry.OwnerData", - "members": [ - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "validatorsDisabled", - "type": "t_bool", - "offset": 0, - "slot": "1" - } - ], - "numberOfBytes": "64" - }, - "t_struct(Validator)4525_storage": { - "label": "struct SSVRegistry.Validator", - "members": [ - { - "label": "ownerAddress", - "type": "t_address", - "offset": 0, - "slot": "0" - }, - { - "label": "operatorIds", - "type": "t_array(t_uint256)dyn_storage", - "offset": 0, - "slot": "1" - }, - { - "label": "active", - "type": "t_bool", - "offset": 0, - "slot": "2" - }, - { - "label": "indexInOwner", - "type": "t_uint256", - "offset": 0, - "slot": "3" - } - ], - "numberOfBytes": "128" - }, - "t_uint256": { - "label": "uint256", - "numberOfBytes": "32" - } - } - } - }, - "b84acd6ee0990dbc253e4db22a98ca7a778b5745d22a6668c6cc9b32b1e69d33": { - "address": "0x9B14332643755FcADf304260e7efbB6F04a6Ae04", - "txHash": "0xfea4f7617cce431bc9354cf928498eef4c78ef40dad061e417cac19ff6bb6c03", - "layout": { - "storage": [ - { - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:23" - }, - { - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:28" - }, - { - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage", - "contract": "ContextUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" - }, - { - "label": "_owner", - "offset": 0, - "slot": "51", - "type": "t_address", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:20" - }, - { - "label": "__gap", - "offset": 0, - "slot": "52", - "type": "t_array(t_uint256)49_storage", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:74" - }, - { - "label": "_ssvRegistryContract", - "offset": 0, - "slot": "101", - "type": "t_contract(ISSVRegistry)1142", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:45" - }, - { - "label": "_token", - "offset": 0, - "slot": "102", - "type": "t_contract(IERC20)299", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:46" - }, - { - "label": "_minimumBlocksBeforeLiquidation", - "offset": 0, - "slot": "103", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:47" - }, - { - "label": "_operatorMaxFeeIncrease", - "offset": 0, - "slot": "104", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:48" - }, - { - "label": "_networkFee", - "offset": 0, - "slot": "105", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:50" - }, - { - "label": "_networkFeeIndex", - "offset": 0, - "slot": "106", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:51" - }, - { - "label": "_networkFeeIndexBlockNumber", - "offset": 0, - "slot": "107", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:52" - }, - { - "label": "_networkEarnings", - "offset": 0, - "slot": "108", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:53" - }, - { - "label": "_networkEarningsBlockNumber", - "offset": 0, - "slot": "109", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:54" - }, - { - "label": "_withdrawnFromTreasury", - "offset": 0, - "slot": "110", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:55" - }, - { - "label": "_operatorDatas", - "offset": 0, - "slot": "111", - "type": "t_mapping(t_uint256,t_struct(OperatorData)1166_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:57" - }, - { - "label": "_owners", - "offset": 0, - "slot": "112", - "type": "t_mapping(t_address,t_struct(OwnerData)1183_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:58" - }, - { - "label": "_operatorsInUseByAddress", - "offset": 0, - "slot": "113", - "type": "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)1194_storage))", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:59" - }, - { - "label": "_operatorsInUseList", - "offset": 0, - "slot": "114", - "type": "t_mapping(t_address,t_array(t_uint256)dyn_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:60" - }, - { - "label": "_lastOperatorUpdateNetworkFeeRun", - "offset": 0, - "slot": "115", - "type": "t_mapping(t_uint256,t_uint256)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:61" - }, - { - "label": "_setOperatorFeePeriod", - "offset": 0, - "slot": "116", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:63" - }, - { - "label": "_approveOperatorFeePeriod", - "offset": 0, - "slot": "117", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:64" - }, - { - "label": "_feeChangeRequests", - "offset": 0, - "slot": "118", - "type": "t_mapping(t_uint256,t_struct(FeeChangeRequest)1201_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:65" - } - ], - "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_array(t_uint256)dyn_storage": { - "label": "uint256[]", - "numberOfBytes": "32" - }, - "t_bool": { - "label": "bool", - "numberOfBytes": "1" - }, - "t_contract(IERC20)299": { - "label": "contract IERC20", - "numberOfBytes": "20" - }, - "t_contract(ISSVRegistry)1142": { - "label": "contract ISSVRegistry", - "numberOfBytes": "20" - }, - "t_mapping(t_address,t_array(t_uint256)dyn_storage)": { - "label": "mapping(address => uint256[])", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)1194_storage))": { - "label": "mapping(address => mapping(uint256 => struct SSVNetwork.OperatorInUse))", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_struct(OwnerData)1183_storage)": { - "label": "mapping(address => struct SSVNetwork.OwnerData)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(FeeChangeRequest)1201_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.FeeChangeRequest)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(OperatorData)1166_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorData)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(OperatorInUse)1194_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorInUse)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_uint256)": { - "label": "mapping(uint256 => uint256)", - "numberOfBytes": "32" - }, - "t_struct(FeeChangeRequest)1201_storage": { - "label": "struct SSVNetwork.FeeChangeRequest", - "members": [ - { - "label": "fee", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "approvalBeginTime", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "approvalEndTime", - "type": "t_uint256", - "offset": 0, - "slot": "2" - } - ], - "numberOfBytes": "96" - }, - "t_struct(OperatorData)1166_storage": { - "label": "struct SSVNetwork.OperatorData", - "members": [ - { - "label": "blockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "earnings", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "index", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "indexBlockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "4" - }, - { - "label": "previousFee", - "type": "t_uint256", - "offset": 0, - "slot": "5" - } - ], - "numberOfBytes": "192" - }, - "t_struct(OperatorInUse)1194_storage": { - "label": "struct SSVNetwork.OperatorInUse", - "members": [ - { - "label": "index", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "validatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "used", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "exists", - "type": "t_bool", - "offset": 0, - "slot": "3" - }, - { - "label": "indexInArray", - "type": "t_uint256", - "offset": 0, - "slot": "4" - } - ], - "numberOfBytes": "160" - }, - "t_struct(OwnerData)1183_storage": { - "label": "struct SSVNetwork.OwnerData", - "members": [ - { - "label": "deposited", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "withdrawn", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "earned", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "used", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "networkFee", - "type": "t_uint256", - "offset": 0, - "slot": "4" - }, - { - "label": "networkFeeIndex", - "type": "t_uint256", - "offset": 0, - "slot": "5" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "6" - }, - { - "label": "validatorsDisabled", - "type": "t_bool", - "offset": 0, - "slot": "7" - } - ], - "numberOfBytes": "256" - }, - "t_uint256": { - "label": "uint256", - "numberOfBytes": "32" - } - } - } - }, - "a9de28a32b9b623094c20297e359a2f1d450c3957f9e78941b8904eb4b711592": { - "address": "0x3b88e6e880D09feB90d1e9C6Dea18A5015fB5F6D", - "txHash": "0x8f32f9f829b781205bedcf4c9b912230965ff9e9647af311a8d5797a0c2c508e", - "layout": { - "storage": [ - { - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:23" - }, - { - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:28" - }, - { - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage", - "contract": "ContextUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" - }, - { - "label": "_owner", - "offset": 0, - "slot": "51", - "type": "t_address", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:20" - }, - { - "label": "__gap", - "offset": 0, - "slot": "52", - "type": "t_array(t_uint256)49_storage", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:74" - }, - { - "label": "_ssvRegistryContract", - "offset": 0, - "slot": "101", - "type": "t_contract(ISSVRegistry)1914", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:45" - }, - { - "label": "_token", - "offset": 0, - "slot": "102", - "type": "t_contract(IERC20)950", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:46" - }, - { - "label": "_minimumBlocksBeforeLiquidation", - "offset": 0, - "slot": "103", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:47" - }, - { - "label": "_operatorMaxFeeIncrease", - "offset": 0, - "slot": "104", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:48" - }, - { - "label": "_networkFee", - "offset": 0, - "slot": "105", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:50" - }, - { - "label": "_networkFeeIndex", - "offset": 0, - "slot": "106", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:51" - }, - { - "label": "_networkFeeIndexBlockNumber", - "offset": 0, - "slot": "107", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:52" - }, - { - "label": "_networkEarnings", - "offset": 0, - "slot": "108", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:53" - }, - { - "label": "_networkEarningsBlockNumber", - "offset": 0, - "slot": "109", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:54" - }, - { - "label": "_withdrawnFromTreasury", - "offset": 0, - "slot": "110", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:55" - }, - { - "label": "_operatorDatas", - "offset": 0, - "slot": "111", - "type": "t_mapping(t_uint256,t_struct(OperatorData)1938_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:57" - }, - { - "label": "_owners", - "offset": 0, - "slot": "112", - "type": "t_mapping(t_address,t_struct(OwnerData)1955_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:58" - }, - { - "label": "_operatorsInUseByAddress", - "offset": 0, - "slot": "113", - "type": "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)1966_storage))", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:59" - }, - { - "label": "_operatorsInUseList", - "offset": 0, - "slot": "114", - "type": "t_mapping(t_address,t_array(t_uint256)dyn_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:60" - }, - { - "label": "_lastOperatorUpdateNetworkFeeRun", - "offset": 0, - "slot": "115", - "type": "t_mapping(t_uint256,t_uint256)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:61" - }, - { - "label": "_setOperatorFeePeriod", - "offset": 0, - "slot": "116", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:63" - }, - { - "label": "_approveOperatorFeePeriod", - "offset": 0, - "slot": "117", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:64" - }, - { - "label": "_feeChangeRequests", - "offset": 0, - "slot": "118", - "type": "t_mapping(t_uint256,t_struct(FeeChangeRequest)1973_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:65" - } - ], - "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_array(t_uint256)dyn_storage": { - "label": "uint256[]", - "numberOfBytes": "32" - }, - "t_bool": { - "label": "bool", - "numberOfBytes": "1" - }, - "t_contract(IERC20)950": { - "label": "contract IERC20", - "numberOfBytes": "20" - }, - "t_contract(ISSVRegistry)1914": { - "label": "contract ISSVRegistry", - "numberOfBytes": "20" - }, - "t_mapping(t_address,t_array(t_uint256)dyn_storage)": { - "label": "mapping(address => uint256[])", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)1966_storage))": { - "label": "mapping(address => mapping(uint256 => struct SSVNetwork.OperatorInUse))", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_struct(OwnerData)1955_storage)": { - "label": "mapping(address => struct SSVNetwork.OwnerData)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(FeeChangeRequest)1973_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.FeeChangeRequest)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(OperatorData)1938_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorData)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(OperatorInUse)1966_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorInUse)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_uint256)": { - "label": "mapping(uint256 => uint256)", - "numberOfBytes": "32" - }, - "t_struct(FeeChangeRequest)1973_storage": { - "label": "struct SSVNetwork.FeeChangeRequest", - "members": [ - { - "label": "fee", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "approvalBeginTime", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "approvalEndTime", - "type": "t_uint256", - "offset": 0, - "slot": "2" - } - ], - "numberOfBytes": "96" - }, - "t_struct(OperatorData)1938_storage": { - "label": "struct SSVNetwork.OperatorData", - "members": [ - { - "label": "blockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "earnings", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "index", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "indexBlockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "4" - }, - { - "label": "previousFee", - "type": "t_uint256", - "offset": 0, - "slot": "5" - } - ], - "numberOfBytes": "192" - }, - "t_struct(OperatorInUse)1966_storage": { - "label": "struct SSVNetwork.OperatorInUse", - "members": [ - { - "label": "index", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "validatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "used", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "exists", - "type": "t_bool", - "offset": 0, - "slot": "3" - }, - { - "label": "indexInArray", - "type": "t_uint256", - "offset": 0, - "slot": "4" - } - ], - "numberOfBytes": "160" - }, - "t_struct(OwnerData)1955_storage": { - "label": "struct SSVNetwork.OwnerData", - "members": [ - { - "label": "deposited", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "withdrawn", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "earned", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "used", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "networkFee", - "type": "t_uint256", - "offset": 0, - "slot": "4" - }, - { - "label": "networkFeeIndex", - "type": "t_uint256", - "offset": 0, - "slot": "5" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "6" - }, - { - "label": "validatorsDisabled", - "type": "t_bool", - "offset": 0, - "slot": "7" - } - ], - "numberOfBytes": "256" - }, - "t_uint256": { - "label": "uint256", - "numberOfBytes": "32" - } - } - } - }, - "1c9e7ff301eba33d844d99d367761c23eeae64bb37b091ff38c009030d7e5b90": { - "address": "0x712147DBE3dc425CA01827A239C9A10d441646ED", - "txHash": "0x3cd912d26f15e28a08b7689a2f8bdaed64da2635992eebb8717cc8141a0e6922", - "layout": { - "storage": [ - { - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:23" - }, - { - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:28" - }, - { - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage", - "contract": "ContextUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" - }, - { - "label": "_owner", - "offset": 0, - "slot": "51", - "type": "t_address", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:20" - }, - { - "label": "__gap", - "offset": 0, - "slot": "52", - "type": "t_array(t_uint256)49_storage", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:74" - }, - { - "label": "_ssvRegistryContract", - "offset": 0, - "slot": "101", - "type": "t_contract(ISSVRegistry)1914", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:45" - }, - { - "label": "_token", - "offset": 0, - "slot": "102", - "type": "t_contract(IERC20)950", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:46" - }, - { - "label": "_minimumBlocksBeforeLiquidation", - "offset": 0, - "slot": "103", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:47" - }, - { - "label": "_operatorMaxFeeIncrease", - "offset": 0, - "slot": "104", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:48" - }, - { - "label": "_networkFee", - "offset": 0, - "slot": "105", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:50" - }, - { - "label": "_networkFeeIndex", - "offset": 0, - "slot": "106", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:51" - }, - { - "label": "_networkFeeIndexBlockNumber", - "offset": 0, - "slot": "107", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:52" - }, - { - "label": "_networkEarnings", - "offset": 0, - "slot": "108", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:53" - }, - { - "label": "_networkEarningsBlockNumber", - "offset": 0, - "slot": "109", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:54" - }, - { - "label": "_withdrawnFromTreasury", - "offset": 0, - "slot": "110", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:55" - }, - { - "label": "_operatorDatas", - "offset": 0, - "slot": "111", - "type": "t_mapping(t_uint256,t_struct(OperatorData)1938_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:57" - }, - { - "label": "_owners", - "offset": 0, - "slot": "112", - "type": "t_mapping(t_address,t_struct(OwnerData)1955_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:58" - }, - { - "label": "_operatorsInUseByAddress", - "offset": 0, - "slot": "113", - "type": "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)1966_storage))", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:59" - }, - { - "label": "_operatorsInUseList", - "offset": 0, - "slot": "114", - "type": "t_mapping(t_address,t_array(t_uint256)dyn_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:60" - }, - { - "label": "_lastOperatorUpdateNetworkFeeRun", - "offset": 0, - "slot": "115", - "type": "t_mapping(t_uint256,t_uint256)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:61" - }, - { - "label": "_setOperatorFeePeriod", - "offset": 0, - "slot": "116", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:63" - }, - { - "label": "_approveOperatorFeePeriod", - "offset": 0, - "slot": "117", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:64" - }, - { - "label": "_feeChangeRequests", - "offset": 0, - "slot": "118", - "type": "t_mapping(t_uint256,t_struct(FeeChangeRequest)1973_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:65" - } - ], - "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_array(t_uint256)dyn_storage": { - "label": "uint256[]", - "numberOfBytes": "32" - }, - "t_bool": { - "label": "bool", - "numberOfBytes": "1" - }, - "t_contract(IERC20)950": { - "label": "contract IERC20", - "numberOfBytes": "20" - }, - "t_contract(ISSVRegistry)1914": { - "label": "contract ISSVRegistry", - "numberOfBytes": "20" - }, - "t_mapping(t_address,t_array(t_uint256)dyn_storage)": { - "label": "mapping(address => uint256[])", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)1966_storage))": { - "label": "mapping(address => mapping(uint256 => struct SSVNetwork.OperatorInUse))", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_struct(OwnerData)1955_storage)": { - "label": "mapping(address => struct SSVNetwork.OwnerData)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(FeeChangeRequest)1973_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.FeeChangeRequest)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(OperatorData)1938_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorData)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(OperatorInUse)1966_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorInUse)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_uint256)": { - "label": "mapping(uint256 => uint256)", - "numberOfBytes": "32" - }, - "t_struct(FeeChangeRequest)1973_storage": { - "label": "struct SSVNetwork.FeeChangeRequest", - "members": [ - { - "label": "fee", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "approvalBeginTime", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "approvalEndTime", - "type": "t_uint256", - "offset": 0, - "slot": "2" - } - ], - "numberOfBytes": "96" - }, - "t_struct(OperatorData)1938_storage": { - "label": "struct SSVNetwork.OperatorData", - "members": [ - { - "label": "blockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "earnings", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "index", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "indexBlockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "4" - }, - { - "label": "previousFee", - "type": "t_uint256", - "offset": 0, - "slot": "5" - } - ], - "numberOfBytes": "192" - }, - "t_struct(OperatorInUse)1966_storage": { - "label": "struct SSVNetwork.OperatorInUse", - "members": [ - { - "label": "index", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "validatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "used", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "exists", - "type": "t_bool", - "offset": 0, - "slot": "3" - }, - { - "label": "indexInArray", - "type": "t_uint256", - "offset": 0, - "slot": "4" - } - ], - "numberOfBytes": "160" - }, - "t_struct(OwnerData)1955_storage": { - "label": "struct SSVNetwork.OwnerData", - "members": [ - { - "label": "deposited", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "withdrawn", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "earned", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "used", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "networkFee", - "type": "t_uint256", - "offset": 0, - "slot": "4" - }, - { - "label": "networkFeeIndex", - "type": "t_uint256", - "offset": 0, - "slot": "5" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "6" - }, - { - "label": "validatorsDisabled", - "type": "t_bool", - "offset": 0, - "slot": "7" - } - ], - "numberOfBytes": "256" - }, - "t_uint256": { - "label": "uint256", - "numberOfBytes": "32" - } - } - } - }, - "91fe9325ead8120671f9e12977b0ed1ef460150f6161faf31000231bb2041db6": { - "address": "0x687018085d02C5F180d78Bc43DC3E74211f25b9A", - "txHash": "0x14437089ff6a284674f8dcd82fd4e908f9fae8fd4b5a681fbb10b7929da63b76", - "layout": { - "storage": [ - { - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:23" - }, - { - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:28" - }, - { - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage", - "contract": "ContextUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" - }, - { - "label": "_owner", - "offset": 0, - "slot": "51", - "type": "t_address", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:20" - }, - { - "label": "__gap", - "offset": 0, - "slot": "52", - "type": "t_array(t_uint256)49_storage", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:74" - }, - { - "label": "_activeValidatorCount", - "offset": 0, - "slot": "101", - "type": "t_uint256", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:34" - }, - { - "label": "_lastOperatorId", - "offset": 0, - "slot": "102", - "type": "t_struct(Counter)227_storage", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:36" - }, - { - "label": "_operators", - "offset": 0, - "slot": "103", - "type": "t_mapping(t_uint256,t_struct(Operator)664_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:38" - }, - { - "label": "_validators", - "offset": 0, - "slot": "104", - "type": "t_mapping(t_bytes_memory_ptr,t_struct(Validator)674_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:39" - }, - { - "label": "_operatorsByOwnerAddress", - "offset": 0, - "slot": "105", - "type": "t_mapping(t_address,t_array(t_uint256)dyn_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:41" - }, - { - "label": "_validatorsByOwnerAddress", - "offset": 0, - "slot": "106", - "type": "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:42" - }, - { - "label": "_owners", - "offset": 0, - "slot": "107", - "type": "t_mapping(t_address,t_struct(OwnerData)679_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:43" - }, - { - "label": "validatorsPerOperator", - "offset": 0, - "slot": "108", - "type": "t_mapping(t_uint256,t_uint256)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:45" - }, - { - "label": "validatorsPerOperatorLimit", - "offset": 0, - "slot": "109", - "type": "t_uint256", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:46" - }, - { - "label": "_operatorPublicKeyToId", - "offset": 0, - "slot": "110", - "type": "t_mapping(t_bytes_memory_ptr,t_uint256)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:47" - } - ], - "types": { - "t_address": { - "label": "address", - "numberOfBytes": "20" - }, - "t_array(t_bytes_storage)dyn_storage": { - "label": "bytes[]", - "numberOfBytes": "32" - }, - "t_array(t_uint256)49_storage": { - "label": "uint256[49]", - "numberOfBytes": "1568" - }, - "t_array(t_uint256)50_storage": { - "label": "uint256[50]", - "numberOfBytes": "1600" - }, - "t_array(t_uint256)dyn_storage": { - "label": "uint256[]", - "numberOfBytes": "32" - }, - "t_bool": { - "label": "bool", - "numberOfBytes": "1" - }, - "t_bytes_memory_ptr": { - "label": "bytes", - "numberOfBytes": "32" - }, - "t_bytes_storage": { - "label": "bytes", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)": { - "label": "mapping(address => bytes[])", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_array(t_uint256)dyn_storage)": { - "label": "mapping(address => uint256[])", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_struct(OwnerData)679_storage)": { - "label": "mapping(address => struct SSVRegistry.OwnerData)", - "numberOfBytes": "32" - }, - "t_mapping(t_bytes_memory_ptr,t_struct(Validator)674_storage)": { - "label": "mapping(bytes => struct SSVRegistry.Validator)", - "numberOfBytes": "32" - }, - "t_mapping(t_bytes_memory_ptr,t_uint256)": { - "label": "mapping(bytes => uint256)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(Operator)664_storage)": { - "label": "mapping(uint256 => struct SSVRegistry.Operator)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_uint256)": { - "label": "mapping(uint256 => uint256)", - "numberOfBytes": "32" - }, - "t_string_storage": { - "label": "string", - "numberOfBytes": "32" - }, - "t_struct(Counter)227_storage": { - "label": "struct Counters.Counter", - "members": [ - { - "label": "_value", - "type": "t_uint256", - "offset": 0, - "slot": "0" - } - ], - "numberOfBytes": "32" - }, - "t_struct(Operator)664_storage": { - "label": "struct SSVRegistry.Operator", - "members": [ - { - "label": "name", - "type": "t_string_storage", - "offset": 0, - "slot": "0" - }, - { - "label": "ownerAddress", - "type": "t_address", - "offset": 0, - "slot": "1" - }, - { - "label": "publicKey", - "type": "t_bytes_storage", - "offset": 0, - "slot": "2" - }, - { - "label": "score", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "fee", - "type": "t_uint256", - "offset": 0, - "slot": "4" - }, - { - "label": "active", - "type": "t_bool", - "offset": 0, - "slot": "5" - }, - { - "label": "indexInOwner", - "type": "t_uint256", - "offset": 0, - "slot": "6" - } - ], - "numberOfBytes": "224" - }, - "t_struct(OwnerData)679_storage": { - "label": "struct SSVRegistry.OwnerData", - "members": [ - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "validatorsDisabled", - "type": "t_bool", - "offset": 0, - "slot": "1" - } - ], - "numberOfBytes": "64" - }, - "t_struct(Validator)674_storage": { - "label": "struct SSVRegistry.Validator", - "members": [ - { - "label": "ownerAddress", - "type": "t_address", - "offset": 0, - "slot": "0" - }, - { - "label": "operatorIds", - "type": "t_array(t_uint256)dyn_storage", - "offset": 0, - "slot": "1" - }, - { - "label": "active", - "type": "t_bool", - "offset": 0, - "slot": "2" - }, - { - "label": "indexInOwner", - "type": "t_uint256", - "offset": 0, - "slot": "3" - } - ], - "numberOfBytes": "128" - }, - "t_uint256": { - "label": "uint256", - "numberOfBytes": "32" - } - } - } - }, - "43c9c7fd4fe1491a613cf7034400a44a16897bf9a2962a9c0972861012496ce5": { - "address": "0x1A537f409e061422C139dEd05f50245ECD957895", - "txHash": "0xde542b42f887d098d512f447d4586fe24ae857dc18bf3371a6d1f3815b88dbb6", - "layout": { - "storage": [ - { - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:23" - }, - { - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:28" - }, - { - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage", - "contract": "ContextUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" - }, - { - "label": "_owner", - "offset": 0, - "slot": "51", - "type": "t_address", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:20" - }, - { - "label": "__gap", - "offset": 0, - "slot": "52", - "type": "t_array(t_uint256)49_storage", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:74" - }, - { - "label": "_ssvRegistryContract", - "offset": 0, - "slot": "101", - "type": "t_contract(ISSVRegistry)1142", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:45" - }, - { - "label": "_token", - "offset": 0, - "slot": "102", - "type": "t_contract(IERC20)299", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:46" - }, - { - "label": "_minimumBlocksBeforeLiquidation", - "offset": 0, - "slot": "103", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:47" - }, - { - "label": "_operatorMaxFeeIncrease", - "offset": 0, - "slot": "104", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:48" - }, - { - "label": "_networkFee", - "offset": 0, - "slot": "105", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:50" - }, - { - "label": "_networkFeeIndex", - "offset": 0, - "slot": "106", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:51" - }, - { - "label": "_networkFeeIndexBlockNumber", - "offset": 0, - "slot": "107", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:52" - }, - { - "label": "_networkEarnings", - "offset": 0, - "slot": "108", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:53" - }, - { - "label": "_networkEarningsBlockNumber", - "offset": 0, - "slot": "109", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:54" - }, - { - "label": "_withdrawnFromTreasury", - "offset": 0, - "slot": "110", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:55" - }, - { - "label": "_operatorDatas", - "offset": 0, - "slot": "111", - "type": "t_mapping(t_uint256,t_struct(OperatorData)1166_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:57" - }, - { - "label": "_owners", - "offset": 0, - "slot": "112", - "type": "t_mapping(t_address,t_struct(OwnerData)1183_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:58" - }, - { - "label": "_operatorsInUseByAddress", - "offset": 0, - "slot": "113", - "type": "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)1194_storage))", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:59" - }, - { - "label": "_operatorsInUseList", - "offset": 0, - "slot": "114", - "type": "t_mapping(t_address,t_array(t_uint256)dyn_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:60" - }, - { - "label": "_lastOperatorUpdateNetworkFeeRun", - "offset": 0, - "slot": "115", - "type": "t_mapping(t_uint256,t_uint256)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:61" - }, - { - "label": "_setOperatorFeePeriod", - "offset": 0, - "slot": "116", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:63" - }, - { - "label": "_approveOperatorFeePeriod", - "offset": 0, - "slot": "117", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:64" - }, - { - "label": "_feeChangeRequests", - "offset": 0, - "slot": "118", - "type": "t_mapping(t_uint256,t_struct(FeeChangeRequest)1201_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:65" - } - ], - "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_array(t_uint256)dyn_storage": { - "label": "uint256[]", - "numberOfBytes": "32" - }, - "t_bool": { - "label": "bool", - "numberOfBytes": "1" - }, - "t_contract(IERC20)299": { - "label": "contract IERC20", - "numberOfBytes": "20" - }, - "t_contract(ISSVRegistry)1142": { - "label": "contract ISSVRegistry", - "numberOfBytes": "20" - }, - "t_mapping(t_address,t_array(t_uint256)dyn_storage)": { - "label": "mapping(address => uint256[])", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)1194_storage))": { - "label": "mapping(address => mapping(uint256 => struct SSVNetwork.OperatorInUse))", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_struct(OwnerData)1183_storage)": { - "label": "mapping(address => struct SSVNetwork.OwnerData)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(FeeChangeRequest)1201_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.FeeChangeRequest)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(OperatorData)1166_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorData)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(OperatorInUse)1194_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorInUse)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_uint256)": { - "label": "mapping(uint256 => uint256)", - "numberOfBytes": "32" - }, - "t_struct(FeeChangeRequest)1201_storage": { - "label": "struct SSVNetwork.FeeChangeRequest", - "members": [ - { - "label": "fee", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "approvalBeginTime", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "approvalEndTime", - "type": "t_uint256", - "offset": 0, - "slot": "2" - } - ], - "numberOfBytes": "96" - }, - "t_struct(OperatorData)1166_storage": { - "label": "struct SSVNetwork.OperatorData", - "members": [ - { - "label": "blockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "earnings", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "index", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "indexBlockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "4" - }, - { - "label": "previousFee", - "type": "t_uint256", - "offset": 0, - "slot": "5" - } - ], - "numberOfBytes": "192" - }, - "t_struct(OperatorInUse)1194_storage": { - "label": "struct SSVNetwork.OperatorInUse", - "members": [ - { - "label": "index", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "validatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "used", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "exists", - "type": "t_bool", - "offset": 0, - "slot": "3" - }, - { - "label": "indexInArray", - "type": "t_uint256", - "offset": 0, - "slot": "4" - } - ], - "numberOfBytes": "160" - }, - "t_struct(OwnerData)1183_storage": { - "label": "struct SSVNetwork.OwnerData", - "members": [ - { - "label": "deposited", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "withdrawn", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "earned", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "used", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "networkFee", - "type": "t_uint256", - "offset": 0, - "slot": "4" - }, - { - "label": "networkFeeIndex", - "type": "t_uint256", - "offset": 0, - "slot": "5" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "6" - }, - { - "label": "validatorsDisabled", - "type": "t_bool", - "offset": 0, - "slot": "7" - } - ], - "numberOfBytes": "256" - }, - "t_uint256": { - "label": "uint256", - "numberOfBytes": "32" - } - } - } - }, - "ea61da3bd81329c50c53a758f45f97243816a7d4317d4775b2891dc935a39f29": { - "address": "0x9F1621b3f28349dF70327300BDF9eD98aA76798e", - "txHash": "0x6c5aac883f3121518ddb2b6195b56e0f0e19b354cecc3a6980d11328c512a8cc", - "layout": { - "storage": [ - { - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:23" - }, - { - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:28" - }, - { - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage", - "contract": "ContextUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" - }, - { - "label": "_owner", - "offset": 0, - "slot": "51", - "type": "t_address", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:20" - }, - { - "label": "__gap", - "offset": 0, - "slot": "52", - "type": "t_array(t_uint256)49_storage", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:74" - }, - { - "label": "_activeValidatorCount", - "offset": 0, - "slot": "101", - "type": "t_uint256", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:34" - }, - { - "label": "_lastOperatorId", - "offset": 0, - "slot": "102", - "type": "t_struct(Counter)1003_storage", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:36" - }, - { - "label": "_operators", - "offset": 0, - "slot": "103", - "type": "t_mapping(t_uint256,t_struct(Operator)4532_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:38" - }, - { - "label": "_validators", - "offset": 0, - "slot": "104", - "type": "t_mapping(t_bytes_memory_ptr,t_struct(Validator)4542_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:39" - }, - { - "label": "_operatorsByOwnerAddress", - "offset": 0, - "slot": "105", - "type": "t_mapping(t_address,t_array(t_uint256)dyn_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:41" - }, - { - "label": "_validatorsByOwnerAddress", - "offset": 0, - "slot": "106", - "type": "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:42" - }, - { - "label": "_owners", - "offset": 0, - "slot": "107", - "type": "t_mapping(t_address,t_struct(OwnerData)4547_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:43" - }, - { - "label": "validatorsPerOperator", - "offset": 0, - "slot": "108", - "type": "t_mapping(t_uint256,t_uint256)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:45" - }, - { - "label": "validatorsPerOperatorLimit", - "offset": 0, - "slot": "109", - "type": "t_uint256", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:46" - }, - { - "label": "_operatorPublicKeyToId", - "offset": 0, - "slot": "110", - "type": "t_mapping(t_bytes_memory_ptr,t_uint256)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:47" - } - ], - "types": { - "t_address": { - "label": "address", - "numberOfBytes": "20" - }, - "t_array(t_bytes_storage)dyn_storage": { - "label": "bytes[]", - "numberOfBytes": "32" - }, - "t_array(t_uint256)49_storage": { - "label": "uint256[49]", - "numberOfBytes": "1568" - }, - "t_array(t_uint256)50_storage": { - "label": "uint256[50]", - "numberOfBytes": "1600" - }, - "t_array(t_uint256)dyn_storage": { - "label": "uint256[]", - "numberOfBytes": "32" - }, - "t_bool": { - "label": "bool", - "numberOfBytes": "1" - }, - "t_bytes_memory_ptr": { - "label": "bytes", - "numberOfBytes": "32" - }, - "t_bytes_storage": { - "label": "bytes", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)": { - "label": "mapping(address => bytes[])", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_array(t_uint256)dyn_storage)": { - "label": "mapping(address => uint256[])", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_struct(OwnerData)4547_storage)": { - "label": "mapping(address => struct SSVRegistry.OwnerData)", - "numberOfBytes": "32" - }, - "t_mapping(t_bytes_memory_ptr,t_struct(Validator)4542_storage)": { - "label": "mapping(bytes => struct SSVRegistry.Validator)", - "numberOfBytes": "32" - }, - "t_mapping(t_bytes_memory_ptr,t_uint256)": { - "label": "mapping(bytes => uint256)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(Operator)4532_storage)": { - "label": "mapping(uint256 => struct SSVRegistry.Operator)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_uint256)": { - "label": "mapping(uint256 => uint256)", - "numberOfBytes": "32" - }, - "t_string_storage": { - "label": "string", - "numberOfBytes": "32" - }, - "t_struct(Counter)1003_storage": { - "label": "struct Counters.Counter", - "members": [ - { - "label": "_value", - "type": "t_uint256", - "offset": 0, - "slot": "0" - } - ], - "numberOfBytes": "32" - }, - "t_struct(Operator)4532_storage": { - "label": "struct SSVRegistry.Operator", - "members": [ - { - "label": "name", - "type": "t_string_storage", - "offset": 0, - "slot": "0" - }, - { - "label": "ownerAddress", - "type": "t_address", - "offset": 0, - "slot": "1" - }, - { - "label": "publicKey", - "type": "t_bytes_storage", - "offset": 0, - "slot": "2" - }, - { - "label": "score", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "fee", - "type": "t_uint256", - "offset": 0, - "slot": "4" - }, - { - "label": "active", - "type": "t_bool", - "offset": 0, - "slot": "5" - }, - { - "label": "indexInOwner", - "type": "t_uint256", - "offset": 0, - "slot": "6" - } - ], - "numberOfBytes": "224" - }, - "t_struct(OwnerData)4547_storage": { - "label": "struct SSVRegistry.OwnerData", - "members": [ - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "validatorsDisabled", - "type": "t_bool", - "offset": 0, - "slot": "1" - } - ], - "numberOfBytes": "64" - }, - "t_struct(Validator)4542_storage": { - "label": "struct SSVRegistry.Validator", - "members": [ - { - "label": "ownerAddress", - "type": "t_address", - "offset": 0, - "slot": "0" - }, - { - "label": "operatorIds", - "type": "t_array(t_uint256)dyn_storage", - "offset": 0, - "slot": "1" - }, - { - "label": "active", - "type": "t_bool", - "offset": 0, - "slot": "2" - }, - { - "label": "indexInOwner", - "type": "t_uint256", - "offset": 0, - "slot": "3" - } - ], - "numberOfBytes": "128" - }, - "t_uint256": { - "label": "uint256", - "numberOfBytes": "32" - } - } - } - }, - "44880359e2962ae163e85b078eaeb8d4a1f8da6999a2519bec9dea8f32c26cca": { - "address": "0xf20df316E71cf623FCEa632e8f055Ae4925d0858", - "txHash": "0xef6260c6bf38f4af90b049cde7e96bed85b3e0beb5625b48b41793aa35f57b3b", - "layout": { - "storage": [ - { - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:23" - }, - { - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:28" - }, - { - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage", - "contract": "ContextUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" - }, - { - "label": "_owner", - "offset": 0, - "slot": "51", - "type": "t_address", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:20" - }, - { - "label": "__gap", - "offset": 0, - "slot": "52", - "type": "t_array(t_uint256)49_storage", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:74" - }, - { - "label": "_ssvRegistryContract", - "offset": 0, - "slot": "101", - "type": "t_contract(ISSVRegistry)1142", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:45" - }, - { - "label": "_token", - "offset": 0, - "slot": "102", - "type": "t_contract(IERC20)299", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:46" - }, - { - "label": "_minimumBlocksBeforeLiquidation", - "offset": 0, - "slot": "103", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:47" - }, - { - "label": "_operatorMaxFeeIncrease", - "offset": 0, - "slot": "104", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:48" - }, - { - "label": "_networkFee", - "offset": 0, - "slot": "105", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:50" - }, - { - "label": "_networkFeeIndex", - "offset": 0, - "slot": "106", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:51" - }, - { - "label": "_networkFeeIndexBlockNumber", - "offset": 0, - "slot": "107", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:52" - }, - { - "label": "_networkEarnings", - "offset": 0, - "slot": "108", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:53" - }, - { - "label": "_networkEarningsBlockNumber", - "offset": 0, - "slot": "109", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:54" - }, - { - "label": "_withdrawnFromTreasury", - "offset": 0, - "slot": "110", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:55" - }, - { - "label": "_operatorDatas", - "offset": 0, - "slot": "111", - "type": "t_mapping(t_uint256,t_struct(OperatorData)1166_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:57" - }, - { - "label": "_owners", - "offset": 0, - "slot": "112", - "type": "t_mapping(t_address,t_struct(OwnerData)1183_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:58" - }, - { - "label": "_operatorsInUseByAddress", - "offset": 0, - "slot": "113", - "type": "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)1194_storage))", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:59" - }, - { - "label": "_operatorsInUseList", - "offset": 0, - "slot": "114", - "type": "t_mapping(t_address,t_array(t_uint256)dyn_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:60" - }, - { - "label": "_lastOperatorUpdateNetworkFeeRun", - "offset": 0, - "slot": "115", - "type": "t_mapping(t_uint256,t_uint256)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:61" - }, - { - "label": "_setOperatorFeePeriod", - "offset": 0, - "slot": "116", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:63" - }, - { - "label": "_approveOperatorFeePeriod", - "offset": 0, - "slot": "117", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:64" - }, - { - "label": "_feeChangeRequests", - "offset": 0, - "slot": "118", - "type": "t_mapping(t_uint256,t_struct(FeeChangeRequest)1201_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:65" - } - ], - "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_array(t_uint256)dyn_storage": { - "label": "uint256[]", - "numberOfBytes": "32" - }, - "t_bool": { - "label": "bool", - "numberOfBytes": "1" - }, - "t_contract(IERC20)299": { - "label": "contract IERC20", - "numberOfBytes": "20" - }, - "t_contract(ISSVRegistry)1142": { - "label": "contract ISSVRegistry", - "numberOfBytes": "20" - }, - "t_mapping(t_address,t_array(t_uint256)dyn_storage)": { - "label": "mapping(address => uint256[])", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)1194_storage))": { - "label": "mapping(address => mapping(uint256 => struct SSVNetwork.OperatorInUse))", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_struct(OwnerData)1183_storage)": { - "label": "mapping(address => struct SSVNetwork.OwnerData)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(FeeChangeRequest)1201_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.FeeChangeRequest)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(OperatorData)1166_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorData)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(OperatorInUse)1194_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorInUse)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_uint256)": { - "label": "mapping(uint256 => uint256)", - "numberOfBytes": "32" - }, - "t_struct(FeeChangeRequest)1201_storage": { - "label": "struct SSVNetwork.FeeChangeRequest", - "members": [ - { - "label": "fee", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "approvalBeginTime", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "approvalEndTime", - "type": "t_uint256", - "offset": 0, - "slot": "2" - } - ], - "numberOfBytes": "96" - }, - "t_struct(OperatorData)1166_storage": { - "label": "struct SSVNetwork.OperatorData", - "members": [ - { - "label": "blockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "earnings", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "index", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "indexBlockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "4" - }, - { - "label": "previousFee", - "type": "t_uint256", - "offset": 0, - "slot": "5" - } - ], - "numberOfBytes": "192" - }, - "t_struct(OperatorInUse)1194_storage": { - "label": "struct SSVNetwork.OperatorInUse", - "members": [ - { - "label": "index", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "validatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "used", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "exists", - "type": "t_bool", - "offset": 0, - "slot": "3" - }, - { - "label": "indexInArray", - "type": "t_uint256", - "offset": 0, - "slot": "4" - } - ], - "numberOfBytes": "160" - }, - "t_struct(OwnerData)1183_storage": { - "label": "struct SSVNetwork.OwnerData", - "members": [ - { - "label": "deposited", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "withdrawn", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "earned", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "used", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "networkFee", - "type": "t_uint256", - "offset": 0, - "slot": "4" - }, - { - "label": "networkFeeIndex", - "type": "t_uint256", - "offset": 0, - "slot": "5" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "6" - }, - { - "label": "validatorsDisabled", - "type": "t_bool", - "offset": 0, - "slot": "7" - } - ], - "numberOfBytes": "256" - }, - "t_uint256": { - "label": "uint256", - "numberOfBytes": "32" - } - } - } - }, - "ef4cbfab967249c519508f2410a677e77e2f349fd73dd14bafaae41bfde112c6": { - "address": "0x035A8c9A827d59af98DE0705126faC981B060692", - "txHash": "0xce3f3aed9495a49bb2a6ff5c2fb736a6eb2924b713dc73c4547748088abe0e3a", - "layout": { - "storage": [ - { - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:23" - }, - { - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:28" - }, - { - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage", - "contract": "ContextUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" - }, - { - "label": "_owner", - "offset": 0, - "slot": "51", - "type": "t_address", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:20" - }, - { - "label": "__gap", - "offset": 0, - "slot": "52", - "type": "t_array(t_uint256)49_storage", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:74" - }, - { - "label": "_ssvRegistryContract", - "offset": 0, - "slot": "101", - "type": "t_contract(ISSVRegistry)1918", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:45" - }, - { - "label": "_token", - "offset": 0, - "slot": "102", - "type": "t_contract(IERC20)950", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:46" - }, - { - "label": "_minimumBlocksBeforeLiquidation", - "offset": 0, - "slot": "103", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:47" - }, - { - "label": "_operatorMaxFeeIncrease", - "offset": 0, - "slot": "104", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:48" - }, - { - "label": "_networkFee", - "offset": 0, - "slot": "105", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:50" - }, - { - "label": "_networkFeeIndex", - "offset": 0, - "slot": "106", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:51" - }, - { - "label": "_networkFeeIndexBlockNumber", - "offset": 0, - "slot": "107", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:52" - }, - { - "label": "_networkEarnings", - "offset": 0, - "slot": "108", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:53" - }, - { - "label": "_networkEarningsBlockNumber", - "offset": 0, - "slot": "109", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:54" - }, - { - "label": "_withdrawnFromTreasury", - "offset": 0, - "slot": "110", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:55" - }, - { - "label": "_operatorDatas", - "offset": 0, - "slot": "111", - "type": "t_mapping(t_uint256,t_struct(OperatorData)1942_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:57" - }, - { - "label": "_owners", - "offset": 0, - "slot": "112", - "type": "t_mapping(t_address,t_struct(OwnerData)1959_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:58" - }, - { - "label": "_operatorsInUseByAddress", - "offset": 0, - "slot": "113", - "type": "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)1970_storage))", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:59" - }, - { - "label": "_operatorsInUseList", - "offset": 0, - "slot": "114", - "type": "t_mapping(t_address,t_array(t_uint256)dyn_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:60" - }, - { - "label": "_lastOperatorUpdateNetworkFeeRun", - "offset": 0, - "slot": "115", - "type": "t_mapping(t_uint256,t_uint256)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:61" - }, - { - "label": "_setOperatorFeePeriod", - "offset": 0, - "slot": "116", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:63" - }, - { - "label": "_approveOperatorFeePeriod", - "offset": 0, - "slot": "117", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:64" - }, - { - "label": "_feeChangeRequests", - "offset": 0, - "slot": "118", - "type": "t_mapping(t_uint256,t_struct(FeeChangeRequest)1977_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:65" - } - ], - "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_array(t_uint256)dyn_storage": { - "label": "uint256[]", - "numberOfBytes": "32" - }, - "t_bool": { - "label": "bool", - "numberOfBytes": "1" - }, - "t_contract(IERC20)950": { - "label": "contract IERC20", - "numberOfBytes": "20" - }, - "t_contract(ISSVRegistry)1918": { - "label": "contract ISSVRegistry", - "numberOfBytes": "20" - }, - "t_mapping(t_address,t_array(t_uint256)dyn_storage)": { - "label": "mapping(address => uint256[])", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)1970_storage))": { - "label": "mapping(address => mapping(uint256 => struct SSVNetwork.OperatorInUse))", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_struct(OwnerData)1959_storage)": { - "label": "mapping(address => struct SSVNetwork.OwnerData)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(FeeChangeRequest)1977_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.FeeChangeRequest)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(OperatorData)1942_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorData)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(OperatorInUse)1970_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorInUse)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_uint256)": { - "label": "mapping(uint256 => uint256)", - "numberOfBytes": "32" - }, - "t_struct(FeeChangeRequest)1977_storage": { - "label": "struct SSVNetwork.FeeChangeRequest", - "members": [ - { - "label": "fee", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "approvalBeginTime", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "approvalEndTime", - "type": "t_uint256", - "offset": 0, - "slot": "2" - } - ], - "numberOfBytes": "96" - }, - "t_struct(OperatorData)1942_storage": { - "label": "struct SSVNetwork.OperatorData", - "members": [ - { - "label": "blockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "earnings", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "index", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "indexBlockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "4" - }, - { - "label": "previousFee", - "type": "t_uint256", - "offset": 0, - "slot": "5" - } - ], - "numberOfBytes": "192" - }, - "t_struct(OperatorInUse)1970_storage": { - "label": "struct SSVNetwork.OperatorInUse", - "members": [ - { - "label": "index", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "validatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "used", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "exists", - "type": "t_bool", - "offset": 0, - "slot": "3" - }, - { - "label": "indexInArray", - "type": "t_uint256", - "offset": 0, - "slot": "4" - } - ], - "numberOfBytes": "160" - }, - "t_struct(OwnerData)1959_storage": { - "label": "struct SSVNetwork.OwnerData", - "members": [ - { - "label": "deposited", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "withdrawn", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "earned", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "used", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "networkFee", - "type": "t_uint256", - "offset": 0, - "slot": "4" - }, - { - "label": "networkFeeIndex", - "type": "t_uint256", - "offset": 0, - "slot": "5" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "6" - }, - { - "label": "validatorsDisabled", - "type": "t_bool", - "offset": 0, - "slot": "7" - } - ], - "numberOfBytes": "256" - }, - "t_uint256": { - "label": "uint256", - "numberOfBytes": "32" - } - } - } - }, - "37d0587e2ab0c2e47bac372b9c3e29c8b23fd7873aa0391d94b7dde4f8124697": { - "address": "0xe1130a5fcD4783E9737905141e5441659dcddEB5", - "txHash": "0xf5d59399a61741217d6d0f40ea194d53c8ca795e35d216a1eccc1f90a1bd2c60", - "layout": { - "storage": [ - { - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:23" - }, - { - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:28" - }, - { - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage", - "contract": "ContextUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" - }, - { - "label": "_owner", - "offset": 0, - "slot": "51", - "type": "t_address", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:20" - }, - { - "label": "__gap", - "offset": 0, - "slot": "52", - "type": "t_array(t_uint256)49_storage", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:74" - }, - { - "label": "_activeValidatorCount", - "offset": 0, - "slot": "101", - "type": "t_uint256", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:34" - }, - { - "label": "_lastOperatorId", - "offset": 0, - "slot": "102", - "type": "t_struct(Counter)1003_storage", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:36" - }, - { - "label": "_operators", - "offset": 0, - "slot": "103", - "type": "t_mapping(t_uint256,t_struct(Operator)4600_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:38" - }, - { - "label": "_validators", - "offset": 0, - "slot": "104", - "type": "t_mapping(t_bytes_memory_ptr,t_struct(Validator)4610_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:39" - }, - { - "label": "_operatorsByOwnerAddress", - "offset": 0, - "slot": "105", - "type": "t_mapping(t_address,t_array(t_uint256)dyn_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:41" - }, - { - "label": "_validatorsByOwnerAddress", - "offset": 0, - "slot": "106", - "type": "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:42" - }, - { - "label": "_owners", - "offset": 0, - "slot": "107", - "type": "t_mapping(t_address,t_struct(OwnerData)4615_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:43" - }, - { - "label": "validatorsPerOperator", - "offset": 0, - "slot": "108", - "type": "t_mapping(t_uint256,t_uint256)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:45" - }, - { - "label": "validatorsPerOperatorLimit", - "offset": 0, - "slot": "109", - "type": "t_uint256", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:46" - }, - { - "label": "_operatorPublicKeyToId", - "offset": 0, - "slot": "110", - "type": "t_mapping(t_bytes_memory_ptr,t_uint256)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:47" - }, - { - "label": "operatorsPerOwnerLimit", - "offset": 0, - "slot": "111", - "type": "t_uint256", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:48" - } - ], - "types": { - "t_address": { - "label": "address", - "numberOfBytes": "20" - }, - "t_array(t_bytes_storage)dyn_storage": { - "label": "bytes[]", - "numberOfBytes": "32" - }, - "t_array(t_uint256)49_storage": { - "label": "uint256[49]", - "numberOfBytes": "1568" - }, - "t_array(t_uint256)50_storage": { - "label": "uint256[50]", - "numberOfBytes": "1600" - }, - "t_array(t_uint256)dyn_storage": { - "label": "uint256[]", - "numberOfBytes": "32" - }, - "t_bool": { - "label": "bool", - "numberOfBytes": "1" - }, - "t_bytes_memory_ptr": { - "label": "bytes", - "numberOfBytes": "32" - }, - "t_bytes_storage": { - "label": "bytes", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)": { - "label": "mapping(address => bytes[])", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_array(t_uint256)dyn_storage)": { - "label": "mapping(address => uint256[])", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_struct(OwnerData)4615_storage)": { - "label": "mapping(address => struct SSVRegistry.OwnerData)", - "numberOfBytes": "32" - }, - "t_mapping(t_bytes_memory_ptr,t_struct(Validator)4610_storage)": { - "label": "mapping(bytes => struct SSVRegistry.Validator)", - "numberOfBytes": "32" - }, - "t_mapping(t_bytes_memory_ptr,t_uint256)": { - "label": "mapping(bytes => uint256)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(Operator)4600_storage)": { - "label": "mapping(uint256 => struct SSVRegistry.Operator)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_uint256)": { - "label": "mapping(uint256 => uint256)", - "numberOfBytes": "32" - }, - "t_string_storage": { - "label": "string", - "numberOfBytes": "32" - }, - "t_struct(Counter)1003_storage": { - "label": "struct Counters.Counter", - "members": [ - { - "label": "_value", - "type": "t_uint256", - "offset": 0, - "slot": "0" - } - ], - "numberOfBytes": "32" - }, - "t_struct(Operator)4600_storage": { - "label": "struct SSVRegistry.Operator", - "members": [ - { - "label": "name", - "type": "t_string_storage", - "offset": 0, - "slot": "0" - }, - { - "label": "ownerAddress", - "type": "t_address", - "offset": 0, - "slot": "1" - }, - { - "label": "publicKey", - "type": "t_bytes_storage", - "offset": 0, - "slot": "2" - }, - { - "label": "score", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "fee", - "type": "t_uint256", - "offset": 0, - "slot": "4" - }, - { - "label": "active", - "type": "t_bool", - "offset": 0, - "slot": "5" - }, - { - "label": "indexInOwner", - "type": "t_uint256", - "offset": 0, - "slot": "6" - } - ], - "numberOfBytes": "224" - }, - "t_struct(OwnerData)4615_storage": { - "label": "struct SSVRegistry.OwnerData", - "members": [ - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "validatorsDisabled", - "type": "t_bool", - "offset": 0, - "slot": "1" - } - ], - "numberOfBytes": "64" - }, - "t_struct(Validator)4610_storage": { - "label": "struct SSVRegistry.Validator", - "members": [ - { - "label": "ownerAddress", - "type": "t_address", - "offset": 0, - "slot": "0" - }, - { - "label": "operatorIds", - "type": "t_array(t_uint256)dyn_storage", - "offset": 0, - "slot": "1" - }, - { - "label": "active", - "type": "t_bool", - "offset": 0, - "slot": "2" - }, - { - "label": "indexInOwner", - "type": "t_uint256", - "offset": 0, - "slot": "3" - } - ], - "numberOfBytes": "128" - }, - "t_uint256": { - "label": "uint256", - "numberOfBytes": "32" - } - } - } - }, - "cb6fba5d58e9f15cc30f60f17e4df7036377e98bc0f544705e2522f6c0b93a16": { - "address": "0x68b36f52a3773763D91817C7b4D593f69D68c0a2", - "txHash": "0x0defff3f9676d548b6d2d0cd8adf2163a5064237c52f98081285bfd73b63c6bf", - "layout": { - "storage": [ - { - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:23" - }, - { - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:28" - }, - { - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage", - "contract": "ContextUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" - }, - { - "label": "_owner", - "offset": 0, - "slot": "51", - "type": "t_address", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:20" - }, - { - "label": "__gap", - "offset": 0, - "slot": "52", - "type": "t_array(t_uint256)49_storage", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:74" - }, - { - "label": "_ssvRegistryContract", - "offset": 0, - "slot": "101", - "type": "t_contract(ISSVRegistry)1946", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:45" - }, - { - "label": "_token", - "offset": 0, - "slot": "102", - "type": "t_contract(IERC20)950", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:46" - }, - { - "label": "_minimumBlocksBeforeLiquidation", - "offset": 0, - "slot": "103", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:47" - }, - { - "label": "_operatorMaxFeeIncrease", - "offset": 0, - "slot": "104", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:48" - }, - { - "label": "_networkFee", - "offset": 0, - "slot": "105", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:50" - }, - { - "label": "_networkFeeIndex", - "offset": 0, - "slot": "106", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:51" - }, - { - "label": "_networkFeeIndexBlockNumber", - "offset": 0, - "slot": "107", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:52" - }, - { - "label": "_networkEarnings", - "offset": 0, - "slot": "108", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:53" - }, - { - "label": "_networkEarningsBlockNumber", - "offset": 0, - "slot": "109", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:54" - }, - { - "label": "_withdrawnFromTreasury", - "offset": 0, - "slot": "110", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:55" - }, - { - "label": "_operatorDatas", - "offset": 0, - "slot": "111", - "type": "t_mapping(t_uint256,t_struct(OperatorData)1970_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:57" - }, - { - "label": "_owners", - "offset": 0, - "slot": "112", - "type": "t_mapping(t_address,t_struct(OwnerData)1987_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:58" - }, - { - "label": "_operatorsInUseByAddress", - "offset": 0, - "slot": "113", - "type": "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)1998_storage))", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:59" - }, - { - "label": "_operatorsInUseList", - "offset": 0, - "slot": "114", - "type": "t_mapping(t_address,t_array(t_uint256)dyn_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:60" - }, - { - "label": "_lastOperatorUpdateNetworkFeeRun", - "offset": 0, - "slot": "115", - "type": "t_mapping(t_uint256,t_uint256)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:61" - }, - { - "label": "_setOperatorFeePeriod", - "offset": 0, - "slot": "116", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:63" - }, - { - "label": "_approveOperatorFeePeriod", - "offset": 0, - "slot": "117", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:64" - }, - { - "label": "_feeChangeRequests", - "offset": 0, - "slot": "118", - "type": "t_mapping(t_uint256,t_struct(FeeChangeRequest)2005_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:65" - } - ], - "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_array(t_uint256)dyn_storage": { - "label": "uint256[]", - "numberOfBytes": "32" - }, - "t_bool": { - "label": "bool", - "numberOfBytes": "1" - }, - "t_contract(IERC20)950": { - "label": "contract IERC20", - "numberOfBytes": "20" - }, - "t_contract(ISSVRegistry)1946": { - "label": "contract ISSVRegistry", - "numberOfBytes": "20" - }, - "t_mapping(t_address,t_array(t_uint256)dyn_storage)": { - "label": "mapping(address => uint256[])", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)1998_storage))": { - "label": "mapping(address => mapping(uint256 => struct SSVNetwork.OperatorInUse))", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_struct(OwnerData)1987_storage)": { - "label": "mapping(address => struct SSVNetwork.OwnerData)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(FeeChangeRequest)2005_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.FeeChangeRequest)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(OperatorData)1970_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorData)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(OperatorInUse)1998_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorInUse)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_uint256)": { - "label": "mapping(uint256 => uint256)", - "numberOfBytes": "32" - }, - "t_struct(FeeChangeRequest)2005_storage": { - "label": "struct SSVNetwork.FeeChangeRequest", - "members": [ - { - "label": "fee", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "approvalBeginTime", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "approvalEndTime", - "type": "t_uint256", - "offset": 0, - "slot": "2" - } - ], - "numberOfBytes": "96" - }, - "t_struct(OperatorData)1970_storage": { - "label": "struct SSVNetwork.OperatorData", - "members": [ - { - "label": "blockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "earnings", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "index", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "indexBlockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "4" - }, - { - "label": "previousFee", - "type": "t_uint256", - "offset": 0, - "slot": "5" - } - ], - "numberOfBytes": "192" - }, - "t_struct(OperatorInUse)1998_storage": { - "label": "struct SSVNetwork.OperatorInUse", - "members": [ - { - "label": "index", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "validatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "used", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "exists", - "type": "t_bool", - "offset": 0, - "slot": "3" - }, - { - "label": "indexInArray", - "type": "t_uint256", - "offset": 0, - "slot": "4" - } - ], - "numberOfBytes": "160" - }, - "t_struct(OwnerData)1987_storage": { - "label": "struct SSVNetwork.OwnerData", - "members": [ - { - "label": "deposited", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "withdrawn", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "earned", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "used", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "networkFee", - "type": "t_uint256", - "offset": 0, - "slot": "4" - }, - { - "label": "networkFeeIndex", - "type": "t_uint256", - "offset": 0, - "slot": "5" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "6" - }, - { - "label": "validatorsDisabled", - "type": "t_bool", - "offset": 0, - "slot": "7" - } - ], - "numberOfBytes": "256" - }, - "t_uint256": { - "label": "uint256", - "numberOfBytes": "32" - } - } - } - }, - "0ab944ed993758bbcef5cbcf09ed4e6a3282bd066007288cb694ec271550e6ff": { - "address": "0x32c681B5d35F6eaD9B6Ec5A49A05EF695712727D", - "txHash": "0x87942864ae09432a45b0a7a229f3bde68714daf3581f7e27be57daec3c3a19ed", - "layout": { - "storage": [ - { - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:23" - }, - { - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:28" - }, - { - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage", - "contract": "ContextUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" - }, - { - "label": "_owner", - "offset": 0, - "slot": "51", - "type": "t_address", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:20" - }, - { - "label": "__gap", - "offset": 0, - "slot": "52", - "type": "t_array(t_uint256)49_storage", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:74" - }, - { - "label": "_activeValidatorCount", - "offset": 0, - "slot": "101", - "type": "t_uint256", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:34" - }, - { - "label": "_lastOperatorId", - "offset": 0, - "slot": "102", - "type": "t_struct(Counter)1003_storage", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:36" - }, - { - "label": "_operators", - "offset": 0, - "slot": "103", - "type": "t_mapping(t_uint256,t_struct(Operator)4511_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:38" - }, - { - "label": "_validators", - "offset": 0, - "slot": "104", - "type": "t_mapping(t_bytes_memory_ptr,t_struct(Validator)4521_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:39" - }, - { - "label": "_operatorsByOwnerAddress", - "offset": 0, - "slot": "105", - "type": "t_mapping(t_address,t_array(t_uint256)dyn_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:41" - }, - { - "label": "_validatorsByOwnerAddress", - "offset": 0, - "slot": "106", - "type": "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:42" - }, - { - "label": "_owners", - "offset": 0, - "slot": "107", - "type": "t_mapping(t_address,t_struct(OwnerData)4526_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:43" - }, - { - "label": "validatorsPerOperator", - "offset": 0, - "slot": "108", - "type": "t_mapping(t_uint256,t_uint256)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:45" - }, - { - "label": "validatorsPerOperatorLimit", - "offset": 0, - "slot": "109", - "type": "t_uint256", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:46" - }, - { - "label": "_operatorPublicKeyToId", - "offset": 0, - "slot": "110", - "type": "t_mapping(t_bytes_memory_ptr,t_uint256)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:47" - }, - { - "label": "registeredOperatorsPerAccountLimit", - "offset": 0, - "slot": "111", - "type": "t_uint256", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:48" - } - ], - "types": { - "t_address": { - "label": "address", - "numberOfBytes": "20" - }, - "t_array(t_bytes_storage)dyn_storage": { - "label": "bytes[]", - "numberOfBytes": "32" - }, - "t_array(t_uint256)49_storage": { - "label": "uint256[49]", - "numberOfBytes": "1568" - }, - "t_array(t_uint256)50_storage": { - "label": "uint256[50]", - "numberOfBytes": "1600" - }, - "t_array(t_uint256)dyn_storage": { - "label": "uint256[]", - "numberOfBytes": "32" - }, - "t_bool": { - "label": "bool", - "numberOfBytes": "1" - }, - "t_bytes_memory_ptr": { - "label": "bytes", - "numberOfBytes": "32" - }, - "t_bytes_storage": { - "label": "bytes", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)": { - "label": "mapping(address => bytes[])", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_array(t_uint256)dyn_storage)": { - "label": "mapping(address => uint256[])", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_struct(OwnerData)4526_storage)": { - "label": "mapping(address => struct SSVRegistry.OwnerData)", - "numberOfBytes": "32" - }, - "t_mapping(t_bytes_memory_ptr,t_struct(Validator)4521_storage)": { - "label": "mapping(bytes => struct SSVRegistry.Validator)", - "numberOfBytes": "32" - }, - "t_mapping(t_bytes_memory_ptr,t_uint256)": { - "label": "mapping(bytes => uint256)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(Operator)4511_storage)": { - "label": "mapping(uint256 => struct SSVRegistry.Operator)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_uint256)": { - "label": "mapping(uint256 => uint256)", - "numberOfBytes": "32" - }, - "t_string_storage": { - "label": "string", - "numberOfBytes": "32" - }, - "t_struct(Counter)1003_storage": { - "label": "struct Counters.Counter", - "members": [ - { - "label": "_value", - "type": "t_uint256", - "offset": 0, - "slot": "0" - } - ], - "numberOfBytes": "32" - }, - "t_struct(Operator)4511_storage": { - "label": "struct SSVRegistry.Operator", - "members": [ - { - "label": "name", - "type": "t_string_storage", - "offset": 0, - "slot": "0" - }, - { - "label": "ownerAddress", - "type": "t_address", - "offset": 0, - "slot": "1" - }, - { - "label": "publicKey", - "type": "t_bytes_storage", - "offset": 0, - "slot": "2" - }, - { - "label": "score", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "fee", - "type": "t_uint256", - "offset": 0, - "slot": "4" - }, - { - "label": "active", - "type": "t_bool", - "offset": 0, - "slot": "5" - }, - { - "label": "indexInOwner", - "type": "t_uint256", - "offset": 0, - "slot": "6" - } - ], - "numberOfBytes": "224" - }, - "t_struct(OwnerData)4526_storage": { - "label": "struct SSVRegistry.OwnerData", - "members": [ - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "validatorsDisabled", - "type": "t_bool", - "offset": 0, - "slot": "1" - } - ], - "numberOfBytes": "64" - }, - "t_struct(Validator)4521_storage": { - "label": "struct SSVRegistry.Validator", - "members": [ - { - "label": "ownerAddress", - "type": "t_address", - "offset": 0, - "slot": "0" - }, - { - "label": "operatorIds", - "type": "t_array(t_uint256)dyn_storage", - "offset": 0, - "slot": "1" - }, - { - "label": "active", - "type": "t_bool", - "offset": 0, - "slot": "2" - }, - { - "label": "indexInOwner", - "type": "t_uint256", - "offset": 0, - "slot": "3" - } - ], - "numberOfBytes": "128" - }, - "t_uint256": { - "label": "uint256", - "numberOfBytes": "32" - } - } - } - }, - "78295b9e6f34d6e24582399c186fc32a263154d8af40d1612d163355245e4498": { - "address": "0xD1B2bBc138A6C9eCaA1eD0cCAC29D2231A8a37c3", - "txHash": "0xe5a96c5368069054e79fd31c13db79a6b05fdbed401d144fb1ea7cccb4b45e33", - "layout": { - "storage": [ - { - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:23" - }, - { - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:28" - }, - { - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage", - "contract": "ContextUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" - }, - { - "label": "_owner", - "offset": 0, - "slot": "51", - "type": "t_address", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:20" - }, - { - "label": "__gap", - "offset": 0, - "slot": "52", - "type": "t_array(t_uint256)49_storage", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:74" - }, - { - "label": "_ssvRegistryContract", - "offset": 0, - "slot": "101", - "type": "t_contract(ISSVRegistry)1145", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:44" - }, - { - "label": "_token", - "offset": 0, - "slot": "102", - "type": "t_contract(IERC20)299", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:45" - }, - { - "label": "_minimumBlocksBeforeLiquidation", - "offset": 0, - "slot": "103", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:46" - }, - { - "label": "_operatorMaxFeeIncrease", - "offset": 0, - "slot": "104", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:47" - }, - { - "label": "_networkFee", - "offset": 0, - "slot": "105", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:49" - }, - { - "label": "_networkFeeIndex", - "offset": 0, - "slot": "106", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:50" - }, - { - "label": "_networkFeeIndexBlockNumber", - "offset": 0, - "slot": "107", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:51" - }, - { - "label": "_networkEarnings", - "offset": 0, - "slot": "108", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:52" - }, - { - "label": "_networkEarningsBlockNumber", - "offset": 0, - "slot": "109", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:53" - }, - { - "label": "_withdrawnFromTreasury", - "offset": 0, - "slot": "110", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:54" - }, - { - "label": "_operatorDatas", - "offset": 0, - "slot": "111", - "type": "t_mapping(t_uint256,t_struct(OperatorData)1167_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:56" - }, - { - "label": "_owners", - "offset": 0, - "slot": "112", - "type": "t_mapping(t_address,t_struct(OwnerData)1184_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:57" - }, - { - "label": "_operatorsInUseByAddress", - "offset": 0, - "slot": "113", - "type": "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)1195_storage))", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:58" - }, - { - "label": "_operatorsInUseList", - "offset": 0, - "slot": "114", - "type": "t_mapping(t_address,t_array(t_uint256)dyn_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:59" - }, - { - "label": "_lastOperatorUpdateNetworkFeeRun", - "offset": 0, - "slot": "115", - "type": "t_mapping(t_uint256,t_uint256)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:60" - }, - { - "label": "_setOperatorFeePeriod", - "offset": 0, - "slot": "116", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:62" - }, - { - "label": "_approveOperatorFeePeriod", - "offset": 0, - "slot": "117", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:63" - }, - { - "label": "_feeChangeRequests", - "offset": 0, - "slot": "118", - "type": "t_mapping(t_uint256,t_struct(FeeChangeRequest)1202_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:64" - } - ], - "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_array(t_uint256)dyn_storage": { - "label": "uint256[]", - "numberOfBytes": "32" - }, - "t_bool": { - "label": "bool", - "numberOfBytes": "1" - }, - "t_contract(IERC20)299": { - "label": "contract IERC20", - "numberOfBytes": "20" - }, - "t_contract(ISSVRegistry)1145": { - "label": "contract ISSVRegistry", - "numberOfBytes": "20" - }, - "t_mapping(t_address,t_array(t_uint256)dyn_storage)": { - "label": "mapping(address => uint256[])", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)1195_storage))": { - "label": "mapping(address => mapping(uint256 => struct SSVNetwork.OperatorInUse))", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_struct(OwnerData)1184_storage)": { - "label": "mapping(address => struct SSVNetwork.OwnerData)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(FeeChangeRequest)1202_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.FeeChangeRequest)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(OperatorData)1167_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorData)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(OperatorInUse)1195_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorInUse)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_uint256)": { - "label": "mapping(uint256 => uint256)", - "numberOfBytes": "32" - }, - "t_struct(FeeChangeRequest)1202_storage": { - "label": "struct SSVNetwork.FeeChangeRequest", - "members": [ - { - "label": "fee", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "approvalBeginTime", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "approvalEndTime", - "type": "t_uint256", - "offset": 0, - "slot": "2" - } - ], - "numberOfBytes": "96" - }, - "t_struct(OperatorData)1167_storage": { - "label": "struct SSVNetwork.OperatorData", - "members": [ - { - "label": "blockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "earnings", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "index", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "indexBlockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "4" - } - ], - "numberOfBytes": "160" - }, - "t_struct(OperatorInUse)1195_storage": { - "label": "struct SSVNetwork.OperatorInUse", - "members": [ - { - "label": "index", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "validatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "used", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "exists", - "type": "t_bool", - "offset": 0, - "slot": "3" - }, - { - "label": "indexInArray", - "type": "t_uint256", - "offset": 0, - "slot": "4" - } - ], - "numberOfBytes": "160" - }, - "t_struct(OwnerData)1184_storage": { - "label": "struct SSVNetwork.OwnerData", - "members": [ - { - "label": "deposited", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "withdrawn", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "earned", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "used", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "networkFee", - "type": "t_uint256", - "offset": 0, - "slot": "4" - }, - { - "label": "networkFeeIndex", - "type": "t_uint256", - "offset": 0, - "slot": "5" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "6" - }, - { - "label": "validatorsDisabled", - "type": "t_bool", - "offset": 0, - "slot": "7" - } - ], - "numberOfBytes": "256" - }, - "t_uint256": { - "label": "uint256", - "numberOfBytes": "32" - } - } - } - }, - "e7f574477b6b8e9706a6ac1323a0f703475e964e5613f4b70b6b5eed2996671c": { - "address": "0xC1099B13178856C94a5cDb3ec92B061A3E21e8d9", - "txHash": "0x92fc6cfee744d88829caf948293510457abce92b30c5b5eb094d7fb3130c303e", - "layout": { - "storage": [ - { - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:23" - }, - { - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:28" - }, - { - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage", - "contract": "ContextUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" - }, - { - "label": "_owner", - "offset": 0, - "slot": "51", - "type": "t_address", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:20" - }, - { - "label": "__gap", - "offset": 0, - "slot": "52", - "type": "t_array(t_uint256)49_storage", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:74" - }, - { - "label": "_ssvRegistryContract", - "offset": 0, - "slot": "101", - "type": "t_contract(ISSVRegistry)1145", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:44" - }, - { - "label": "_token", - "offset": 0, - "slot": "102", - "type": "t_contract(IERC20)299", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:45" - }, - { - "label": "_minimumBlocksBeforeLiquidation", - "offset": 0, - "slot": "103", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:46" - }, - { - "label": "_operatorMaxFeeIncrease", - "offset": 0, - "slot": "104", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:47" - }, - { - "label": "_networkFee", - "offset": 0, - "slot": "105", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:49" - }, - { - "label": "_networkFeeIndex", - "offset": 0, - "slot": "106", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:50" - }, - { - "label": "_networkFeeIndexBlockNumber", - "offset": 0, - "slot": "107", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:51" - }, - { - "label": "_networkEarnings", - "offset": 0, - "slot": "108", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:52" - }, - { - "label": "_networkEarningsBlockNumber", - "offset": 0, - "slot": "109", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:53" - }, - { - "label": "_withdrawnFromTreasury", - "offset": 0, - "slot": "110", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:54" - }, - { - "label": "_operatorDatas", - "offset": 0, - "slot": "111", - "type": "t_mapping(t_uint256,t_struct(OperatorData)1167_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:56" - }, - { - "label": "_owners", - "offset": 0, - "slot": "112", - "type": "t_mapping(t_address,t_struct(OwnerData)1184_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:57" - }, - { - "label": "_operatorsInUseByAddress", - "offset": 0, - "slot": "113", - "type": "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)1195_storage))", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:58" - }, - { - "label": "_operatorsInUseList", - "offset": 0, - "slot": "114", - "type": "t_mapping(t_address,t_array(t_uint256)dyn_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:59" - }, - { - "label": "_lastOperatorUpdateNetworkFeeRun", - "offset": 0, - "slot": "115", - "type": "t_mapping(t_uint256,t_uint256)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:60" - }, - { - "label": "_setOperatorFeePeriod", - "offset": 0, - "slot": "116", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:62" - }, - { - "label": "_approveOperatorFeePeriod", - "offset": 0, - "slot": "117", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:63" - }, - { - "label": "_feeChangeRequests", - "offset": 0, - "slot": "118", - "type": "t_mapping(t_uint256,t_struct(FeeChangeRequest)1202_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:64" - } - ], - "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_array(t_uint256)dyn_storage": { - "label": "uint256[]", - "numberOfBytes": "32" - }, - "t_bool": { - "label": "bool", - "numberOfBytes": "1" - }, - "t_contract(IERC20)299": { - "label": "contract IERC20", - "numberOfBytes": "20" - }, - "t_contract(ISSVRegistry)1145": { - "label": "contract ISSVRegistry", - "numberOfBytes": "20" - }, - "t_mapping(t_address,t_array(t_uint256)dyn_storage)": { - "label": "mapping(address => uint256[])", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)1195_storage))": { - "label": "mapping(address => mapping(uint256 => struct SSVNetwork.OperatorInUse))", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_struct(OwnerData)1184_storage)": { - "label": "mapping(address => struct SSVNetwork.OwnerData)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(FeeChangeRequest)1202_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.FeeChangeRequest)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(OperatorData)1167_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorData)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(OperatorInUse)1195_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorInUse)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_uint256)": { - "label": "mapping(uint256 => uint256)", - "numberOfBytes": "32" - }, - "t_struct(FeeChangeRequest)1202_storage": { - "label": "struct SSVNetwork.FeeChangeRequest", - "members": [ - { - "label": "fee", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "approvalBeginTime", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "approvalEndTime", - "type": "t_uint256", - "offset": 0, - "slot": "2" - } - ], - "numberOfBytes": "96" - }, - "t_struct(OperatorData)1167_storage": { - "label": "struct SSVNetwork.OperatorData", - "members": [ - { - "label": "blockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "earnings", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "index", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "indexBlockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "4" - } - ], - "numberOfBytes": "160" - }, - "t_struct(OperatorInUse)1195_storage": { - "label": "struct SSVNetwork.OperatorInUse", - "members": [ - { - "label": "index", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "validatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "used", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "exists", - "type": "t_bool", - "offset": 0, - "slot": "3" - }, - { - "label": "indexInArray", - "type": "t_uint256", - "offset": 0, - "slot": "4" - } - ], - "numberOfBytes": "160" - }, - "t_struct(OwnerData)1184_storage": { - "label": "struct SSVNetwork.OwnerData", - "members": [ - { - "label": "deposited", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "withdrawn", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "earned", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "used", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "networkFee", - "type": "t_uint256", - "offset": 0, - "slot": "4" - }, - { - "label": "networkFeeIndex", - "type": "t_uint256", - "offset": 0, - "slot": "5" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "6" - }, - { - "label": "validatorsDisabled", - "type": "t_bool", - "offset": 0, - "slot": "7" - } - ], - "numberOfBytes": "256" - }, - "t_uint256": { - "label": "uint256", - "numberOfBytes": "32" - } - } - } - }, - "098282ac761c51912ee507318413e8d6b167811709f42f4d9e763496a9c9788b": { - "address": "0x57A3F4DE4021Bed66F817B15043562b69971a3Ae", - "txHash": "0x6dd25843673401798c175386aeed2689d63e38139f9f6cbfd39b6f29a0de41b2", - "layout": { - "storage": [ - { - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:23" - }, - { - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:28" - }, - { - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage", - "contract": "ContextUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" - }, - { - "label": "_owner", - "offset": 0, - "slot": "51", - "type": "t_address", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:20" - }, - { - "label": "__gap", - "offset": 0, - "slot": "52", - "type": "t_array(t_uint256)49_storage", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:74" - }, - { - "label": "_activeValidatorCount", - "offset": 0, - "slot": "101", - "type": "t_uint256", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:34" - }, - { - "label": "_lastOperatorId", - "offset": 0, - "slot": "102", - "type": "t_struct(Counter)1003_storage", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:36" - }, - { - "label": "_operators", - "offset": 0, - "slot": "103", - "type": "t_mapping(t_uint256,t_struct(Operator)4511_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:38" - }, - { - "label": "_validators", - "offset": 0, - "slot": "104", - "type": "t_mapping(t_bytes_memory_ptr,t_struct(Validator)4521_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:39" - }, - { - "label": "_operatorsByOwnerAddress", - "offset": 0, - "slot": "105", - "type": "t_mapping(t_address,t_array(t_uint256)dyn_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:41" - }, - { - "label": "_validatorsByOwnerAddress", - "offset": 0, - "slot": "106", - "type": "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:42" - }, - { - "label": "_owners", - "offset": 0, - "slot": "107", - "type": "t_mapping(t_address,t_struct(OwnerData)4526_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:43" - }, - { - "label": "validatorsPerOperator", - "offset": 0, - "slot": "108", - "type": "t_mapping(t_uint256,t_uint256)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:45" - }, - { - "label": "validatorsPerOperatorLimit", - "offset": 0, - "slot": "109", - "type": "t_uint256", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:46" - }, - { - "label": "_operatorPublicKeyToId", - "offset": 0, - "slot": "110", - "type": "t_mapping(t_bytes_memory_ptr,t_uint256)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:47" - }, - { - "label": "registeredOperatorsPerAccountLimit", - "offset": 0, - "slot": "111", - "type": "t_uint256", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:48" - } - ], - "types": { - "t_address": { - "label": "address", - "numberOfBytes": "20" - }, - "t_array(t_bytes_storage)dyn_storage": { - "label": "bytes[]", - "numberOfBytes": "32" - }, - "t_array(t_uint256)49_storage": { - "label": "uint256[49]", - "numberOfBytes": "1568" - }, - "t_array(t_uint256)50_storage": { - "label": "uint256[50]", - "numberOfBytes": "1600" - }, - "t_array(t_uint256)dyn_storage": { - "label": "uint256[]", - "numberOfBytes": "32" - }, - "t_bool": { - "label": "bool", - "numberOfBytes": "1" - }, - "t_bytes_memory_ptr": { - "label": "bytes", - "numberOfBytes": "32" - }, - "t_bytes_storage": { - "label": "bytes", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)": { - "label": "mapping(address => bytes[])", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_array(t_uint256)dyn_storage)": { - "label": "mapping(address => uint256[])", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_struct(OwnerData)4526_storage)": { - "label": "mapping(address => struct SSVRegistry.OwnerData)", - "numberOfBytes": "32" - }, - "t_mapping(t_bytes_memory_ptr,t_struct(Validator)4521_storage)": { - "label": "mapping(bytes => struct SSVRegistry.Validator)", - "numberOfBytes": "32" - }, - "t_mapping(t_bytes_memory_ptr,t_uint256)": { - "label": "mapping(bytes => uint256)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(Operator)4511_storage)": { - "label": "mapping(uint256 => struct SSVRegistry.Operator)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_uint256)": { - "label": "mapping(uint256 => uint256)", - "numberOfBytes": "32" - }, - "t_string_storage": { - "label": "string", - "numberOfBytes": "32" - }, - "t_struct(Counter)1003_storage": { - "label": "struct Counters.Counter", - "members": [ - { - "label": "_value", - "type": "t_uint256", - "offset": 0, - "slot": "0" - } - ], - "numberOfBytes": "32" - }, - "t_struct(Operator)4511_storage": { - "label": "struct SSVRegistry.Operator", - "members": [ - { - "label": "name", - "type": "t_string_storage", - "offset": 0, - "slot": "0" - }, - { - "label": "ownerAddress", - "type": "t_address", - "offset": 0, - "slot": "1" - }, - { - "label": "publicKey", - "type": "t_bytes_storage", - "offset": 0, - "slot": "2" - }, - { - "label": "score", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "fee", - "type": "t_uint256", - "offset": 0, - "slot": "4" - }, - { - "label": "active", - "type": "t_bool", - "offset": 0, - "slot": "5" - }, - { - "label": "indexInOwner", - "type": "t_uint256", - "offset": 0, - "slot": "6" - } - ], - "numberOfBytes": "224" - }, - "t_struct(OwnerData)4526_storage": { - "label": "struct SSVRegistry.OwnerData", - "members": [ - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "validatorsDisabled", - "type": "t_bool", - "offset": 0, - "slot": "1" - } - ], - "numberOfBytes": "64" - }, - "t_struct(Validator)4521_storage": { - "label": "struct SSVRegistry.Validator", - "members": [ - { - "label": "ownerAddress", - "type": "t_address", - "offset": 0, - "slot": "0" - }, - { - "label": "operatorIds", - "type": "t_array(t_uint256)dyn_storage", - "offset": 0, - "slot": "1" - }, - { - "label": "active", - "type": "t_bool", - "offset": 0, - "slot": "2" - }, - { - "label": "indexInOwner", - "type": "t_uint256", - "offset": 0, - "slot": "3" - } - ], - "numberOfBytes": "128" - }, - "t_uint256": { - "label": "uint256", - "numberOfBytes": "32" - } - } - } - }, - "491e17656472cbfaad7ad7294f23d2c625564b2a5467edfd6ec931668b44d802": { - "address": "0x30C8cB43696e1620d0659b8B1726C4cAf3EB77B6", - "txHash": "0x4f77438a1684b0379cc74b51a6b661c207111b016afd4bd75d3822a3c5d893a0", - "layout": { - "storage": [ - { - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:23" - }, - { - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:28" - }, - { - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage", - "contract": "ContextUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" - }, - { - "label": "_owner", - "offset": 0, - "slot": "51", - "type": "t_address", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:20" - }, - { - "label": "__gap", - "offset": 0, - "slot": "52", - "type": "t_array(t_uint256)49_storage", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:74" - }, - { - "label": "_ssvRegistryContract", - "offset": 0, - "slot": "101", - "type": "t_contract(ISSVRegistry)1917", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:44" - }, - { - "label": "_token", - "offset": 0, - "slot": "102", - "type": "t_contract(IERC20)950", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:45" - }, - { - "label": "_minimumBlocksBeforeLiquidation", - "offset": 0, - "slot": "103", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:46" - }, - { - "label": "_operatorMaxFeeIncrease", - "offset": 0, - "slot": "104", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:47" - }, - { - "label": "_networkFee", - "offset": 0, - "slot": "105", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:49" - }, - { - "label": "_networkFeeIndex", - "offset": 0, - "slot": "106", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:50" - }, - { - "label": "_networkFeeIndexBlockNumber", - "offset": 0, - "slot": "107", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:51" - }, - { - "label": "_networkEarnings", - "offset": 0, - "slot": "108", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:52" - }, - { - "label": "_networkEarningsBlockNumber", - "offset": 0, - "slot": "109", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:53" - }, - { - "label": "_withdrawnFromTreasury", - "offset": 0, - "slot": "110", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:54" - }, - { - "label": "_operatorDatas", - "offset": 0, - "slot": "111", - "type": "t_mapping(t_uint256,t_struct(OperatorData)1939_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:56" - }, - { - "label": "_owners", - "offset": 0, - "slot": "112", - "type": "t_mapping(t_address,t_struct(OwnerData)1956_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:57" - }, - { - "label": "_operatorsInUseByAddress", - "offset": 0, - "slot": "113", - "type": "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)1967_storage))", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:58" - }, - { - "label": "_operatorsInUseList", - "offset": 0, - "slot": "114", - "type": "t_mapping(t_address,t_array(t_uint256)dyn_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:59" - }, - { - "label": "_lastOperatorUpdateNetworkFeeRun", - "offset": 0, - "slot": "115", - "type": "t_mapping(t_uint256,t_uint256)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:60" - }, - { - "label": "_setOperatorFeePeriod", - "offset": 0, - "slot": "116", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:62" - }, - { - "label": "_approveOperatorFeePeriod", - "offset": 0, - "slot": "117", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:63" - }, - { - "label": "_feeChangeRequests", - "offset": 0, - "slot": "118", - "type": "t_mapping(t_uint256,t_struct(FeeChangeRequest)1974_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:64" - } - ], - "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_array(t_uint256)dyn_storage": { - "label": "uint256[]", - "numberOfBytes": "32" - }, - "t_bool": { - "label": "bool", - "numberOfBytes": "1" - }, - "t_contract(IERC20)950": { - "label": "contract IERC20", - "numberOfBytes": "20" - }, - "t_contract(ISSVRegistry)1917": { - "label": "contract ISSVRegistry", - "numberOfBytes": "20" - }, - "t_mapping(t_address,t_array(t_uint256)dyn_storage)": { - "label": "mapping(address => uint256[])", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)1967_storage))": { - "label": "mapping(address => mapping(uint256 => struct SSVNetwork.OperatorInUse))", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_struct(OwnerData)1956_storage)": { - "label": "mapping(address => struct SSVNetwork.OwnerData)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(FeeChangeRequest)1974_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.FeeChangeRequest)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(OperatorData)1939_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorData)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(OperatorInUse)1967_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorInUse)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_uint256)": { - "label": "mapping(uint256 => uint256)", - "numberOfBytes": "32" - }, - "t_struct(FeeChangeRequest)1974_storage": { - "label": "struct SSVNetwork.FeeChangeRequest", - "members": [ - { - "label": "fee", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "approvalBeginTime", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "approvalEndTime", - "type": "t_uint256", - "offset": 0, - "slot": "2" - } - ], - "numberOfBytes": "96" - }, - "t_struct(OperatorData)1939_storage": { - "label": "struct SSVNetwork.OperatorData", - "members": [ - { - "label": "blockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "earnings", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "index", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "indexBlockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "4" - } - ], - "numberOfBytes": "160" - }, - "t_struct(OperatorInUse)1967_storage": { - "label": "struct SSVNetwork.OperatorInUse", - "members": [ - { - "label": "index", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "validatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "used", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "exists", - "type": "t_bool", - "offset": 0, - "slot": "3" - }, - { - "label": "indexInArray", - "type": "t_uint256", - "offset": 0, - "slot": "4" - } - ], - "numberOfBytes": "160" - }, - "t_struct(OwnerData)1956_storage": { - "label": "struct SSVNetwork.OwnerData", - "members": [ - { - "label": "deposited", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "withdrawn", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "earned", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "used", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "networkFee", - "type": "t_uint256", - "offset": 0, - "slot": "4" - }, - { - "label": "networkFeeIndex", - "type": "t_uint256", - "offset": 0, - "slot": "5" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "6" - }, - { - "label": "validatorsDisabled", - "type": "t_bool", - "offset": 0, - "slot": "7" - } - ], - "numberOfBytes": "256" - }, - "t_uint256": { - "label": "uint256", - "numberOfBytes": "32" - } - } - } - }, - "7181a9ab954b655fdbe22f4c7aeec94732521a726864f38b87b2c7580d50fb8d": { - "address": "0xd220566c2085f53c57bb0F8E9C5B0ecFbd3045d4", - "txHash": "0xc9bc6668111802af2a9b144c77dc79b19a8476d354763adf8c08d54594e9b9dc", - "layout": { - "storage": [ - { - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:23" - }, - { - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:28" - }, - { - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage", - "contract": "ContextUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" - }, - { - "label": "_owner", - "offset": 0, - "slot": "51", - "type": "t_address", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:20" - }, - { - "label": "__gap", - "offset": 0, - "slot": "52", - "type": "t_array(t_uint256)49_storage", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:74" - }, - { - "label": "_activeValidatorCount", - "offset": 0, - "slot": "101", - "type": "t_uint256", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:34" - }, - { - "label": "_lastOperatorId", - "offset": 0, - "slot": "102", - "type": "t_struct(Counter)1003_storage", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:36" - }, - { - "label": "_operators", - "offset": 0, - "slot": "103", - "type": "t_mapping(t_uint256,t_struct(Operator)4535_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:38" - }, - { - "label": "_validators", - "offset": 0, - "slot": "104", - "type": "t_mapping(t_bytes_memory_ptr,t_struct(Validator)4545_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:39" - }, - { - "label": "_operatorsByOwnerAddress", - "offset": 0, - "slot": "105", - "type": "t_mapping(t_address,t_array(t_uint256)dyn_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:41" - }, - { - "label": "_validatorsByOwnerAddress", - "offset": 0, - "slot": "106", - "type": "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:42" - }, - { - "label": "_owners", - "offset": 0, - "slot": "107", - "type": "t_mapping(t_address,t_struct(OwnerData)4550_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:43" - }, - { - "label": "validatorsPerOperator", - "offset": 0, - "slot": "108", - "type": "t_mapping(t_uint256,t_uint256)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:45" - }, - { - "label": "validatorsPerOperatorLimit", - "offset": 0, - "slot": "109", - "type": "t_uint256", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:46" - }, - { - "label": "_operatorPublicKeyToId", - "offset": 0, - "slot": "110", - "type": "t_mapping(t_bytes_memory_ptr,t_uint256)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:47" - }, - { - "label": "registeredOperatorsPerAccountLimit", - "offset": 0, - "slot": "111", - "type": "t_uint256", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:48" - } - ], - "types": { - "t_address": { - "label": "address", - "numberOfBytes": "20" - }, - "t_array(t_bytes_storage)dyn_storage": { - "label": "bytes[]", - "numberOfBytes": "32" - }, - "t_array(t_uint256)49_storage": { - "label": "uint256[49]", - "numberOfBytes": "1568" - }, - "t_array(t_uint256)50_storage": { - "label": "uint256[50]", - "numberOfBytes": "1600" - }, - "t_array(t_uint256)dyn_storage": { - "label": "uint256[]", - "numberOfBytes": "32" - }, - "t_bool": { - "label": "bool", - "numberOfBytes": "1" - }, - "t_bytes_memory_ptr": { - "label": "bytes", - "numberOfBytes": "32" - }, - "t_bytes_storage": { - "label": "bytes", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_array(t_bytes_storage)dyn_storage)": { - "label": "mapping(address => bytes[])", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_array(t_uint256)dyn_storage)": { - "label": "mapping(address => uint256[])", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_struct(OwnerData)4550_storage)": { - "label": "mapping(address => struct SSVRegistry.OwnerData)", - "numberOfBytes": "32" - }, - "t_mapping(t_bytes_memory_ptr,t_struct(Validator)4545_storage)": { - "label": "mapping(bytes => struct SSVRegistry.Validator)", - "numberOfBytes": "32" - }, - "t_mapping(t_bytes_memory_ptr,t_uint256)": { - "label": "mapping(bytes => uint256)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(Operator)4535_storage)": { - "label": "mapping(uint256 => struct SSVRegistry.Operator)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_uint256)": { - "label": "mapping(uint256 => uint256)", - "numberOfBytes": "32" - }, - "t_string_storage": { - "label": "string", - "numberOfBytes": "32" - }, - "t_struct(Counter)1003_storage": { - "label": "struct Counters.Counter", - "members": [ - { - "label": "_value", - "type": "t_uint256", - "offset": 0, - "slot": "0" - } - ], - "numberOfBytes": "32" - }, - "t_struct(Operator)4535_storage": { - "label": "struct SSVRegistry.Operator", - "members": [ - { - "label": "name", - "type": "t_string_storage", - "offset": 0, - "slot": "0" - }, - { - "label": "ownerAddress", - "type": "t_address", - "offset": 0, - "slot": "1" - }, - { - "label": "publicKey", - "type": "t_bytes_storage", - "offset": 0, - "slot": "2" - }, - { - "label": "score", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "fee", - "type": "t_uint256", - "offset": 0, - "slot": "4" - }, - { - "label": "active", - "type": "t_bool", - "offset": 0, - "slot": "5" - }, - { - "label": "indexInOwner", - "type": "t_uint256", - "offset": 0, - "slot": "6" - } - ], - "numberOfBytes": "224" - }, - "t_struct(OwnerData)4550_storage": { - "label": "struct SSVRegistry.OwnerData", - "members": [ - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "validatorsDisabled", - "type": "t_bool", - "offset": 0, - "slot": "1" - } - ], - "numberOfBytes": "64" - }, - "t_struct(Validator)4545_storage": { - "label": "struct SSVRegistry.Validator", - "members": [ - { - "label": "ownerAddress", - "type": "t_address", - "offset": 0, - "slot": "0" - }, - { - "label": "operatorIds", - "type": "t_array(t_uint256)dyn_storage", - "offset": 0, - "slot": "1" - }, - { - "label": "active", - "type": "t_bool", - "offset": 0, - "slot": "2" - }, - { - "label": "indexInOwner", - "type": "t_uint256", - "offset": 0, - "slot": "3" - } - ], - "numberOfBytes": "128" - }, - "t_uint256": { - "label": "uint256", - "numberOfBytes": "32" - } - } - } - }, - "43e8a71368bbd8cce5134b383a3975e2b923a3da15b288d6b718f1bb12019d2a": { - "address": "0xb8188337DCDF6263DFcFf9C8a766124D7113C5f2", - "txHash": "0x0a98c991ffb3fda5a3cc24cc908fb1666b4da06b219612bf7c923c5c80c1050b", - "layout": { - "storage": [ - { - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:23" - }, - { - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:28" - }, - { - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage", - "contract": "ContextUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" - }, - { - "label": "_owner", - "offset": 0, - "slot": "51", - "type": "t_address", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:20" - }, - { - "label": "__gap", - "offset": 0, - "slot": "52", - "type": "t_array(t_uint256)49_storage", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:74" - }, - { - "label": "_ssvRegistryContract", - "offset": 0, - "slot": "101", - "type": "t_contract(ISSVRegistry)1933", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:44" - }, - { - "label": "_token", - "offset": 0, - "slot": "102", - "type": "t_contract(IERC20)950", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:45" - }, - { - "label": "_minimumBlocksBeforeLiquidation", - "offset": 0, - "slot": "103", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:46" - }, - { - "label": "_operatorMaxFeeIncrease", - "offset": 0, - "slot": "104", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:47" - }, - { - "label": "_networkFee", - "offset": 0, - "slot": "105", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:49" - }, - { - "label": "_networkFeeIndex", - "offset": 0, - "slot": "106", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:50" - }, - { - "label": "_networkFeeIndexBlockNumber", - "offset": 0, - "slot": "107", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:51" - }, - { - "label": "_networkEarnings", - "offset": 0, - "slot": "108", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:52" - }, - { - "label": "_networkEarningsBlockNumber", - "offset": 0, - "slot": "109", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:53" - }, - { - "label": "_withdrawnFromTreasury", - "offset": 0, - "slot": "110", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:54" - }, - { - "label": "_operatorDatas", - "offset": 0, - "slot": "111", - "type": "t_mapping(t_uint256,t_struct(OperatorData)1955_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:56" - }, - { - "label": "_owners", - "offset": 0, - "slot": "112", - "type": "t_mapping(t_address,t_struct(OwnerData)1972_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:57" - }, - { - "label": "_operatorsInUseByAddress", - "offset": 0, - "slot": "113", - "type": "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)1983_storage))", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:58" - }, - { - "label": "_operatorsInUseList", - "offset": 0, - "slot": "114", - "type": "t_mapping(t_address,t_array(t_uint256)dyn_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:59" - }, - { - "label": "_lastOperatorUpdateNetworkFeeRun", - "offset": 0, - "slot": "115", - "type": "t_mapping(t_uint256,t_uint256)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:60" - }, - { - "label": "_declareOperatorFeePeriod", - "offset": 0, - "slot": "116", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:62" - }, - { - "label": "_executeOperatorFeePeriod", - "offset": 0, - "slot": "117", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:63" - }, - { - "label": "_feeChangeRequests", - "offset": 0, - "slot": "118", - "type": "t_mapping(t_uint256,t_struct(FeeChangeRequest)1990_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:64" - } - ], - "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_array(t_uint256)dyn_storage": { - "label": "uint256[]", - "numberOfBytes": "32" - }, - "t_bool": { - "label": "bool", - "numberOfBytes": "1" - }, - "t_contract(IERC20)950": { - "label": "contract IERC20", - "numberOfBytes": "20" - }, - "t_contract(ISSVRegistry)1933": { - "label": "contract ISSVRegistry", - "numberOfBytes": "20" - }, - "t_mapping(t_address,t_array(t_uint256)dyn_storage)": { - "label": "mapping(address => uint256[])", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_mapping(t_uint256,t_struct(OperatorInUse)1983_storage))": { - "label": "mapping(address => mapping(uint256 => struct SSVNetwork.OperatorInUse))", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_struct(OwnerData)1972_storage)": { - "label": "mapping(address => struct SSVNetwork.OwnerData)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(FeeChangeRequest)1990_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.FeeChangeRequest)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(OperatorData)1955_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorData)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_struct(OperatorInUse)1983_storage)": { - "label": "mapping(uint256 => struct SSVNetwork.OperatorInUse)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint256,t_uint256)": { - "label": "mapping(uint256 => uint256)", - "numberOfBytes": "32" - }, - "t_struct(FeeChangeRequest)1990_storage": { - "label": "struct SSVNetwork.FeeChangeRequest", - "members": [ - { - "label": "fee", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "approvalBeginTime", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "approvalEndTime", - "type": "t_uint256", - "offset": 0, - "slot": "2" - } - ], - "numberOfBytes": "96" - }, - "t_struct(OperatorData)1955_storage": { - "label": "struct SSVNetwork.OperatorData", - "members": [ - { - "label": "blockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "earnings", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "index", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "indexBlockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "4" - } - ], - "numberOfBytes": "160" - }, - "t_struct(OperatorInUse)1983_storage": { - "label": "struct SSVNetwork.OperatorInUse", - "members": [ - { - "label": "index", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "validatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "used", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "exists", - "type": "t_bool", - "offset": 0, - "slot": "3" - }, - { - "label": "indexInArray", - "type": "t_uint256", - "offset": 0, - "slot": "4" - } - ], - "numberOfBytes": "160" - }, - "t_struct(OwnerData)1972_storage": { - "label": "struct SSVNetwork.OwnerData", - "members": [ - { - "label": "deposited", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "withdrawn", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "earned", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "used", - "type": "t_uint256", - "offset": 0, - "slot": "3" - }, - { - "label": "networkFee", - "type": "t_uint256", - "offset": 0, - "slot": "4" - }, - { - "label": "networkFeeIndex", - "type": "t_uint256", - "offset": 0, - "slot": "5" - }, - { - "label": "activeValidatorCount", - "type": "t_uint256", - "offset": 0, - "slot": "6" - }, - { - "label": "validatorsDisabled", - "type": "t_bool", - "offset": 0, - "slot": "7" - } - ], - "numberOfBytes": "256" - }, - "t_uint256": { - "label": "uint256", - "numberOfBytes": "32" - } - } - } - }, - "a137d6976fb8417660caab4bd2f922f40e1be67494354ba6d1e2b4677b308b8a": { - "address": "0x37Ab7eA3377239ff8A8AB8924C3a68eF956997f3", - "txHash": "0x4d9b40db96bbdacd2022d1318154298ede8c12bd06e376dabb93df32472e4001", - "layout": { - "storage": [ - { - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_uint8", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:62", - "retypedFrom": "bool" - }, - { - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:67" - }, - { - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage", - "contract": "ContextUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" - }, - { - "label": "_owner", - "offset": 0, - "slot": "51", - "type": "t_address", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" - }, - { - "label": "__gap", - "offset": 0, - "slot": "52", - "type": "t_array(t_uint256)49_storage", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:87" - }, - { - "label": "_ssvRegistryContract", - "offset": 0, - "slot": "101", - "type": "t_contract(ISSVRegistry)2133", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:47" - }, - { - "label": "_token", - "offset": 0, - "slot": "102", - "type": "t_contract(IERC20)1319", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:48" - }, - { - "label": "_minimumBlocksBeforeLiquidation", - "offset": 20, - "slot": "102", - "type": "t_uint64", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:49" - }, - { - "label": "_operatorMaxFeeIncrease", - "offset": 0, - "slot": "103", - "type": "t_uint64", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:50" - }, - { - "label": "_networkFee", - "offset": 8, - "slot": "103", - "type": "t_uint64", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:52" - }, - { - "label": "_networkFeeIndex", - "offset": 16, - "slot": "103", - "type": "t_uint64", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:53" - }, - { - "label": "_networkFeeIndexBlockNumber", - "offset": 0, - "slot": "104", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:54" - }, - { - "label": "_networkEarnings", - "offset": 0, - "slot": "105", - "type": "t_uint64", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:55" - }, - { - "label": "_networkEarningsBlockNumber", - "offset": 0, - "slot": "106", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:56" - }, - { - "label": "_withdrawnFromTreasury", - "offset": 0, - "slot": "107", - "type": "t_uint64", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:57" - }, - { - "label": "_operatorDatas", - "offset": 0, - "slot": "108", - "type": "t_mapping(t_uint32,t_struct(OperatorData)2163_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:59" - }, - { - "label": "_owners", - "offset": 0, - "slot": "109", - "type": "t_mapping(t_address,t_struct(OwnerData)2178_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:60" - }, - { - "label": "_operatorsInUseByAddress", - "offset": 0, - "slot": "110", - "type": "t_mapping(t_address,t_mapping(t_uint32,t_struct(OperatorInUse)2189_storage))", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:61" - }, - { - "label": "_operatorsInUseList", - "offset": 0, - "slot": "111", - "type": "t_mapping(t_address,t_array(t_uint32)dyn_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:62" - }, - { - "label": "_declareOperatorFeePeriod", - "offset": 0, - "slot": "112", - "type": "t_uint64", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:64" - }, - { - "label": "_executeOperatorFeePeriod", - "offset": 8, - "slot": "112", - "type": "t_uint64", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:65" - }, - { - "label": "_feeChangeRequests", - "offset": 0, - "slot": "113", - "type": "t_mapping(t_uint32,t_struct(FeeChangeRequest)2196_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:66" - }, - { - "label": "______gap", - "offset": 0, - "slot": "114", - "type": "t_array(t_uint256)50_storage", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:810" - } - ], - "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_array(t_uint32)dyn_storage": { - "label": "uint32[]", - "numberOfBytes": "32" - }, - "t_bool": { - "label": "bool", - "numberOfBytes": "1" - }, - "t_contract(IERC20)1319": { - "label": "contract IERC20", - "numberOfBytes": "20" - }, - "t_contract(ISSVRegistry)2133": { - "label": "contract ISSVRegistry", - "numberOfBytes": "20" - }, - "t_mapping(t_address,t_array(t_uint32)dyn_storage)": { - "label": "mapping(address => uint32[])", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_mapping(t_uint32,t_struct(OperatorInUse)2189_storage))": { - "label": "mapping(address => mapping(uint32 => struct SSVNetwork.OperatorInUse))", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_struct(OwnerData)2178_storage)": { - "label": "mapping(address => struct SSVNetwork.OwnerData)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint32,t_struct(FeeChangeRequest)2196_storage)": { - "label": "mapping(uint32 => struct SSVNetwork.FeeChangeRequest)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint32,t_struct(OperatorData)2163_storage)": { - "label": "mapping(uint32 => struct SSVNetwork.OperatorData)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint32,t_struct(OperatorInUse)2189_storage)": { - "label": "mapping(uint32 => struct SSVNetwork.OperatorInUse)", - "numberOfBytes": "32" - }, - "t_struct(FeeChangeRequest)2196_storage": { - "label": "struct SSVNetwork.FeeChangeRequest", - "members": [ - { - "label": "fee", - "type": "t_uint64", - "offset": 0, - "slot": "0" - }, - { - "label": "approvalBeginTime", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "approvalEndTime", - "type": "t_uint256", - "offset": 0, - "slot": "2" - } - ], - "numberOfBytes": "96" - }, - "t_struct(OperatorData)2163_storage": { - "label": "struct SSVNetwork.OperatorData", - "members": [ - { - "label": "blockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "earnings", - "type": "t_uint64", - "offset": 0, - "slot": "1" - }, - { - "label": "index", - "type": "t_uint64", - "offset": 8, - "slot": "1" - }, - { - "label": "indexBlockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "activeValidatorCount", - "type": "t_uint32", - "offset": 0, - "slot": "3" - } - ], - "numberOfBytes": "128" - }, - "t_struct(OperatorInUse)2189_storage": { - "label": "struct SSVNetwork.OperatorInUse", - "members": [ - { - "label": "index", - "type": "t_uint64", - "offset": 0, - "slot": "0" - }, - { - "label": "used", - "type": "t_uint64", - "offset": 8, - "slot": "0" - }, - { - "label": "validatorCount", - "type": "t_uint32", - "offset": 16, - "slot": "0" - }, - { - "label": "indexInArray", - "type": "t_uint32", - "offset": 20, - "slot": "0" - }, - { - "label": "exists", - "type": "t_bool", - "offset": 24, - "slot": "0" - } - ], - "numberOfBytes": "32" - }, - "t_struct(OwnerData)2178_storage": { - "label": "struct SSVNetwork.OwnerData", - "members": [ - { - "label": "deposited", - "type": "t_uint64", - "offset": 0, - "slot": "0" - }, - { - "label": "withdrawn", - "type": "t_uint64", - "offset": 8, - "slot": "0" - }, - { - "label": "used", - "type": "t_uint64", - "offset": 16, - "slot": "0" - }, - { - "label": "networkFee", - "type": "t_uint64", - "offset": 24, - "slot": "0" - }, - { - "label": "networkFeeIndex", - "type": "t_uint64", - "offset": 0, - "slot": "1" - }, - { - "label": "activeValidatorCount", - "type": "t_uint32", - "offset": 8, - "slot": "1" - }, - { - "label": "validatorsDisabled", - "type": "t_bool", - "offset": 12, - "slot": "1" - } - ], - "numberOfBytes": "64" - }, - "t_uint256": { - "label": "uint256", - "numberOfBytes": "32" - }, - "t_uint32": { - "label": "uint32", - "numberOfBytes": "4" - }, - "t_uint64": { - "label": "uint64", - "numberOfBytes": "8" - }, - "t_uint8": { - "label": "uint8", - "numberOfBytes": "1" - } - } - } - }, - "8e963b78dd2789e61e41bc9b746b63957dd1ec3744546b2eb37c569420383a25": { - "address": "0x5CeCA85e9087D1528540920d64eB348C71BBCD34", - "txHash": "0x73c6d29dc9566b610d020f61028edc2e6ad6109dfe3f67515fbbf7195a2a09dd", - "layout": { - "storage": [ - { - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_uint8", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:62", - "retypedFrom": "bool" - }, - { - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:67" - }, - { - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage", - "contract": "ContextUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" - }, - { - "label": "_owner", - "offset": 0, - "slot": "51", - "type": "t_address", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" - }, - { - "label": "__gap", - "offset": 0, - "slot": "52", - "type": "t_array(t_uint256)49_storage", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:87" - }, - { - "label": "_lastOperatorId", - "offset": 0, - "slot": "101", - "type": "t_struct(Counter)1372_storage", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:41" - }, - { - "label": "_operators", - "offset": 0, - "slot": "102", - "type": "t_mapping(t_uint32,t_struct(Operator)4837_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:43" - }, - { - "label": "_validators", - "offset": 0, - "slot": "103", - "type": "t_mapping(t_bytes_memory_ptr,t_struct(Validator)4847_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:44" - }, - { - "label": "_operatorsByOwnerAddress", - "offset": 0, - "slot": "104", - "type": "t_mapping(t_address,t_array(t_uint32)dyn_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:45" - }, - { - "label": "_owners", - "offset": 0, - "slot": "105", - "type": "t_mapping(t_address,t_struct(OwnerData)4855_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:46" - }, - { - "label": "_activeValidatorCount", - "offset": 0, - "slot": "106", - "type": "t_uint32", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:48" - }, - { - "label": "______gap", - "offset": 0, - "slot": "107", - "type": "t_array(t_uint256)50_storage", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:312" - } - ], - "types": { - "t_address": { - "label": "address", - "numberOfBytes": "20" - }, - "t_array(t_bytes_storage)dyn_storage": { - "label": "bytes[]", - "numberOfBytes": "32" - }, - "t_array(t_uint256)49_storage": { - "label": "uint256[49]", - "numberOfBytes": "1568" - }, - "t_array(t_uint256)50_storage": { - "label": "uint256[50]", - "numberOfBytes": "1600" - }, - "t_array(t_uint32)dyn_storage": { - "label": "uint32[]", - "numberOfBytes": "32" - }, - "t_bool": { - "label": "bool", - "numberOfBytes": "1" - }, - "t_bytes_memory_ptr": { - "label": "bytes", - "numberOfBytes": "32" - }, - "t_bytes_storage": { - "label": "bytes", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_array(t_uint32)dyn_storage)": { - "label": "mapping(address => uint32[])", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_struct(OwnerData)4855_storage)": { - "label": "mapping(address => struct SSVRegistry.OwnerData)", - "numberOfBytes": "32" - }, - "t_mapping(t_bytes_memory_ptr,t_struct(Validator)4847_storage)": { - "label": "mapping(bytes => struct SSVRegistry.Validator)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint32,t_struct(Operator)4837_storage)": { - "label": "mapping(uint32 => struct SSVRegistry.Operator)", - "numberOfBytes": "32" - }, - "t_string_storage": { - "label": "string", - "numberOfBytes": "32" - }, - "t_struct(Counter)1372_storage": { - "label": "struct Counters.Counter", - "members": [ - { - "label": "_value", - "type": "t_uint256", - "offset": 0, - "slot": "0" - } - ], - "numberOfBytes": "32" - }, - "t_struct(Operator)4837_storage": { - "label": "struct SSVRegistry.Operator", - "members": [ - { - "label": "name", - "type": "t_string_storage", - "offset": 0, - "slot": "0" - }, - { - "label": "publicKey", - "type": "t_bytes_storage", - "offset": 0, - "slot": "1" - }, - { - "label": "fee", - "type": "t_uint64", - "offset": 0, - "slot": "2" - }, - { - "label": "ownerAddress", - "type": "t_address", - "offset": 8, - "slot": "2" - }, - { - "label": "score", - "type": "t_uint32", - "offset": 28, - "slot": "2" - }, - { - "label": "indexInOwner", - "type": "t_uint32", - "offset": 0, - "slot": "3" - }, - { - "label": "validatorCount", - "type": "t_uint32", - "offset": 4, - "slot": "3" - }, - { - "label": "active", - "type": "t_bool", - "offset": 8, - "slot": "3" - } - ], - "numberOfBytes": "128" - }, - "t_struct(OwnerData)4855_storage": { - "label": "struct SSVRegistry.OwnerData", - "members": [ - { - "label": "activeValidatorCount", - "type": "t_uint32", - "offset": 0, - "slot": "0" - }, - { - "label": "validatorsDisabled", - "type": "t_bool", - "offset": 4, - "slot": "0" - }, - { - "label": "validators", - "type": "t_array(t_bytes_storage)dyn_storage", - "offset": 0, - "slot": "1" - } - ], - "numberOfBytes": "64" - }, - "t_struct(Validator)4847_storage": { - "label": "struct SSVRegistry.Validator", - "members": [ - { - "label": "operatorIds", - "type": "t_array(t_uint32)dyn_storage", - "offset": 0, - "slot": "0" - }, - { - "label": "ownerAddress", - "type": "t_address", - "offset": 0, - "slot": "1" - }, - { - "label": "indexInOwner", - "type": "t_uint32", - "offset": 20, - "slot": "1" - }, - { - "label": "active", - "type": "t_bool", - "offset": 24, - "slot": "1" - } - ], - "numberOfBytes": "64" - }, - "t_uint256": { - "label": "uint256", - "numberOfBytes": "32" - }, - "t_uint32": { - "label": "uint32", - "numberOfBytes": "4" - }, - "t_uint64": { - "label": "uint64", - "numberOfBytes": "8" - }, - "t_uint8": { - "label": "uint8", - "numberOfBytes": "1" - } - } - } - }, - "9fbc3c50a96da0f4a4b05451aae4b5508e1501da7c2dea105259f5af42dd03ee": { - "address": "0x3D776231fE7EE264c89a9B09647ACFD955cD1d9b", - "txHash": "0xc65b440b9d585cf6d25c8552fc89c6609755aadd259ae8143dc71a9b8ffd9128", - "layout": { - "storage": [ - { - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_uint8", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:62", - "retypedFrom": "bool" - }, - { - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:67" - }, - { - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage", - "contract": "ContextUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" - }, - { - "label": "_owner", - "offset": 0, - "slot": "51", - "type": "t_address", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" - }, - { - "label": "__gap", - "offset": 0, - "slot": "52", - "type": "t_array(t_uint256)49_storage", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:87" - }, - { - "label": "_ssvRegistryContract", - "offset": 0, - "slot": "101", - "type": "t_contract(ISSVRegistry)2133", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:47" - }, - { - "label": "_token", - "offset": 0, - "slot": "102", - "type": "t_contract(IERC20)1319", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:48" - }, - { - "label": "_minimumBlocksBeforeLiquidation", - "offset": 20, - "slot": "102", - "type": "t_uint64", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:49" - }, - { - "label": "_operatorMaxFeeIncrease", - "offset": 0, - "slot": "103", - "type": "t_uint64", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:50" - }, - { - "label": "_networkFee", - "offset": 8, - "slot": "103", - "type": "t_uint64", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:52" - }, - { - "label": "_networkFeeIndex", - "offset": 16, - "slot": "103", - "type": "t_uint64", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:53" - }, - { - "label": "_networkFeeIndexBlockNumber", - "offset": 0, - "slot": "104", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:54" - }, - { - "label": "_networkEarnings", - "offset": 0, - "slot": "105", - "type": "t_uint64", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:55" - }, - { - "label": "_networkEarningsBlockNumber", - "offset": 0, - "slot": "106", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:56" - }, - { - "label": "_withdrawnFromTreasury", - "offset": 0, - "slot": "107", - "type": "t_uint64", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:57" - }, - { - "label": "_operatorDatas", - "offset": 0, - "slot": "108", - "type": "t_mapping(t_uint32,t_struct(OperatorData)2163_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:59" - }, - { - "label": "_owners", - "offset": 0, - "slot": "109", - "type": "t_mapping(t_address,t_struct(OwnerData)2178_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:60" - }, - { - "label": "_operatorsInUseByAddress", - "offset": 0, - "slot": "110", - "type": "t_mapping(t_address,t_mapping(t_uint32,t_struct(OperatorInUse)2189_storage))", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:61" - }, - { - "label": "_operatorsInUseList", - "offset": 0, - "slot": "111", - "type": "t_mapping(t_address,t_array(t_uint32)dyn_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:62" - }, - { - "label": "_declareOperatorFeePeriod", - "offset": 0, - "slot": "112", - "type": "t_uint64", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:64" - }, - { - "label": "_executeOperatorFeePeriod", - "offset": 8, - "slot": "112", - "type": "t_uint64", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:65" - }, - { - "label": "_feeChangeRequests", - "offset": 0, - "slot": "113", - "type": "t_mapping(t_uint32,t_struct(FeeChangeRequest)2196_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:66" - }, - { - "label": "______gap", - "offset": 0, - "slot": "114", - "type": "t_array(t_uint256)50_storage", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:810" - } - ], - "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_array(t_uint32)dyn_storage": { - "label": "uint32[]", - "numberOfBytes": "32" - }, - "t_bool": { - "label": "bool", - "numberOfBytes": "1" - }, - "t_contract(IERC20)1319": { - "label": "contract IERC20", - "numberOfBytes": "20" - }, - "t_contract(ISSVRegistry)2133": { - "label": "contract ISSVRegistry", - "numberOfBytes": "20" - }, - "t_mapping(t_address,t_array(t_uint32)dyn_storage)": { - "label": "mapping(address => uint32[])", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_mapping(t_uint32,t_struct(OperatorInUse)2189_storage))": { - "label": "mapping(address => mapping(uint32 => struct SSVNetwork.OperatorInUse))", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_struct(OwnerData)2178_storage)": { - "label": "mapping(address => struct SSVNetwork.OwnerData)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint32,t_struct(FeeChangeRequest)2196_storage)": { - "label": "mapping(uint32 => struct SSVNetwork.FeeChangeRequest)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint32,t_struct(OperatorData)2163_storage)": { - "label": "mapping(uint32 => struct SSVNetwork.OperatorData)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint32,t_struct(OperatorInUse)2189_storage)": { - "label": "mapping(uint32 => struct SSVNetwork.OperatorInUse)", - "numberOfBytes": "32" - }, - "t_struct(FeeChangeRequest)2196_storage": { - "label": "struct SSVNetwork.FeeChangeRequest", - "members": [ - { - "label": "fee", - "type": "t_uint64", - "offset": 0, - "slot": "0" - }, - { - "label": "approvalBeginTime", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "approvalEndTime", - "type": "t_uint256", - "offset": 0, - "slot": "2" - } - ], - "numberOfBytes": "96" - }, - "t_struct(OperatorData)2163_storage": { - "label": "struct SSVNetwork.OperatorData", - "members": [ - { - "label": "blockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "earnings", - "type": "t_uint64", - "offset": 0, - "slot": "1" - }, - { - "label": "index", - "type": "t_uint64", - "offset": 8, - "slot": "1" - }, - { - "label": "indexBlockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "activeValidatorCount", - "type": "t_uint32", - "offset": 0, - "slot": "3" - } - ], - "numberOfBytes": "128" - }, - "t_struct(OperatorInUse)2189_storage": { - "label": "struct SSVNetwork.OperatorInUse", - "members": [ - { - "label": "index", - "type": "t_uint64", - "offset": 0, - "slot": "0" - }, - { - "label": "used", - "type": "t_uint64", - "offset": 8, - "slot": "0" - }, - { - "label": "validatorCount", - "type": "t_uint32", - "offset": 16, - "slot": "0" - }, - { - "label": "indexInArray", - "type": "t_uint32", - "offset": 20, - "slot": "0" - }, - { - "label": "exists", - "type": "t_bool", - "offset": 24, - "slot": "0" - } - ], - "numberOfBytes": "32" - }, - "t_struct(OwnerData)2178_storage": { - "label": "struct SSVNetwork.OwnerData", - "members": [ - { - "label": "deposited", - "type": "t_uint64", - "offset": 0, - "slot": "0" - }, - { - "label": "withdrawn", - "type": "t_uint64", - "offset": 8, - "slot": "0" - }, - { - "label": "used", - "type": "t_uint64", - "offset": 16, - "slot": "0" - }, - { - "label": "networkFee", - "type": "t_uint64", - "offset": 24, - "slot": "0" - }, - { - "label": "networkFeeIndex", - "type": "t_uint64", - "offset": 0, - "slot": "1" - }, - { - "label": "activeValidatorCount", - "type": "t_uint32", - "offset": 8, - "slot": "1" - }, - { - "label": "validatorsDisabled", - "type": "t_bool", - "offset": 12, - "slot": "1" - } - ], - "numberOfBytes": "64" - }, - "t_uint256": { - "label": "uint256", - "numberOfBytes": "32" - }, - "t_uint32": { - "label": "uint32", - "numberOfBytes": "4" - }, - "t_uint64": { - "label": "uint64", - "numberOfBytes": "8" - }, - "t_uint8": { - "label": "uint8", - "numberOfBytes": "1" - } - } - } - }, - "7ae45990633d68c16107a7c80e119861d9b29ea79b764ccb309281b1579a5b7c": { - "address": "0xC3e7ec559D2EC1B9e0d75a00FfB54304a3571bAA", - "txHash": "0x8705996dc5bbf5ef63a975cb41a5435cccf1d28510ca63394f9df1e446bc73b2", - "layout": { - "storage": [ - { - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_uint8", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:62", - "retypedFrom": "bool" - }, - { - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:67" - }, - { - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage", - "contract": "ContextUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" - }, - { - "label": "_owner", - "offset": 0, - "slot": "51", - "type": "t_address", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" - }, - { - "label": "__gap", - "offset": 0, - "slot": "52", - "type": "t_array(t_uint256)49_storage", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:87" - }, - { - "label": "_lastOperatorId", - "offset": 0, - "slot": "101", - "type": "t_struct(Counter)1372_storage", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:41" - }, - { - "label": "_operators", - "offset": 0, - "slot": "102", - "type": "t_mapping(t_uint32,t_struct(Operator)4837_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:43" - }, - { - "label": "_validators", - "offset": 0, - "slot": "103", - "type": "t_mapping(t_bytes_memory_ptr,t_struct(Validator)4847_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:44" - }, - { - "label": "_operatorsByOwnerAddress", - "offset": 0, - "slot": "104", - "type": "t_mapping(t_address,t_array(t_uint32)dyn_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:45" - }, - { - "label": "_owners", - "offset": 0, - "slot": "105", - "type": "t_mapping(t_address,t_struct(OwnerData)4855_storage)", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:46" - }, - { - "label": "_activeValidatorCount", - "offset": 0, - "slot": "106", - "type": "t_uint32", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:48" - }, - { - "label": "______gap", - "offset": 0, - "slot": "107", - "type": "t_array(t_uint256)50_storage", - "contract": "SSVRegistry", - "src": "contracts/SSVRegistry.sol:312" - } - ], - "types": { - "t_address": { - "label": "address", - "numberOfBytes": "20" - }, - "t_array(t_bytes_storage)dyn_storage": { - "label": "bytes[]", - "numberOfBytes": "32" - }, - "t_array(t_uint256)49_storage": { - "label": "uint256[49]", - "numberOfBytes": "1568" - }, - "t_array(t_uint256)50_storage": { - "label": "uint256[50]", - "numberOfBytes": "1600" - }, - "t_array(t_uint32)dyn_storage": { - "label": "uint32[]", - "numberOfBytes": "32" - }, - "t_bool": { - "label": "bool", - "numberOfBytes": "1" - }, - "t_bytes_memory_ptr": { - "label": "bytes", - "numberOfBytes": "32" - }, - "t_bytes_storage": { - "label": "bytes", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_array(t_uint32)dyn_storage)": { - "label": "mapping(address => uint32[])", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_struct(OwnerData)4855_storage)": { - "label": "mapping(address => struct SSVRegistry.OwnerData)", - "numberOfBytes": "32" - }, - "t_mapping(t_bytes_memory_ptr,t_struct(Validator)4847_storage)": { - "label": "mapping(bytes => struct SSVRegistry.Validator)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint32,t_struct(Operator)4837_storage)": { - "label": "mapping(uint32 => struct SSVRegistry.Operator)", - "numberOfBytes": "32" - }, - "t_string_storage": { - "label": "string", - "numberOfBytes": "32" - }, - "t_struct(Counter)1372_storage": { - "label": "struct Counters.Counter", - "members": [ - { - "label": "_value", - "type": "t_uint256", - "offset": 0, - "slot": "0" - } - ], - "numberOfBytes": "32" - }, - "t_struct(Operator)4837_storage": { - "label": "struct SSVRegistry.Operator", - "members": [ - { - "label": "name", - "type": "t_string_storage", - "offset": 0, - "slot": "0" - }, - { - "label": "publicKey", - "type": "t_bytes_storage", - "offset": 0, - "slot": "1" - }, - { - "label": "fee", - "type": "t_uint64", - "offset": 0, - "slot": "2" - }, - { - "label": "ownerAddress", - "type": "t_address", - "offset": 8, - "slot": "2" - }, - { - "label": "score", - "type": "t_uint32", - "offset": 28, - "slot": "2" - }, - { - "label": "indexInOwner", - "type": "t_uint32", - "offset": 0, - "slot": "3" - }, - { - "label": "validatorCount", - "type": "t_uint32", - "offset": 4, - "slot": "3" - }, - { - "label": "active", - "type": "t_bool", - "offset": 8, - "slot": "3" - } - ], - "numberOfBytes": "128" - }, - "t_struct(OwnerData)4855_storage": { - "label": "struct SSVRegistry.OwnerData", - "members": [ - { - "label": "activeValidatorCount", - "type": "t_uint32", - "offset": 0, - "slot": "0" - }, - { - "label": "validatorsDisabled", - "type": "t_bool", - "offset": 4, - "slot": "0" - }, - { - "label": "validators", - "type": "t_array(t_bytes_storage)dyn_storage", - "offset": 0, - "slot": "1" - } - ], - "numberOfBytes": "64" - }, - "t_struct(Validator)4847_storage": { - "label": "struct SSVRegistry.Validator", - "members": [ - { - "label": "operatorIds", - "type": "t_array(t_uint32)dyn_storage", - "offset": 0, - "slot": "0" - }, - { - "label": "ownerAddress", - "type": "t_address", - "offset": 0, - "slot": "1" - }, - { - "label": "indexInOwner", - "type": "t_uint32", - "offset": 20, - "slot": "1" - }, - { - "label": "active", - "type": "t_bool", - "offset": 24, - "slot": "1" - } - ], - "numberOfBytes": "64" - }, - "t_uint256": { - "label": "uint256", - "numberOfBytes": "32" - }, - "t_uint32": { - "label": "uint32", - "numberOfBytes": "4" - }, - "t_uint64": { - "label": "uint64", - "numberOfBytes": "8" - }, - "t_uint8": { - "label": "uint8", - "numberOfBytes": "1" - } - } - } - }, - "8ccca9e8e4945603d703a9f6291c363b0d55c2da050d38f2ddd015496db999d7": { - "address": "0x37FEC9dDB914de93aBBab16c2eb8bBa661a8c961", - "txHash": "0x511a2f5dd4152bc2368cba492f7f8309f75e6a0f2dd68a38ba79ff76bf64b014", - "layout": { - "storage": [ - { - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_uint8", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:62", - "retypedFrom": "bool" - }, - { - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool", - "contract": "Initializable", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:67" - }, - { - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage", - "contract": "ContextUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" - }, - { - "label": "_owner", - "offset": 0, - "slot": "51", - "type": "t_address", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" - }, - { - "label": "__gap", - "offset": 0, - "slot": "52", - "type": "t_array(t_uint256)49_storage", - "contract": "OwnableUpgradeable", - "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:87" - }, - { - "label": "_ssvRegistryContract", - "offset": 0, - "slot": "101", - "type": "t_contract(ISSVRegistry)2133", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:47" - }, - { - "label": "_token", - "offset": 0, - "slot": "102", - "type": "t_contract(IERC20)1319", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:48" - }, - { - "label": "_minimumBlocksBeforeLiquidation", - "offset": 20, - "slot": "102", - "type": "t_uint64", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:49" - }, - { - "label": "_operatorMaxFeeIncrease", - "offset": 0, - "slot": "103", - "type": "t_uint64", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:50" - }, - { - "label": "_networkFee", - "offset": 8, - "slot": "103", - "type": "t_uint64", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:52" - }, - { - "label": "_networkFeeIndex", - "offset": 16, - "slot": "103", - "type": "t_uint64", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:53" - }, - { - "label": "_networkFeeIndexBlockNumber", - "offset": 0, - "slot": "104", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:54" - }, - { - "label": "_networkEarnings", - "offset": 0, - "slot": "105", - "type": "t_uint64", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:55" - }, - { - "label": "_networkEarningsBlockNumber", - "offset": 0, - "slot": "106", - "type": "t_uint256", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:56" - }, - { - "label": "_withdrawnFromTreasury", - "offset": 0, - "slot": "107", - "type": "t_uint64", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:57" - }, - { - "label": "_operatorDatas", - "offset": 0, - "slot": "108", - "type": "t_mapping(t_uint32,t_struct(OperatorData)2163_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:59" - }, - { - "label": "_owners", - "offset": 0, - "slot": "109", - "type": "t_mapping(t_address,t_struct(OwnerData)2178_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:60" - }, - { - "label": "_operatorsInUseByAddress", - "offset": 0, - "slot": "110", - "type": "t_mapping(t_address,t_mapping(t_uint32,t_struct(OperatorInUse)2189_storage))", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:61" - }, - { - "label": "_operatorsInUseList", - "offset": 0, - "slot": "111", - "type": "t_mapping(t_address,t_array(t_uint32)dyn_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:62" - }, - { - "label": "_declareOperatorFeePeriod", - "offset": 0, - "slot": "112", - "type": "t_uint64", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:64" - }, - { - "label": "_executeOperatorFeePeriod", - "offset": 8, - "slot": "112", - "type": "t_uint64", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:65" - }, - { - "label": "_feeChangeRequests", - "offset": 0, - "slot": "113", - "type": "t_mapping(t_uint32,t_struct(FeeChangeRequest)2196_storage)", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:66" - }, - { - "label": "______gap", - "offset": 0, - "slot": "114", - "type": "t_array(t_uint256)50_storage", - "contract": "SSVNetwork", - "src": "contracts/SSVNetwork.sol:810" - } - ], - "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_array(t_uint32)dyn_storage": { - "label": "uint32[]", - "numberOfBytes": "32" - }, - "t_bool": { - "label": "bool", - "numberOfBytes": "1" - }, - "t_contract(IERC20)1319": { - "label": "contract IERC20", - "numberOfBytes": "20" - }, - "t_contract(ISSVRegistry)2133": { - "label": "contract ISSVRegistry", - "numberOfBytes": "20" - }, - "t_mapping(t_address,t_array(t_uint32)dyn_storage)": { - "label": "mapping(address => uint32[])", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_mapping(t_uint32,t_struct(OperatorInUse)2189_storage))": { - "label": "mapping(address => mapping(uint32 => struct SSVNetwork.OperatorInUse))", - "numberOfBytes": "32" - }, - "t_mapping(t_address,t_struct(OwnerData)2178_storage)": { - "label": "mapping(address => struct SSVNetwork.OwnerData)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint32,t_struct(FeeChangeRequest)2196_storage)": { - "label": "mapping(uint32 => struct SSVNetwork.FeeChangeRequest)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint32,t_struct(OperatorData)2163_storage)": { - "label": "mapping(uint32 => struct SSVNetwork.OperatorData)", - "numberOfBytes": "32" - }, - "t_mapping(t_uint32,t_struct(OperatorInUse)2189_storage)": { - "label": "mapping(uint32 => struct SSVNetwork.OperatorInUse)", - "numberOfBytes": "32" - }, - "t_struct(FeeChangeRequest)2196_storage": { - "label": "struct SSVNetwork.FeeChangeRequest", - "members": [ - { - "label": "fee", - "type": "t_uint64", - "offset": 0, - "slot": "0" - }, - { - "label": "approvalBeginTime", - "type": "t_uint256", - "offset": 0, - "slot": "1" - }, - { - "label": "approvalEndTime", - "type": "t_uint256", - "offset": 0, - "slot": "2" - } - ], - "numberOfBytes": "96" - }, - "t_struct(OperatorData)2163_storage": { - "label": "struct SSVNetwork.OperatorData", - "members": [ - { - "label": "blockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "0" - }, - { - "label": "earnings", - "type": "t_uint64", - "offset": 0, - "slot": "1" - }, - { - "label": "index", - "type": "t_uint64", - "offset": 8, - "slot": "1" - }, - { - "label": "indexBlockNumber", - "type": "t_uint256", - "offset": 0, - "slot": "2" - }, - { - "label": "activeValidatorCount", - "type": "t_uint32", - "offset": 0, - "slot": "3" - } - ], - "numberOfBytes": "128" - }, - "t_struct(OperatorInUse)2189_storage": { - "label": "struct SSVNetwork.OperatorInUse", - "members": [ - { - "label": "index", - "type": "t_uint64", - "offset": 0, - "slot": "0" - }, - { - "label": "used", - "type": "t_uint64", - "offset": 8, - "slot": "0" - }, - { - "label": "validatorCount", - "type": "t_uint32", - "offset": 16, - "slot": "0" - }, - { - "label": "indexInArray", - "type": "t_uint32", - "offset": 20, - "slot": "0" - }, - { - "label": "exists", - "type": "t_bool", - "offset": 24, - "slot": "0" - } - ], - "numberOfBytes": "32" - }, - "t_struct(OwnerData)2178_storage": { - "label": "struct SSVNetwork.OwnerData", - "members": [ - { - "label": "deposited", - "type": "t_uint64", - "offset": 0, - "slot": "0" - }, - { - "label": "withdrawn", - "type": "t_uint64", - "offset": 8, - "slot": "0" - }, - { - "label": "used", - "type": "t_uint64", - "offset": 16, - "slot": "0" - }, - { - "label": "networkFee", - "type": "t_uint64", - "offset": 24, - "slot": "0" - }, - { - "label": "networkFeeIndex", - "type": "t_uint64", - "offset": 0, - "slot": "1" - }, - { - "label": "activeValidatorCount", - "type": "t_uint32", - "offset": 8, - "slot": "1" - }, - { - "label": "validatorsDisabled", - "type": "t_bool", - "offset": 12, - "slot": "1" - } - ], - "numberOfBytes": "64" - }, - "t_uint256": { - "label": "uint256", - "numberOfBytes": "32" - }, - "t_uint32": { - "label": "uint32", - "numberOfBytes": "4" - }, - "t_uint64": { - "label": "uint64", - "numberOfBytes": "8" - }, - "t_uint8": { - "label": "uint8", - "numberOfBytes": "1" - } - } - } - } - } -} diff --git a/.openzeppelin/mainnet.json b/.openzeppelin/mainnet.json deleted file mode 100644 index 5b0d86ab..00000000 --- a/.openzeppelin/mainnet.json +++ /dev/null @@ -1,170 +0,0 @@ -{ - "manifestVersion": "3.2", - "admin": { - "address": "0xaf8a99140871538ac7a6883890c83892aF950bED", - "txHash": "0x448aa0d55730452d0c3a2d2001cf56197ac7c6b8fa24bcde7b1d3ea645443baa", - "deployTransaction": { - "hash": "0x448aa0d55730452d0c3a2d2001cf56197ac7c6b8fa24bcde7b1d3ea645443baa", - "type": 0, - "accessList": null, - "blockHash": null, - "blockNumber": null, - "transactionIndex": null, - "confirmations": 0, - "from": "0x3187a42658417a4d60866163A4534Ce00D40C0C8", - "gasPrice": { - "type": "BigNumber", - "hex": "0x09c7652400" - }, - "gasLimit": { - "type": "BigNumber", - "hex": "0x0762b4" - }, - "to": null, - "value": { - "type": "BigNumber", - "hex": "0x00" - }, - "nonce": 8, - "data": "0x608060405234801561001057600080fd5b50600080546001600160a01b031916339081178255604051909182917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350610759806100616000396000f3fe60806040526004361061007b5760003560e01c80639623609d1161004e5780639623609d1461011157806399a88ec414610124578063f2fde38b14610144578063f3b7dead146101645761007b565b8063204e1c7a14610080578063715018a6146100bc5780637eff275e146100d35780638da5cb5b146100f3575b600080fd5b34801561008c57600080fd5b506100a061009b366004610515565b610184565b6040516001600160a01b03909116815260200160405180910390f35b3480156100c857600080fd5b506100d1610215565b005b3480156100df57600080fd5b506100d16100ee366004610554565b610292565b3480156100ff57600080fd5b506000546001600160a01b03166100a0565b6100d161011f36600461058c565b61031c565b34801561013057600080fd5b506100d161013f366004610554565b6103ad565b34801561015057600080fd5b506100d161015f366004610515565b610405565b34801561017057600080fd5b506100a061017f366004610515565b6104ef565b6000806000836001600160a01b03166040516101aa90635c60da1b60e01b815260040190565b600060405180830381855afa9150503d80600081146101e5576040519150601f19603f3d011682016040523d82523d6000602084013e6101ea565b606091505b5091509150816101f957600080fd5b8080602001905181019061020d9190610538565b949350505050565b6000546001600160a01b031633146102485760405162461bcd60e51b815260040161023f906106c0565b60405180910390fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000546001600160a01b031633146102bc5760405162461bcd60e51b815260040161023f906106c0565b6040516308f2839760e41b81526001600160a01b038281166004830152831690638f283970906024015b600060405180830381600087803b15801561030057600080fd5b505af1158015610314573d6000803e3d6000fd5b505050505050565b6000546001600160a01b031633146103465760405162461bcd60e51b815260040161023f906106c0565b60405163278f794360e11b81526001600160a01b03841690634f1ef286903490610376908690869060040161065d565b6000604051808303818588803b15801561038f57600080fd5b505af11580156103a3573d6000803e3d6000fd5b5050505050505050565b6000546001600160a01b031633146103d75760405162461bcd60e51b815260040161023f906106c0565b604051631b2ce7f360e11b81526001600160a01b038281166004830152831690633659cfe6906024016102e6565b6000546001600160a01b0316331461042f5760405162461bcd60e51b815260040161023f906106c0565b6001600160a01b0381166104945760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161023f565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000806000836001600160a01b03166040516101aa906303e1469160e61b815260040190565b600060208284031215610526578081fd5b81356105318161070b565b9392505050565b600060208284031215610549578081fd5b81516105318161070b565b60008060408385031215610566578081fd5b82356105718161070b565b915060208301356105818161070b565b809150509250929050565b6000806000606084860312156105a0578081fd5b83356105ab8161070b565b925060208401356105bb8161070b565b9150604084013567ffffffffffffffff808211156105d7578283fd5b818601915086601f8301126105ea578283fd5b8135818111156105fc576105fc6106f5565b604051601f8201601f19908116603f01168101908382118183101715610624576106246106f5565b8160405282815289602084870101111561063c578586fd5b82602086016020830137856020848301015280955050505050509250925092565b600060018060a01b038416825260206040818401528351806040850152825b818110156106985785810183015185820160600152820161067c565b818111156106a95783606083870101525b50601f01601f191692909201606001949350505050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461072057600080fd5b5056fea2646970667358221220d849f96f3086b9f82cdcf665adb8c697ace05638da1c7c16ab2d26293717af6764736f6c63430008020033", - "r": "0x9279312f1874ba0669f96f50218c71dacd44c349ab7a21ab15a6326932a10b6b", - "s": "0x03082669d14c90746ee5a55abbc4cee24a07c24f0404ea72570d2f9e7559ffd6", - "v": 38, - "creates": "0xaf8a99140871538ac7a6883890c83892aF950bED", - "chainId": 1 - } - }, - "proxies": [ - { - "address": "0xedf62bBaE1c246a2879d4CDF7D057843D236534a", - "txHash": "0x4369ac13010a739cf5ab7870ad03b6a7d281e76fd099028e16e91cbb21d4dcbd", - "kind": "transparent" - }, - { - "address": "0xc398C2935a274a3a39D86B4E3d36dabA616442e6", - "txHash": "0x2afeb4d533bf5ceb4816f93f349eaf10c154b2e972af9bbafbe80f4ca1e34e30", - "kind": "transparent" - } - ], - "impls": { - "465630543d7a7c3cda9d0c8c5c83972657651e848f528060f68573798893ff16": { - "address": "0x051cD7c00d37d54A9eAAcBb0Ef17AB790D93e4a5", - "txHash": "0x1d92d59ea4708904c40275cbf3a016dc3bdb15bc280bc9dd6c46bc08692ce875", - "layout": { - "storage": [ - { - "contract": "Initializable", - "label": "_initialized", - "type": "t_bool", - "src": "@openzeppelin/contracts/proxy/utils/Initializable.sol:21" - }, - { - "contract": "Initializable", - "label": "_initializing", - "type": "t_bool", - "src": "@openzeppelin/contracts/proxy/utils/Initializable.sol:26" - }, - { - "contract": "TokenVestingController", - "label": "_token", - "type": "t_contract(IERC20)987", - "src": "contracts/vesting/TokenVestingController.sol:13" - }, - { - "contract": "TokenVestingController", - "label": "_minimumAmountPerContract", - "type": "t_uint256", - "src": "contracts/vesting/TokenVestingController.sol:14" - }, - { - "contract": "TokenVestingController", - "label": "_vestings", - "type": "t_mapping(t_address,t_array(t_contract(TokenVesting)5114)dyn_storage)", - "src": "contracts/vesting/TokenVestingController.sol:15" - }, - { - "contract": "TokenVestingController", - "label": "_owners", - "type": "t_mapping(t_contract(TokenVesting)5114,t_address)", - "src": "contracts/vesting/TokenVestingController.sol:16" - } - ], - "types": { - "t_contract(IERC20)987": { - "label": "contract IERC20" - }, - "t_uint256": { - "label": "uint256" - }, - "t_mapping(t_address,t_array(t_contract(TokenVesting)5114)dyn_storage)": { - "label": "mapping(address => contract TokenVesting[])" - }, - "t_address": { - "label": "address" - }, - "t_array(t_contract(TokenVesting)5114)dyn_storage": { - "label": "contract TokenVesting[]" - }, - "t_contract(TokenVesting)5114": { - "label": "contract TokenVesting" - }, - "t_mapping(t_contract(TokenVesting)5114,t_address)": { - "label": "mapping(contract TokenVesting => address)" - }, - "t_bool": { - "label": "bool" - } - } - } - }, - "baf9cc9d16f9682ee3153164cd1610c561f4a2b4e9bf09bd3b7fc9f175992efc": { - "address": "0x77511aA462c73C28016084477e5C7dFC315Db8b1", - "txHash": "0x15dbd84fadb837b594007a3c099a111de564e63700204077a3be4c81550750d6", - "layout": { - "storage": [ - { - "contract": "Initializable", - "label": "_initialized", - "type": "t_bool", - "src": "@openzeppelin/contracts/proxy/utils/Initializable.sol:21" - }, - { - "contract": "Initializable", - "label": "_initializing", - "type": "t_bool", - "src": "@openzeppelin/contracts/proxy/utils/Initializable.sol:26" - }, - { - "contract": "DEX", - "label": "_cdtToken", - "type": "t_contract(IERC20)987", - "src": "contracts/DEX.sol:14" - }, - { - "contract": "DEX", - "label": "_ssvToken", - "type": "t_contract(IERC20)987", - "src": "contracts/DEX.sol:15" - }, - { - "contract": "DEX", - "label": "_rate", - "type": "t_uint256", - "src": "contracts/DEX.sol:16" - } - ], - "types": { - "t_contract(IERC20)987": { - "label": "contract IERC20" - }, - "t_uint256": { - "label": "uint256" - }, - "t_bool": { - "label": "bool" - } - } - } - } - } -} diff --git a/contracts/ISSVNetwork.sol b/contracts/ISSVNetwork.sol deleted file mode 100644 index a1549e62..00000000 --- a/contracts/ISSVNetwork.sol +++ /dev/null @@ -1,403 +0,0 @@ -// File: contracts/ISSVNetwork.sol -// SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity ^0.8.2; - -import "./ISSVRegistry.sol"; -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; - -interface ISSVNetwork { - /** - * @dev Emitted when the account has been enabled. - * @param ownerAddress Operator's owner. - */ - event AccountEnable(address indexed ownerAddress); - - /** - * @dev Emitted when the account has been liquidated. - * @param ownerAddress Operator's owner. - */ - event AccountLiquidation(address indexed ownerAddress); - - /** - * @dev Emitted when the operator has been added. - * @param id operator's ID. - * @param name Operator's display name. - * @param ownerAddress Operator's ethereum address that can collect fees. - * @param publicKey Operator's public key. Will be used to encrypt secret shares of validators keys. - * @param fee Operator's initial fee. - */ - event OperatorRegistration( - uint32 indexed id, - string name, - address indexed ownerAddress, - bytes publicKey, - uint256 fee - ); - - /** - * @dev Emitted when the operator has been removed. - * @param operatorId operator's ID. - * @param ownerAddress Operator's owner. - */ - event OperatorRemoval(uint32 operatorId, address indexed ownerAddress); - - event OperatorFeeDeclaration( - address indexed ownerAddress, - uint32 operatorId, - uint256 blockNumber, - uint256 fee - ); - - event DeclaredOperatorFeeCancelation(address indexed ownerAddress, uint32 operatorId); - - /** - * @dev Emitted when an operator's fee is updated. - * @param ownerAddress Operator's owner. - * @param blockNumber from which block number. - * @param fee updated fee value. - */ - event OperatorFeeExecution( - address indexed ownerAddress, - uint32 operatorId, - uint256 blockNumber, - uint256 fee - ); - - /** - * @dev Emitted when an operator's score is updated. - * @param operatorId operator's ID. - * @param ownerAddress Operator's owner. - * @param blockNumber from which block number. - * @param score updated score value. - */ - event OperatorScoreUpdate( - uint32 operatorId, - address indexed ownerAddress, - uint256 blockNumber, - uint256 score - ); - - /** - * @dev Emitted when the validator has been added. - * @param ownerAddress The user's ethereum address that is the owner of the validator. - * @param publicKey The public key of a validator. - * @param operatorIds The operators public keys list for this validator. - * @param sharesPublicKeys The shared publick keys list for this validator. - * @param encryptedKeys The encrypted keys list for this validator. - */ - event ValidatorRegistration( - address indexed ownerAddress, - bytes publicKey, - uint32[] operatorIds, - bytes[] sharesPublicKeys, - bytes[] encryptedKeys - ); - - /** - * @dev Emitted when the validator is removed. - * @param ownerAddress Validator's owner. - * @param publicKey The public key of a validator. - */ - event ValidatorRemoval(address indexed ownerAddress, bytes publicKey); - - /** - * @dev Emitted when an owner deposits funds. - * @param value Amount of tokens. - * @param ownerAddress Owner's address. - * @param senderAddress Sender's address. - */ - event FundsDeposit(uint256 value, address indexed ownerAddress, address indexed senderAddress); - - /** - * @dev Emitted when an owner withdraws funds. - * @param value Amount of tokens. - * @param ownerAddress Owner's address. - */ - event FundsWithdrawal(uint256 value, address indexed ownerAddress); - - /** - * @dev Emitted when the network fee is updated. - * @param oldFee The old fee - * @param newFee The new fee - */ - event NetworkFeeUpdate(uint256 oldFee, uint256 newFee); - - /** - * @dev Emitted when transfer fees are withdrawn. - * @param value The amount of tokens withdrawn. - * @param recipient The recipient address. - */ - event NetworkFeesWithdrawal(uint256 value, address recipient); - - event DeclareOperatorFeePeriodUpdate(uint256 value); - - event ExecuteOperatorFeePeriodUpdate(uint256 value); - - event LiquidationThresholdPeriodUpdate(uint256 value); - - event OperatorFeeIncreaseLimitUpdate(uint256 value); - - event ValidatorsPerOperatorLimitUpdate(uint256 value); - - event RegisteredOperatorsPerAccountLimitUpdate(uint256 value); - - event MinimumBlocksBeforeLiquidationUpdate(uint256 value); - - event OperatorMaxFeeIncreaseUpdate(uint256 value); - - /** errors */ - error ValidatorWithPublicKeyNotExist(); - error CallerNotValidatorOwner(); - error OperatorWithPublicKeyNotExist(); - error CallerNotOperatorOwner(); - error FeeTooLow(); - error FeeExceedsIncreaseLimit(); - error NoPendingFeeChangeRequest(); - error ApprovalNotWithinTimeframe(); - error NotEnoughBalance(); - error BurnRatePositive(); - error AccountAlreadyEnabled(); - error NegativeBalance(); - error BelowMinimumBlockPeriod(); - error ExceedManagingOperatorsPerAccountLimit(); - - /** - * @dev Initializes the contract. - * @param registryAddress_ The registry address. - * @param token_ The network token. - * @param minimumBlocksBeforeLiquidation_ The minimum blocks before liquidation. - * @param declareOperatorFeePeriod_ The period an operator needs to wait before they can approve their fee. - * @param executeOperatorFeePeriod_ The length of the period in which an operator can approve their fee. - */ - function initialize( - ISSVRegistry registryAddress_, - IERC20 token_, - uint64 minimumBlocksBeforeLiquidation_, - uint64 operatorMaxFeeIncrease_, - uint64 declareOperatorFeePeriod_, - uint64 executeOperatorFeePeriod_ - ) external; - - /** - * @dev Registers a new operator. - * @param name Operator's display name. - * @param publicKey Operator's public key. Used to encrypt secret shares of validators keys. - */ - function registerOperator( - string calldata name, - bytes calldata publicKey, - uint256 fee - ) external returns (uint32); - - /** - * @dev Removes an operator. - * @param operatorId Operator's id. - */ - function removeOperator(uint32 operatorId) external; - - /** - * @dev Set operator's fee change request by public key. - * @param operatorId Operator's id. - * @param operatorFee The operator's updated fee. - */ - function declareOperatorFee(uint32 operatorId, uint256 operatorFee) external; - - function cancelDeclaredOperatorFee(uint32 operatorId) external; - - function executeOperatorFee(uint32 operatorId) external; - - /** - * @dev Updates operator's score by public key. - * @param operatorId Operator's id. - * @param score The operators's updated score. - */ - function updateOperatorScore(uint32 operatorId, uint32 score) external; - - /** - * @dev Registers a new validator. - * @param publicKey Validator public key. - * @param operatorIds Operator public keys. - * @param sharesPublicKeys Shares public keys. - * @param sharesEncrypted Encrypted private keys. - * @param amount Amount of tokens to deposit. - */ - function registerValidator( - bytes calldata publicKey, - uint32[] calldata operatorIds, - bytes[] calldata sharesPublicKeys, - bytes[] calldata sharesEncrypted, - uint256 amount - ) external; - - /** - * @dev Updates a validator. - * @param publicKey Validator public key. - * @param operatorIds Operator public keys. - * @param sharesPublicKeys Shares public keys. - * @param sharesEncrypted Encrypted private keys. - * @param amount Amount of tokens to deposit. - */ - function updateValidator( - bytes calldata publicKey, - uint32[] calldata operatorIds, - bytes[] calldata sharesPublicKeys, - bytes[] calldata sharesEncrypted, - uint256 amount - ) external; - - /** - * @dev Removes a validator. - * @param publicKey Validator's public key. - */ - function removeValidator(bytes calldata publicKey) external; - - /** - * @dev Deposits tokens for the sender. - * @param ownerAddress Owners' addresses. - * @param tokenAmount Tokens amount. - */ - function deposit(address ownerAddress, uint256 tokenAmount) external; - - /** - * @dev Withdraw tokens for the sender. - * @param tokenAmount Tokens amount. - */ - function withdraw(uint256 tokenAmount) external; - - /** - * @dev Withdraw total balance to the sender, deactivating their validators if necessary. - */ - function withdrawAll() external; - - /** - * @dev Liquidates multiple owners. - * @param ownerAddresses Owners' addresses. - */ - function liquidate(address[] calldata ownerAddresses) external; - - /** - * @dev Enables msg.sender account. - * @param amount Tokens amount. - */ - function reactivateAccount(uint256 amount) external; - - /** - * @dev Updates the number of blocks left for an owner before they can be liquidated. - * @param blocks The new value. - */ - function updateLiquidationThresholdPeriod(uint64 blocks) external; - - /** - * @dev Updates the maximum fee increase in pecentage. - * @param newOperatorMaxFeeIncrease The new value. - */ - function updateOperatorFeeIncreaseLimit(uint64 newOperatorMaxFeeIncrease) external; - - function updateDeclareOperatorFeePeriod(uint64 newDeclareOperatorFeePeriod) external; - - function updateExecuteOperatorFeePeriod(uint64 newExecuteOperatorFeePeriod) external; - - /** - * @dev Updates the network fee. - * @param fee the new fee - */ - function updateNetworkFee(uint256 fee) external; - - /** - * @dev Withdraws network fees. - * @param amount Amount to withdraw - */ - function withdrawNetworkEarnings(uint256 amount) external; - - /** - * @dev Gets total balance for an owner. - * @param ownerAddress Owner's address. - */ - function getAddressBalance(address ownerAddress) external view returns (uint256); - - function isLiquidated(address ownerAddress) external view returns (bool); - - /** - * @dev Gets an operator by operator id. - * @param operatorId Operator's id. - */ - function getOperatorById(uint32 operatorId) - external view - returns ( - string memory, - address, - bytes memory, - uint256, - uint256, - uint256, - bool - ); - - /** - * @dev Gets a validator public keys by owner's address. - * @param ownerAddress Owner's Address. - */ - function getValidatorsByOwnerAddress(address ownerAddress) - external view - returns (bytes[] memory); - - /** - * @dev Gets operators list which are in use by validator. - * @param validatorPublicKey Validator's public key. - */ - function getOperatorsByValidator(bytes calldata validatorPublicKey) - external view - returns (uint32[] memory); - - function getOperatorDeclaredFee(uint32 operatorId) external view returns (uint256, uint256, uint256); - - /** - * @dev Gets operator current fee. - * @param operatorId Operator's id. - */ - function getOperatorFee(uint32 operatorId) external view returns (uint256); - - /** - * @dev Gets the network fee for an address. - * @param ownerAddress Owner's address. - */ - function addressNetworkFee(address ownerAddress) external view returns (uint256); - - /** - * @dev Returns the burn rate of an owner, returns 0 if negative. - * @param ownerAddress Owner's address. - */ - function getAddressBurnRate(address ownerAddress) external view returns (uint256); - - /** - * @dev Check if an owner is liquidatable. - * @param ownerAddress Owner's address. - */ - function isLiquidatable(address ownerAddress) external view returns (bool); - - /** - * @dev Returns the network fee. - */ - function getNetworkFee() external view returns (uint256); - - /** - * @dev Gets the available network earnings - */ - function getNetworkEarnings() external view returns (uint256); - - /** - * @dev Returns the number of blocks left for an owner before they can be liquidated. - */ - function getLiquidationThresholdPeriod() external view returns (uint256); - - /** - * @dev Returns the maximum fee increase in pecentage - */ - function getOperatorFeeIncreaseLimit() external view returns (uint256); - - function getExecuteOperatorFeePeriod() external view returns (uint256); - - function getDeclaredOperatorFeePeriod() external view returns (uint256); - - function validatorsPerOperatorCount(uint32 operatorId) external view returns (uint32); -} diff --git a/contracts/ISSVRegistry.sol b/contracts/ISSVRegistry.sol deleted file mode 100644 index d5992ed2..00000000 --- a/contracts/ISSVRegistry.sol +++ /dev/null @@ -1,171 +0,0 @@ -// File: contracts/ISSVRegistry.sol -// SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity ^0.8.2; - -interface ISSVRegistry { - struct Oess { - uint32 operatorId; - bytes sharedPublicKey; - bytes encryptedKey; - } - - /** errors */ - error ExceedRegisteredOperatorsByAccountLimit(); - error OperatorDeleted(); - error ValidatorAlreadyExists(); - error ExceedValidatorLimit(); - error OperatorNotFound(); - error InvalidPublicKeyLength(); - error OessDataStructureInvalid(); - - /** - * @dev Initializes the contract - */ - function initialize() external; - - /** - * @dev Registers a new operator. - * @param name Operator's display name. - * @param ownerAddress Operator's ethereum address that can collect fees. - * @param publicKey Operator's public key. Will be used to encrypt secret shares of validators keys. - * @param fee The fee which the operator charges for each block. - */ - function registerOperator(string calldata name, address ownerAddress, bytes calldata publicKey, uint64 fee) external returns (uint32); - - /** - * @dev removes an operator. - * @param operatorId Operator id. - */ - function removeOperator(uint32 operatorId) external; - - /** - * @dev Updates an operator fee. - * @param operatorId Operator id. - * @param fee New operator fee. - */ - function updateOperatorFee( - uint32 operatorId, - uint64 fee - ) external; - - /** - * @dev Updates an operator fee. - * @param operatorId Operator id. - * @param score New score. - */ - function updateOperatorScore( - uint32 operatorId, - uint32 score - ) external; - - /** - * @dev Registers a new validator. - * @param ownerAddress The user's ethereum address that is the owner of the validator. - * @param publicKey Validator public key. - * @param operatorIds Operator ids. - * @param sharesPublicKeys Shares public keys. - * @param sharesEncrypted Encrypted private keys. - */ - function registerValidator( - address ownerAddress, - bytes calldata publicKey, - uint32[] calldata operatorIds, - bytes[] calldata sharesPublicKeys, - bytes[] calldata sharesEncrypted - ) external; - - /** - * @dev removes a validator. - * @param publicKey Validator's public key. - */ - function removeValidator(bytes calldata publicKey) external; - - function enableOwnerValidators(address ownerAddress) external; - - function disableOwnerValidators(address ownerAddress) external; - - function isLiquidated(address ownerAddress) external view returns (bool); - - /** - * @dev Gets an operator by operator id. - * @param operatorId Operator id. - */ - function getOperatorById(uint32 operatorId) - external view - returns ( - string memory, - address, - bytes memory, - uint256, - uint256, - uint256, - bool - ); - - /** - * @dev Returns operators for owner. - * @param ownerAddress Owner's address. - */ - function getOperatorsByOwnerAddress(address ownerAddress) - external view - returns (uint32[] memory); - - /** - * @dev Gets operators list which are in use by validator. - * @param validatorPublicKey Validator's public key. - */ - function getOperatorsByValidator(bytes calldata validatorPublicKey) - external view - returns (uint32[] memory); - - /** - * @dev Gets operator's owner. - * @param operatorId Operator id. - */ - function getOperatorOwner(uint32 operatorId) external view returns (address); - - /** - * @dev Gets operator current fee. - * @param operatorId Operator id. - */ - function getOperatorFee(uint32 operatorId) - external view - returns (uint64); - - /** - * @dev Gets active validator count. - */ - function activeValidatorCount() external view returns (uint32); - - /** - * @dev Gets an validator by public key. - * @param publicKey Validator's public key. - */ - function validators(bytes calldata publicKey) - external view - returns ( - address, - bytes memory, - bool - ); - - /** - * @dev Gets a validator public keys by owner's address. - * @param ownerAddress Owner's Address. - */ - function getValidatorsByAddress(address ownerAddress) - external view - returns (bytes[] memory); - - /** - * @dev Get validator's owner. - * @param publicKey Validator's public key. - */ - function getValidatorOwner(bytes calldata publicKey) external view returns (address); - - /** - * @dev Get validators amount per operator. - * @param operatorId Operator public key - */ - function validatorsPerOperatorCount(uint32 operatorId) external view returns (uint32); -} \ No newline at end of file diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol deleted file mode 100644 index 72125212..00000000 --- a/contracts/SSVNetwork.sol +++ /dev/null @@ -1,811 +0,0 @@ -// File: contracts/SSVNetwork.sol -// SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity ^0.8.2; - -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; -import "./utils/VersionedContract.sol"; -import "./utils/Types.sol"; -import "./ISSVNetwork.sol"; - -contract SSVNetwork is OwnableUpgradeable, ISSVNetwork, VersionedContract { - using Types256 for uint256; - using Types64 for uint64; - - struct OperatorData { - uint256 blockNumber; - uint64 earnings; - uint64 index; - uint256 indexBlockNumber; - uint32 activeValidatorCount; - } - - struct OwnerData { - uint64 deposited; - uint64 withdrawn; - uint64 used; - uint64 networkFee; - uint64 networkFeeIndex; - uint32 activeValidatorCount; - bool validatorsDisabled; - } - - struct OperatorInUse { - uint64 index; - uint64 used; - uint32 validatorCount; - uint32 indexInArray; - bool exists; - } - - struct FeeChangeRequest { - uint64 fee; - uint256 approvalBeginTime; - uint256 approvalEndTime; - } - - ISSVRegistry private _ssvRegistryContract; - IERC20 private _token; - uint64 private _minimumBlocksBeforeLiquidation; - uint64 private _operatorMaxFeeIncrease; - - uint64 private _networkFee; - uint64 private _networkFeeIndex; - uint256 private _networkFeeIndexBlockNumber; - uint64 private _networkEarnings; - uint256 private _networkEarningsBlockNumber; - uint64 private _withdrawnFromTreasury; - - mapping(uint32 => OperatorData) private _operatorDatas; - mapping(address => OwnerData) private _owners; - mapping(address => mapping(uint32 => OperatorInUse)) private _operatorsInUseByAddress; - mapping(address => uint32[]) private _operatorsInUseList; - - uint64 private _declareOperatorFeePeriod; - uint64 private _executeOperatorFeePeriod; - mapping(uint32 => FeeChangeRequest) private _feeChangeRequests; - - uint16 constant private MINIMAL_OPERATOR_FEE = 1000; - uint16 constant private MANAGING_OPERATORS_PER_ACCOUNT_LIMIT = 50; - uint16 constant private MINIMAL_LIQUIDATION_THRESHOLD = 6570; - - function initialize( - ISSVRegistry registryAddress_, - IERC20 token_, - uint64 minimumBlocksBeforeLiquidation_, - uint64 operatorMaxFeeIncrease_, - uint64 declareOperatorFeePeriod_, - uint64 executeOperatorFeePeriod_ - ) external initializer override { - __SSVNetwork_init(registryAddress_, token_, minimumBlocksBeforeLiquidation_, operatorMaxFeeIncrease_, declareOperatorFeePeriod_, executeOperatorFeePeriod_); - } - - function __SSVNetwork_init( - ISSVRegistry registryAddress_, - IERC20 token_, - uint64 minimumBlocksBeforeLiquidation_, - uint64 operatorMaxFeeIncrease_, - uint64 declareOperatorFeePeriod_, - uint64 executeOperatorFeePeriod_ - ) internal initializer { - __Ownable_init_unchained(); - __SSVNetwork_init_unchained(registryAddress_, token_, minimumBlocksBeforeLiquidation_, operatorMaxFeeIncrease_, declareOperatorFeePeriod_, executeOperatorFeePeriod_); - } - - function __SSVNetwork_init_unchained( - ISSVRegistry registryAddress_, - IERC20 token_, - uint64 minimumBlocksBeforeLiquidation_, - uint64 operatorMaxFeeIncrease_, - uint64 declareOperatorFeePeriod_, - uint64 executeOperatorFeePeriod_ - ) internal onlyInitializing { - _ssvRegistryContract = registryAddress_; - _token = token_; - _updateLiquidationThresholdPeriod(minimumBlocksBeforeLiquidation_); - _updateOperatorFeeIncreaseLimit(operatorMaxFeeIncrease_); - _updateDeclareOperatorFeePeriod(declareOperatorFeePeriod_); - _updateExecuteOperatorFeePeriod(executeOperatorFeePeriod_); - _ssvRegistryContract.initialize(); - } - - modifier onlyValidatorOwnerOrContractOwner(bytes calldata publicKey) { - _onlyValidatorOwnerOrContractOwner(publicKey); - _; - } - - modifier onlyOperatorOwnerOrContractOwner(uint32 operatorId) { - _onlyOperatorOwnerOrContractOwner(operatorId); - _; - } - - modifier ensureMinimalOperatorFee(uint256 fee) { - _ensureMinimalOperatorFee(fee.shrink()); - _; - } - - /** - * @dev See {ISSVNetwork-registerOperator}. - */ - function registerOperator( - string calldata name, - bytes calldata publicKey, - uint256 fee - ) ensureMinimalOperatorFee(fee) external override returns (uint32 operatorId) { - operatorId = _ssvRegistryContract.registerOperator( - name, - msg.sender, - publicKey, - fee.shrink() - ); - - _operatorDatas[operatorId] = OperatorData({ blockNumber: block.number, earnings: 0, index: 0, indexBlockNumber: block.number, activeValidatorCount: 0 }); - emit OperatorRegistration(operatorId, name, msg.sender, publicKey, fee.shrink().expand()); - } - - /** - * @dev See {ISSVNetwork-removeOperator}. - */ - function removeOperator(uint32 operatorId) onlyOperatorOwnerOrContractOwner(operatorId) external override { - address owner = _ssvRegistryContract.getOperatorOwner(operatorId); - - _updateOperatorFeeUnsafe(operatorId, 0); - _ssvRegistryContract.removeOperator(operatorId); - - emit OperatorRemoval(operatorId, owner); - } - - function declareOperatorFee(uint32 operatorId, uint256 operatorFee) onlyOperatorOwnerOrContractOwner(operatorId) ensureMinimalOperatorFee(operatorFee) external override { - if (operatorFee.shrink() > _ssvRegistryContract.getOperatorFee(operatorId) * (10000 + _operatorMaxFeeIncrease) / 10000) { - revert FeeExceedsIncreaseLimit(); - } - _feeChangeRequests[operatorId] = FeeChangeRequest(operatorFee.shrink(), block.timestamp + _declareOperatorFeePeriod, block.timestamp + _declareOperatorFeePeriod + _executeOperatorFeePeriod); - - emit OperatorFeeDeclaration(msg.sender, operatorId, block.number, operatorFee); - } - - function cancelDeclaredOperatorFee(uint32 operatorId) onlyOperatorOwnerOrContractOwner(operatorId) external override { - delete _feeChangeRequests[operatorId]; - - emit DeclaredOperatorFeeCancelation(msg.sender, operatorId); - } - - function executeOperatorFee(uint32 operatorId) onlyOperatorOwnerOrContractOwner(operatorId) external override { - FeeChangeRequest storage feeChangeRequest = _feeChangeRequests[operatorId]; - - if(feeChangeRequest.fee == 0) { - revert NoPendingFeeChangeRequest(); - } - if(block.timestamp < feeChangeRequest.approvalBeginTime || block.timestamp > feeChangeRequest.approvalEndTime) { - revert ApprovalNotWithinTimeframe(); - } - - _updateOperatorFeeUnsafe(operatorId, feeChangeRequest.fee); - - emit OperatorFeeExecution(msg.sender, operatorId, block.number, feeChangeRequest.fee.expand()); - - delete _feeChangeRequests[operatorId]; - } - - function updateOperatorScore(uint32 operatorId, uint32 score) onlyOwner external override { - _ssvRegistryContract.updateOperatorScore(operatorId, score); - - emit OperatorScoreUpdate(operatorId, msg.sender, block.number, score); - } - - /** - * @dev See {ISSVNetwork-registerValidator}. - */ - function registerValidator( - bytes calldata publicKey, - uint32[] calldata operatorIds, - bytes[] calldata sharesPublicKeys, - bytes[] calldata sharesEncrypted, - uint256 amount - ) external override { - _updateNetworkEarnings(); - _updateAddressNetworkFee(msg.sender); - _registerValidatorUnsafe(msg.sender, publicKey, operatorIds, sharesPublicKeys, sharesEncrypted, amount); - } - - /** - * @dev See {ISSVNetwork-updateValidator}. - */ - function updateValidator( - bytes calldata publicKey, - uint32[] calldata operatorIds, - bytes[] calldata sharesPublicKeys, - bytes[] calldata sharesEncrypted, - uint256 amount - ) onlyValidatorOwnerOrContractOwner(publicKey) external override { - _removeValidatorUnsafe(msg.sender, publicKey); - _registerValidatorUnsafe(msg.sender, publicKey, operatorIds, sharesPublicKeys, sharesEncrypted, amount); - } - - /** - * @dev See {ISSVNetwork-removeValidator}. - */ - function removeValidator(bytes calldata publicKey) onlyValidatorOwnerOrContractOwner(publicKey) external override { - _updateNetworkEarnings(); - _updateAddressNetworkFee(msg.sender); - _removeValidatorUnsafe(msg.sender, publicKey); - _totalBalanceOf(msg.sender); // For assertion - } - - function deposit(address ownerAddress, uint256 amount) external override { - _deposit(ownerAddress, amount); - } - - function withdraw(uint256 amount) external override { - if(_totalBalanceOf(msg.sender) < amount.shrink()) { - revert NotEnoughBalance(); - } - - _withdrawUnsafe(amount.shrink()); - - if(_liquidatable(msg.sender)) { - revert NotEnoughBalance(); - } - } - - function withdrawAll() external override { - if(_burnRate(msg.sender) > 0) { - revert BurnRatePositive(); - } - - _withdrawUnsafe(_totalBalanceOf(msg.sender)); - } - - function liquidate(address[] calldata ownerAddresses) external override { - uint64 balanceToTransfer = 0; - - for (uint32 index = 0; index < ownerAddresses.length; ++index) { - if (_canLiquidate(ownerAddresses[index])) { - balanceToTransfer += _liquidateUnsafe(ownerAddresses[index]); - } - } - - _token.transfer(msg.sender, balanceToTransfer.expand()); - } - - function reactivateAccount(uint256 amount) external override { - if (!_owners[msg.sender].validatorsDisabled) { - revert AccountAlreadyEnabled(); - } - - _deposit(msg.sender, amount); - - _enableOwnerValidatorsUnsafe(msg.sender); - - if(_liquidatable(msg.sender)) { - revert NotEnoughBalance(); - } - - emit AccountEnable(msg.sender); - } - - function updateLiquidationThresholdPeriod(uint64 blocks) external onlyOwner override { - if(blocks < MINIMAL_LIQUIDATION_THRESHOLD) { - revert BelowMinimumBlockPeriod(); - } - - _updateLiquidationThresholdPeriod(blocks); - } - - function updateOperatorFeeIncreaseLimit(uint64 newOperatorMaxFeeIncrease) external onlyOwner override { - _updateOperatorFeeIncreaseLimit(newOperatorMaxFeeIncrease); - } - - function updateDeclareOperatorFeePeriod(uint64 newDeclareOperatorFeePeriod) external onlyOwner override { - _updateDeclareOperatorFeePeriod(newDeclareOperatorFeePeriod); - } - - function updateExecuteOperatorFeePeriod(uint64 newExecuteOperatorFeePeriod) external onlyOwner override { - _updateExecuteOperatorFeePeriod(newExecuteOperatorFeePeriod); - } - - /** - * @dev See {ISSVNetwork-updateNetworkFee}. - */ - function updateNetworkFee(uint256 fee) external onlyOwner override { - emit NetworkFeeUpdate(_networkFee.expand(), fee); - _updateNetworkEarnings(); - _updateNetworkFeeIndex(); - _networkFee = fee.shrink(); - } - - function withdrawNetworkEarnings(uint256 amount) external onlyOwner override { - if(amount.shrink() > _getNetworkEarnings()) { - revert NotEnoughBalance(); - } - - _withdrawnFromTreasury += amount.shrink(); - _token.transfer(msg.sender, amount); - - emit NetworkFeesWithdrawal(amount, msg.sender); - } - - function getAddressBalance(address ownerAddress) external override view returns (uint256) { - return _totalBalanceOf(ownerAddress).expand(); - } - - function isLiquidated(address ownerAddress) external view override returns (bool) { - return _owners[ownerAddress].validatorsDisabled; - } - - /** - * @dev See {ISSVNetwork-getOperatorById}. - */ - function getOperatorById(uint32 operatorId) external view override returns (string memory, address, bytes memory, uint256, uint256, uint256, bool) { - return _ssvRegistryContract.getOperatorById(operatorId); - } - - function getOperatorDeclaredFee(uint32 operatorId) external view override returns (uint256, uint256, uint256) { - FeeChangeRequest storage feeChangeRequest = _feeChangeRequests[operatorId]; - - return (feeChangeRequest.fee.expand(), feeChangeRequest.approvalBeginTime, feeChangeRequest.approvalEndTime); - } - - /** - * @dev See {ISSVNetwork-getOperatorFee}. - */ - function getOperatorFee(uint32 operatorId) external view override returns (uint256) { - return _ssvRegistryContract.getOperatorFee(operatorId).expand(); - } - - /** - * @dev See {ISSVNetwork-getOperatorsByValidator}. - */ - function getOperatorsByValidator(bytes memory publicKey) external view override returns (uint32[] memory) { - return _ssvRegistryContract.getOperatorsByValidator(publicKey); - } - - /** - * @dev See {ISSVNetwork-getValidatorsByAddress}. - */ - function getValidatorsByOwnerAddress(address ownerAddress) external view override returns (bytes[] memory) { - return _ssvRegistryContract.getValidatorsByAddress(ownerAddress); - } - - /** - * @dev See {ISSVNetwork-addressNetworkFee}. - */ - function addressNetworkFee(address ownerAddress) external view override returns (uint256) { - return _addressNetworkFee(ownerAddress); - } - - function getAddressBurnRate(address ownerAddress) external view override returns (uint256) { - return _burnRate(ownerAddress).expand(); - } - - function isLiquidatable(address ownerAddress) external view override returns (bool) { - return _liquidatable(ownerAddress); - } - - function getNetworkFee() external view override returns (uint256) { - return _networkFee.expand(); - } - - function getNetworkEarnings() external view override returns (uint256) { - return _getNetworkEarnings().expand(); - } - - function getLiquidationThresholdPeriod() external view override returns (uint256) { - return _minimumBlocksBeforeLiquidation; - } - - function getOperatorFeeIncreaseLimit() external view override returns (uint256) { - return _operatorMaxFeeIncrease; - } - - function getExecuteOperatorFeePeriod() external view override returns (uint256) { - return _executeOperatorFeePeriod; - } - - function getDeclaredOperatorFeePeriod() external view override returns (uint256) { - return _declareOperatorFeePeriod; - } - - function validatorsPerOperatorCount(uint32 operatorId) external view returns (uint32) { - return _ssvRegistryContract.validatorsPerOperatorCount(operatorId); - } - - function _deposit(address ownerAddress, uint256 amount) private { - _token.transferFrom(msg.sender, address(this), amount); - _owners[ownerAddress].deposited += amount.shrink(); - - emit FundsDeposit(amount, ownerAddress, msg.sender); - } - - function _withdrawUnsafe(uint64 amount) private { - _owners[msg.sender].withdrawn += amount; - _token.transfer(msg.sender, amount.expand()); - - emit FundsWithdrawal(amount.expand(), msg.sender); - } - - /** - * @dev Update network fee for the address. - * @param ownerAddress Owner address. - */ - function _updateAddressNetworkFee(address ownerAddress) private { - _owners[ownerAddress].networkFee = _addressNetworkFee(ownerAddress); - _owners[ownerAddress].networkFeeIndex = _currentNetworkFeeIndex(); - } - - function _updateOperatorIndex(uint32 operatorId) private { - _operatorDatas[operatorId].index = _operatorIndexOf(operatorId); - } - - /** - * @dev Updates operators's balance. - */ - function _updateOperatorBalance(uint32 operatorId) private { - OperatorData storage operatorData = _operatorDatas[operatorId]; - operatorData.earnings = _operatorEarningsOf(operatorId); - operatorData.blockNumber = block.number; - } - - function _liquidateUnsafe(address ownerAddress) private returns (uint64) { - _disableOwnerValidatorsUnsafe(ownerAddress); - - uint64 balanceToTransfer = _totalBalanceOf(ownerAddress); - - _owners[ownerAddress].used += balanceToTransfer; - - emit AccountLiquidation(ownerAddress); - - return balanceToTransfer; - } - - function _updateNetworkEarnings() private { - _networkEarnings = _getTotalNetworkEarnings(); - _networkEarningsBlockNumber = block.number; - } - - function _updateNetworkFeeIndex() private { - _networkFeeIndex = _currentNetworkFeeIndex(); - _networkFeeIndexBlockNumber = block.number; - } - - function _registerValidatorUnsafe( - address ownerAddress, - bytes calldata publicKey, - uint32[] calldata operatorIds, - bytes[] calldata sharesPublicKeys, - bytes[] calldata encryptedKeys, - uint256 tokenAmount) private { - - _ssvRegistryContract.registerValidator( - ownerAddress, - publicKey, - operatorIds, - sharesPublicKeys, - encryptedKeys - ); - - OwnerData storage owner = _owners[ownerAddress]; - - if (!owner.validatorsDisabled) { - ++owner.activeValidatorCount; - } - - for (uint32 index = 0; index < operatorIds.length; ++index) { - uint32 operatorId = operatorIds[index]; - _updateOperatorBalance(operatorId); - - if (!owner.validatorsDisabled) { - ++_operatorDatas[operatorId].activeValidatorCount; - } - - _useOperatorByOwner(ownerAddress, operatorId); - } - if (tokenAmount > 0) { - _deposit(msg.sender, tokenAmount); - } - - if(_liquidatable(ownerAddress)) { - revert NotEnoughBalance(); - } - - emit ValidatorRegistration(ownerAddress, publicKey, operatorIds, sharesPublicKeys, encryptedKeys); - } - - function _removeValidatorUnsafe(address ownerAddress, bytes memory publicKey) private { - _unregisterValidator(ownerAddress, publicKey); - _ssvRegistryContract.removeValidator(publicKey); - - if (!_owners[ownerAddress].validatorsDisabled) { - --_owners[ownerAddress].activeValidatorCount; - } - - emit ValidatorRemoval(ownerAddress, publicKey); - } - - function _unregisterValidator(address ownerAddress, bytes memory publicKey) private { - // calculate balances for current operators in use and update their balances - uint32[] memory currentOperatorIds = _ssvRegistryContract.getOperatorsByValidator(publicKey); - for (uint32 index = 0; index < currentOperatorIds.length; ++index) { - uint32 operatorId = currentOperatorIds[index]; - _updateOperatorBalance(operatorId); - - if (!_owners[ownerAddress].validatorsDisabled) { - --_operatorDatas[operatorId].activeValidatorCount; - } - - _stopUsingOperatorByOwner(ownerAddress, operatorId); - } - } - - function _useOperatorByOwner(address ownerAddress, uint32 operatorId) private { - _updateUsingOperatorByOwner(ownerAddress, operatorId, true); - } - - function _stopUsingOperatorByOwner(address ownerAddress, uint32 operatorId) private { - _updateUsingOperatorByOwner(ownerAddress, operatorId, false); - } - - function _updateOperatorFeeUnsafe(uint32 operatorId, uint64 fee) private { - OperatorData storage operatorData = _operatorDatas[operatorId]; - _updateOperatorIndex(operatorId); - operatorData.indexBlockNumber = block.number; - _updateOperatorBalance(operatorId); - _ssvRegistryContract.updateOperatorFee(operatorId, fee); - } - - /** - * @dev Updates the relation between operator and owner - * @param ownerAddress Owner address. - * @param increase Change value for validators amount. - */ - function _updateUsingOperatorByOwner(address ownerAddress, uint32 operatorId, bool increase) private { - OperatorInUse storage operatorInUseData = _operatorsInUseByAddress[ownerAddress][operatorId]; - - if (operatorInUseData.exists) { - _updateOperatorUsageByOwner(operatorInUseData, ownerAddress, operatorId); - - if (increase) { - ++operatorInUseData.validatorCount; - } else { - if (--operatorInUseData.validatorCount == 0) { - _owners[ownerAddress].used += operatorInUseData.used; - - // remove from mapping and list; - - _operatorsInUseList[ownerAddress][operatorInUseData.indexInArray] = _operatorsInUseList[ownerAddress][_operatorsInUseList[ownerAddress].length - 1]; - _operatorsInUseByAddress[ownerAddress][_operatorsInUseList[ownerAddress][operatorInUseData.indexInArray]].indexInArray = operatorInUseData.indexInArray; - _operatorsInUseList[ownerAddress].pop(); - - delete _operatorsInUseByAddress[ownerAddress][operatorId]; - } - } - } else { - if (_operatorsInUseList[ownerAddress].length > MANAGING_OPERATORS_PER_ACCOUNT_LIMIT) { - revert ExceedManagingOperatorsPerAccountLimit(); - } - - _operatorsInUseByAddress[ownerAddress][operatorId] = OperatorInUse({ index: _operatorIndexOf(operatorId), validatorCount: 1, used: 0, exists: true, indexInArray: uint32(_operatorsInUseList[ownerAddress].length) }); - _operatorsInUseList[ownerAddress].push(operatorId); - } - } - - function _disableOwnerValidatorsUnsafe(address ownerAddress) private { - _updateNetworkEarnings(); - _updateAddressNetworkFee(ownerAddress); - - for (uint32 index = 0; index < _operatorsInUseList[ownerAddress].length; ++index) { - uint32 operatorId = _operatorsInUseList[ownerAddress][index]; - _updateOperatorBalance(operatorId); - OperatorInUse storage operatorInUseData = _operatorsInUseByAddress[ownerAddress][operatorId]; - _updateOperatorUsageByOwner(operatorInUseData, ownerAddress, operatorId); - _operatorDatas[operatorId].activeValidatorCount -= operatorInUseData.validatorCount; - } - - _ssvRegistryContract.disableOwnerValidators(ownerAddress); - - _owners[ownerAddress].validatorsDisabled = true; - } - - function _enableOwnerValidatorsUnsafe(address ownerAddress) private { - _updateNetworkEarnings(); - _updateAddressNetworkFee(ownerAddress); - - for (uint32 index = 0; index < _operatorsInUseList[ownerAddress].length; ++index) { - uint32 operatorId = _operatorsInUseList[ownerAddress][index]; - _updateOperatorBalance(operatorId); - OperatorInUse storage operatorInUseData = _operatorsInUseByAddress[ownerAddress][operatorId]; - _updateOperatorUsageByOwner(operatorInUseData, ownerAddress, operatorId); - _operatorDatas[operatorId].activeValidatorCount += operatorInUseData.validatorCount; - } - - _ssvRegistryContract.enableOwnerValidators(ownerAddress); - - _owners[ownerAddress].validatorsDisabled = false; - } - - function _updateOperatorUsageByOwner(OperatorInUse storage operatorInUseData, address ownerAddress, uint32 operatorId) private { - operatorInUseData.used = _operatorInUseUsageOf(operatorInUseData, ownerAddress, operatorId); - operatorInUseData.index = _operatorIndexOf(operatorId); - } - - function _updateLiquidationThresholdPeriod(uint64 newMinimumBlocksBeforeLiquidation) private { - _minimumBlocksBeforeLiquidation = newMinimumBlocksBeforeLiquidation; - - emit LiquidationThresholdPeriodUpdate(_minimumBlocksBeforeLiquidation); - } - - function _updateOperatorFeeIncreaseLimit(uint64 newOperatorMaxFeeIncrease) private { - _operatorMaxFeeIncrease = newOperatorMaxFeeIncrease; - - emit OperatorFeeIncreaseLimitUpdate(_operatorMaxFeeIncrease); - - } - - function _updateDeclareOperatorFeePeriod(uint64 newDeclareOperatorFeePeriod) private { - _declareOperatorFeePeriod = newDeclareOperatorFeePeriod; - - emit DeclareOperatorFeePeriodUpdate(newDeclareOperatorFeePeriod); - } - - function _updateExecuteOperatorFeePeriod(uint64 newExecuteOperatorFeePeriod) private { - _executeOperatorFeePeriod = newExecuteOperatorFeePeriod; - - emit ExecuteOperatorFeePeriodUpdate(newExecuteOperatorFeePeriod); - } - - function _expensesOf(address ownerAddress) private view returns(uint64) { - uint64 usage = _owners[ownerAddress].used + _addressNetworkFee(ownerAddress); - for (uint32 index = 0; index < _operatorsInUseList[ownerAddress].length; ++index) { - OperatorInUse storage operatorInUseData = _operatorsInUseByAddress[ownerAddress][_operatorsInUseList[ownerAddress][index]]; - usage += _operatorInUseUsageOf(operatorInUseData, ownerAddress, _operatorsInUseList[ownerAddress][index]); - } - - return usage; - } - - function _totalEarningsOf(address ownerAddress) private view returns (uint64) { - uint64 earnings = 0; - uint32[] memory operatorsByOwner = _ssvRegistryContract.getOperatorsByOwnerAddress(ownerAddress); - for (uint32 index = 0; index < operatorsByOwner.length; ++index) { - earnings += _operatorEarningsOf(operatorsByOwner[index]); - } - - return earnings; - } - - function _totalBalanceOf(address ownerAddress) private view returns (uint64) { - uint64 balance = _owners[ownerAddress].deposited + _totalEarningsOf(ownerAddress); - - uint64 usage = _owners[ownerAddress].withdrawn + _expensesOf(ownerAddress); - - if(balance < usage) { - revert NegativeBalance(); - } - - return balance - usage; - } - - function _operatorEarnRate(uint32 operatorId) private view returns (uint64) { - return _ssvRegistryContract.getOperatorFee(operatorId) * _operatorDatas[operatorId].activeValidatorCount; - } - - /** - * @dev See {ISSVNetwork-operatorEarningsOf}. - */ - function _operatorEarningsOf(uint32 operatorId) private view returns (uint64) { - return _operatorDatas[operatorId].earnings + - uint64(block.number - _operatorDatas[operatorId].blockNumber) * - _operatorEarnRate(operatorId); - } - - function _addressNetworkFee(address ownerAddress) private view returns (uint64) { - return _owners[ownerAddress].networkFee + - uint64(_currentNetworkFeeIndex() - _owners[ownerAddress].networkFeeIndex) * - _owners[ownerAddress].activeValidatorCount; - } - - function _burnRate(address ownerAddress) private view returns (uint64 ownerBurnRate) { - if (_owners[ownerAddress].validatorsDisabled) { - return 0; - } - - for (uint32 index = 0; index < _operatorsInUseList[ownerAddress].length; ++index) { - ownerBurnRate += _operatorInUseBurnRateWithNetworkFeeUnsafe(ownerAddress, _operatorsInUseList[ownerAddress][index]); - } - - ownerBurnRate += _owners[ownerAddress].activeValidatorCount * _networkFee; - - uint32[] memory operatorsByOwner = _ssvRegistryContract.getOperatorsByOwnerAddress(ownerAddress); - - for (uint32 index = 0; index < operatorsByOwner.length; ++index) { - if (ownerBurnRate <= _operatorEarnRate(operatorsByOwner[index])) { - return 0; - } else { - ownerBurnRate -= _operatorEarnRate(operatorsByOwner[index]); - } - } - } - - function _overdue(address ownerAddress) private view returns (bool) { - return _totalBalanceOf(ownerAddress) < _minimumBlocksBeforeLiquidation * _burnRate(ownerAddress); - } - - function _liquidatable(address ownerAddress) private view returns (bool) { - return !_owners[ownerAddress].validatorsDisabled && _overdue(ownerAddress); - } - - function _canLiquidate(address ownerAddress) private view returns (bool) { - return !_owners[ownerAddress].validatorsDisabled && (msg.sender == ownerAddress || _overdue(ownerAddress)); - } - - function _getTotalNetworkEarnings() private view returns (uint64) { - uint256 result = _networkEarnings + (block.number - _networkEarningsBlockNumber) * _networkFee * _ssvRegistryContract.activeValidatorCount(); - return uint64(result); - } - - function _getNetworkEarnings() private view returns (uint64) { - return _getTotalNetworkEarnings() - _withdrawnFromTreasury; - } - - /** - * @dev Get operator index by address. - */ - function _operatorIndexOf(uint32 operatorId) private view returns (uint64) { - return _operatorDatas[operatorId].index + - _ssvRegistryContract.getOperatorFee(operatorId) * - uint64(block.number - _operatorDatas[operatorId].indexBlockNumber); - } - - function _operatorInUseUsageOf(OperatorInUse storage operatorInUseData, address ownerAddress, uint32 operatorId) private view returns (uint64) { - return operatorInUseData.used + ( - _owners[ownerAddress].validatorsDisabled ? 0 : - uint64(_operatorIndexOf(operatorId) - operatorInUseData.index) * operatorInUseData.validatorCount - ); - } - - function _operatorInUseBurnRateWithNetworkFeeUnsafe(address ownerAddress, uint32 operatorId) private view returns (uint64) { - OperatorInUse storage operatorInUseData = _operatorsInUseByAddress[ownerAddress][operatorId]; - return _ssvRegistryContract.getOperatorFee(operatorId) * operatorInUseData.validatorCount; - } - - /** - * @dev Returns the current network fee index - */ - function _currentNetworkFeeIndex() private view returns(uint64) { - return _networkFeeIndex + uint64(block.number - _networkFeeIndexBlockNumber) * _networkFee; - } - - function _onlyValidatorOwnerOrContractOwner(bytes calldata publicKey) private view { - address validatorOwner = _ssvRegistryContract.getValidatorOwner(publicKey); - if (validatorOwner == address(0)) { - revert ValidatorWithPublicKeyNotExist(); - } - if (msg.sender != validatorOwner && msg.sender != owner()) { - revert CallerNotValidatorOwner(); - } - } - - function _onlyOperatorOwnerOrContractOwner(uint32 operatorId) private view { - address operatorOwner = _ssvRegistryContract.getOperatorOwner(operatorId); - - if(operatorOwner == address(0)) { - revert OperatorWithPublicKeyNotExist(); - } - - if(msg.sender != operatorOwner && msg.sender != owner()) { - revert CallerNotOperatorOwner(); - } - } - - function _ensureMinimalOperatorFee(uint64 fee) private pure { - if (fee < MINIMAL_OPERATOR_FEE) { - revert FeeTooLow(); - } - } - - function version() external pure override returns (uint32) { - return 20000; - } - - uint256[50] ______gap; -} \ No newline at end of file diff --git a/contracts/SSVRegistry.sol b/contracts/SSVRegistry.sol index 34395a8c..a54fd80d 100644 --- a/contracts/SSVRegistry.sol +++ b/contracts/SSVRegistry.sol @@ -3,311 +3,378 @@ pragma solidity ^0.8.2; import "@openzeppelin/contracts/utils/Counters.sol"; -import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; -import "./utils/VersionedContract.sol"; -import "./utils/Types.sol"; -import "./ISSVRegistry.sol"; +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "hardhat/console.sol"; -contract SSVRegistry is Initializable, OwnableUpgradeable, ISSVRegistry, VersionedContract { +contract SSVRegistryNew { using Counters for Counters.Counter; - using Types256 for uint256; - using Types64 for uint64; + + struct Snapshot { + // block is the last block in which last index was set + uint64 block; + // index is the last index calculated by index += (currentBlock - block) * fee + uint64 index; + // accumulated is all the accumulated earnings, calculated by accumulated + lastIndex * validatorCount + // uint64 accumulated; + } struct Operator { - string name; - bytes publicKey; + address owner; uint64 fee; - address ownerAddress; - uint32 score; - uint32 indexInOwner; - uint32 validatorCount; - bool active; + uint64 validatorCount; + + Snapshot earnings; + } + + struct DAO { + uint64 validatorCount; + uint64 withdrawn; + + Snapshot earnings; } - struct Validator { - uint32[] operatorIds; - address ownerAddress; - uint32 indexInOwner; - bool active; + struct OperatorCollection { + uint64[] operatorIds; } - struct OwnerData { - uint32 activeValidatorCount; - bool validatorsDisabled; - bytes[] validators; + struct Group { + uint64 balance; + uint64 validatorCount; + uint64 lastIndex; } + struct Owner { + uint64 earnRate; + uint64 validatorCount; - Counters.Counter private _lastOperatorId; + Snapshot earnings; + } - mapping(uint32 => Operator) private _operators; - mapping(bytes => Validator) private _validators; - mapping(address => uint32[]) private _operatorsByOwnerAddress; - mapping(address => OwnerData) private _owners; + event OperatorAdded(uint64 operatorId, address indexed owner, bytes encryptionPK); + event OperatorRemoved(uint64 operatorId); + event ValidatorAdded(bytes validatorPK, bytes32 groupId); - uint32 private _activeValidatorCount; + // global vars + Counters.Counter private lastOperatorId; + Counters.Counter private lastGroupId; - uint32 constant private VALIDATORS_PER_OPERATOR_LIMIT = 2000; - uint32 constant private REGISTERED_OPERATORS_PER_ACCOUNT_LIMIT = 10; + // operator vars + mapping(uint64 => Operator) private _operators; + mapping(bytes32 => OperatorCollection) private _operatorCollections; + mapping(address => mapping(bytes32 => Group)) private _groups; + mapping(address => uint64) _availableBalances; + mapping(address => Owner) _owners; - /** - * @dev See {ISSVRegistry-initialize}. - */ - function initialize() external override initializer { - __SSVRegistry_init(); - } + uint64 private _networkFee; + uint64 constant LIQUIDATION_MIN_BLOCKS = 50; + // uint64 constant NETWORK_FEE_PER_BLOCK = 1; - function __SSVRegistry_init() internal onlyInitializing { - __Ownable_init_unchained(); - __SSVRegistry_init_unchained(); - } + DAO private _dao; + IERC20 private _token; - function __SSVRegistry_init_unchained() internal onlyInitializing { + constructor() public { } - /** - * @dev See {ISSVRegistry-registerOperator}. - */ function registerOperator( - string calldata name, - address ownerAddress, - bytes calldata publicKey, + bytes calldata encryptionPK, uint64 fee - ) external onlyOwner override returns (uint32 operatorId) { + ) external returns (uint64 operatorId) { + require(fee > 0); - if (_operatorsByOwnerAddress[ownerAddress].length >= REGISTERED_OPERATORS_PER_ACCOUNT_LIMIT) { - revert ExceedRegisteredOperatorsByAccountLimit(); - } + lastOperatorId.increment(); + operatorId = uint64(lastOperatorId.current()); + _operators[operatorId] = Operator({ owner: msg.sender, earnings: Snapshot({ block: uint64(block.number), index: 0}), validatorCount: 0, fee: fee }); - _lastOperatorId.increment(); - operatorId = uint32(_lastOperatorId.current()); - _operators[operatorId] = Operator({name: name, ownerAddress: ownerAddress, publicKey: publicKey, score: 0, fee: 0, active: true, indexInOwner: uint32(_operatorsByOwnerAddress[ownerAddress].length), validatorCount: 0}); - _operatorsByOwnerAddress[ownerAddress].push(operatorId); - _updateOperatorFeeUnsafe(operatorId, fee); + emit OperatorAdded(operatorId, msg.sender, encryptionPK); } - /** - * @dev See {ISSVRegistry-removeOperator}. - */ - function removeOperator( - uint32 operatorId - ) external onlyOwner override { - Operator storage operator = _operators[operatorId]; + function removeOperator(uint64 operatorId) external { + Operator memory operator = _operators[operatorId]; + require(operator.owner == msg.sender, "not owner"); - if (!operator.active) { - revert OperatorDeleted(); - } + uint64 currentBlock = uint64(block.number); - operator.active = false; - } + Owner memory owner = _owners[operator.owner]; + owner.earnings = _updateOwnerEarnings(owner, currentBlock); + owner.earnRate -= operator.fee * operator.validatorCount; + _owners[operator.owner] = owner; + + _operators[operatorId] = _setFee(operator, 0, currentBlock); + operator.validatorCount = 0; - /** - * @dev See {ISSVRegistry-updateOperatorFee}. - */ - function updateOperatorFee(uint32 operatorId, uint64 fee) external onlyOwner override { - _updateOperatorFeeUnsafe(operatorId, fee); + emit OperatorRemoved(operatorId); } - /** - * @dev See {ISSVRegistry-updateOperatorScore}. - */ - function updateOperatorScore(uint32 operatorId, uint32 score) external onlyOwner override { - Operator storage operator = _operators[operatorId]; - operator.score = score; + function _createOperatorCollection(uint64[] memory operators) private returns (uint64 groupId) { + for (uint64 index = 0; index < operators.length; ++index) { + require(_operators[operators[index]].owner != address(0), "operator not found"); + } + + _operatorCollections[keccak256(abi.encodePacked(operators))] = OperatorCollection({ operatorIds: operators }); } - /** - * @dev See {ISSVRegistry-registerValidator}. - */ function registerValidator( - address ownerAddress, - bytes calldata publicKey, - uint32[] calldata operatorIds, - bytes[] calldata sharesPublicKeys, - bytes[] calldata sharesEncrypted - ) external onlyOwner override { - _validateValidatorParams( - publicKey, - operatorIds, - sharesPublicKeys, - sharesEncrypted - ); - - if (_validators[publicKey].ownerAddress != address(0)) { - revert ValidatorAlreadyExists(); - } + uint64[] memory operatorIds, + bytes calldata validatorPK, + bytes[] calldata encryptedShares, + bytes[] calldata sharesPK, + uint64 amount + ) external { + bytes32 groupId; + { + Operator[] memory operators; + { + OperatorCollection memory operatorCollection; + (groupId, operatorCollection) = _getOrCreateOperatorCollection(operatorIds); + operators = _extractOperators(operatorCollection); + } - _validators[publicKey] = Validator({ - operatorIds: operatorIds, - ownerAddress: ownerAddress, - indexInOwner: uint32(_owners[ownerAddress].validators.length), - active: true - }); + Group memory group; + { + uint64 groupIndex = _groupCurrentIndex(operators); - _owners[ownerAddress].validators.push(publicKey); + _availableBalances[msg.sender] -= amount; - for (uint32 index = 0; index < operatorIds.length; ++index) { - if (!_operators[operatorIds[index]].active) { - revert OperatorDeleted(); + group = _groups[msg.sender][groupId]; + + group.balance = _ownerGroupBalance(group, groupIndex) + amount; + group.lastIndex = groupIndex; + ++group.validatorCount; } - if (++_operators[operatorIds[index]].validatorCount > VALIDATORS_PER_OPERATOR_LIMIT) { - revert ExceedValidatorLimit(); + uint64 currentBlock = uint64(block.number); + { + for (uint64 i = 0; i < operators.length; ++i) { + Owner memory owner = _owners[operators[i].owner]; + owner.earnings = _updateOwnerEarnings(owner, currentBlock); + ++owner.validatorCount; + owner.earnRate += operators[i].fee; + _owners[operators[i].owner] = owner; + } } - } - ++_activeValidatorCount; - } - /** - * @dev See {ISSVRegistry-removeValidator}. - */ - function removeValidator( - bytes calldata publicKey - ) external onlyOwner override { - Validator storage validator = _validators[publicKey]; + { + // // update DAO earnings + DAO memory dao = _dao; + dao = _updateDAOEarnings(dao, uint64(block.number)); + ++dao.validatorCount; + _dao = dao; + } - for (uint32 index = 0; index < validator.operatorIds.length; ++index) { - --_operators[validator.operatorIds[index]].validatorCount; - } + require(!_liquidatable(group.balance, group.validatorCount, operators), "account liquidatable"); - bytes[] storage ownerValidators = _owners[validator.ownerAddress].validators; + _groups[msg.sender][groupId] = group; + } - ownerValidators[validator.indexInOwner] = ownerValidators[ownerValidators.length - 1]; - _validators[ownerValidators[validator.indexInOwner]].indexInOwner = validator.indexInOwner; - ownerValidators.pop(); + emit ValidatorAdded(validatorPK, groupId); + } - --_activeValidatorCount; + // function removeValidator(validatorPK) - delete _validators[publicKey]; + function deposit(uint64 amount) public { + _availableBalances[msg.sender] += amount; } - function enableOwnerValidators(address ownerAddress) external onlyOwner override { - _activeValidatorCount += _owners[ownerAddress].activeValidatorCount; - _owners[ownerAddress].validatorsDisabled = false; - } + function _setFee(Operator memory operator, uint64 fee, uint64 currentBlock) private returns (Operator memory) { + operator.earnings = _updateOperatorIndex(operator, currentBlock); + operator.fee = fee; - function disableOwnerValidators(address ownerAddress) external onlyOwner override { - _activeValidatorCount -= _owners[ownerAddress].activeValidatorCount; - _owners[ownerAddress].validatorsDisabled = true; + return operator; } - function isLiquidated(address ownerAddress) external view override returns (bool) { - return _owners[ownerAddress].validatorsDisabled; + function _updateOperatorIndex(Operator memory operator, uint64 currentBlock) private returns (Snapshot memory) { + return Snapshot({ index: _operatorCurrentIndex(operator), block: currentBlock }); } - /** - * @dev See {ISSVRegistry-operators}. - */ - function getOperatorById(uint32 operatorId) external view override returns (string memory, address, bytes memory, uint256, uint256, uint256, bool) { - Operator storage operator = _operators[operatorId]; - return (operator.name, operator.ownerAddress, operator.publicKey, _operators[operatorId].validatorCount, operator.fee.expand(), operator.score, operator.active); + function _getOrCreateOperatorCollection(uint64[] memory operatorIds) private returns (bytes32, OperatorCollection memory) { + for (uint64 i = 0; i < operatorIds.length - 1;) { + require(operatorIds[i] <= operatorIds[++i]); + } + + bytes32 key = keccak256(abi.encodePacked(operatorIds)); + + OperatorCollection storage operatorCollection = _operatorCollections[key]; + if (operatorCollection.operatorIds.length == 0) { + operatorCollection.operatorIds = operatorIds; + } + + return (key, operatorCollection); } - /** - * @dev See {ISSVRegistry-getOperatorsByOwnerAddress}. - */ - function getOperatorsByOwnerAddress(address ownerAddress) external view override returns (uint32[] memory) { - return _operatorsByOwnerAddress[ownerAddress]; + function _updateOwnerEarnings(Owner memory owner, uint64 currentBlock) private returns (Snapshot memory) { + owner.earnings.index = _ownerCurrentEarnings(owner, currentBlock); + owner.earnings.block = currentBlock; + + return owner.earnings; } - /** - * @dev See {ISSVRegistry-getOperatorsByValidator}. - */ - function getOperatorsByValidator(bytes calldata validatorPublicKey) external view override returns (uint32[] memory operatorIds) { - Validator storage validator = _validators[validatorPublicKey]; + function _updateDAOEarnings(DAO memory dao, uint64 currentBlock) private returns (DAO memory) { + dao.earnings.index = _networkTotalEarnings(dao, currentBlock); + dao.earnings.block = currentBlock; - return validator.operatorIds; + return dao; } - /** - * @dev See {ISSVRegistry-getOperatorOwner}. - */ - function getOperatorOwner(uint32 operatorId) external view override returns (address) { - return _operators[operatorId].ownerAddress; + function _ownerCurrentEarnings(Owner memory owner, uint64 currentBlock) private returns (uint64) { + return owner.earnings.index + (currentBlock - owner.earnings.block) * owner.earnRate; } - /** - * @dev See {ISSVRegistry-getOperatorFee}. - */ - function getOperatorFee(uint32 operatorId) external view override returns (uint64) { - if (_operators[operatorId].ownerAddress == address(0)) { - revert OperatorNotFound(); + function _extractOperators(OperatorCollection memory operatorCollection) private view returns (Operator[] memory) { + Operator[] memory operators = new Operator[](operatorCollection.operatorIds.length); + for (uint64 i = 0; i < operatorCollection.operatorIds.length; ++i) { + operators[i] = _operators[operatorCollection.operatorIds[i]]; } - return _operators[operatorId].fee; + + return operators; } - /** - * @dev See {ISSVRegistry-activeValidatorCount}. - */ - function activeValidatorCount() external view override returns (uint32) { - return _activeValidatorCount; + function _networkTotalEarnings(DAO memory dao, uint64 currentBlock) private view returns (uint64) { + return dao.earnings.index + (currentBlock - dao.earnings.block) * _networkFee * dao.validatorCount; } - /** - * @dev See {ISSVRegistry-validators}. - */ - function validators(bytes calldata publicKey) external view override returns (address, bytes memory, bool) { - Validator storage validator = _validators[publicKey]; + function _networkBalance(DAO memory dao, uint64 currentBlock) private view returns (uint64) { + return _networkTotalEarnings(dao, currentBlock) - dao.withdrawn; + } - return (validator.ownerAddress, publicKey, validator.active); + function _groupCurrentIndex(Operator[] memory operators) private view returns (uint64 groupIndex) { + for (uint64 i = 0; i < operators.length; ++i) { + groupIndex += _operatorCurrentIndex(operators[i]); + } } - /** - * @dev See {ISSVRegistry-getValidatorsByAddress}. - */ - function getValidatorsByAddress(address ownerAddress) external view override returns (bytes[] memory) { - return _owners[ownerAddress].validators; + function _operatorCurrentIndex(Operator memory operator) private view returns (uint64) { + return operator.earnings.index + (uint64(block.number) - operator.earnings.block) * operator.fee; } - /** - * @dev See {ISSVRegistry-getValidatorOwner}. - */ - function getValidatorOwner(bytes calldata publicKey) external view override returns (address) { - return _validators[publicKey].ownerAddress; + function _ownerGroupBalance(Group memory group, uint64 currentGroupIndex) private pure returns (uint64) { + return group.balance - (currentGroupIndex - group.lastIndex) * group.validatorCount; } - /** - * @dev See {ISSVRegistry-validatorsPerOperatorCount}. - */ - function validatorsPerOperatorCount(uint32 operatorId) external view override returns (uint32) { - return _operators[operatorId].validatorCount; + function _burnRatePerValidator(Operator[] memory operators) private pure returns (uint64 rate) { + for (uint64 i = 0; i < operators.length; ++i) { + rate += operators[i].fee; + } } - /** - * @dev See {ISSVRegistry-updateOperatorFee}. - */ - function _updateOperatorFeeUnsafe(uint32 operatorId, uint64 fee) private { - _operators[operatorId].fee = fee; + function _liquidatable(uint64 balance, uint64 validatorCount, Operator[] memory operators) private view returns (bool) { + return balance < LIQUIDATION_MIN_BLOCKS * (_burnRatePerValidator(operators) + _networkFee) * validatorCount; } - /** - * @dev Validates the paramss for a validator. - * @param publicKey Validator public key. - * @param operatorIds Operator operatorIds. - * @param sharesPublicKeys Shares public keys. - * @param encryptedKeys Encrypted private keys. - */ - function _validateValidatorParams( - bytes calldata publicKey, - uint32[] calldata operatorIds, - bytes[] calldata sharesPublicKeys, - bytes[] calldata encryptedKeys - ) private pure { - if (publicKey.length != 48) { - revert InvalidPublicKeyLength(); + function liquidate(address owner, bytes32 groupId) external { + OperatorCollection memory operatorCollection = _operatorCollections[groupId]; + Operator[] memory operators = new Operator[](operatorCollection.operatorIds.length); + for (uint64 i = 0; i < operatorCollection.operatorIds.length; ++i) { + operators[i] = _operators[operatorCollection.operatorIds[i]]; } - if ( - operatorIds.length != sharesPublicKeys.length || - operatorIds.length != encryptedKeys.length || - operatorIds.length < 4 || operatorIds.length % 3 != 1 - ) { - revert OessDataStructureInvalid(); + uint64 groupIndex = _groupCurrentIndex(operators); + Group memory group = _groups[owner][groupId]; + uint64 balance = _ownerGroupBalance(group, groupIndex); + require(_liquidatable(balance, group.validatorCount, operators)); + _availableBalances[msg.sender] += balance; + uint64 currentBlock = uint64(block.number); + { + for (uint64 i = 0; i < operators.length; ++i) { + Owner memory owner = _owners[operators[i].owner]; + owner.earnings = _updateOwnerEarnings(owner, currentBlock); + owner.earnRate -= operators[i].fee; + --owner.validatorCount; + _owners[operators[i].owner] = owner; + } } } - function version() external pure override returns (uint32) { - return 1; - } - - uint256[50] ______gap; +// function addOperatorToValidator( +// function _validateRegistryState( +// uint64[] memory usedOperators, +// uint64[] memory validatorCnt, +// bytes32 root +// ) private view { +// require(_registryStateRoot(usedOperators, validatorCnt) == root, "operator registry hash invalid"); +// } +// +// uint16 constant OPERATORS_INDX = 0; +// uint16 constant OPERATORS_CNT_INDX = 1; +// uint16 constant USED_OPERATORS_INDX = 2; +// uint16 constant SHARES_PK_INDX = 0; +// uint16 constant ENCRYPTED_SHARES_INDX = 1; +// function registerValidator( +// uint64[][] memory db, +// bytes calldata validatorPK, +// bytes[][] calldata shares +// ) external { +// uint64 currentBlock = uint64(block.number); +// Validator memory validator = validators[msg.sender]; +// DAO memory _dao = dao; +// +// _validateRegistryState(db[OPERATORS_INDX], db[OPERATORS_CNT_INDX], validator.operatorRegistryHash); +// +// for (uint64 index = 0; index < db[USED_OPERATORS_INDX].length; ++index) { +// uint64 id = db[OPERATORS_INDX][db[USED_OPERATORS_INDX][index]]; +// // update and save operator +// uint64 operatorLastIndex = _updateOperatorCurrentIndex(id, currentBlock); +// +// // update operator in use +// validator.aggregatedIndex.lastIndex += operatorLastIndex; +// db[1][db[USED_OPERATORS_INDX][index]] ++; +// } +// validator.aggregatedIndex.validatorCount ++; +// validator.operatorRegistryHash = _registryStateRoot(db[OPERATORS_INDX], db[OPERATORS_CNT_INDX]); +// +// // update DAO earnings +// uint64 indexChange = (currentBlock - _dao.index.block)*NETWORK_FEE_PER_BLOCK; +// _dao.index.lastIndex += indexChange; +// _dao.index.block = currentBlock; +// _dao.index.accumulated += indexChange * _dao.index.validatorCount; +// _dao.index.validatorCount++; +// // update validator DAO debt +// validator.aggregatedIndex.lastIndex += _dao.index.lastIndex; +// +// // save to storage +// validators[msg.sender] = validator; +// dao = _dao; +// +//// require(_liquidatable(validator, db, _dao.index.lastIndex, currentBlock) == false, "not enough ssv in balance"); +// +// emit ValidatorAdded(validatorPK); +// } +// +// function daoCurrentIndex(DAO memory _dao, uint64 currentBlock) private view returns (uint64) { +// return _dao.index.lastIndex + (currentBlock - _dao.index.block)*NETWORK_FEE_PER_BLOCK; +// } +// + +// // function liquidatable( +// // address account, +// // uint64[][] calldata db +// // ) public view returns (bool) { +// // Validator memory validator = validators[account]; +// // uint64 currentBlock = uint64(block.number); +// // uint64 daoIndex = daoCurrentIndex(dao, currentBlock); +// // return _liquidatable(validator, db, daoIndex, currentBlock); +// // } +// // +// function balanceOf() public view returns (uint64) { +// return 1000000; // hard coded for now +// } + +// function _validatorLifetimeCost( +// DebtIndex memory debtIndex, +// uint64[] memory usedOperators, +// uint64 validatorCnt, +// uint64 daoCurrentIndex, +// uint64 currentBlock +// ) private view returns (uint64) { +// uint64 aggregatedCurrentIndex = 0; + +// for (uint256 index = 0; index < usedOperators.length; ++index) { +// uint64 operatorId = usedOperators[index]; +// Operator memory operator = _operators[usedOperators[index]]; +// aggregatedCurrentIndex += operatorCurrentIndex(operator, currentBlock) * validatorCnt; +// } + +// aggregatedCurrentIndex += daoCurrentIndex * validatorCnt; +// uint64 accumulatedCost = debtIndex.accumulated + (aggregatedCurrentIndex - debtIndex.lastIndex); + +// return accumulatedCost; +// } } diff --git a/contracts/mocks/SSVTokenMock.sol b/contracts/mocks/SSVTokenMock.sol deleted file mode 100644 index b04a74aa..00000000 --- a/contracts/mocks/SSVTokenMock.sol +++ /dev/null @@ -1,22 +0,0 @@ -//SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity ^0.8.13; -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 - */ - function mint(address to, uint256 amount) external onlyOwner { - _mint(to, amount); - } -} diff --git a/contracts/utils/Types.sol b/contracts/utils/Types.sol deleted file mode 100644 index 660b8659..00000000 --- a/contracts/utils/Types.sol +++ /dev/null @@ -1,18 +0,0 @@ -// File: contracts/SSVNetwork.sol -// SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity ^0.8.2; - -uint64 constant DEDUCTED_DIGITS = 10000000; - -library Types64 { - function expand(uint64 value) internal pure returns (uint256) { - return uint256(value) * DEDUCTED_DIGITS; - } -} - -library Types256 { - function shrink(uint256 value) internal pure returns (uint64) { - require(value % DEDUCTED_DIGITS == 0, "Precision is over the maximum defined"); - return uint64(value / DEDUCTED_DIGITS); - } -} \ No newline at end of file diff --git a/contracts/utils/Utils.sol b/contracts/utils/Utils.sol deleted file mode 100644 index c69e295c..00000000 --- a/contracts/utils/Utils.sol +++ /dev/null @@ -1,14 +0,0 @@ -// File: contracts/SSVNetwork.sol -// SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity ^0.8.2; - -contract Utils { - - function blockNumber() external view returns (uint256) { - return block.number; - } - - function blockTimestamp() external view returns (uint256) { - return block.timestamp; - } -} \ No newline at end of file diff --git a/contracts/utils/VersionedContract.sol b/contracts/utils/VersionedContract.sol deleted file mode 100644 index 7dfc4ecc..00000000 --- a/contracts/utils/VersionedContract.sol +++ /dev/null @@ -1,8 +0,0 @@ -// File: contracts/utils/VersionedContract.sol -// SPDX-License-Identifier: GPL-3.0-or-later - -pragma solidity ^0.8.2; - -interface VersionedContract { - function version() external pure returns (uint32); -} diff --git a/docs/_config.yml b/docs/_config.yml deleted file mode 100644 index 2f7efbea..00000000 --- a/docs/_config.yml +++ /dev/null @@ -1 +0,0 @@ -theme: jekyll-theme-minimal \ No newline at end of file diff --git a/hardhat.config.ts b/hardhat.config.ts index 2e80dc10..1a4d06bc 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -34,6 +34,10 @@ const config: HardhatUserConfig = { // Your API key for Etherscan // Obtain one at https://etherscan.io/ apiKey: process.env.ETHERSCAN_KEY + }, + gasReporter: { + currency: 'USD', + gasPrice: 0.3 } }; diff --git a/scripts/ssv-network-deploy.ts b/scripts/ssv-network-deploy.ts deleted file mode 100644 index ef325e3a..00000000 --- a/scripts/ssv-network-deploy.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { ethers, upgrades } from 'hardhat'; -import { publishAbi } from './utils'; - -async function main() { - await publishAbi('SSVNetwork'); - - const ssvRegistryAddress = process.env.SSVREGISTRY_ADDRESS; - const ssvTokenAddress = process.env.SSVTOKEN_ADDRESS; - const ssvNetworkFactory = await ethers.getContractFactory('SSVNetwork'); - console.log(`Deploying SSVNetwork with ssvRegistry ${ssvRegistryAddress} and ssvToken ${ssvTokenAddress}...`); - const contract = await upgrades.deployProxy(ssvNetworkFactory, [ - ssvRegistryAddress, - ssvTokenAddress, - process.env.MINIMUM_BLOCKS_BEFORE_LIQUIDATION, - process.env.OPERATOR_MAX_FEE_INCREASE, - process.env.DECLARE_OPERATOR_FEE_PERIOD, - process.env.EXECUTE_OPERATOR_FEE_PERIOD, - ]); - await contract.deployed(); - console.log(`SSVNetwork deployed to: ${contract.address}`); -} - -main() - .then(() => process.exit(0)) - .catch(error => { - console.error(error); - process.exit(1); - }); \ No newline at end of file diff --git a/scripts/ssv-network-upgrade.ts b/scripts/ssv-network-upgrade.ts deleted file mode 100644 index a95e48c1..00000000 --- a/scripts/ssv-network-upgrade.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { ethers, upgrades } from 'hardhat'; -import { publishAbi } from './utils'; - -async function main() { - await publishAbi('SSVNetwork'); - - const proxyAddress = process.env.PROXY_ADDRESS || ''; - const ContractUpgraded = await ethers.getContractFactory('SSVNetwork'); - console.log('Running upgrade...'); - const newContract = await upgrades.upgradeProxy(proxyAddress, ContractUpgraded); - console.log(`SSVNetwork upgraded at: ${newContract.address}`); -} - -main() - .then(() => process.exit(0)) - .catch(error => { - console.error(error); - process.exit(1); - }); diff --git a/scripts/utils.ts b/scripts/utils.ts deleted file mode 100644 index 9bc8767d..00000000 --- a/scripts/utils.ts +++ /dev/null @@ -1,58 +0,0 @@ -const fs = require('fs'); -const simpleGit = require("simple-git"); -const ghpages = require('gh-pages'); -const hre = require('hardhat'); -const prompts = require('prompts'); - -const git = simpleGit.default(); - -export async function publishAbi(name: string) { - const { all } = await git.tags(); - const gitTagChoices = [ - { title: '[create new tag]', description: 'Create new git tag before contract deployment', value: 'create-tag' }, - ...all.map((tag: any) => ({ title: tag, value: tag })) - ]; - const response = await prompts([ - { - type: 'select', - name: 'gitTag', - message: 'Git tag to deploy?', - choices: gitTagChoices - }, - { - type: (prev: any) => prev === 'create-tag' ? 'text' : null, - name: 'newTag', - message: `Tag name?`, - validate: (value: any) => value === '' ? `Sorry, git tag can't be null` : true - }, - { - type: (prev: any, values: any) => values.gitTag === 'create-tag' ? 'toggle' : null, - name: 'createTag', - initial: true, - active: 'yes', - inactive: 'no', - message: 'Create and publish new tag?' - } - ]); - - let tag = null; - if (response.createTag) { - await git.addAnnotatedTag(response.newTag, `new version ${response.newTag}`); - await git.push('origin', response.newTag); - tag = response.newTag; - } else if (response.gitTag !== 'create-tag') { - tag = response.gitTag; - } - - if (!tag) throw 'Please select git tag to deploy the contract.'; - - const fullNames = await hre.artifacts.getAllFullyQualifiedNames(); - const contract = fullNames.find((item: string) => item.includes(`/${name}.sol`)); - - const { abi, contractName } = await hre.artifacts.readArtifact(contract); - const dir = `${hre.config.paths.root}/dist`; - await fs.promises.mkdir(`${dir}/abi/${tag}`, { recursive: true }); - await fs.promises.writeFile(`${dir}/abi/${tag}/${contractName.toLowerCase()}.json`, `${JSON.stringify(abi, null, 2)}\n`, { flag: 'w' }); - await ghpages.publish(dir); - console.log(`> ${name} contract abi published to:`, `https://bloxapp.github.io/ssv-network/abi/${tag}/${contractName.toLowerCase()}.json`); -} \ No newline at end of file diff --git a/test/e2e/balances.ts b/test/e2e/balances.ts deleted file mode 100644 index 19a61c91..00000000 --- a/test/e2e/balances.ts +++ /dev/null @@ -1,94 +0,0 @@ -// Balances E2E Test - -// Declare all imports -import { - initContracts, - registerOperator, - registerValidator, - updateOperatorFee, - processTestCase, - updateNetworkFee, - account1, - account2 -} from '../helpers/setup' - -import { - checkOperatorBalances, - checkTotalBalance, - checkTotalEarnings, - checkNetworkTreasury -} from '../helpers/asserts' - -describe('SSV Network', function () { - beforeEach(async function () { - await initContracts() - }) - - it('Operator and validator balances', async function () { - const testFlow = { - 10: { - funcs: [ - () => updateNetworkFee(20000000), - () => registerOperator([ - { account: account2, idx: 0, fee: 20000000 }, - { account: account2, idx: 1, fee: 40000000 }, - { account: account1, idx: 2, fee: 50000000 }, - { account: account2, idx: 3, fee: 30000000 } - ]) - ], - asserts: [ - () => checkNetworkTreasury() - ] - }, - 20: { - funcs: [ - () => registerValidator([{ account: account1, validatorIdx: 0, operatorIdxs: [0, 1, 2, 3], depositAmount: 1000000000 },]) - ], - asserts: [ - () => checkOperatorBalances([0, 1, 2, 3]), - () => checkNetworkTreasury() - ] - }, - 30: { - funcs: [ - () => updateOperatorFee(account2, 0, 11000), - () => registerValidator([{ account: account1, validatorIdx: 1, operatorIdxs: [0, 1, 2, 3], depositAmount: 1000000000 },]) - ], - asserts: [ - () => checkOperatorBalances([0, 1, 2, 3]), - () => checkNetworkTreasury() - ] - }, - 40: { - funcs: [ - () => registerValidator([{ account: account1, validatorIdx: 2, operatorIdxs: [0, 1, 2, 3], depositAmount: 1000000000 },]) - ], - asserts: [ - () => checkOperatorBalances([0, 1, 2, 3]), - () => checkNetworkTreasury() - ] - }, - 50: { - funcs: [ - () => registerValidator([{ account: account1, validatorIdx: 3, operatorIdxs: [0, 1, 2, 3], depositAmount: 1000000000 },]) - ], - asserts: [ - () => checkOperatorBalances([0, 1, 2, 3]), - () => checkTotalBalance([account1.address, account2.address]), - () => checkTotalEarnings([account1.address, account2.address]), - () => checkNetworkTreasury() - ] - }, - 100: { - asserts: [ - () => checkOperatorBalances([0, 1, 2, 3]), - () => checkTotalBalance([account1.address, account2.address]), - () => checkTotalEarnings([account1.address, account2.address]), - () => checkNetworkTreasury() - ] - } - } - - // await processTestCase(testFlow) - }) -}) \ No newline at end of file diff --git a/test/e2e/deposit.ts b/test/e2e/deposit.ts deleted file mode 100644 index 78e231f5..00000000 --- a/test/e2e/deposit.ts +++ /dev/null @@ -1,65 +0,0 @@ -// Deposit E2E Test - -// Declare all imports -import { - initContracts, - registerOperator, - registerValidator, - deposit, - processTestCase, - account1, - account2 -} from '../helpers/setup' - -import { - checkTotalBalance, - checkTotalEarnings -} from '../helpers/asserts' - -describe('SSV Network', function () { - beforeEach(async function () { - await initContracts() - }) - - it('Deposit', async function () { - const testFlow = { - 10: { - funcs: [ - () => registerOperator([ - { account: account2, idx: 0, fee: 20000 }, - { account: account2, idx: 1, fee: 10000 }, - { account: account1, idx: 2, fee: 10000 }, - { account: account2, idx: 3, fee: 30000 } - ]) - ], - asserts: [] - }, - 20: { - funcs: [ - () => registerValidator([{ account: account1, validatorIdx: 0, operatorIdxs: [0, 1, 2, 3], depositAmount: 1000000000 },]) - ], - asserts: [ - () => checkTotalBalance([account1.address, account2.address]), - () => checkTotalEarnings([account1.address, account2.address]) - ] - }, - 30: { - funcs: [ - () => deposit(account1, 5000) - ], - asserts: [ - () => checkTotalBalance([account1.address, account2.address]), - () => checkTotalEarnings([account1.address, account2.address]) - ] - }, - 40: { - asserts: [ - () => checkTotalBalance([account1.address, account2.address]), - () => checkTotalEarnings([account1.address, account2.address]) - ] - } - } - - // await processTestCase(testFlow) - }) -}) \ No newline at end of file diff --git a/test/e2e/validator.ts b/test/e2e/validator.ts deleted file mode 100644 index dbed00e6..00000000 --- a/test/e2e/validator.ts +++ /dev/null @@ -1,80 +0,0 @@ -// Validator E2E Test - -// Declare all imports -import { - initContracts, - registerOperator, - registerValidator, - updateValidator, - removeValidator, - processTestCase, - updateNetworkFee, - account1, - account2 -} from '../helpers/setup' - -import { - checkOperatorBalances, - checkTotalBalance, - checkTotalEarnings, - checkNetworkTreasury -} from '../helpers/asserts' - -describe('SSV Network', function () { - beforeEach(async function () { - await initContracts() - }) - - it('Operator and validator balances', async function () { - const testFlow = { - 10: { - funcs: [ - () => updateNetworkFee(10000), - () => registerOperator([ - { account: account2, idx: 0, fee: 20000 }, - { account: account2, idx: 1, fee: 10000 }, - { account: account1, idx: 2, fee: 10000 }, - { account: account2, idx: 3, fee: 30000 } - ]) - ], - asserts: [ - () => checkNetworkTreasury() - ] - }, - 20: { - funcs: [ - () => registerValidator([{ account: account1, validatorIdx: 0, operatorIdxs: [0, 1, 2, 3], depositAmount: 2000000000 },]) - ], - asserts: [ - () => checkOperatorBalances([0, 1, 2, 3]), - () => checkNetworkTreasury() - ] - }, - 100: { - funcs: [ - () => updateValidator(account1, 0, [0, 1, 2, 3], 2500000000) - ] - }, - 140: { - asserts: [ - () => checkTotalBalance([account1.address, account2.address]), - () => checkNetworkTreasury() - ] - }, - 150: { - funcs: [ - () => removeValidator(account1, 0) - ] - }, - 180: { - asserts: [ - () => checkTotalBalance([account1.address, account2.address]), - () => checkTotalEarnings([account1.address, account2.address]), - () => checkNetworkTreasury() - ] - } - } - - // await processTestCase(testFlow) - }) -}) \ No newline at end of file diff --git a/test/e2e/withdraw.ts b/test/e2e/withdraw.ts deleted file mode 100644 index 563b380f..00000000 --- a/test/e2e/withdraw.ts +++ /dev/null @@ -1,69 +0,0 @@ -// Withdraw E2E Test - -// Declare all imports -import { - initContracts, - registerOperator, - registerValidator, - withdraw, - processTestCase, - account1, - account2 -} from '../helpers/setup' - -import { - checkWithdrawFail, - checkTotalBalance, - checkTotalEarnings -} from '../helpers/asserts' - -describe('SSV Network', function () { - beforeEach(async function () { - await initContracts() - }) - - it('Withdraw', async function () { - const testFlow = { - 10: { - funcs: [ - () => registerOperator([ - { account: account2, idx: 0, fee: 20000 }, - { account: account2, idx: 1, fee: 10000 }, - { account: account1, idx: 2, fee: 10000 }, - { account: account2, idx: 3, fee: 30000 } - ]) - ] - }, - 20: { - funcs: [ - () => registerValidator([{ account: account1, validatorIdx: 0, operatorIdxs: [0, 1, 2, 3], depositAmount: 1000000000 },]) - ], - asserts: [ - () => checkTotalBalance([account1.address, account2.address]), - () => checkTotalEarnings([account1.address, account2.address]) - ] - }, - 100: { - funcs: [ - () => withdraw(account2, 500000000) - ], - asserts: [ - () => checkTotalBalance([account1.address, account2.address]), - () => checkTotalEarnings([account1.address, account2.address]) - ] - }, - 110: { - asserts: [() => checkWithdrawFail(account2, 10000000000000)] - }, - 120: { - asserts: [ - // () => checkTotalBalance([account1.address, account2.address]), - () => checkTotalEarnings([account1.address, account2.address]), - () => checkWithdrawFail(account2, 1000000000) - ] - } - } - - // await processTestCase(testFlow) - }) -}) \ No newline at end of file diff --git a/test/helpers/asserts.ts b/test/helpers/asserts.ts deleted file mode 100644 index e6a9cab4..00000000 --- a/test/helpers/asserts.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { ethers, upgrades } from 'hardhat'; -import * as chai from 'chai'; -import * as chaiAsPromised from 'chai-as-promised'; -const { expect } = chai; - -import { - operatorsIds, - operatorEarningsOf, - addressBalanceOf, - totalEarningsOf, - getNetworkTreasury, - ssvNetwork, -} from './setup'; - -//@ts-ignore -export const checkOperatorBalances = async (operatorIdxs) => { - for (const oidx of operatorIdxs) { - console.log(` | Operator Balance > [OPERATOR] ${oidx} | [VALUE] ${+await operatorEarningsOf(oidx)}`); - // expect(+await ssvNetwork.getOperatorEarnings(operatorsIds[oidx])).to.equal(+await operatorEarningsOf(oidx)); - } -} - -//@ts-ignore -export const checkTotalBalance = async (addresses) => { - for (const address of addresses) { - console.log(` | Total balance > [ADDRESS] ${address} | [VALUE] ${+await addressBalanceOf(address)} | [BLOCKCHAIN] ${await ssvNetwork.getAddressBalance(address)}`); - expect(+await ssvNetwork.getAddressBalance(address)).to.equal(+await addressBalanceOf(address)); - } -} - -//@ts-ignore -export const checkTotalEarnings = async (addresses) => { - for (const address of addresses) { - console.log(` | Total Earnings > [ADDRESS] ${address} | [VALUE] ${+await totalEarningsOf(address)}`); // | [BLOCKCHAIN] ${await ssvNetwork.getAddressEarnings(address)} - // expect(+await ssvNetwork.getAddressEarnings(address)).to.equal(+await totalEarningsOf(address)); - } -} - -//@ts-ignore -export const checkLiquidationStatus = async (address, result) => { - console.log(` | Liquidation Status > [ADDRESS] ${address} | [STATUS] ${await ssvNetwork.isLiquidatable(address)}`); // | [BLOCKCHAIN] ${await ssvNetwork.getAddressEarnings(address)} - expect(await ssvNetwork.isLiquidatable(address)).to.equal(result) -} - -//@ts-ignore -export const checkWithdrawFail = async (account, amount) => await expect(ssvNetwork.connect(account).withdraw(`${amount}`)).to.be.revertedWith('NotEnoughBalance'); - -export const checkNetworkTreasury = async () => { - console.log("====>", await ssvNetwork.getNetworkEarnings(), await getNetworkTreasury()) - expect(await ssvNetwork.getNetworkEarnings()).to.equal(await getNetworkTreasury()) -}; \ No newline at end of file diff --git a/test/helpers/setup.ts b/test/helpers/setup.ts deleted file mode 100644 index 6a22167e..00000000 --- a/test/helpers/setup.ts +++ /dev/null @@ -1,351 +0,0 @@ -import { ethers, upgrades } from 'hardhat'; -import { progressTime, progressBlocks, snapshot, mine } from './utils'; - -declare var network: any; - -const operatorPublicKeyPrefix = '12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345'; -const validatorPublicKeyPrefix = '98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765'; -const minimumBlocksBeforeLiquidation = 7000; -const operatorMaxFeeIncrease = 10; - -//@ts-ignore -export let ssvToken: any, ssvRegistry: any, ssvNetwork: any, utils: any; -//@ts-ignore -export let owner: any, account1: any, account2: any, account3: any, account4: any; - -export const operatorsPub = Array.from(Array(10).keys()).map(k => `0x${operatorPublicKeyPrefix}${k}`); -export const validatorsPub = Array.from(Array(10).keys()).map(k => `0x${validatorPublicKeyPrefix}${k}`); -export const operatorsIds = Array.from(Array(10).keys()).map(k => k + 1); - -const DAY = 86400; -const YEAR = 365 * DAY; - -const setOperatorFeePeriod = 0; -const approveOperatorFeePeriod = DAY; - -const operatorData: any = []; -const addressData: any = {}; -const globalData: any = {}; - -export const initContracts = async () => { - [owner, account1, account2, account3] = await ethers.getSigners(); - - // for tests - initGlobalData(); - initAddressData(account1.address); - initAddressData(account2.address); - initAddressData(account3.address); - // - const utilsFactory = await ethers.getContractFactory('Utils'); - const ssvTokenFactory = await ethers.getContractFactory('SSVTokenMock'); - const ssvRegistryFactory = await ethers.getContractFactory('SSVRegistry'); - const ssvNetworkFactory = await ethers.getContractFactory('SSVNetwork'); - utils = await utilsFactory.deploy(); - ssvToken = await ssvTokenFactory.deploy(); - ssvRegistry = await upgrades.deployProxy(ssvRegistryFactory, { initializer: false }); - await utils.deployed(); - await ssvToken.deployed(); - await ssvRegistry.deployed(); - ssvNetwork = await upgrades.deployProxy(ssvNetworkFactory, [ssvRegistry.address, ssvToken.address, minimumBlocksBeforeLiquidation, operatorMaxFeeIncrease, setOperatorFeePeriod, approveOperatorFeePeriod]); - await ssvNetwork.deployed(); - await ssvToken.mint(account1.address, '100000000000'); - await ssvToken.mint(account2.address, '100000000000'); -} - -const initGlobalData = () => { - globalData.networkFeeIndexBlockNumber = 0; - globalData.networkFeeIndex = 0; - globalData.networkFee = 0; - globalData.validatorCount = 0; - globalData.networkEarnings = 0; - globalData.networkEarningsBlockNumber = 0; - globalData.withdrawnFromTreasury = 0; -} -//@ts-ignore -const initAddressData = (address) => { - addressData[address] = { - operatorIdxs: [], - operatorsInUse: {}, - validatorOperators: {}, - used: 0, - withdrawn: 0, - deposited: 0, - earned: 0, - networkFee: 0, - networkFeeIndex: 0, - activeValidators: 0, - } -}; - -const globalNetworkFeeIndex = async () => { - return globalData.networkFeeIndex + - (+await utils.blockNumber() - globalData.networkFeeIndexBlockNumber) * - globalData.networkFee; -} -//@ts-ignore -export const operatorIndexOf = async (idx) => { - const currentBlockNumber = await utils.blockNumber(); - const value = operatorData[idx].index + - (currentBlockNumber - operatorData[idx].indexBlockNumber) * - operatorData[idx].fee; - return value; -} -//@ts-ignore -const operatorExpenseOf = async (address, oidx) => { - return addressData[address].operatorsInUse[oidx].used + - (await operatorIndexOf(oidx) - addressData[address].operatorsInUse[oidx].index) * - addressData[address].operatorsInUse[oidx].validatorsCount; -} -//@ts-ignore -export const operatorEarningsOf = async (idx) => { - const currentBlockNumber = await utils.blockNumber(); - const value = operatorData[idx].balance + - (currentBlockNumber - operatorData[idx].blockNumber) * - operatorData[idx].fee * operatorData[idx].validatorsCount; - return value; -} -//@ts-ignore -export const addressNetworkFee = async (address) => { - let { - activeValidators, - networkFee, - networkFeeIndex, - } = addressData[address]; - return networkFee + - (+await globalNetworkFeeIndex() - networkFeeIndex) * activeValidators; -} -//@ts-ignore -export const addressBalanceOf = async (address) => { - let { - deposited, - withdrawn, - networkFee, - used, - operatorsInUse, - } = addressData[address]; - let total = deposited; - - total += await totalEarningsOf(address); - - for (const oidx of Object.keys(operatorsInUse)) { - used += await operatorExpenseOf(address, oidx); - } - - total -= withdrawn + used + await addressNetworkFee(address); - - return total; -} -//@ts-ignore -export const totalEarningsOf = async (address) => { - let { - earned, - operatorIdxs, - } = addressData[address]; - - let total = earned; - - for (const oidx of operatorIdxs) { - total += await operatorEarningsOf(oidx); - } - - return total; -} -//@ts-ignore -export const registerOperator = async (operators) => { - for (const operatorObject of operators) { - await ssvNetwork.connect(operatorObject.account).registerOperator(`testOperator ${operatorObject.idx}`, operatorsPub[operatorObject.idx], operatorObject.fee); - await progressBlocks(1); - const fee = operatorObject.fee - operatorData[operatorObject.idx] = { - fee, - blockNumber: await utils.blockNumber(), - indexBlockNumber: await utils.blockNumber(), - index: 0, - validatorsCount: 0, - balance: 0, - }; - - addressData[operatorObject.account.address].operatorIdxs.push(operatorObject.idx); - console.log(` | Register operator ${operatorObject.idx} > [ADDRESS] ${operatorObject.account.address} | [ACTUAL_BLOCK] ${await utils.blockNumber()}`); - } -} -//@ts-ignore -export const registerValidator = async (validators) => { - for (const validatorObject of validators) { - await ssvToken.connect(validatorObject.account).approve(ssvNetwork.address, validatorObject.depositAmount); - await ssvNetwork.connect(validatorObject.account).registerValidator( - validatorsPub[validatorObject.validatorIdx], - validatorObject.operatorIdxs.map((oidx: number) => operatorsIds[oidx]), - validatorObject.operatorIdxs.map((oidx: number) => operatorsPub[oidx]), - validatorObject.operatorIdxs.map((oidx: number) => operatorsPub[oidx]), - `${validatorObject.depositAmount}`, - ); - console.log(`[ACTUAL_BLOCK] ${await utils.blockNumber()}`) - await progressBlocks(1); - await updateAddressNetworkFee(validatorObject.account.address); - await updateNetworkEarnings(); - addressData[validatorObject.account.address].validatorOperators[validatorObject.validatorIdx] = []; - for (const oidx of validatorObject.operatorIdxs) { - await updateOperatorBalance(oidx); - operatorData[oidx].validatorsCount += 1; - addressData[validatorObject.account.address].operatorsInUse[oidx] = addressData[validatorObject.account.address].operatorsInUse[oidx] || { validatorsCount: 0, index: 0, used: 0 }; - addressData[validatorObject.account.address].operatorsInUse[oidx].used = await operatorExpenseOf(validatorObject.account.address, oidx); - addressData[validatorObject.account.address].operatorsInUse[oidx].validatorsCount += 1; - addressData[validatorObject.account.address].operatorsInUse[oidx].index = await operatorIndexOf(oidx); - // - addressData[validatorObject.account.address].validatorOperators[validatorObject.validatorIdx].push(oidx); - }; - addressData[validatorObject.account.address].activeValidators++; - addressData[validatorObject.account.address].deposited += validatorObject.depositAmount; - globalData.validatorCount++; - - console.log(` | Register validator ${validatorObject.validatorIdx} > [ADDRESS] ${validatorObject.account.address} [ACTUAL_BLOCK] ${await utils.blockNumber()}`); - } -} -//@ts-ignore -export const updateValidator = async (account, validatorIdx, operatorIdxs, depositAmount) => { - await ssvToken.connect(account).approve(ssvNetwork.address, depositAmount); - await ssvNetwork.connect(account).updateValidator( - validatorsPub[validatorIdx], - operatorIdxs.map((oidx: number) => operatorsIds[oidx]), - operatorIdxs.map((oidx: number) => operatorsPub[oidx]), - operatorIdxs.map((oidx: number) => operatorsPub[oidx]), - `${depositAmount}`, - ); - await progressBlocks(1); - for (const oidx of addressData[account.address].validatorOperators[validatorIdx]) { - await updateOperatorBalance(oidx); - operatorData[oidx].validatorsCount -= 1; - addressData[account.address].operatorsInUse[oidx].used = await operatorExpenseOf(account.address, oidx); - addressData[account.address].operatorsInUse[oidx].validatorsCount -= 1; - addressData[account.address].operatorsInUse[oidx].index = await operatorIndexOf(oidx); - } - addressData[account.address].validatorOperators[validatorIdx] = []; - - for (const oidx of operatorIdxs) { - await updateOperatorBalance(oidx); - operatorData[oidx].validatorsCount += 1 - addressData[account.address].operatorsInUse[oidx] = addressData[account.address].operatorsInUse[oidx] || { validatorsCount: 0, index: 0, used: 0 }; - addressData[account.address].operatorsInUse[oidx].used = await operatorExpenseOf(account.address, oidx); - addressData[account.address].operatorsInUse[oidx].validatorsCount += 1; - addressData[account.address].operatorsInUse[oidx].index = await operatorIndexOf(oidx); - - addressData[account.address].validatorOperators[validatorIdx].push(oidx); - }; - addressData[account.address].deposited += depositAmount; - console.log(` | Update validator ${validatorIdx} > [ACTUAL_BLOCK] ${await utils.blockNumber()}`); -} -//@ts-ignore -export const removeValidator = async (account, validatorIdx) => { - await ssvNetwork.connect(account).removeValidator(validatorsPub[validatorIdx]); - await progressBlocks(1); - await updateNetworkEarnings(); - await updateAddressNetworkFee(account.address); - for (const oidx of addressData[account.address].validatorOperators[validatorIdx]) { - await updateOperatorBalance(oidx); - operatorData[oidx].validatorsCount -= 1; - addressData[account.address].operatorsInUse[oidx].used = await operatorExpenseOf(account.address, oidx); - addressData[account.address].operatorsInUse[oidx].validatorsCount -= 1; - addressData[account.address].operatorsInUse[oidx].index = await operatorIndexOf(oidx); - } - addressData[account.address].validatorOperators[validatorIdx] = []; - addressData[account.address].activeValidators--; - globalData.validatorCount--; - console.log(` | Remove validator ${validatorIdx} > [ACTUAL_BLOCK] ${await utils.blockNumber()}`); -} -//@ts-ignore -export const deposit = async (account, amount) => { - await ssvToken.connect(account).approve(ssvNetwork.address, `${amount}`); - await ssvNetwork.connect(account).deposit(account.address, `${amount}`); - addressData[account.address].deposited += amount; - console.log(` | Deposited [ADDRESS] ${account.address} | [VALUE]: ${amount}`); -} -//@ts-ignore -export const withdraw = async (account, amount) => { - await ssvNetwork.connect(account).withdraw(`${amount}`); - addressData[account.address].withdrawn += amount; -} -//@ts-ignore -export const liquidate = async (account) => { - await ssvToken.connect(account).liquidate(account.address); - console.log(` | Liquidated [ADDRESS] ${account.address}`); -} -//@ts-ignore -export const updateOperatorFee = async (account, idx, fee) => { - await ssvNetwork.connect(account).declareOperatorFee(operatorsIds[idx], fee); - await ssvNetwork.connect(account).executeOperatorFee(operatorsIds[idx]); - await progressBlocks(1); - // update balance - await updateOperatorBalance(idx); - // update index - operatorData[idx].index = +await operatorIndexOf(idx); - operatorData[idx].indexBlockNumber = await utils.blockNumber(); - operatorData[idx].fee = fee; - console.log(` | Update operator fee ${idx} > [VALUE] ${fee} [ACTUAL_BLOCK] ${await utils.blockNumber()}`); -} - -const getNetworkEarnings = async () => { - console.log("-> det", globalData.networkEarnings, (await utils.blockNumber()), globalData.networkEarningsBlockNumber, globalData.networkFee, globalData.validatorCount) - return globalData.networkEarnings + ((await utils.blockNumber()) - globalData.networkEarningsBlockNumber) * globalData.networkFee * globalData.validatorCount; -} - -export const getNetworkTreasury = async () => { - return (await getNetworkEarnings()) - globalData.withdrawnFromTreasury; -} -//@ts-ignore -const updateAddressNetworkFee = async (address) => { - addressData[address].networkFee = await addressNetworkFee(address); - addressData[address].networkFeeIndex = await globalNetworkFeeIndex(); -} - -const updateNetworkEarnings = async () => { - globalData.networkEarnings = await getNetworkEarnings(); - globalData.networkEarningsBlockNumber = await utils.blockNumber(); -} -//@ts-ignore -export const updateNetworkFee = async (fee) => { - await ssvNetwork.updateNetworkFee(fee); - await progressBlocks(1); - globalData.networkFeeIndex = await globalNetworkFeeIndex(); - globalData.networkFee = fee; - globalData.networkFeeIndexBlockNumber = await utils.blockNumber(); - console.log(` | Update network fee > [VALUE] ${fee} [ACTUAL_BLOCK] ${await utils.blockNumber()}`); -} -//@ts-ignore -export const updateOperatorBalance = async (idx) => { - operatorData[idx].balance = +await operatorEarningsOf(idx); - operatorData[idx].blockNumber = await utils.blockNumber(); -} -//@ts-ignore -// export const currentBurnRate = async (address) => { -// let operatorFees = 0 -// for (const operators of addressData[address].operatorsInUse) { -// operatorFees += operators.fees -// } - -// operatorData[idx].balance = +await operatorEarningsOf(idx); -// operatorData[idx].blockNumber = await utils.blockNumber(); -// } -//@ts-ignore -export const processTestCase = async (testFlow) => { - const baseBlockNumber = await utils.blockNumber(); - // await network.provider.send('evm_setAutomine', [false]); - for (const blockNumber of Object.keys(testFlow)) { - const targetBlock = +blockNumber - -baseBlockNumber; - const diffBlocks = targetBlock - (await utils.blockNumber()); - const { funcs, asserts } = testFlow[blockNumber]; - await progressBlocks(diffBlocks); - console.log(`[BLOCK] ${+await utils.blockNumber()} (${blockNumber})`); - // await network.provider.send('evm_setAutomine', [true]); - if (Array.isArray(asserts)) for (const assert of asserts) await assert(); - // await network.provider.send('evm_setAutomine', [false]); - if (Array.isArray(funcs)) { - for (const func of funcs) { - await func(); - await progressBlocks(1); - } - } - } - - await network.provider.send('evm_setAutomine', [true]); -} \ No newline at end of file diff --git a/test/helpers/utils.ts b/test/helpers/utils.ts deleted file mode 100644 index 66a90b98..00000000 --- a/test/helpers/utils.ts +++ /dev/null @@ -1,66 +0,0 @@ -declare var network: any; -//@ts-ignore -export const strToHex = str => `0x${Buffer.from(str, 'utf8').toString('hex')}`; -//@ts-ignore -export const asciiToHex = str => { - var arr1 = []; - for (var n = 0, l = str.length; n < l; n ++) { - var hex = Number(str.charCodeAt(n)).toString(16); - arr1.push(hex); - } - return arr1.join(''); -} -//@ts-ignore -export const progress = async function(time, blocks, func = null) { - let snapshot; - - if (func) { - snapshot = await network.provider.send("evm_snapshot"); - } - - if (time) { - await network.provider.send("evm_increaseTime", [time]); - if (!blocks) { - await network.provider.send("evm_mine", []); - } - } - - for (let index = 0; index < blocks; ++index) { - await network.provider.send("evm_mine", []); - } - - if (func) { - //@ts-ignore - await func(); - await network.provider.send("evm_revert", [snapshot]); - } -} -//@ts-ignore -export const progressTime = async function(time, func = null) { - return progress(time, 1, func); -} -//@ts-ignore -export const progressBlocks = async function(blocks, func = null) { - return progress(0, blocks, func); -} -//@ts-ignore -export const snapshot = async function(func) { - return progress(0, 0, func); -} - -export const mineOneBlock = async () => network.provider.send("evm_mine", []); - -export const mineChunk = async (amount: number) => - Promise.all( - Array.from({ length: amount }, () => mineOneBlock()) - ) as unknown as Promise; - -export const mine = async (amount: number) => { - if (amount < 0) throw new Error('mine cannot be called with a negative value'); - const MAX_PARALLEL_CALLS = 1000; - // Do it on parallel but do not overflow connections - for (let i = 0; i < Math.floor(amount / MAX_PARALLEL_CALLS); i++) { - await mineChunk(MAX_PARALLEL_CALLS); - } - return mineChunk(amount % MAX_PARALLEL_CALLS); -}; \ No newline at end of file diff --git a/test/unit/burn-rate.ts b/test/unit/burn-rate.ts deleted file mode 100644 index 38f3d0ab..00000000 --- a/test/unit/burn-rate.ts +++ /dev/null @@ -1,138 +0,0 @@ -// Burn Rate Unit Tests - -// Declare all imports -import { ethers, upgrades } from 'hardhat' -import * as chai from 'chai' -import chaiAsPromised from 'chai-as-promised' -beforeEach(() => { - chai.should() - chai.use(chaiAsPromised) -}) -const { expect } = chai - -// Define global variables -const minimumBlocksBeforeLiquidation = 7000 -const operatorMaxFeeIncrease = 99999999999999 -const operatorPublicKeyPrefix = '12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345' -const validatorPublicKeyPrefix = '98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765' -let ssvToken: any, ssvRegistry: any, ssvNetwork: any -let owner: any, account1: any, account2: any, account3: any, account4: any, account5: any -const operatorsPub = Array.from(Array(10).keys()).map(k => `0x${operatorPublicKeyPrefix}${k}`) -const validatorsPub = Array.from(Array(10).keys()).map(k => `0x${validatorPublicKeyPrefix}${k}`) -const operatorsIds = Array.from(Array(10).keys()).map(k => k + 1) -const tokens = '90000000000000000' -const allowance = '99999999999999999999' -const operatorFee = 10010000000 -const DAY = 86400 -const setOperatorFeePeriod = 0 -const approveOperatorFeePeriod = DAY - -describe('Burn Rate', function () { - beforeEach(async function () { - // Create accounts - [owner, account1, account2, account3, account4, account5] = await ethers.getSigners() - - // Deploy Contracts - const ssvTokenFactory = await ethers.getContractFactory('SSVTokenMock') - const ssvRegistryFactory = await ethers.getContractFactory('SSVRegistry') - const ssvNetworkFactory = await ethers.getContractFactory('SSVNetwork') - ssvToken = await ssvTokenFactory.deploy() - ssvRegistry = await upgrades.deployProxy(ssvRegistryFactory, { initializer: false }) - await ssvToken.deployed() - await ssvRegistry.deployed() - ssvNetwork = await upgrades.deployProxy(ssvNetworkFactory, [ssvRegistry.address, ssvToken.address, minimumBlocksBeforeLiquidation, operatorMaxFeeIncrease, setOperatorFeePeriod, approveOperatorFeePeriod]) - await ssvNetwork.deployed() - - // Mint tokens - await ssvToken.mint(account1.address, '10000000000000000000') - await ssvToken.mint(account2.address, '10000000000000000000') - - // Register operators - await ssvNetwork.connect(account2).registerOperator('testOperator 0', operatorsPub[0], operatorFee) - await ssvNetwork.connect(account2).registerOperator('testOperator 1', operatorsPub[1], operatorFee) - await ssvNetwork.connect(account3).registerOperator('testOperator 2', operatorsPub[2], operatorFee) - await ssvNetwork.connect(account3).registerOperator('testOperator 3', operatorsPub[3], operatorFee) - }) - - it('Check burn rate', async function () { - await ssvNetwork.connect(owner).updateNetworkFee(10020000000) - // Register validator to non owned operators - await ssvToken.connect(account1).approve(ssvNetwork.address, allowance) - await ssvToken.connect(account2).approve(ssvNetwork.address, allowance) - await ssvNetwork.connect(account1).registerValidator(validatorsPub[0], operatorsIds.slice(0, 4), operatorsPub.slice(0, 4), operatorsPub.slice(0, 4), tokens) - let currentNetworkFee = await ssvNetwork.getNetworkFee() - expect(await ssvNetwork.getAddressBurnRate(account1.address)).to.equal(+currentNetworkFee + (operatorFee * 4)) - - // Register another validator to same non owned operators - await ssvNetwork.connect(account1).registerValidator(validatorsPub[1], operatorsIds.slice(0, 4), operatorsPub.slice(0, 4), operatorsPub.slice(0, 4), tokens) - expect(await ssvNetwork.getAddressBurnRate(account1.address)).to.equal((+currentNetworkFee * 2) + ((operatorFee * 4) * 2)) - - // Register an operator - await ssvNetwork.connect(account1).registerOperator('testOperator 4', operatorsPub[4], operatorFee * 4) - expect(await ssvNetwork.getAddressBurnRate(account1.address)).to.equal((+currentNetworkFee * 2) + ((operatorFee * 4) * 2)) - - // Register a validator from another account to my operator - await ssvNetwork.connect(account2).registerValidator(validatorsPub[2], operatorsIds.slice(1, 5), operatorsPub.slice(1, 5), operatorsPub.slice(1, 5), tokens) - expect(await ssvNetwork.getAddressBurnRate(account1.address)).to.equal((+currentNetworkFee * 2) + (operatorFee * 4)) - - // Register a validator 3 operators i dont own and 1 i do own - await ssvNetwork.connect(account1).registerValidator(validatorsPub[3], operatorsIds.slice(1, 5), operatorsPub.slice(1, 5), operatorsPub.slice(1, 5), tokens) - expect(await ssvNetwork.getAddressBurnRate(account1.address)).to.equal((+currentNetworkFee * 3) + (operatorFee * 7)) - - // Register another operator - await ssvNetwork.connect(account1).registerOperator('testOperator 5', operatorsPub[5], operatorFee) - expect(await ssvNetwork.getAddressBurnRate(account1.address)).to.equal((+currentNetworkFee * 3) + (operatorFee * 7)) - - // Register a validator from another account to both of my operators - await ssvNetwork.connect(account2).registerValidator(validatorsPub[4], operatorsIds.slice(2, 6), operatorsPub.slice(2, 6), operatorsPub.slice(2, 6), tokens) - expect(await ssvNetwork.getAddressBurnRate(account1.address)).to.equal((+currentNetworkFee * 3) + (operatorFee * 2)) - - // Remove an operator i own - await ssvNetwork.connect(account1).removeOperator(operatorsIds[4]) - expect(await ssvNetwork.getAddressBurnRate(account1.address)).to.equal((+currentNetworkFee * 3) + (operatorFee * 10)) - - // Update the network fee - await ssvNetwork.connect(owner).updateNetworkFee(9000000000) - currentNetworkFee = await ssvNetwork.getNetworkFee() - expect(await ssvNetwork.getAddressBurnRate(account1.address)).to.equal((+currentNetworkFee * 3) + (operatorFee * 10)) - - // Remove operator i down own - await ssvNetwork.connect(account2).removeOperator(operatorsIds[1]) - expect(await ssvNetwork.getAddressBurnRate(account1.address)).to.equal((+currentNetworkFee * 3) + (operatorFee * 7)) - - // Remove a validator i own - await ssvNetwork.connect(account1).removeValidator(validatorsPub[1]) - expect(await ssvNetwork.getAddressBurnRate(account1.address)).to.equal((+currentNetworkFee * 2) + (operatorFee * 4)) - - // Remove a validator i dont own - await ssvNetwork.connect(account2).removeValidator(validatorsPub[4]) - expect(await ssvNetwork.getAddressBurnRate(account1.address)).to.equal((+currentNetworkFee * 2) + (operatorFee * 5)) - - // Operator i dont own change fee - await ssvNetwork.connect(account2).declareOperatorFee(operatorsIds[0], operatorFee * 2) - expect(await ssvNetwork.connect(account2).executeOperatorFee(operatorsIds[0])) - expect(await ssvNetwork.getAddressBurnRate(account1.address)).to.equal((+currentNetworkFee * 2) + (operatorFee * 6)) - - // Operator i do own change fee - await ssvNetwork.connect(account1).declareOperatorFee(operatorsIds[5], operatorFee * 2) - expect(await ssvNetwork.connect(account1).executeOperatorFee(operatorsIds[5])) - expect(await ssvNetwork.getAddressBurnRate(account1.address)).to.equal((+currentNetworkFee * 2) + (operatorFee * 6)) - - // Register another 3 operators - await ssvNetwork.connect(account1).registerOperator('testOperator 6', operatorsPub[6], operatorFee) - await ssvNetwork.connect(account1).registerOperator('testOperator 7', operatorsPub[7], operatorFee) - await ssvNetwork.connect(account1).registerOperator('testOperator 8', operatorsPub[8], operatorFee) - expect(await ssvNetwork.getAddressBurnRate(account1.address)).to.equal((+currentNetworkFee * 2) + (operatorFee * 6)) - - // Update validator i dont own - await ssvNetwork.connect(account2).updateValidator(validatorsPub[2], operatorsIds.slice(5, 9), operatorsPub.slice(5, 9), operatorsPub.slice(5, 9), tokens) - expect(await ssvNetwork.getAddressBurnRate(account1.address)).to.equal((+currentNetworkFee * 2) + (operatorFee * 1)) - - // Update validator i do own - await ssvNetwork.connect(account1).updateValidator(validatorsPub[3], operatorsIds.slice(5, 9), operatorsPub.slice(5, 9), operatorsPub.slice(5, 9), tokens) - expect(await ssvNetwork.getAddressBurnRate(account1.address)).to.equal((+currentNetworkFee * 2) - (operatorFee * 1)) - - // other account gets liquidated that has validators to my own operators - - }) -}) diff --git a/test/unit/liquidation.ts b/test/unit/liquidation.ts deleted file mode 100644 index 6dc9d851..00000000 --- a/test/unit/liquidation.ts +++ /dev/null @@ -1,207 +0,0 @@ -// Liquidation Unit Tests - -// Declare all imports -import { ethers, upgrades } from 'hardhat' -import * as chai from 'chai' -import chaiAsPromised from 'chai-as-promised' -import { progressBlocks } from '../helpers/utils' -beforeEach(() => { - chai.should() - chai.use(chaiAsPromised) -}) -const { expect } = chai -const { BigNumber } = ethers; - -// Define global variables -const minimumBlocksBeforeLiquidation = 7000 -const operatorMaxFeeIncrease = 10 -const operatorPublicKeyPrefix = '12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345' -const validatorPublicKeyPrefix = '98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765' -let ssvToken: any, ssvRegistry: any, ssvNetwork: any -let owner: any, account1: any, account2: any, account3: any, account4: any, account5: any -const operatorsPub = Array.from(Array(10).keys()).map(k => `0x${operatorPublicKeyPrefix}${k}`) -const validatorsPub = Array.from(Array(10).keys()).map(k => `0x${validatorPublicKeyPrefix}${k}`) -const operatorsIds = Array.from(Array(10).keys()).map(k => k + 1) -const tokens = '10000000000000000' -const DAY = 86400 -const setOperatorFeePeriod = 0 -const approveOperatorFeePeriod = DAY - -describe('Liquidation', function () { - beforeEach(async function () { - // Create accounts - [owner, account1, account2, account3, account4, account5] = await ethers.getSigners() - - // Deploy Contracts - const ssvTokenFactory = await ethers.getContractFactory('SSVTokenMock') - const ssvRegistryFactory = await ethers.getContractFactory('SSVRegistry') - const ssvNetworkFactory = await ethers.getContractFactory('SSVNetwork') - ssvToken = await ssvTokenFactory.deploy() - ssvRegistry = await upgrades.deployProxy(ssvRegistryFactory, { initializer: false }) - await ssvToken.deployed() - await ssvRegistry.deployed() - ssvNetwork = await upgrades.deployProxy(ssvNetworkFactory, [ssvRegistry.address, ssvToken.address, minimumBlocksBeforeLiquidation, operatorMaxFeeIncrease, setOperatorFeePeriod, approveOperatorFeePeriod]) - await ssvNetwork.deployed() - - // Mint tokens - await ssvToken.mint(account1.address, '2000000000000000000') - - // Register operators - await ssvNetwork.connect(account2).registerOperator('testOperator 0', operatorsPub[0], 100000000000) - await ssvNetwork.connect(account2).registerOperator('testOperator 1', operatorsPub[1], 200000000000) - await ssvNetwork.connect(account3).registerOperator('testOperator 2', operatorsPub[2], 300000000000) - await ssvNetwork.connect(account3).registerOperator('testOperator 3', operatorsPub[3], 400000000000) - await ssvNetwork.connect(account3).registerOperator('testOperator 4', operatorsPub[4], 500000000000) - - // Register validators - await ssvToken.connect(account1).approve(ssvNetwork.address, tokens) - await ssvNetwork.connect(account1).registerValidator(validatorsPub[0], operatorsIds.slice(0, 4), operatorsPub.slice(0, 4), operatorsPub.slice(0, 4), tokens) - }) - - it('Register validator with 0 balance', async function () { - await expect(ssvNetwork.connect(account2).registerValidator(validatorsPub[1], operatorsIds.slice(0, 4), operatorsPub.slice(0, 4), operatorsPub.slice(0, 4), 0)).to.be.revertedWith("NotEnoughBalance") - }) - - it('Check balance after 100 blocks', async function () { - await progressBlocks(100) - expect(await ssvNetwork.getAddressBalance(account1.address)).to.equal(BigNumber.from('9900000000000000')) - expect(await ssvNetwork.getAddressBalance(account2.address)).to.equal(30000000000000) - expect(await ssvNetwork.getAddressBalance(account3.address)).to.equal(70000000000000) - }) - - it('Try to liquidate a valid account', async function () { - await ssvNetwork.connect(account4).liquidate([account1.address]) - expect(await ssvNetwork.isLiquidated(account1.address)).to.equal(false) - }) - - it('Check burn rates', async function (): Promise { - expect(await ssvNetwork.getAddressBurnRate(owner.address)).to.equal(0) - expect(await ssvNetwork.getAddressBurnRate(account1.address)).to.equal(1000000000000) - expect(await ssvNetwork.getAddressBurnRate(account2.address)).to.equal(0) - expect(await ssvNetwork.getAddressBurnRate(account3.address)).to.equal(0) - }) - - it('Try to withdraw to a liquidatable state', async function () { - await progressBlocks(948) - expect(await ssvNetwork.getAddressBalance(account1.address)).to.equal(BigNumber.from('9052000000000000')) - await expect(ssvNetwork.connect(account1).withdraw(BigNumber.from('200000000000000000'))).to.be.revertedWith('NotEnoughBalance') - expect(await ssvNetwork.getAddressBalance(account1.address)).to.equal(BigNumber.from('9051000000000000')) - }) - - it('Update to a valid state using tokens', async function () { - // Get to a liquidatable state - await ssvNetwork.connect(account1).withdraw('2999000000000000'); - await progressBlocks(100); - - expect(await ssvNetwork.isLiquidatable(account1.address)).to.equal(true) - - // Change operator triggering to put in more SSV - await ssvToken.connect(account1).approve(ssvNetwork.address, tokens) - const tx = ssvNetwork.connect(account1).updateValidator(validatorsPub[0], operatorsIds.slice(1, 5), operatorsPub.slice(1, 5), operatorsPub.slice(1, 5), tokens) - await expect(tx).to.emit(ssvNetwork, 'ValidatorRemoval') - await expect(tx).to.emit(ssvNetwork, 'ValidatorRegistration') - - // No longer liquidatable - expect(await ssvNetwork.isLiquidatable(account1.address)).to.equal(false) - await ssvNetwork.connect(account4).liquidate([account1.address]) - expect(await ssvNetwork.isLiquidated(account1.address)).to.equal(false) - - // Get to a liquidatable state - await ssvNetwork.connect(account1).withdraw('6749400000000000'); - await progressBlocks(250) - expect(await ssvNetwork.isLiquidatable(account1.address)).to.equal(true) - - // Try to withdraw with in liquidatable state - await expect(ssvNetwork.connect(account1).withdraw(10000000)).to.be.revertedWith("NotEnoughBalance") - - // Deposit more SSV - await ssvToken.connect(account1).approve(ssvNetwork.address, tokens) - await ssvNetwork.connect(account1).deposit(account1.address, tokens) - - // No longer liquidatable - expect(await ssvNetwork.isLiquidatable(account1.address)).to.equal(false) - }) - - it('Liquidate', async function () { - // Try to liquidate non liquidatable accounts - await ssvNetwork.connect(account1).withdraw('90900000000000'); - await progressBlocks(100); - expect(await ssvNetwork.getAddressBalance(account1.address)).to.equal(BigNumber.from('9808100000000000')) - expect(await ssvNetwork.isLiquidatable(account1.address)).to.equal(false) - await ssvNetwork.connect(account4).liquidate([account1.address]) - expect(await ssvNetwork.isLiquidated(account1.address)).to.equal(false) - - // Liquidate account1 - await progressBlocks(8350) - expect(await ssvNetwork.isLiquidatable(account1.address)).to.equal(true) - expect(await ssvToken.balanceOf(account4.address)).to.equal(0) - await ssvNetwork.connect(account4).liquidate([account1.address]) - expect(await ssvNetwork.isLiquidatable(account1.address)).to.equal(false) - await ssvNetwork.connect(account4).liquidate([account1.address]) - expect(await ssvNetwork.isLiquidated(account1.address)).to.equal(true) - expect(await ssvNetwork.getAddressBurnRate(account1.address)).to.equal(0) - expect(await ssvNetwork.getAddressBalance(account1.address)).to.equal(0) - expect(await ssvNetwork.getAddressBalance(account4.address)).to.equal(0) - expect(await ssvToken.balanceOf(account4.address)).to.equal('1456100000000000') - }) - - it('Liquidate multiple accounts', async function () { - // Register validator with account5 - await ssvToken.connect(account1).transfer(account5.address, tokens) - await ssvToken.connect(account5).approve(ssvNetwork.address, tokens) - await ssvNetwork.connect(account5).registerValidator(validatorsPub[1], operatorsIds.slice(0, 4), operatorsPub.slice(0, 4), operatorsPub.slice(0, 4), tokens) - await progressBlocks(900) - expect(await ssvNetwork.getAddressBalance(account1.address)).to.equal('9097000000000000') - expect(await ssvNetwork.getAddressBalance(account5.address)).to.equal('9100000000000000') - expect(await ssvNetwork.getAddressBalance(account4.address)).to.equal(0) - expect(await ssvToken.balanceOf(account4.address)).to.equal(0) - - // Try to liquidate non liquidatable accounts - await ssvNetwork.connect(account4).liquidate([account1.address, account2.address, account5.address]) - expect(await ssvNetwork.getAddressBalance(account1.address)).to.equal('9096000000000000') - expect(await ssvNetwork.getAddressBalance(account2.address)).to.equal('541500000000000') - expect(await ssvNetwork.getAddressBalance(account5.address)).to.equal('9099000000000000') - expect(await ssvNetwork.getAddressBalance(account4.address)).to.equal(0) - await ssvNetwork.connect(account1).withdraw('1995000000000000') - await ssvNetwork.connect(account5).withdraw('1998000000000000') - await progressBlocks(100) - - // Liquidate account1 (actually liquidatable), account2 (not liquidatable) and account5 (actually liquidatable) - await ssvNetwork.connect(account4).liquidate([account1.address, account2.address, account5.address]) - expect(await ssvNetwork.getAddressBalance(account1.address)).to.equal(0) - expect(await ssvNetwork.getAddressBalance(account2.address)).to.equal(603300000000000) - expect(await ssvNetwork.getAddressBalance(account5.address)).to.equal(0) - expect(await ssvNetwork.getAddressBalance(account4.address)).to.equal(0) - - // Account4 only got liquidation reward from account1 and account2 only - expect(await ssvToken.balanceOf(account4.address)).to.equal('13996000000000000') - expect(await ssvNetwork.isLiquidated(account1.address)).to.equal(true) - }) - - it('Try to enable account to liquitable status', async function () { - // Expect to not be liquidatable - expect(await ssvNetwork.getAddressBalance(account1.address)).to.equal(BigNumber.from('10000000000000000')) - expect(await ssvNetwork.isLiquidatable(account1.address)).to.equal(false) - await ssvNetwork.connect(account1).withdraw(BigNumber.from('2899000000000000')); - await progressBlocks(100); - // Liquidate account1 - await ssvNetwork.connect(account2).liquidate([account1.address]) - expect(await ssvNetwork.getAddressBalance(account1.address)).to.equal(0) - expect(await ssvNetwork.isLiquidated(account1.address)).to.equal(true) - expect(await ssvNetwork.isLiquidatable(account1.address)).to.equal(false) - - // Enable account not enough SSV - await ssvToken.connect(account1).approve(ssvNetwork.address, 7000000000000000) - await expect(ssvNetwork.connect(account1).reactivateAccount(4900000000)).to.be.revertedWith("NotEnoughBalance") - - // Enable account - await ssvNetwork.connect(account1).reactivateAccount(7000000000000000) - expect(await ssvNetwork.isLiquidated(account1.address)).to.equal(false) - expect(await ssvNetwork.getAddressBalance(account1.address)).to.equal(7000000000000000) - - // Liquidate again immediately - await ssvNetwork.connect(account2).liquidate([account1.address]) - expect(await ssvNetwork.getAddressBalance(account1.address)).to.equal(0) - expect(await ssvNetwork.isLiquidated(account1.address)).to.equal(true) - }) -}) diff --git a/test/unit/operator-register.ts b/test/unit/operator-register.ts deleted file mode 100644 index 69392b06..00000000 --- a/test/unit/operator-register.ts +++ /dev/null @@ -1,88 +0,0 @@ -// Operator Registration Unit Tests - -// Declare all imports -import * as chai from 'chai' -import chaiAsPromised from 'chai-as-promised' -beforeEach(() => { - chai.should() - chai.use(chaiAsPromised) -}) - -// Define global variables -declare const ethers: any -declare const upgrades: any -const { expect } = chai -const DAY = 86400 -const minimumBlocksBeforeLiquidation = 7000 -const operatorMaxFeeIncrease = 1000 -const setOperatorFeePeriod = 0 -const approveOperatorFeePeriod = DAY -const operatorPublicKeyPrefix = '12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345' -let ssvToken: any, ssvRegistry: any, ssvNetwork: any -let owner: any, account1: any, account2: any, account3: any -const operatorsPub = Array.from(Array(10).keys()).map(k => `0x${operatorPublicKeyPrefix}${k}`) -const operatorsIds = Array.from(Array(10).keys()).map(k => k + 1) - -describe('Register Operators', function () { - beforeEach(async function () { - // Create accounts - [owner, account1, account2, account3] = await ethers.getSigners() - - // Deploy Contracts - const ssvTokenFactory = await ethers.getContractFactory('SSVTokenMock') - const ssvRegistryFactory = await ethers.getContractFactory('SSVRegistry') - const ssvNetworkFactory = await ethers.getContractFactory('SSVNetwork') - ssvToken = await ssvTokenFactory.deploy() - ssvRegistry = await upgrades.deployProxy(ssvRegistryFactory, { initializer: false }) - await ssvToken.deployed() - await ssvRegistry.deployed() - ssvNetwork = await upgrades.deployProxy(ssvNetworkFactory, [ssvRegistry.address, ssvToken.address, minimumBlocksBeforeLiquidation, operatorMaxFeeIncrease, setOperatorFeePeriod, approveOperatorFeePeriod]) - await ssvNetwork.deployed() - - // Mint tokens - await ssvToken.mint(account1.address, '1000000000000000000') - - // Register operators - await expect(ssvNetwork.connect(account2).registerOperator('testOperator 0', operatorsPub[0], 100000000000)) - .to.emit(ssvNetwork, 'OperatorRegistration').withArgs(operatorsIds[0], 'testOperator 0', account2.address, operatorsPub[0], 100000000000) - await ssvNetwork.connect(account2).registerOperator('testOperator 1', operatorsPub[1], 200000000000) - await ssvNetwork.connect(account3).registerOperator('testOperator 2', operatorsPub[2], 300000000000) - await ssvNetwork.connect(account3).registerOperator('testOperator 3', operatorsPub[3], 400000000000) - }) - - - it('Get operators by ID', async function () { - expect((await ssvNetwork.getOperatorById(operatorsIds[1]))[0]).to.equal('testOperator 1') - expect((await ssvNetwork.getOperatorById(operatorsIds[1]))[1]).to.equal(account2.address) - expect((await ssvNetwork.getOperatorById(operatorsIds[1]))[2]).to.equal(operatorsPub[1]) - expect((await ssvNetwork.getOperatorById(operatorsIds[1]))[3]).to.equal('0') - expect((await ssvNetwork.getOperatorById(operatorsIds[1]))[4]).to.equal(200000000000) - expect((await ssvNetwork.getOperatorById(operatorsIds[1]))[5]).to.equal('0') - expect((await ssvNetwork.getOperatorById(operatorsIds[1]))[6]).to.equal(true) - - // Non-existing operator - expect((await ssvNetwork.getOperatorById(operatorsIds[5]))[1]).to.equal('0x0000000000000000000000000000000000000000') - }) - - it('Register validator with same public key', async function () { - await expect(ssvNetwork.connect(account2).registerOperator('testOperator 0', operatorsPub[0], 100000000000)) - .to.emit(ssvNetwork, 'OperatorRegistration').withArgs(operatorsIds[4], 'testOperator 0', account2.address, operatorsPub[0], 100000000000) - }) - - it('Try to register operator with errors', async function () { - // Try to register operator with public key too many characters - await ssvNetwork - .connect(account3).registerOperator('invalid pubkey', `${operatorsPub[1]}7`, 100000000000) - .should.eventually.be.rejectedWith('hex data is odd-length') - - // Try to register operator with invalid public key - await ssvNetwork - .connect(account3).registerOperator('invalid pubkey', '1234567890123456789-123456789012345678901234567890123456789012345678901234567890123456789012345', 100000000000) - .should.eventually.be.rejectedWith('invalid arrayify value') - - // Try to register operator SSV amount too small - await ssvNetwork - .connect(account3).registerOperator('invalid pubkey', operatorsPub[1], 9999999) - .should.eventually.be.rejectedWith('Precision is over the maximum defined') - }) -}) \ No newline at end of file diff --git a/test/unit/operator-remove.ts b/test/unit/operator-remove.ts deleted file mode 100644 index c4a6c96a..00000000 --- a/test/unit/operator-remove.ts +++ /dev/null @@ -1,132 +0,0 @@ -// Operator Remove Unit Tests - -// Declare all imports -import * as chai from 'chai' -import chaiAsPromised from 'chai-as-promised' -import { progressBlocks, progressTime } from '../helpers/utils' -beforeEach(() => { - chai.should() - chai.use(chaiAsPromised) -}) - -// Define global variables -declare const ethers: any -declare const upgrades: any -const { expect } = chai -const DAY = 86400 -const minimumBlocksBeforeLiquidation = 50 -const operatorMaxFeeIncrease = 10 -const setOperatorFeePeriod = 0 -const approveOperatorFeePeriod = DAY -const operatorPublicKeyPrefix = '12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345' -const validatorPublicKeyPrefix = '98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765' -let ssvToken: any, ssvRegistry: any, ssvNetwork: any -let owner: any, account1: any, account2: any, account3: any -const operatorsPub = Array.from(Array(10).keys()).map(k => `0x${operatorPublicKeyPrefix}${k}`) -const validatorsPub = Array.from(Array(10).keys()).map(k => `0x${validatorPublicKeyPrefix}${k}`) -const operatorsIds = Array.from(Array(10).keys()).map(k => k + 1) - -describe('Operator Remove', function () { - beforeEach(async function () { - // Create accounts - [owner, account1, account2, account3] = await ethers.getSigners() - - // Deploy Contracts - const ssvTokenFactory = await ethers.getContractFactory('SSVTokenMock') - const ssvRegistryFactory = await ethers.getContractFactory('SSVRegistry') - const ssvNetworkFactory = await ethers.getContractFactory('SSVNetwork') - ssvToken = await ssvTokenFactory.deploy() - ssvRegistry = await upgrades.deployProxy(ssvRegistryFactory, { initializer: false }) - await ssvToken.deployed() - await ssvRegistry.deployed() - ssvNetwork = await upgrades.deployProxy(ssvNetworkFactory, [ssvRegistry.address, ssvToken.address, minimumBlocksBeforeLiquidation, operatorMaxFeeIncrease, setOperatorFeePeriod, approveOperatorFeePeriod]) - await ssvNetwork.deployed() - - // Mint tokens - await ssvToken.mint(account1.address, '60000000000000') - - // Register operators - await ssvNetwork.connect(account2).registerOperator('testOperator 0', operatorsPub[0], 100000000000) - await ssvNetwork.connect(account3).registerOperator('testOperator 1', operatorsPub[1], 200000000000) - await ssvNetwork.connect(account3).registerOperator('testOperator 2', operatorsPub[2], 300000000000) - await ssvNetwork.connect(account3).registerOperator('testOperator 3', operatorsPub[3], 400000000000) - }) - - it('Remove operator no validators', async function () { - // Remove an operator with no validators - await progressTime(DAY) - await expect(ssvNetwork.connect(account2).removeOperator(operatorsIds[0])) - .to.emit(ssvNetwork, 'OperatorRemoval').withArgs(operatorsIds[0], account2.address) - - // Check that the operator statuses - expect((await ssvNetwork.getOperatorById(operatorsIds[0]))[0]).to.equal('testOperator 0') - expect((await ssvNetwork.getOperatorById(operatorsIds[0]))[1]).to.equal(account2.address) - expect((await ssvNetwork.getOperatorById(operatorsIds[0]))[2]).to.equal(operatorsPub[0]) - expect((await ssvNetwork.getOperatorById(operatorsIds[0]))[3]).to.equal('0') - expect((await ssvNetwork.getOperatorById(operatorsIds[0]))[4]).to.equal(0) - expect((await ssvNetwork.getOperatorById(operatorsIds[0]))[5]).to.equal('0') - expect((await ssvNetwork.getOperatorById(operatorsIds[0]))[6]).to.equal(false) - }) - - it('Remove operator with validators', async function () { - // Register a validator - await ssvToken.connect(account1).approve(ssvNetwork.address, 60000000000000) - await ssvNetwork.connect(account1).registerValidator(validatorsPub[0], operatorsIds.slice(0, 4), operatorsPub.slice(0, 4), operatorsPub.slice(0, 4), 60000000000000) - - // Delete an operator that the validator is using - await expect(ssvNetwork.connect(account2).removeOperator(operatorsIds[0])) - .to.emit(ssvNetwork, 'OperatorRemoval').withArgs(operatorsIds[0], account2.address) - - // Check that the operator statuses - expect((await ssvNetwork.getOperatorById(operatorsIds[0]))[0]).to.equal('testOperator 0') - expect((await ssvNetwork.getOperatorById(operatorsIds[0]))[1]).to.equal(account2.address) - expect((await ssvNetwork.getOperatorById(operatorsIds[0]))[2]).to.equal(operatorsPub[0]) - expect((await ssvNetwork.getOperatorById(operatorsIds[0]))[3]).to.equal('1') - expect((await ssvNetwork.getOperatorById(operatorsIds[0]))[4]).to.equal(0) - expect((await ssvNetwork.getOperatorById(operatorsIds[0]))[5]).to.equal('0') - expect((await ssvNetwork.getOperatorById(operatorsIds[0]))[6]).to.equal(false) - - // Check that operator did not earn anything since deleted - const account2Balance = await ssvNetwork.getAddressBalance(account2.address) - await progressBlocks(100) - expect(await ssvNetwork.getAddressBalance(account2.address)).to.equal(account2Balance) - }) - - it('Remove operator errors', async function () { - // Try to remove non-existent operator - await ssvNetwork.connect(account3).removeOperator(operatorsIds[6]) - .should.eventually.be.rejectedWith('OperatorWithPublicKeyNotExist') - - // Remove operator: tx was sent as non-owner - await ssvNetwork.connect(account3).removeOperator(operatorsIds[0]) - .should.eventually.be.rejectedWith('CallerNotOperatorOwner') - - // Remove already removed operator - await ssvNetwork.connect(account2).removeOperator(operatorsIds[0]) - await ssvNetwork.connect(account2).removeOperator(operatorsIds[0]) - .should.eventually.be.rejectedWith('OperatorDeleted') - }) - - // **** NEED TO UPDATE FOR DAO WHEN FUNCTIONALITY IS ADDED **** - // it('Remove operator from DAO', async function () { - // // Register a validator - // await ssvToken.connect(account1).approve(ssvNetwork.address, 1000000000) - // await ssvNetwork.connect(account1).registerValidator(validatorsPub[0], operatorsIds.slice(0, 4), operatorsPub.slice(0, 4), operatorsPub.slice(0, 4), 100000000) - - // // Delete an operator that the validator is using - // await expect(ssvNetwork.connect(account2).removeOperator(operatorsIds[0])) - // .to.emit(ssvRegistry, 'OperatorRemoved') - // .withArgs(operatorsIds[0], account2.address, operatorsPub[0]) - - // // Check that the operator fee is 0 - // expect((await ssvRegistry.getOperatorCurrentFee(operatorsIds[0])).toString()).to.equal('0') - - // // Check that the operator status is false - // expect((await ssvNetwork.getOperatorByPublicKey(operatorsPub[1]))[5]).to.equal(false) - - // // Chat that operator did not earn anything since deleted - // const operatorEarnings = (await ssvNetwork.operatorEarningsOf(operatorsIds[0])).toString() - // await progressBlocks(100) - // expect((await ssvNetwork.operatorEarningsOf(operatorsIds[0])).toString()).to.equal(operatorEarnings) - // }) -}) \ No newline at end of file diff --git a/test/unit/operator-update.ts b/test/unit/operator-update.ts deleted file mode 100644 index 8052188a..00000000 --- a/test/unit/operator-update.ts +++ /dev/null @@ -1,172 +0,0 @@ -// Operator Update Unit Tests - -// Declare all imports -import * as chai from 'chai' -import chaiAsPromised from 'chai-as-promised' -import { progressBlocks, progressTime } from '../helpers/utils' -beforeEach(() => { - chai.should() - chai.use(chaiAsPromised) -}) - -// Define global variables -declare const ethers: any -declare const upgrades: any -const { expect } = chai -const DAY = 86400 -const minimumBlocksBeforeLiquidation = 7000 -const operatorMaxFeeIncrease = 1000 -const setOperatorFeePeriod = 0 -const approveOperatorFeePeriod = DAY -const operatorPublicKeyPrefix = '12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345' -let ssvToken: any, ssvRegistry: any, ssvNetwork: any, utils: any -let owner: any, account1: any, account2: any, account3: any -const operatorsPub = Array.from(Array(10).keys()).map(k => `0x${operatorPublicKeyPrefix}${k}`) -const operatorsIds = Array.from(Array(10).keys()).map(k => k + 1) - -describe('Operator Update', function () { - beforeEach(async function () { - // Create accounts - [owner, account1, account2, account3] = await ethers.getSigners() - - // Deploy Contracts - const ssvTokenFactory = await ethers.getContractFactory('SSVTokenMock') - const ssvRegistryFactory = await ethers.getContractFactory('SSVRegistry') - const ssvNetworkFactory = await ethers.getContractFactory('SSVNetwork') - const utilsFactory = await ethers.getContractFactory('Utils'); - ssvToken = await ssvTokenFactory.deploy() - ssvRegistry = await upgrades.deployProxy(ssvRegistryFactory, { initializer: false }) - await ssvToken.deployed() - await ssvRegistry.deployed() - ssvNetwork = await upgrades.deployProxy(ssvNetworkFactory, [ssvRegistry.address, ssvToken.address, minimumBlocksBeforeLiquidation, operatorMaxFeeIncrease, setOperatorFeePeriod, approveOperatorFeePeriod]) - await ssvNetwork.deployed() - utils = await utilsFactory.deploy(); - - // Mint tokens - await ssvToken.mint(account1.address, '10000000000') - - // Register operators - await ssvNetwork.connect(account2).registerOperator('testOperator 0', operatorsPub[0], 100000000000) - await ssvNetwork.connect(account2).registerOperator('testOperator 1', operatorsPub[1], 200000000000) - await ssvNetwork.connect(account3).registerOperator('testOperator 2', operatorsPub[2], 300000000000) - await ssvNetwork.connect(account3).registerOperator('testOperator 3', operatorsPub[3], 400000000000) - await ssvNetwork.connect(account3).registerOperator('testOperator 4', operatorsPub[4], 100000000000) - }) - - it('Update operators score', async function () { - await ssvNetwork.connect(owner).updateOperatorScore(operatorsIds[0], 105) - - // Update as non-owner to get error - await ssvNetwork - .connect(account2) - .updateOperatorScore(operatorsIds[0], 110) - .should.eventually.be.rejectedWith('caller is not the owner') - }) - - it('Update operators fee', async function () { - // Set new operator fee - await progressTime(DAY) - await ssvNetwork.connect(account2).declareOperatorFee(operatorsIds[0], 105000000000) - expect(await ssvNetwork.connect(account2).executeOperatorFee(operatorsIds[0])) - .to.emit(ssvNetwork, 'OperatorFeeUpdated').withArgs(account2.address, operatorsIds[0], +await utils.blockNumber(), '105000000000') - expect((await ssvNetwork.getOperatorFee(operatorsIds[0])).toString()).to.equal('105000000000') - - // Set new operator fee too high - await expect(ssvNetwork.connect(account2).declareOperatorFee(operatorsIds[0], 11560000000000)).to.be.revertedWith('FeeExceedsIncreaseLimit') - - // declareOperatorFee incorrect user - await expect(ssvNetwork.connect(account1).declareOperatorFee(operatorsIds[0], 105000100000)).to.be.revertedWith('CallerNotOperatorOwner') - }) - - it('Update operators fee incorrect precision', async function () { - await ssvNetwork.connect(account2).declareOperatorFee(operatorsIds[0], 101000000000) - await expect(ssvNetwork.connect(account2).declareOperatorFee(operatorsIds[0], 101220000)).to.be.revertedWith('Precision is over the maximum defined') - await expect(ssvNetwork.connect(account2).declareOperatorFee(operatorsIds[0], 100000000 * 1.0122)).to.be.revertedWith('Precision is over the maximum defined') - }) - - it('Update operators max fee increase percentage', async function () { - // Change the max fee increase percentage - expect(await ssvNetwork.getOperatorFeeIncreaseLimit()).to.equal('1000') - await ssvNetwork.connect(owner).updateOperatorFeeIncreaseLimit(2000) - expect(await ssvNetwork.getOperatorFeeIncreaseLimit()).to.equal('2000') - - // Change the max fee increase percentage not owner - await expect(ssvNetwork.connect(account2).updateOperatorFeeIncreaseLimit(20)).to.be.revertedWith('Ownable: caller is not the owner') - - // Set operator fee too high - await expect(ssvNetwork.connect(account2).declareOperatorFee(operatorsIds[0], 1200000000000)).to.be.revertedWith('FeeExceedsIncreaseLimit') - - // Set operator fee at 20% higher - await ssvNetwork.connect(account2).declareOperatorFee(operatorsIds[0], 120000000000) - await ssvNetwork.connect(account2).executeOperatorFee(operatorsIds[0]) - expect((await ssvNetwork.getOperatorFee(operatorsIds[0])).toString()).to.equal('120000000000') - - // Try to lower fee too low - await expect(ssvNetwork.connect(account2).declareOperatorFee(operatorsIds[1], 105)).to.be.revertedWith('Precision is over the maximum defined') - }) - - it('Update operators fee less than approval time', async function () { - await ssvNetwork.connect(account2).declareOperatorFee(operatorsIds[0], 105000000000) - await ssvNetwork.connect(account2).declareOperatorFee(operatorsIds[0], 106000000000) - await ssvNetwork.connect(account2).executeOperatorFee(operatorsIds[0]) - expect((await ssvNetwork.getOperatorFee(operatorsIds[0])).toString()).to.equal('106000000000') - }) - - it('Update operator fee expired', async function () { - await ssvNetwork.connect(account2).declareOperatorFee(operatorsIds[0], 110000000000) - await progressTime(DAY * 7) - await expect(ssvNetwork.connect(account2).executeOperatorFee(operatorsIds[0])).to.be.revertedWith('ApprovalNotWithinTimeframe') - }) - - it('Cant update operator fee (fee too small)', async function () { - await expect(ssvNetwork.connect(account3).declareOperatorFee(operatorsIds[4], 11000000)).to.be.revertedWith('Precision is over the maximum defined') - await expect(ssvNetwork.connect(account3).declareOperatorFee(operatorsIds[4], 10100000)).to.be.revertedWith('Precision is over the maximum defined') - }) - - it('Cancel update operator fee', async function () { - // Cancel update operator fee before approval time - await ssvNetwork.connect(account2).declareOperatorFee(operatorsIds[0], 105000000000) - await ssvNetwork.connect(account2).cancelDeclaredOperatorFee(operatorsIds[0]) - await progressTime(DAY * 7) - expect((await ssvNetwork.getOperatorFee(operatorsIds[0])).toString()).to.equal('100000000000') - - // Cancel update operator fee incorrect account - await ssvNetwork.connect(account2).declareOperatorFee(operatorsIds[0], 105000000000) - await expect(ssvNetwork.connect(account1).cancelDeclaredOperatorFee(operatorsIds[0])).to.be.revertedWith('CallerNotOperatorOwner') - expect((await ssvNetwork.getOperatorFee(operatorsIds[0])).toString()).to.equal('100000000000') - }) - - it('Change expiry time / Cancel update operator fee before expiry time', async function () { - // Get fee periods - expect((await ssvNetwork.getDeclaredOperatorFeePeriod()).toString()).to.equal('0') - expect((await ssvNetwork.getExecuteOperatorFeePeriod()).toString()).to.equal('86400') - - // Change fee periods - await ssvNetwork.connect(owner).updateDeclareOperatorFeePeriod(5) - await ssvNetwork.connect(owner).updateExecuteOperatorFeePeriod(10) - - // Get fee periods - expect((await ssvNetwork.getDeclaredOperatorFeePeriod()).toString()).to.equal('5') - expect((await ssvNetwork.getExecuteOperatorFeePeriod()).toString()).to.equal('10') - - // Cancel update operator fee before expiry time - await ssvNetwork.connect(account2).declareOperatorFee(operatorsIds[0], 105000000000) - await progressBlocks(6) - await ssvNetwork.connect(account2).cancelDeclaredOperatorFee(operatorsIds[0]) - await expect(ssvNetwork.connect(account2).executeOperatorFee(operatorsIds[0])).to.be.revertedWith('NoPendingFeeChangeRequest') - expect((await ssvNetwork.getOperatorFee(operatorsIds[0])).toString()).to.equal('100000000000') - }) - - it('Update set operator fee period', async function () { - // Change set operator fee period not owner - await expect(ssvNetwork.connect(account2).updateDeclareOperatorFeePeriod(5)).to.be.revertedWith('Ownable: caller is not the owner') - - // Change set operator fee - await ssvNetwork.connect(owner).updateDeclareOperatorFeePeriod(5) - await ssvNetwork.connect(account2).declareOperatorFee(operatorsIds[0], 105000000000) - await progressBlocks(3) - await expect(ssvNetwork.connect(account2).executeOperatorFee(operatorsIds[0])).to.be.revertedWith('ApprovalNotWithinTimeframe') - await ssvNetwork.connect(account2).executeOperatorFee(operatorsIds[0]) - expect((await ssvNetwork.getOperatorFee(operatorsIds[0])).toString()).to.equal('105000000000') - }) -}) diff --git a/test/unit/ssv-network-balances.ts b/test/unit/ssv-network-balances.ts deleted file mode 100644 index 84561893..00000000 --- a/test/unit/ssv-network-balances.ts +++ /dev/null @@ -1,162 +0,0 @@ -// Network Balances Unit Tests - -// Declare all imports -import { ethers, upgrades } from 'hardhat'; -import * as chai from 'chai'; -import chaiAsPromised from 'chai-as-promised'; -import { progress, progressBlocks, snapshot } from '../helpers/utils'; -import Table from 'cli-table'; -declare var network: any; -beforeEach(() => { - chai.should(); - chai.use(chaiAsPromised); -}); - -// Define global variables -const { expect } = chai; -const minimumBlocksBeforeLiquidation = 7000; -const operatorMaxFeeIncrease = 1000; -const operatorPublicKeyPrefix = '12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345'; -const validatorPublicKeyPrefix = '98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765'; -let ssvToken: any, ssvRegistry: any, ssvNetwork: any; -let owner: any, account1: any, account2: any, account3: any, account4: any; -const operatorsPub = Array.from(Array(10).keys()).map(k => `0x${operatorPublicKeyPrefix}${k}`); -const validatorsPub = Array.from(Array(10).keys()).map(k => `0x${validatorPublicKeyPrefix}${k}`); -const operatorsIds = Array.from(Array(10).keys()).map(k => k + 1); -const DAY = 86400; -const operatorIndexes: any = []; -const setOperatorFeePeriod = 0; -const approveOperatorFeePeriod = DAY; - -const registerOperator = async (account: string, idx: number, fee: number) => { - await ssvNetwork.connect(account).registerOperator(`testOperator ${idx}`, operatorsPub[idx], fee); - operatorIndexes.push({ - fee, - blockNumber: await ethers.provider.getBlockNumber(), - index: 0, - validatorsCount: 0, - used: 0 - }); -} - -describe('SSV Network Balances', function () { - beforeEach(async function () { - [owner, account1, account2, account3] = await ethers.getSigners(); - const ssvTokenFactory = await ethers.getContractFactory('SSVTokenMock'); - const ssvRegistryFactory = await ethers.getContractFactory('SSVRegistry'); - const ssvNetworkFactory = await ethers.getContractFactory('SSVNetwork'); - ssvToken = await ssvTokenFactory.deploy(); - ssvRegistry = await upgrades.deployProxy(ssvRegistryFactory, { initializer: false }); - await ssvToken.deployed(); - await ssvRegistry.deployed(); - ssvNetwork = await upgrades.deployProxy(ssvNetworkFactory, [ssvRegistry.address, ssvToken.address, minimumBlocksBeforeLiquidation, operatorMaxFeeIncrease, setOperatorFeePeriod, approveOperatorFeePeriod]); - await ssvNetwork.deployed(); - await ssvToken.mint(account1.address, '80000000000000000'); - }); - - it('Address Balance', async function () { - const table = new Table({ head: ["", "Block #", "10", "20", "30", "40", "50", "60", "100"] }); - const balancesByBlocks = [""]; - const networkAddFeeByBlocks = [""]; - await snapshot(async () => { - const chargedAmount = 10000000000000000; - await ssvToken.connect(account1).approve(ssvNetwork.address, '80000000000000000'); - (await ssvNetwork.updateNetworkFee(100000000000)).wait(); - // Register operators - await network.provider.send("evm_setAutomine", [false]); - await registerOperator(account2, 0, 200000000000); - await registerOperator(account2, 1, 100000000000); - await registerOperator(account2, 2, 100000000000); - await registerOperator(account2, 3, 300000000000); - - await progressBlocks(1); - - /* - block #10 - */ - networkAddFeeByBlocks.push(`${+await ssvNetwork.addressNetworkFee(account1.address)}`); - balancesByBlocks.push(`${+await ssvNetwork.getAddressBalance(account1.address)}`); - await progressBlocks(10); - - /* - block #20 - */ - await network.provider.send("evm_setAutomine", [true]); - - balancesByBlocks.push(`${+await ssvNetwork.getAddressBalance(account1.address)}`); - networkAddFeeByBlocks.push(`${+await ssvNetwork.addressNetworkFee(account1.address)}`); - - // Register validator - (await ssvNetwork.connect(account1).registerValidator(validatorsPub[0], operatorsIds.slice(0, 4), operatorsPub.slice(0, 4), operatorsPub.slice(0, 4), `${chargedAmount}`)).wait(); - - // await progress(4 * DAY, 9); - await progressBlocks(10); - - /* - block #30 - */ - balancesByBlocks.push(`${chargedAmount - +await ssvNetwork.getAddressBalance(account1.address)}`); - networkAddFeeByBlocks.push(`${+await ssvNetwork.addressNetworkFee(account1.address)}`); - - await network.provider.send("evm_setAutomine", [false]); - (await ssvNetwork.connect(account2).declareOperatorFee(operatorsIds[0], 220000000000)).wait(); - (await ssvNetwork.connect(account2).executeOperatorFee(operatorsIds[0])).wait(); - - // Register validator - (await ssvNetwork.connect(account1).registerValidator(validatorsPub[1], operatorsIds.slice(0, 4), operatorsPub.slice(0, 4), operatorsPub.slice(0, 4), `${chargedAmount}`)).wait(); - await network.provider.send("evm_setAutomine", [true]); - - await progressBlocks(10); - - /* - block #40 - */ - balancesByBlocks.push(`${2 * chargedAmount - +await ssvNetwork.getAddressBalance(account1.address)}`); - networkAddFeeByBlocks.push(`${+await ssvNetwork.addressNetworkFee(account1.address)}`); - - // Register validator - (await ssvNetwork.connect(account1).registerValidator(validatorsPub[2], operatorsIds.slice(0, 4), operatorsPub.slice(0, 4), operatorsPub.slice(0, 4), `${chargedAmount}`)).wait(); - - // await progress(4 * DAY, 9); - await progressBlocks(9); - - /* - block #50 - */ - balancesByBlocks.push(`${3 * chargedAmount - +await ssvNetwork.getAddressBalance(account1.address)} (${await ssvNetwork.getAddressBalance(account1.address)})`); - networkAddFeeByBlocks.push(`${+await ssvNetwork.addressNetworkFee(account1.address)}`); - await network.provider.send("evm_setAutomine", [false]); - (await ssvNetwork.connect(account2).declareOperatorFee(operatorsIds[0], 180000000000)).wait(); - (await ssvNetwork.connect(account2).executeOperatorFee(operatorsIds[0])).wait(); - (await ssvNetwork.updateNetworkFee(200000000000)).wait(); - // register validator - (await ssvNetwork.connect(account1).registerValidator(validatorsPub[3], operatorsIds.slice(0, 4), operatorsPub.slice(0, 4), operatorsPub.slice(0, 4), `${chargedAmount}`)).wait(); - await network.provider.send("evm_setAutomine", [true]); - - await progressBlocks(10); - - /* - block #60 - */ - balancesByBlocks.push(`${4 * chargedAmount - +await ssvNetwork.getAddressBalance(account1.address)} (${await ssvNetwork.getAddressBalance(account1.address)})`); - networkAddFeeByBlocks.push(`${+await ssvNetwork.addressNetworkFee(account1.address)}`); - - await progressBlocks(40); - - /* - block #100 - */ - balancesByBlocks.push(`${4 * chargedAmount - +await ssvNetwork.getAddressBalance(account1.address)} (${await ssvNetwork.getAddressBalance(account1.address)})`); - networkAddFeeByBlocks.push(`${+await ssvNetwork.addressNetworkFee(account1.address)}`); - - table.push( - { 'Acc. Payments': balancesByBlocks }, - { 'Network Fee': networkAddFeeByBlocks } - ); - - console.log(table.toString()); - expect(4 * chargedAmount - +await ssvNetwork.getAddressBalance(account1.address)).to.equal(222280000000000); - - }); - }); -}); \ No newline at end of file diff --git a/test/unit/ssv-network.ts b/test/unit/ssv-network.ts deleted file mode 100644 index 263ed0a6..00000000 --- a/test/unit/ssv-network.ts +++ /dev/null @@ -1,412 +0,0 @@ -// Network Contract Unit Tests - -// Declare all imports -import { ethers, upgrades } from 'hardhat'; -import * as chai from 'chai'; -import chaiAsPromised from 'chai-as-promised'; -import { progressBlocks, progressTime } from '../helpers/utils'; -before(() => { - chai.should(); - chai.use(chaiAsPromised); -}); -const { expect } = chai; - -// Define global variables -const minimumBlocksBeforeLiquidation = 7000; -const operatorMaxFeeIncrease = 1000; -const operatorPublicKeyPrefix = '12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345'; -const operatorPublicKeyPrefix2 = '12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012346'; -const validatorPublicKeyPrefix = '98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765'; -let ssvToken: any, ssvRegistry: any, ssvNetwork: any, utils: any; -let owner: any, account1: any, account2: any, account3: any, account4: any; -const operatorsPub = Array.from(Array(10).keys()).map(k => `0x${operatorPublicKeyPrefix}${k}`); -const operatorsPub2 = Array.from(Array(10).keys()).map(k => `0x${operatorPublicKeyPrefix2}${k}`); -const validatorsPub = Array.from(Array(10).keys()).map(k => `0x${validatorPublicKeyPrefix}${k}`); -const operatorsIds = Array.from(Array(10).keys()).map(k => k + 1); -const tokens = '100000000000000000'; -const DAY = 86400; -const setOperatorFeePeriod = 0; -const approveOperatorFeePeriod = DAY; - -describe('SSV Network Contract', function () { - beforeEach(async function () { - [owner, account1, account2, account3, account4] = await ethers.getSigners(); - const utilsFactory = await ethers.getContractFactory('Utils'); - const ssvTokenFactory = await ethers.getContractFactory('SSVTokenMock'); - const ssvRegistryFactory = await ethers.getContractFactory('SSVRegistry'); - const ssvNetworkFactory = await ethers.getContractFactory('SSVNetwork'); - - utils = await utilsFactory.deploy(); - ssvToken = await ssvTokenFactory.deploy(); - ssvRegistry = await upgrades.deployProxy(ssvRegistryFactory, { initializer: false }); - await ssvToken.deployed(); - await ssvRegistry.deployed(); - ssvNetwork = await upgrades.deployProxy(ssvNetworkFactory, [ssvRegistry.address, ssvToken.address, minimumBlocksBeforeLiquidation, operatorMaxFeeIncrease, setOperatorFeePeriod, approveOperatorFeePeriod]); - await ssvNetwork.deployed(); - await ssvToken.mint(account1.address, tokens); - await ssvToken.mint(account2.address, tokens); - - // Register operators - await ssvNetwork.connect(account2).registerOperator('testOperator 0', operatorsPub[0], 100000000000); - await ssvNetwork.connect(account2).registerOperator('testOperator 1', operatorsPub[1], 200000000000); - await ssvNetwork.connect(account3).registerOperator('testOperator 2', operatorsPub[2], 300000000000); - await ssvNetwork.connect(account3).registerOperator('testOperator 3', operatorsPub[3], 400000000000); - await ssvNetwork.connect(account3).registerOperator('testOperator 4', operatorsPub[4], 500000000000); - - // Register validators - await ssvToken.connect(account1).approve(ssvNetwork.address, tokens); - await ssvNetwork.connect(account1).registerValidator(validatorsPub[0], operatorsIds.slice(0, 4), operatorsPub.slice(0, 4), operatorsPub.slice(0, 4), tokens); - }); - - - it('Check contract version', async function () { - expect(await ssvNetwork.version()).to.equal(20000) - }); - - it('Operator limit', async function () { - await ssvNetwork.connect(account3).registerOperator('testOperator 5', operatorsPub[5], 50000000000); - await ssvNetwork.connect(account3).registerOperator('testOperator 6', operatorsPub[6], 50000000000); - await ssvNetwork.connect(account3).registerOperator('testOperator 7', operatorsPub[7], 50000000000); - await ssvNetwork.connect(account3).registerOperator('testOperator 8', operatorsPub[8], 50000000000); - await ssvNetwork.connect(account3).registerOperator('testOperator 9', operatorsPub[9], 50000000000); - await ssvNetwork.connect(account3).registerOperator('testOperator 10', operatorsPub2[0], 50000000000); - await ssvNetwork.connect(account3).registerOperator('testOperator 11', operatorsPub2[1], 50000000000); - await expect(ssvNetwork.connect(account3).registerOperator('testOperator 12', operatorsPub2[2], 50000000000)).to.be.revertedWith("ExceedRegisteredOperatorsByAccountLimit") - }); - - it('Operators getter', async function () { - expect((await ssvNetwork.getOperatorById(operatorsIds[0])).map((v: any) => v.toString())).to.eql(['testOperator 0', account2.address, operatorsPub[0], '1', '100000000000', '0', 'true']); - expect((await ssvNetwork.getOperatorById(operatorsIds[1])).map((v: any) => v.toString())).to.eql(['testOperator 1', account2.address, operatorsPub[1], '1', '200000000000', '0', 'true']); - expect((await ssvNetwork.getOperatorById(operatorsIds[2])).map((v: any) => v.toString())).to.eql(['testOperator 2', account3.address, operatorsPub[2], '1', '300000000000', '0', 'true']); - }); - - it('Get operator current fee', async function () { - expect(await ssvNetwork.getOperatorFee(operatorsIds[0])).to.equal(100000000000); - expect(await ssvNetwork.getOperatorFee(operatorsIds[1])).to.equal(200000000000); - expect(await ssvNetwork.getOperatorFee(operatorsIds[2])).to.equal(300000000000); - }); - - it('Balances should be correct after 100 blocks', async function () { - await progressBlocks(100); - expect(await ssvNetwork.getAddressBalance(account1.address)).to.equal('99900000000000000'); - expect(await ssvNetwork.getAddressBalance(account2.address)).to.equal(30000000000000); - expect(await ssvNetwork.getAddressBalance(account3.address)).to.equal(70000000000000); - }); - - it('Withdraw', async function () { - await progressBlocks(200); - await ssvNetwork.connect(account1).withdraw('10000000000'); - await ssvNetwork.connect(account2).withdraw('10000000000'); - await ssvNetwork.connect(account3).withdraw('10000000000'); - expect(await ssvNetwork.getAddressBalance(account1.address)).to.equal('99796990000000000'); - expect(await ssvNetwork.getAddressBalance(account2.address)).to.equal('60890000000000'); - expect(await ssvNetwork.getAddressBalance(account3.address)).to.equal('142090000000000'); - }); - - it('Revert withdraw: NotEnoughBalance', async function () { - await progressBlocks(350) - await expect(ssvNetwork.connect(account1) - .withdraw('800000000000000000')) - .to.be.revertedWith('NotEnoughBalance'); - await expect(ssvNetwork.connect(account2) - .withdraw('90000000000000000')) - .to.be.revertedWith('NotEnoughBalance'); - await expect(ssvNetwork.connect(account3) - .withdraw('25000000000000000')) - .to.be.revertedWith('NotEnoughBalance'); - }); - - it('Register same validator', async function () { - await expect(ssvNetwork.connect(account2).registerValidator(validatorsPub[0], operatorsIds.slice(0, 4), operatorsPub.slice(0, 4), operatorsPub.slice(0, 4), tokens)).to.be.revertedWith('ValidatorAlreadyExists'); - }); - - it('Register another validator', async function () { - await progressBlocks(600); - expect(await ssvNetwork.getAddressBalance(account1.address)).to.equal('99400000000000000'); - expect(await ssvNetwork.getAddressBalance(account2.address)).to.equal('180000000000000'); - expect(await ssvNetwork.getAddressBalance(account3.address)).to.equal('420000000000000'); - await ssvToken.connect(account2).approve(ssvNetwork.address, tokens); - await ssvNetwork.connect(account2).registerValidator(validatorsPub[1], operatorsIds.slice(0, 4), operatorsPub.slice(0, 4), operatorsPub.slice(0, 4), tokens); - await progressBlocks(100); - expect(await ssvNetwork.getAddressBalance(account1.address)).to.equal('99298000000000000'); - expect(await ssvNetwork.getAddressBalance(account2.address)).to.equal('100140600000000000'); - expect(await ssvNetwork.getAddressBalance(account3.address)).to.equal('561400000000000'); - }); - - it('Get validators by owner address', async function () { - expect(await ssvNetwork.getValidatorsByOwnerAddress(account1.address)).to.eql([validatorsPub[0]]); - }); - - it('Withdraw all when burn rate is positive', async function () { - await ssvToken.connect(account2).approve(ssvNetwork.address, tokens); - await ssvNetwork.connect(account2).registerValidator(validatorsPub[1], operatorsIds.slice(0, 4), operatorsPub.slice(0, 4), operatorsPub.slice(0, 4), tokens); - expect(await ssvNetwork.getAddressBurnRate(account1.address)).to.equal(1000000000000); - expect(await ssvNetwork.getAddressBurnRate(account2.address)).to.equal(400000000000); - expect(await ssvNetwork.getAddressBalance(account1.address)).to.equal('99998000000000000'); - expect(await ssvNetwork.getAddressBalance(account2.address)).to.equal('100000600000000000'); - await expect(ssvNetwork.connect(account1).withdrawAll()).to.be.revertedWith("BurnRatePositive"); - }); - - it('Liquidate when burn rate is positive', async function () { - await ssvToken.connect(account2).approve(ssvNetwork.address, tokens); - await ssvNetwork.connect(account2).registerValidator(validatorsPub[1], operatorsIds.slice(0, 4), operatorsPub.slice(0, 4), operatorsPub.slice(0, 4), tokens); - expect(await ssvNetwork.getAddressBurnRate(account1.address)).to.equal(1000000000000); - expect(await ssvNetwork.getAddressBurnRate(account2.address)).to.equal(400000000000); - expect(await ssvNetwork.getAddressBalance(account1.address)).to.equal('99998000000000000'); - expect(await ssvNetwork.getAddressBalance(account2.address)).to.equal('100000600000000000'); - await expect(ssvNetwork.connect(account1).liquidate([account1.address])).to.emit(ssvToken, 'Transfer').withArgs(ssvNetwork.address, account1.address, '99997000000000000'); - expect(await ssvToken.balanceOf(account1.address)).to.equal('99997000000000000'); - await ssvNetwork.connect(account1).registerValidator(validatorsPub[2], operatorsIds.slice(1, 5), operatorsPub.slice(1, 5), operatorsPub.slice(1, 5), 0); - expect(await ssvNetwork.getAddressBurnRate(account1.address)).to.equal(0); - expect(await ssvNetwork.getAddressBurnRate(account2.address)).to.equal('700000000000'); - await ssvNetwork.connect(account1).removeValidator(validatorsPub[2]); - expect(await ssvNetwork.getAddressBurnRate(account1.address)).to.equal(0); - expect(await ssvNetwork.getAddressBurnRate(account2.address)).to.equal('700000000000'); - await ssvNetwork.connect(account1).registerValidator(validatorsPub[2], operatorsIds.slice(1, 5), operatorsPub.slice(1, 5), operatorsPub.slice(1, 5), 0); - expect(await ssvNetwork.getAddressBurnRate(account1.address)).to.equal(0); - expect(await ssvNetwork.getAddressBurnRate(account2.address)).to.equal('700000000000'); - await ssvNetwork.connect(account1).removeValidator(validatorsPub[2]); - expect(await ssvNetwork.getAddressBurnRate(account1.address)).to.equal(0); - expect(await ssvNetwork.getAddressBurnRate(account2.address)).to.equal('700000000000'); - await ssvNetwork.connect(account1).registerValidator(validatorsPub[2], operatorsIds.slice(1, 5), operatorsPub.slice(1, 5), operatorsPub.slice(1, 5), 0); - expect(await ssvNetwork.getAddressBurnRate(account1.address)).to.equal(0); - expect(await ssvNetwork.getAddressBurnRate(account2.address)).to.equal('700000000000'); - await ssvNetwork.connect(account1).updateValidator(validatorsPub[2], operatorsIds.slice(0, 4), operatorsPub.slice(0, 4), operatorsPub.slice(0, 4), 0); - expect(await ssvNetwork.getAddressBurnRate(account1.address)).to.equal(0); - expect(await ssvNetwork.getAddressBurnRate(account2.address)).to.equal('700000000000'); - expect(await ssvNetwork.getAddressBalance(account1.address)).to.equal(0); - expect(await ssvNetwork.getAddressBalance(account2.address)).to.equal('99996000000000000'); - - await progressBlocks(100) - expect(await ssvNetwork.getAddressBalance(account2.address)).to.equal('99926000000000000'); - - await expect(ssvNetwork.connect(account1).reactivateAccount(0)).to.be.revertedWith('NotEnoughBalance'); - await ssvToken.mint(account1.address, '100000000000000000'); - await ssvToken.connect(account1).approve(ssvNetwork.address, '100000000000000000'); - await ssvNetwork.connect(account1).reactivateAccount('100000000000000000'); - await expect(ssvNetwork.connect(account1).reactivateAccount(0)).to.be.revertedWith('AccountAlreadyEnabled'); - - expect(await ssvNetwork.getAddressBurnRate(account1.address)).to.equal(2000000000000); - expect(await ssvNetwork.getAddressBurnRate(account2.address)).to.equal(100000000000); - - await progressBlocks(50) - expect(await ssvNetwork.getAddressBalance(account1.address)).to.equal('99898000000000000'); - expect(await ssvNetwork.getAddressBalance(account2.address)).to.equal('99918100000000000'); - }); - - it('Withdraw all when burn rate is non-positive', async function () { - await ssvNetwork.connect(account3).registerValidator(validatorsPub[2], operatorsIds.slice(0, 4), operatorsPub.slice(0, 4), operatorsPub.slice(0, 4), 0); - expect(await ssvNetwork.getAddressBurnRate(account3.address)).to.equal(0); - await expect(ssvNetwork.connect(account3).withdrawAll()).to.emit(ssvToken, 'Transfer').withArgs(ssvNetwork.address, account3.address, 1100000000000); - expect(await ssvNetwork.getAddressBalance(account3.address)).to.equal(0); - expect(await ssvNetwork.isLiquidated(account3.address)).to.equal(false); - expect(await ssvToken.balanceOf(account3.address)).to.equal(1100000000000); - }); - - it('Remove a validator', async function () { - await ssvNetwork.connect(account1).removeValidator(validatorsPub[0]); - await progressBlocks(99); - expect(await ssvNetwork.getAddressBalance(account1.address)).to.equal('99999000000000000'); - expect(await ssvNetwork.getAddressBalance(account2.address)).to.equal('300000000000'); - expect(await ssvNetwork.getAddressBalance(account3.address)).to.equal('700000000000'); - }); - - it('Try to approve when no pending fee', async function () { - await expect(ssvNetwork.connect(account3).executeOperatorFee(operatorsIds[3])).to.be.revertedWith('NoPendingFeeChangeRequest'); - }); - - it('Update operator fee', async function () { - await ssvNetwork.connect(account3).declareOperatorFee(operatorsIds[3], "44000000000"); - await ssvNetwork.connect(account3).executeOperatorFee(operatorsIds[3]); - await progressBlocks(99); - expect(await ssvNetwork.getAddressBalance(account1.address)).to.equal('99934244000000000'); - expect(await ssvNetwork.getAddressBalance(account2.address)).to.equal('30300000000000'); - expect(await ssvNetwork.getAddressBalance(account3.address)).to.equal('35456000000000'); - }); - - it('Register a validator with deposit', async function () { - await ssvToken.connect(account2).approve(ssvNetwork.address, tokens); - await ssvNetwork.connect(account2).registerValidator(validatorsPub[1], operatorsIds.slice(0, 4), operatorsPub.slice(0, 4), operatorsPub.slice(0, 4), tokens); - await progressBlocks(10); - expect(await ssvNetwork.getAddressBalance(account1.address)).to.equal('99988000000000000'); - expect(await ssvNetwork.getAddressBalance(account2.address)).to.equal('99996600000000000'); - expect(await ssvNetwork.getAddressBalance(account3.address)).to.equal('15400000000000'); - }); - - it('Activate a validator', async function () { - await ssvToken.connect(account2).approve(ssvNetwork.address, tokens); - await ssvNetwork.connect(account2).registerValidator(validatorsPub[1], operatorsIds.slice(0, 4), operatorsPub.slice(0, 4), operatorsPub.slice(0, 4), tokens); - await progressBlocks(10); - expect(await ssvNetwork.getAddressBalance(account1.address)).to.equal('99988000000000000'); - expect(await ssvNetwork.getAddressBalance(account2.address)).to.equal('99996600000000000'); - expect(await ssvNetwork.getAddressBalance(account3.address)).to.equal('15400000000000'); - }); - - it('Remove a validator when overdue', async function () { - await ssvNetwork.connect(account1).withdraw('92001000000000000'); - await progressBlocks(8000); - await expect(ssvNetwork.connect(account1).removeValidator(validatorsPub[0])).to.be.revertedWith('NegativeBalance'); - }); - - it('Balance when overdue', async function () { - await ssvNetwork.connect(account1).withdraw('92001000000000000'); - await progressBlocks(8000); - await expect(ssvNetwork.getAddressBalance(account1.address)).to.be.revertedWith('NegativeBalance'); - }); - - it('Update operator fee not from owner', async function () { - await expect(ssvNetwork.connect(account1).declareOperatorFee(operatorsIds[3], 6)).to.be.revertedWith('CallerNotOperatorOwner'); - }); - - it('Remove an operator not from owner', async function () { - await expect(ssvNetwork.connect(account1).removeOperator(operatorsIds[4])).to.be.revertedWith('CallerNotOperatorOwner'); - }); - - it('Remove an operator', async function () { - await ssvToken.connect(account2).approve(ssvNetwork.address, tokens); - await ssvNetwork.connect(account2).registerValidator(validatorsPub[2], operatorsIds.slice(1, 5), operatorsPub.slice(1, 5), operatorsPub.slice(1, 5), tokens); - expect(await ssvNetwork.getAddressBalance(account1.address)).to.equal('99998000000000000'); - expect(await ssvNetwork.getAddressBalance(account2.address)).to.equal('100000600000000000'); - expect(await ssvNetwork.getAddressBalance(account3.address)).to.equal('1400000000000'); - await progressBlocks(10) - expect(await ssvNetwork.getAddressBalance(account1.address)).to.equal('99988000000000000'); - expect(await ssvNetwork.getAddressBalance(account2.address)).to.equal('99991600000000000'); - expect(await ssvNetwork.getAddressBalance(account3.address)).to.equal('20400000000000'); - await ssvNetwork.connect(account2).removeValidator(validatorsPub[2]); - expect(await ssvNetwork.getAddressBalance(account1.address)).to.equal('99987000000000000'); - expect(await ssvNetwork.getAddressBalance(account2.address)).to.equal('99990700000000000'); - expect(await ssvNetwork.getAddressBalance(account3.address)).to.equal(22300000000000); - await progressBlocks(10); - expect(await ssvNetwork.getAddressBalance(account1.address)).to.equal('99977000000000000'); - expect(await ssvNetwork.getAddressBalance(account2.address)).to.equal('99993700000000000'); - expect(await ssvNetwork.getAddressBalance(account3.address)).to.equal(29300000000000); - await ssvNetwork.connect(account3).removeOperator(operatorsIds[4]); - await progressBlocks(9); - expect(await ssvNetwork.getAddressBalance(account1.address)).to.equal('99967000000000000'); - expect(await ssvNetwork.getAddressBalance(account2.address)).to.equal('99996700000000000'); - expect(await ssvNetwork.getAddressBalance(account3.address)).to.equal(36300000000000); - }); - - it('Deactivate an operator', async function () { - await progressBlocks(10) - expect(await ssvNetwork.getAddressBalance(account1.address)).to.equal('99990000000000000'); - expect(await ssvNetwork.getAddressBalance(account2.address)).to.equal('3000000000000'); - expect(await ssvNetwork.getAddressBalance(account3.address)).to.equal('7000000000000'); - await ssvNetwork.connect(account1).removeValidator(validatorsPub[0]); - expect(await ssvNetwork.getAddressBalance(account1.address)).to.equal('99989000000000000'); - expect(await ssvNetwork.getAddressBalance(account2.address)).to.equal('3300000000000'); - expect(await ssvNetwork.getAddressBalance(account3.address)).to.equal('7700000000000'); - await progressBlocks(10); - expect(await ssvNetwork.getAddressBalance(account1.address)).to.equal('99989000000000000'); - expect(await ssvNetwork.getAddressBalance(account2.address)).to.equal('3300000000000'); - expect(await ssvNetwork.getAddressBalance(account3.address)).to.equal('7700000000000'); - await ssvNetwork.connect(account3).removeOperator(operatorsIds[4]); - await progressBlocks(9); - expect(await ssvNetwork.getAddressBalance(account1.address)).to.equal('99989000000000000'); - expect(await ssvNetwork.getAddressBalance(account2.address)).to.equal('3300000000000'); - expect(await ssvNetwork.getAddressBalance(account3.address)).to.equal('7700000000000'); - expect((await ssvRegistry.getOperatorById(operatorsIds[4]))[1]).to.equal(account3.address); - expect((await ssvRegistry.getOperatorById(operatorsIds[4]))[6]).to.equal(false); - }); - - it('Operator max fee increase', async function () { - expect(await ssvNetwork.getOperatorFeeIncreaseLimit()).to.equal(1000); - await expect(ssvNetwork.connect(account2).declareOperatorFee(operatorsIds[0], 1200000000000)).to.be.revertedWith('FeeExceedsIncreaseLimit'); - await expect(ssvNetwork.connect(account2).declareOperatorFee(operatorsIds[1], 2400000000000)).to.be.revertedWith('FeeExceedsIncreaseLimit'); - await ssvNetwork.connect(account2).declareOperatorFee(operatorsIds[0], 11000000000); - await ssvNetwork.connect(account2).executeOperatorFee(operatorsIds[0]); - expect(await ssvNetwork.getOperatorFee(operatorsIds[0])).to.equal(11000000000); - await ssvNetwork.updateOperatorFeeIncreaseLimit(2000); - expect(await ssvNetwork.getOperatorFeeIncreaseLimit()).to.equal(2000); - await expect(ssvNetwork.connect(account2).declareOperatorFee(operatorsIds[1], 250000000000)).to.be.revertedWith('FeeExceedsIncreaseLimit'); - await ssvNetwork.connect(account2).declareOperatorFee(operatorsIds[1], 24000000000); - await ssvNetwork.connect(account2).executeOperatorFee(operatorsIds[1]); - }); - - it('Update operator max fee increase emits event', async function () { - await expect(ssvNetwork.updateOperatorFeeIncreaseLimit(200)).to.emit(ssvNetwork, 'OperatorFeeIncreaseLimitUpdate').withArgs(200); - }); - - it('Minimum blocks before liquidation', async function () { - expect(await ssvNetwork.getLiquidationThresholdPeriod()).to.equal(7000); - await expect(ssvNetwork.updateLiquidationThresholdPeriod(6569)).to.be.revertedWith('BelowMinimumBlockPeriod'); - await ssvNetwork.updateLiquidationThresholdPeriod(7001); - expect(await ssvNetwork.getLiquidationThresholdPeriod()).to.equal(7001); - }); - - it('Update minimum blocks before liquidation emits event', async function () { - await expect(ssvNetwork.updateLiquidationThresholdPeriod(9999999999999)).to.emit(ssvNetwork, 'LiquidationThresholdPeriodUpdate').withArgs(9999999999999); - }); - - it('Set network fee', async function () { - expect(await ssvNetwork.getNetworkFee()).to.equal('0'); - await expect(ssvNetwork.updateNetworkFee(10000000)).to.emit(ssvNetwork, 'NetworkFeeUpdate').withArgs('0', '10000000'); - expect(await ssvNetwork.getNetworkFee()).to.equal('10000000'); - await progressBlocks(20); - expect(await ssvNetwork.getNetworkEarnings()).to.equal(200000000); - }); - - it('Withdraw network fees', async function () { - await expect(ssvNetwork.updateNetworkFee(10000000)).to.emit(ssvNetwork, 'NetworkFeeUpdate').withArgs('0', '10000000'); - await progressBlocks(20); - await expect(ssvNetwork.connect(account2).withdrawNetworkEarnings(6000000000)).to.be.revertedWith('Ownable: caller is not the owner'); - await expect(ssvNetwork.withdrawNetworkEarnings(80000000000000)).to.be.revertedWith('NotEnoughBalance'); - await expect(ssvNetwork.withdrawNetworkEarnings(200000000)).to.emit(ssvToken, 'Transfer').withArgs(ssvNetwork.address, owner.address, '200000000'); - expect(await ssvNetwork.getNetworkEarnings()).to.equal(30000000); - await expect(ssvNetwork.withdrawNetworkEarnings(60000000000000)).to.be.revertedWith('NotEnoughBalance'); - }); - - it('Update declare operator fee period', async function () { - await expect(ssvNetwork.updateDeclareOperatorFeePeriod(DAY)); - expect(await ssvNetwork.getDeclaredOperatorFeePeriod()).to.equal(DAY); - }); - - it('Update execute operator fee period', async function () { - await expect(ssvNetwork.updateExecuteOperatorFeePeriod(DAY)) - expect(await ssvNetwork.getExecuteOperatorFeePeriod()).to.equal(DAY); - }); - - it('Create an operator with low fee', async function () { - await expect(ssvNetwork.connect(account3).registerOperator('testOperator 5', operatorsIds[5], 1000)).to.be.revertedWith('Precision is over the maximum defined'); - }); - - it('Fee change request', async function () { - await expect(ssvNetwork.updateDeclareOperatorFeePeriod(DAY)) - await expect(ssvNetwork.updateExecuteOperatorFeePeriod(DAY)) - await ssvNetwork.connect(account3).declareOperatorFee(operatorsIds[3], '41000000000'); - expect(await ssvNetwork.getOperatorFee(operatorsIds[3])).to.equal(400000000000); - const currentBlockTime = await utils.blockTimestamp(); - expect((await ssvNetwork.getOperatorDeclaredFee(operatorsIds[3])).map((v: any) => v.toString())).to.eql(['41000000000', (+currentBlockTime + DAY).toString(), (+currentBlockTime + 2 * DAY).toString()]); - - //approve fee too soon - await expect(ssvNetwork.connect(account3).executeOperatorFee(operatorsIds[3])).to.be.revertedWith('ApprovalNotWithinTimeframe'); - - // Approve too late - await progressTime(3 * DAY) - await expect(ssvNetwork.connect(account3).executeOperatorFee(operatorsIds[3])).to.be.revertedWith('ApprovalNotWithinTimeframe'); - - // Cancel set operator fee - await ssvNetwork.connect(account3).declareOperatorFee(operatorsIds[3], '41000000000'); - await ssvNetwork.connect(account3).cancelDeclaredOperatorFee(operatorsIds[3]); - expect(await ssvNetwork.getOperatorFee(operatorsIds[3])).to.equal('400000000000'); - expect((await ssvNetwork.getOperatorDeclaredFee(operatorsIds[3])).map((v: any) => v.toString())).to.eql(['0', '0', '0']); - - // Approve fee on time - await ssvNetwork.connect(account3).declareOperatorFee(operatorsIds[3], '41000000000'); - await progressTime(DAY * 15 / 10) - await ssvNetwork.connect(account3).executeOperatorFee(operatorsIds[3]) - expect(await ssvNetwork.getOperatorFee(operatorsIds[3])).to.equal('41000000000'); - expect((await ssvNetwork.getOperatorDeclaredFee(operatorsIds[3])).map((v: any) => v.toString())).to.eql(['0', '0', '0']); - - // update fee with low fee - await expect(ssvNetwork.connect(account3).declareOperatorFee(operatorsIds[3], 1000)).to.be.revertedWith('Precision is over the maximum defined'); - }); - - it('Deposit account from another address', async function () { - const balanceBefore = +await ssvNetwork.getAddressBalance(account4.address); - const tokens = 100000000; - await ssvToken.connect(owner).approve(ssvNetwork.address, tokens) - await ssvNetwork.connect(owner).deposit(account4.address, tokens); - expect(await ssvNetwork.getAddressBalance(account4.address)).to.equal(balanceBefore + tokens); - }); -}); \ No newline at end of file diff --git a/test/unit/ssv-registry.js b/test/unit/ssv-registry.js new file mode 100644 index 00000000..c40d67ce --- /dev/null +++ b/test/unit/ssv-registry.js @@ -0,0 +1,67 @@ +const { expect } = require("chai"); +const operator_fee_block = 1; + + +async function mineNBlocks(n) { + for (let index = 0; index < n; index++) { + await ethers.provider.send('evm_mine'); + } +} + +const operatorsIndexes = Array.from(Array(4).keys()).map(k => k + 1); + + +describe("Validators", () => { + var deployedRegistryContract + beforeEach(async () => { + const Registry = await ethers.getContractFactory("SSVRegistryNew"); + deployedRegistryContract = await Registry.deploy(); + await deployedRegistryContract.deployed(); + + for (let i = 0; i < operatorsIndexes.length; i++) { + var encryptionPK = "0x123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123451"; + await deployedRegistryContract.registerOperator(encryptionPK, operator_fee_block); + } + // await deployedRegistryContract.addOperatorToValidator([], operatorsIndexes, []); + }) + + it("should create group", async () => { + // await deployedRegistryContract.createGroup([1,2,3,4]); + }) + + it("should register validator", async () => { + const validatorPK = "0x987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987651"; + const sharePKs = Array.from(Array(10).keys()).map(k => `0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765${k}`); + const encryptedShares = Array.from(Array(10).keys()).map(k => `0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765${k}98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765${k}`); + // const operatorsIndexes = Array.from(Array(10).keys()).map(k => k + 1); + + // await deployedRegistryContract.createGroup([1,2,3,4]); + // await deployedRegistryContract.createGroup([1,2,3,4]); + + await deployedRegistryContract.deposit("100000000000"); + + // validator 1 + expect(await deployedRegistryContract.registerValidator( + [1,2,3,4], + validatorPK, + sharePKs.slice(0, 4), + encryptedShares.slice(0, 4), + "10000" + )) + .to.emit(deployedRegistryContract, 'ValidatorAdded') + .withArgs(validatorPK); + + // validator 2 + expect(await deployedRegistryContract.registerValidator( + [1,2,3,4], + validatorPK, + sharePKs.slice(0, 4), + encryptedShares.slice(0, 4), + "10000" + )) + .to.emit(deployedRegistryContract, 'ValidatorAdded') + .withArgs(validatorPK); + + // await deployedRegistryContract.liquidate("0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", "0x392791df626408017a264f53fde61065d5a93a32b60171df9d8a46afdf82992d"); + }); +}); diff --git a/test/unit/ssv-registry.ts b/test/unit/ssv-registry.ts deleted file mode 100644 index c18f6fbb..00000000 --- a/test/unit/ssv-registry.ts +++ /dev/null @@ -1,105 +0,0 @@ -// Registry Contract Unit Tests - -// Declare all imports -import { ethers, upgrades } from 'hardhat' -import * as chai from 'chai' -import chaiAsPromised from 'chai-as-promised' -beforeEach(() => { - chai.should() - chai.use(chaiAsPromised) -}) -const { expect } = chai - -// Define global variables -const operatorPublicKeyPrefix = '12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345' -const operatorPublicKeyPrefix2 = '12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012346'; -const validatorPublicKeyPrefix = '98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765' -let ssvRegistry: any, owner: any, account1: any, account2: any, account3: any -const operatorsPub = Array.from(Array(10).keys()).map(k => `0x${operatorPublicKeyPrefix}${k}`) -const operatorsPub2 = Array.from(Array(10).keys()).map(k => `0x${operatorPublicKeyPrefix2}${k}`); -const validatorsPub = Array.from(Array(10).keys()).map(k => `0x${validatorPublicKeyPrefix}${k}`) -const operatorsIds = Array.from(Array(10).keys()).map(k => k + 1) - -describe('SSV Registry Contract', function () { - beforeEach(async function () { - [owner, account1, account2, account3] = await ethers.getSigners() - const ssvRegistryFactory = await ethers.getContractFactory('SSVRegistry') - ssvRegistry = await upgrades.deployProxy(ssvRegistryFactory, []); - await ssvRegistry.deployed() - await ssvRegistry.registerOperator('testOperator 0', account1.address, operatorsPub[0], 100000000000) - await ssvRegistry.registerOperator('testOperator 1', account1.address, operatorsPub[1], 200000000000) - await ssvRegistry.registerOperator('testOperator 2', account1.address, operatorsPub[2], 300000000000) - await ssvRegistry.registerOperator('testOperator 3', account2.address, operatorsPub[3], 400000000000) - await ssvRegistry.registerOperator('testOperator 4', account2.address, operatorsPub[4], 500000000000) - await ssvRegistry.registerValidator(account1.address, validatorsPub[0], operatorsIds.slice(0, 4), operatorsPub.slice(0, 4), operatorsPub.slice(0, 4)) - await ssvRegistry.registerValidator(account1.address, validatorsPub[1], operatorsIds.slice(0, 4), operatorsPub.slice(0, 4), operatorsPub.slice(0, 4)) - await ssvRegistry.registerValidator(account2.address, validatorsPub[2], operatorsIds.slice(0, 4), operatorsPub.slice(0, 4), operatorsPub.slice(0, 4)) - }) - - it('Check contract version', async function () { - expect(await ssvRegistry.version()).to.equal(1) - }); - - it('Operator limit', async function () { - await ssvRegistry.registerOperator('testOperator 5', account1.address, operatorsPub[5], 500000000000); - await ssvRegistry.registerOperator('testOperator 6', account1.address, operatorsPub[6], 500000000000); - await ssvRegistry.registerOperator('testOperator 7', account1.address, operatorsPub[7], 500000000000); - await ssvRegistry.registerOperator('testOperator 8', account1.address, operatorsPub[8], 500000000000); - await ssvRegistry.registerOperator('testOperator 9', account1.address, operatorsPub[9], 500000000000); - await ssvRegistry.registerOperator('testOperator 10', account1.address, operatorsPub2[0], 500000000000); - await ssvRegistry.registerOperator('testOperator 11', account1.address, operatorsPub2[1], 500000000000); - await expect(ssvRegistry.registerOperator('testOperator 12', account1.address, operatorsPub2[2], 500000000000)).to.be.revertedWith("ExceedRegisteredOperatorsByAccountLimit") - }) - - it('Remove Operator', async function () { - await ssvRegistry.removeOperator(1); - await expect(ssvRegistry.removeOperator(1)).to.be.revertedWith("OperatorDeleted") - }) - - it('Register validators with errors', async () => { - await expect(ssvRegistry.registerValidator(account3.address, "0x12345678", operatorsIds.slice(0, 4), operatorsPub.slice(0, 4), operatorsPub.slice(0, 4))).to.be.revertedWith('InvalidPublicKeyLength') - await expect(ssvRegistry.registerValidator(account3.address, validatorsPub[3], operatorsIds.slice(0, 3), operatorsPub.slice(0, 4), operatorsPub.slice(0, 4))).to.be.revertedWith('OessDataStructureInvalid') - await expect(ssvRegistry.registerValidator(account3.address, validatorsPub[3], operatorsIds.slice(0, 4), operatorsPub.slice(0, 3), operatorsPub.slice(0, 4))).to.be.revertedWith('OessDataStructureInvalid') - await expect(ssvRegistry.registerValidator(account3.address, validatorsPub[3], operatorsIds.slice(0, 4), operatorsPub.slice(0, 4), operatorsPub.slice(0, 3))).to.be.revertedWith('OessDataStructureInvalid') - await expect(ssvRegistry.registerValidator(account3.address, validatorsPub[3], operatorsIds.slice(0, 1), operatorsPub.slice(0, 1), operatorsPub.slice(0, 1))).to.be.revertedWith('OessDataStructureInvalid') - await expect(ssvRegistry.registerValidator(account3.address, validatorsPub[3], operatorsIds.slice(0, 3), operatorsPub.slice(0, 3), operatorsPub.slice(0, 3))).to.be.revertedWith('OessDataStructureInvalid') - await ssvRegistry.removeOperator(1); - await expect(ssvRegistry.registerValidator(account3.address, validatorsPub[3], operatorsIds.slice(0, 4), operatorsPub.slice(0, 4), operatorsPub.slice(0, 4))).to.be.revertedWith('OperatorDeleted') - }) - - it('Register a valid validator', async () => { - await ssvRegistry.registerValidator(account3.address, validatorsPub[3], operatorsIds.slice(1, 5), operatorsPub.slice(1, 5), operatorsPub.slice(1, 5)); - expect((await ssvRegistry.validatorsPerOperatorCount(1)).toString()).to.equal('3') - expect((await ssvRegistry.validatorsPerOperatorCount(2)).toString()).to.equal('4') - expect((await ssvRegistry.validatorsPerOperatorCount(5)).toString()).to.equal('1') - }) - - it('Validators getter', async () => { - expect((await ssvRegistry.validators(validatorsPub[0])).map((v: any) => v.toString())).to.eql([account1.address, validatorsPub[0], 'true']) - expect((await ssvRegistry.validators(validatorsPub[1])).map((v: any) => v.toString())).to.eql([account1.address, validatorsPub[1], 'true']) - expect((await ssvRegistry.validators(validatorsPub[2])).map((v: any) => v.toString())).to.eql([account2.address, validatorsPub[2], 'true']) - }) - - it('Get validators by address', async () => { - expect(await ssvRegistry.getValidatorsByAddress(account1.address)).to.eql([validatorsPub[0], validatorsPub[1]]) - expect(await ssvRegistry.getValidatorsByAddress(account2.address)).to.eql([validatorsPub[2]]) - }) - - it('Get validator owner', async () => { - expect(await ssvRegistry.getValidatorOwner(validatorsPub[0])).to.equal(account1.address) - expect(await ssvRegistry.getValidatorOwner(validatorsPub[2])).to.equal(account2.address) - }) - - it('Disable owner validators', async () => { - expect(await ssvRegistry.isLiquidated(account1.address)).to.equal(false) - await ssvRegistry.disableOwnerValidators(account1.address) - expect(await ssvRegistry.isLiquidated(account1.address)).to.equal(true) - }) - - it('Enable owner validators', async () => { - await ssvRegistry.disableOwnerValidators(account1.address) - expect(await ssvRegistry.isLiquidated(account1.address)).to.equal(true) - await ssvRegistry.enableOwnerValidators(account1.address) - expect(await ssvRegistry.isLiquidated(account1.address)).to.equal(false) - }) -}) \ No newline at end of file diff --git a/test/unit/validator-register.ts b/test/unit/validator-register.ts deleted file mode 100644 index 07449296..00000000 --- a/test/unit/validator-register.ts +++ /dev/null @@ -1,104 +0,0 @@ -// Validators Registration Unit Tests - -// Declare all imports -import * as chai from 'chai' -import chaiAsPromised from 'chai-as-promised' -beforeEach(() => { - chai.should() - chai.use(chaiAsPromised) -}) -declare var ethers: any -declare var upgrades: any -const { expect } = chai - -// Define global variables -const DAY = 86400 -const minimumBlocksBeforeLiquidation = 7000 -const operatorMaxFeeIncrease = 10 -const setOperatorFeePeriod = 0 -const approveOperatorFeePeriod = DAY -const operatorPublicKeyPrefix = '12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345' -const validatorPublicKeyPrefix = '98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765' -let ssvToken: any, ssvRegistry: any, ssvNetwork: any -let owner: any, account1: any, account2: any, account3: any -const operatorsPub = Array.from(Array(10).keys()).map(k => `0x${operatorPublicKeyPrefix}${k}`) -const validatorsPub = Array.from(Array(10).keys()).map(k => `0x${validatorPublicKeyPrefix}${k}`) -const operatorsIds = Array.from(Array(10).keys()).map(k => k + 1) -const tokens = '8000000000000000' - -describe('Validator Registration', function () { - beforeEach(async function () { - [owner, account1, account2, account3] = await ethers.getSigners() - const ssvTokenFactory = await ethers.getContractFactory('SSVTokenMock') - const ssvRegistryFactory = await ethers.getContractFactory('SSVRegistry') - const ssvNetworkFactory = await ethers.getContractFactory('SSVNetwork') - ssvToken = await ssvTokenFactory.deploy() - ssvRegistry = await upgrades.deployProxy(ssvRegistryFactory, { initializer: false }) - await ssvToken.deployed() - await ssvRegistry.deployed() - ssvNetwork = await upgrades.deployProxy(ssvNetworkFactory, [ssvRegistry.address, ssvToken.address, minimumBlocksBeforeLiquidation, operatorMaxFeeIncrease, setOperatorFeePeriod, approveOperatorFeePeriod]) - await ssvNetwork.deployed() - - // Mint tokens - await ssvToken.mint(account1.address, '80000000000000000') - - // Register operators - await ssvNetwork.connect(account2).registerOperator('testOperator 0', operatorsPub[0], 100000000000) - await ssvNetwork.connect(account2).registerOperator('testOperator 1', operatorsPub[1], 200000000000) - await ssvNetwork.connect(account3).registerOperator('testOperator 2', operatorsPub[2], 300000000000) - await ssvNetwork.connect(account3).registerOperator('testOperator 3', operatorsPub[3], 400000000000) - await ssvNetwork.connect(account3).registerOperator('testOperator 4', operatorsPub[4], 500000000000) - - // Register Validator - await ssvToken.connect(account1).approve(ssvNetwork.address, tokens) - await expect(ssvNetwork.connect(account1).registerValidator( - validatorsPub[0], operatorsIds.slice(0, 4), operatorsPub.slice(0, 4), operatorsPub.slice(0, 4), tokens)) - .to.emit(ssvNetwork, 'ValidatorRegistration') - }) - - it('Get operators by validator', async function () { - expect((await ssvNetwork.getOperatorsByValidator(validatorsPub[0])).map(String)).to.eql(operatorsIds.slice(0, 4).map(String)) - }) - - it('Register validator errors', async function () { - // Register validator not enough approved tokens - await ssvToken.connect(account1).transfer(account2.address, tokens); - await ssvNetwork.connect(account2).registerValidator( - validatorsPub[1], operatorsIds.slice(0, 4), operatorsPub.slice(0, 4), operatorsPub.slice(0, 4), '10000') - .should.eventually.be.rejectedWith('ERC20: insufficient allowance') - - // Register validator not enough tokens - await ssvToken.connect(account1).approve(ssvNetwork.address, 1); - await ssvNetwork.connect(account2).registerValidator( - validatorsPub[1], operatorsIds.slice(0, 4), operatorsPub.slice(0, 4), operatorsPub.slice(0, 4), '10000') - .should.eventually.be.rejectedWith('ERC20: insufficient allowance') - - // Register validator invalid public key - await ssvToken.connect(account1).approve(ssvNetwork.address, tokens); - await ssvNetwork.connect(account2).registerValidator( - '0x894350h3498345h', operatorsIds.slice(0, 4), operatorsPub.slice(0, 4), operatorsPub.slice(0, 4), '10000') - .should.eventually.be.rejectedWith('invalid arrayify value') - - // Register validator invalid operator ids - await ssvNetwork.connect(account2).registerValidator( - validatorsPub[1], operatorsIds.slice(3, 7), operatorsPub.slice(0, 4), operatorsPub.slice(0, 4), '10000') - .should.eventually.be.rejectedWith('OperatorDeleted') - - // Register validator invalid shares - await ssvNetwork.connect(account2).registerValidator( - validatorsPub[1], operatorsIds.slice(0, 4), ['0x89435h3498345h', '0x89435h3398345h', '0x89435h3441345h', '0x89435h3498d45h'], operatorsPub.slice(0, 4), '10000') - .should.eventually.be.rejectedWith('invalid arrayify value') - - // Register validator invalid enrypted keys - await ssvNetwork.connect(account2).registerValidator( - validatorsPub[1], operatorsIds.slice(0, 4), operatorsPub.slice(0, 4), ['0x89435h3498345h', '0x89435h3398345h', '0x89435h3441345h', '0x89435h3498d45h'], '10000') - .should.eventually.be.rejectedWith('invalid arrayify value') - - // Register validator invalid amount - await ssvNetwork.connect(account2).registerValidator( - validatorsPub[1], operatorsIds.slice(0, 4), operatorsPub.slice(0, 4), ['0x89435h3498345h', '0x89435h3398345h', '0x89435h3441345h', '0x89435h3498d45h'], 1) - .should.eventually.be.rejectedWith('invalid arrayify value') - - expect((await ssvRegistry.activeValidatorCount()).toString()).to.equal('1') - }) -}) diff --git a/test/unit/validator-remove.ts b/test/unit/validator-remove.ts deleted file mode 100644 index 5ab2f874..00000000 --- a/test/unit/validator-remove.ts +++ /dev/null @@ -1,93 +0,0 @@ -// Validator Remove Unit Tests - -// Declare all imports -import * as chai from 'chai' -import chaiAsPromised from 'chai-as-promised' -import { progressBlocks } from '../helpers/utils' -beforeEach(() => { - chai.should() - chai.use(chaiAsPromised) -}) -declare var ethers: any -declare var upgrades: any -const { expect } = chai - -// Define global variables -const DAY = 86400 -const minimumBlocksBeforeLiquidation = 7000 -const operatorMaxFeeIncrease = 10 -const setOperatorFeePeriod = 0 -const approveOperatorFeePeriod = DAY -const operatorPublicKeyPrefix = '12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345' -const validatorPublicKeyPrefix = '98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765' -let ssvToken: any, ssvRegistry: any, ssvNetwork: any -let owner: any, account1: any, account2: any, account3: any -const operatorsPub = Array.from(Array(10).keys()).map(k => `0x${operatorPublicKeyPrefix}${k}`) -const validatorsPub = Array.from(Array(10).keys()).map(k => `0x${validatorPublicKeyPrefix}${k}`) -const operatorsIds = Array.from(Array(10).keys()).map(k => k + 1) - -describe('Validator Removal', function () { - beforeEach(async function () { - [owner, account1, account2, account3] = await ethers.getSigners() - const ssvTokenFactory = await ethers.getContractFactory('SSVTokenMock') - const ssvRegistryFactory = await ethers.getContractFactory('SSVRegistry') - const ssvNetworkFactory = await ethers.getContractFactory('SSVNetwork') - ssvToken = await ssvTokenFactory.deploy() - ssvRegistry = await upgrades.deployProxy(ssvRegistryFactory, { initializer: false }) - await ssvToken.deployed() - await ssvRegistry.deployed() - ssvNetwork = await upgrades.deployProxy(ssvNetworkFactory, [ssvRegistry.address, ssvToken.address, minimumBlocksBeforeLiquidation, operatorMaxFeeIncrease, setOperatorFeePeriod, approveOperatorFeePeriod]) - await ssvNetwork.deployed() - - // Mint tokens - const tokens = '10501500000000000' - await ssvToken.mint(account1.address, tokens) - - // Register operators - await ssvNetwork.connect(account2).registerOperator('testOperator 0', operatorsPub[0], 100000000000) - await ssvNetwork.connect(account2).registerOperator('testOperator 1', operatorsPub[1], 200000000000) - await ssvNetwork.connect(account3).registerOperator('testOperator 2', operatorsPub[2], 300000000000) - await ssvNetwork.connect(account3).registerOperator('testOperator 3', operatorsPub[3], 400000000000) - await ssvNetwork.connect(account3).registerOperator('testOperator 4', operatorsPub[4], 500000000000) - - // Register Validator - await ssvToken.connect(account1).approve(ssvNetwork.address, tokens) - await expect(ssvNetwork.connect(account1).registerValidator( - validatorsPub[0], operatorsIds.slice(0, 4), operatorsPub.slice(0, 4), operatorsPub.slice(0, 4), tokens)) - .to.emit(ssvNetwork, 'ValidatorRegistration') - }) - - it('Remove validator', async function () { - await expect(ssvNetwork.connect(account1).removeValidator(validatorsPub[0])) - .to.emit(ssvNetwork, 'ValidatorRemoval').withArgs(account1.address, validatorsPub[0]) - expect((await ssvRegistry.activeValidatorCount()).toString()).to.equal('0') - - // Try to remove the validator again - await ssvNetwork.connect(account1).removeValidator(validatorsPub[0]) - .should.eventually.be.rejectedWith('ValidatorWithPublicKeyNotExist') - }) - - it('Remove validator non existent key', async function () { - await ssvNetwork.connect(account2).removeValidator(validatorsPub[1]) - .should.eventually.be.rejectedWith('ValidatorWithPublicKeyNotExist') - }) - - it('Remove validator sent by non owner', async function () { - await ssvNetwork.connect(account2).removeValidator(validatorsPub[0]) - .should.eventually.be.rejectedWith('CallerNotValidatorOwner') - }) - - it('Remove validator with not enough SSV', async function () { - await ssvNetwork.connect(account1).withdraw('2501500000000000'); - await progressBlocks(8000); - await ssvNetwork.connect(account1).removeValidator(validatorsPub[0]) - .should.eventually.be.rejectedWith('NegativeBalance') - }) - - // Need to update once functionality added - // it('Remove validator as DAO', async function () { - // await expect(ssvNetwork.connect(owner).removeValidator(validatorsPub[0])) - // .to.emit(ssvRegistry, 'ValidatorRemoved').withArgs(account1.address, validatorsPub[0]) - // expect((await ssvRegistry.activeValidatorCount()).toString()).to.equal('0') - // }) -}) diff --git a/test/unit/validator-update.ts b/test/unit/validator-update.ts deleted file mode 100644 index bd691c0b..00000000 --- a/test/unit/validator-update.ts +++ /dev/null @@ -1,106 +0,0 @@ -// Validator Update Unit Tests - -// Declare all imports -import * as chai from 'chai' -import chaiAsPromised from 'chai-as-promised' -beforeEach(() => { - chai.should() - chai.use(chaiAsPromised) -}) -declare var ethers: any -declare var upgrades: any -const { expect } = chai - -// Define global variables -const DAY = 86400 -const minimumBlocksBeforeLiquidation = 7000 -const operatorMaxFeeIncrease = 10 -const setOperatorFeePeriod = 0 -const approveOperatorFeePeriod = DAY -const operatorPublicKeyPrefix = '12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345' -const validatorPublicKeyPrefix = '98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765' -let ssvToken: any, ssvRegistry: any, ssvNetwork: any -let owner: any, account1: any, account2: any, account3: any -const operatorsPub = Array.from(Array(10).keys()).map(k => `0x${operatorPublicKeyPrefix}${k}`) -const validatorsPub = Array.from(Array(10).keys()).map(k => `0x${validatorPublicKeyPrefix}${k}`) -const operatorsIds = Array.from(Array(10).keys()).map(k => k + 1) -const tokens = '10000000000000' - -describe('Validator Update', function () { - beforeEach(async function () { - [owner, account1, account2, account3] = await ethers.getSigners() - const ssvTokenFactory = await ethers.getContractFactory('SSVTokenMock') - const ssvRegistryFactory = await ethers.getContractFactory('SSVRegistry') - const ssvNetworkFactory = await ethers.getContractFactory('SSVNetwork') - ssvToken = await ssvTokenFactory.deploy() - ssvRegistry = await upgrades.deployProxy(ssvRegistryFactory, { initializer: false }) - await ssvToken.deployed() - await ssvRegistry.deployed() - ssvNetwork = await upgrades.deployProxy(ssvNetworkFactory, [ssvRegistry.address, ssvToken.address, minimumBlocksBeforeLiquidation, operatorMaxFeeIncrease, setOperatorFeePeriod, approveOperatorFeePeriod]) - await ssvNetwork.deployed() - - // Mint tokens - await ssvToken.mint(account1.address, '30501500000000000') - - // Register operators - await ssvNetwork.connect(account2).registerOperator('testOperator 0', operatorsPub[0], 100000000000) - await ssvNetwork.connect(account2).registerOperator('testOperator 1', operatorsPub[1], 200000000000) - await ssvNetwork.connect(account3).registerOperator('testOperator 2', operatorsPub[2], 300000000000) - await ssvNetwork.connect(account3).registerOperator('testOperator 3', operatorsPub[3], 400000000000) - await ssvNetwork.connect(account3).registerOperator('testOperator 4', operatorsPub[4], 500000000000) - - // Register Validator - const tokens = '10501500000000000' - await ssvToken.connect(account1).approve(ssvNetwork.address, tokens) - await expect(ssvNetwork.connect(account1).registerValidator( - validatorsPub[0], operatorsIds.slice(0, 4), operatorsPub.slice(0, 4), operatorsPub.slice(0, 4), tokens)) - .to.emit(ssvNetwork, 'ValidatorRegistration') - }) - - it('Update validator', async function () { - const tokens = '10000000000000' - await ssvToken.connect(account1).approve(ssvNetwork.address, tokens) - const tx = ssvNetwork.connect(account1) - .updateValidator(validatorsPub[0], operatorsIds.slice(0, 4), operatorsPub.slice(0, 4), operatorsPub.slice(0, 4), tokens) - await expect(tx).to.emit(ssvNetwork, 'ValidatorRemoval') - await expect(tx).to.emit(ssvNetwork, 'ValidatorRegistration') - }) - - it('Update validator errorsr', async function () { - const tokens = '10501500000000000' - await ssvToken.connect(account1).approve(ssvNetwork.address, tokens) - await ssvNetwork.connect(account2) - .updateValidator(validatorsPub[0], operatorsIds.slice(0, 4), operatorsPub.slice(0, 4), operatorsPub.slice(0, 4), tokens - ).should.eventually.be.rejectedWith('CallerNotValidatorOwner') - - // Update validator not enough ssv - await ssvNetwork.connect(account2).updateValidator( - '0x89435h3498345h', operatorsIds.slice(0, 4), operatorsPub.slice(0, 4), operatorsPub.slice(0, 4), '20000000000') - .should.eventually.be.rejectedWith('invalid arrayify value') - - // Update validator invalid public key - await ssvNetwork.connect(account2).updateValidator( - '0x89435h3498345h', operatorsIds.slice(0, 4), operatorsPub.slice(0, 4), operatorsPub.slice(0, 4), '10000') - .should.eventually.be.rejectedWith('invalid arrayify value') - - // Update validator invalid operator ids - await ssvNetwork.connect(account2).updateValidator( - validatorsPub[1], operatorsIds.slice(3, 7), operatorsPub.slice(0, 4), operatorsPub.slice(0, 4), '10000') - .should.eventually.be.rejectedWith('ValidatorWithPublicKeyNotExist') - - // Update validator invalid shares - await ssvNetwork.connect(account2).updateValidator( - validatorsPub[1], operatorsIds.slice(0, 4), ['0x89435h3498345h', '0x89435h3398345h', '0x89435h3441345h', '0x89435h3498d45h'], operatorsPub.slice(0, 4), '10000') - .should.eventually.be.rejectedWith('invalid arrayify value') - - // Update validator invalid enrypted keys - await ssvNetwork.connect(account2).updateValidator( - validatorsPub[1], operatorsIds.slice(0, 4), operatorsPub.slice(0, 4), ['0x89435h3498345h', '0x89435h3398345h', '0x89435h3441345h', '0x89435h3498d45h'], '10000') - .should.eventually.be.rejectedWith('invalid arrayify value') - - // Update validator invalid amount - await ssvNetwork.connect(account2).updateValidator( - validatorsPub[1], operatorsIds.slice(0, 4), operatorsPub.slice(0, 4), ['0x89435h3498345h', '0x89435h3398345h', '0x89435h3441345h', '0x89435h3498d45h'], 1) - .should.eventually.be.rejectedWith('invalid arrayify value') - }) -}) From 29830c563e910eb4e108c3a55e32ec1453d3bc2f Mon Sep 17 00:00:00 2001 From: Vadim Date: Mon, 8 Aug 2022 12:04:02 +0200 Subject: [PATCH 002/149] replace owner earns logic by operator --- contracts/SSVRegistry.sol | 48 ++++++++++++++------------------------- 1 file changed, 17 insertions(+), 31 deletions(-) diff --git a/contracts/SSVRegistry.sol b/contracts/SSVRegistry.sol index a54fd80d..fb4c13e2 100644 --- a/contracts/SSVRegistry.sol +++ b/contracts/SSVRegistry.sol @@ -22,6 +22,7 @@ contract SSVRegistryNew { address owner; uint64 fee; uint64 validatorCount; + uint64 earnRate; Snapshot earnings; } @@ -43,13 +44,6 @@ contract SSVRegistryNew { uint64 lastIndex; } - struct Owner { - uint64 earnRate; - uint64 validatorCount; - - Snapshot earnings; - } - event OperatorAdded(uint64 operatorId, address indexed owner, bytes encryptionPK); event OperatorRemoved(uint64 operatorId); event ValidatorAdded(bytes validatorPK, bytes32 groupId); @@ -63,7 +57,6 @@ contract SSVRegistryNew { mapping(bytes32 => OperatorCollection) private _operatorCollections; mapping(address => mapping(bytes32 => Group)) private _groups; mapping(address => uint64) _availableBalances; - mapping(address => Owner) _owners; uint64 private _networkFee; uint64 constant LIQUIDATION_MIN_BLOCKS = 50; @@ -83,7 +76,7 @@ contract SSVRegistryNew { lastOperatorId.increment(); operatorId = uint64(lastOperatorId.current()); - _operators[operatorId] = Operator({ owner: msg.sender, earnings: Snapshot({ block: uint64(block.number), index: 0}), validatorCount: 0, fee: fee }); + _operators[operatorId] = Operator({ owner: msg.sender, earnings: Snapshot({ block: uint64(block.number), index: 0}), validatorCount: 0, fee: fee, earnRate: 0 }); emit OperatorAdded(operatorId, msg.sender, encryptionPK); } @@ -94,12 +87,9 @@ contract SSVRegistryNew { uint64 currentBlock = uint64(block.number); - Owner memory owner = _owners[operator.owner]; - owner.earnings = _updateOwnerEarnings(owner, currentBlock); - owner.earnRate -= operator.fee * operator.validatorCount; - _owners[operator.owner] = owner; - - _operators[operatorId] = _setFee(operator, 0, currentBlock); + operator.earnings = _updateOperatorEarnings(operator, currentBlock); + operator.earnRate -= operator.fee * operator.validatorCount; + _operators[operatorId] = _setFee(operator, 0, currentBlock); // TODO vadim, remove _setFee output operator.validatorCount = 0; emit OperatorRemoved(operatorId); @@ -145,11 +135,9 @@ contract SSVRegistryNew { uint64 currentBlock = uint64(block.number); { for (uint64 i = 0; i < operators.length; ++i) { - Owner memory owner = _owners[operators[i].owner]; - owner.earnings = _updateOwnerEarnings(owner, currentBlock); - ++owner.validatorCount; - owner.earnRate += operators[i].fee; - _owners[operators[i].owner] = owner; + operators[i].earnings = _updateOperatorEarnings(operators[i], currentBlock); + operators[i].earnRate += operators[i].fee; + ++operators[i].validatorCount; } } @@ -201,11 +189,11 @@ contract SSVRegistryNew { return (key, operatorCollection); } - function _updateOwnerEarnings(Owner memory owner, uint64 currentBlock) private returns (Snapshot memory) { - owner.earnings.index = _ownerCurrentEarnings(owner, currentBlock); - owner.earnings.block = currentBlock; + function _updateOperatorEarnings(Operator memory operator, uint64 currentBlock) private returns (Snapshot memory) { + operator.earnings.index = _operatorCurrentEarnings(operator, currentBlock); + operator.earnings.block = currentBlock; - return owner.earnings; + return operator.earnings; } function _updateDAOEarnings(DAO memory dao, uint64 currentBlock) private returns (DAO memory) { @@ -215,8 +203,8 @@ contract SSVRegistryNew { return dao; } - function _ownerCurrentEarnings(Owner memory owner, uint64 currentBlock) private returns (uint64) { - return owner.earnings.index + (currentBlock - owner.earnings.block) * owner.earnRate; + function _operatorCurrentEarnings(Operator memory operator, uint64 currentBlock) private returns (uint64) { + return operator.earnings.index + (currentBlock - operator.earnings.block) * operator.earnRate; } function _extractOperators(OperatorCollection memory operatorCollection) private view returns (Operator[] memory) { @@ -274,11 +262,9 @@ contract SSVRegistryNew { uint64 currentBlock = uint64(block.number); { for (uint64 i = 0; i < operators.length; ++i) { - Owner memory owner = _owners[operators[i].owner]; - owner.earnings = _updateOwnerEarnings(owner, currentBlock); - owner.earnRate -= operators[i].fee; - --owner.validatorCount; - _owners[operators[i].owner] = owner; + operators[i].earnings = _updateOperatorEarnings(operators[i], currentBlock); + operators[i].earnRate -= operators[i].fee; + --operators[i].validatorCount; } } } From cdc607f7ee5194e08727dab42887d4abb072b548 Mon Sep 17 00:00:00 2001 From: Vadim Date: Mon, 8 Aug 2022 12:11:35 +0200 Subject: [PATCH 003/149] turn off optimizer --- hardhat.config.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hardhat.config.ts b/hardhat.config.ts index 1a4d06bc..85c5c3fe 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -17,10 +17,12 @@ const config: HardhatUserConfig = { { version: '0.8.13', settings: { + /* optimizer: { enabled: true, runs: 10000 } + */ } } ], From 455abfa19ca06bebca217cab3db29bb6e0077064 Mon Sep 17 00:00:00 2001 From: Vadim Date: Mon, 8 Aug 2022 16:27:53 +0200 Subject: [PATCH 004/149] wip optimisation --- contracts/SSVRegistry.sol | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/contracts/SSVRegistry.sol b/contracts/SSVRegistry.sol index fb4c13e2..99aae955 100644 --- a/contracts/SSVRegistry.sol +++ b/contracts/SSVRegistry.sol @@ -95,14 +95,6 @@ contract SSVRegistryNew { emit OperatorRemoved(operatorId); } - function _createOperatorCollection(uint64[] memory operators) private returns (uint64 groupId) { - for (uint64 index = 0; index < operators.length; ++index) { - require(_operators[operators[index]].owner != address(0), "operator not found"); - } - - _operatorCollections[keccak256(abi.encodePacked(operators))] = OperatorCollection({ operatorIds: operators }); - } - function registerValidator( uint64[] memory operatorIds, bytes calldata validatorPK, @@ -114,9 +106,8 @@ contract SSVRegistryNew { { Operator[] memory operators; { - OperatorCollection memory operatorCollection; - (groupId, operatorCollection) = _getOrCreateOperatorCollection(operatorIds); - operators = _extractOperators(operatorCollection); + groupId = _getOrCreateOperatorCollection(operatorIds); + operators = _extractOperators(operatorIds); } Group memory group; @@ -163,6 +154,14 @@ contract SSVRegistryNew { _availableBalances[msg.sender] += amount; } + function _createOperatorCollection(uint64[] memory operators) private returns (uint64 groupId) { + for (uint64 index = 0; index < operators.length; ++index) { + require(_operators[operators[index]].owner != address(0), "operator not found"); + } + + _operatorCollections[keccak256(abi.encodePacked(operators))] = OperatorCollection({ operatorIds: operators }); + } + function _setFee(Operator memory operator, uint64 fee, uint64 currentBlock) private returns (Operator memory) { operator.earnings = _updateOperatorIndex(operator, currentBlock); operator.fee = fee; @@ -174,7 +173,7 @@ contract SSVRegistryNew { return Snapshot({ index: _operatorCurrentIndex(operator), block: currentBlock }); } - function _getOrCreateOperatorCollection(uint64[] memory operatorIds) private returns (bytes32, OperatorCollection memory) { + function _getOrCreateOperatorCollection(uint64[] memory operatorIds) private returns (bytes32) { // , OperatorCollection memory for (uint64 i = 0; i < operatorIds.length - 1;) { require(operatorIds[i] <= operatorIds[++i]); } @@ -186,7 +185,7 @@ contract SSVRegistryNew { operatorCollection.operatorIds = operatorIds; } - return (key, operatorCollection); + return key; // (key, operatorCollection); } function _updateOperatorEarnings(Operator memory operator, uint64 currentBlock) private returns (Snapshot memory) { @@ -207,10 +206,10 @@ contract SSVRegistryNew { return operator.earnings.index + (currentBlock - operator.earnings.block) * operator.earnRate; } - function _extractOperators(OperatorCollection memory operatorCollection) private view returns (Operator[] memory) { - Operator[] memory operators = new Operator[](operatorCollection.operatorIds.length); - for (uint64 i = 0; i < operatorCollection.operatorIds.length; ++i) { - operators[i] = _operators[operatorCollection.operatorIds[i]]; + function _extractOperators(uint64[] memory operatorIds) private view returns (Operator[] memory) { + Operator[] memory operators = new Operator[](operatorIds.length); + for (uint64 i = 0; i < operatorIds.length; ++i) { + operators[i] = _operators[operatorIds[i]]; } return operators; From 69774570c8642441f867727c3f5fc55074853051 Mon Sep 17 00:00:00 2001 From: Vadim Date: Mon, 8 Aug 2022 18:25:17 +0200 Subject: [PATCH 005/149] WIP updateValidator --- contracts/SSVRegistry.sol | 85 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/contracts/SSVRegistry.sol b/contracts/SSVRegistry.sol index 99aae955..66458193 100644 --- a/contracts/SSVRegistry.sol +++ b/contracts/SSVRegistry.sol @@ -148,6 +148,91 @@ contract SSVRegistryNew { emit ValidatorAdded(validatorPK, groupId); } + function updateValidator( + uint64[] memory operatorIds, + bytes32 currentGroupId, + bytes calldata validatorPK, + uint64 amount + ) external { + { + Group memory group = _groups[msg.sender][currentGroupId]; + OperatorCollection memory operatorCollection = _operatorCollections[currentGroupId]; + Operator[] memory operators = _extractOperators(operatorCollection.operatorIds); + + uint64 groupIndex = _groupCurrentIndex(operators); + group.balance = _ownerGroupBalance(group, groupIndex); + group.lastIndex = groupIndex; + --group.validatorCount; + + uint64 currentBlock = uint64(block.number); + + for (uint64 i = 0; i < operatorCollection.operatorIds.length; ++i) { + bool found; + for (uint64 j = 0; j < operatorIds.length; ++j) { + if (operatorCollection.operatorIds[i] == operatorIds[j]) { + found = true; + } + } + if (!found) { + operators[i].earnings = _updateOperatorEarnings(operators[i], currentBlock); + operators[i].earnRate -= operators[i].fee; + --operators[i].validatorCount; + } + } + + for (uint64 i = 0; i < operatorIds.length; ++i) { + bool found; + for (uint64 j = 0; j < operatorCollection.operatorIds.length; ++j) { + if (operatorIds[i] == operatorCollection.operatorIds[j]) { + found = true; + } + } + if (!found) { + Operator memory operator = _operators[operatorIds[i]]; + operator.earnings = _updateOperatorEarnings(operator, currentBlock); + operator.earnRate += operators[i].fee; + ++operator.validatorCount; + } + } + } + + bytes32 newGroupId; + { + Operator[] memory operators; + { + newGroupId = _getOrCreateOperatorCollection(operatorIds); + operators = _extractOperators(operatorIds); + } + + Group memory group; + { + uint64 groupIndex = _groupCurrentIndex(operators); + + _availableBalances[msg.sender] -= amount; + + group = _groups[msg.sender][newGroupId]; + + group.balance = _ownerGroupBalance(group, groupIndex) + amount; + group.lastIndex = groupIndex; + ++group.validatorCount; + } + + { + // // update DAO earnings + DAO memory dao = _dao; + dao = _updateDAOEarnings(dao, uint64(block.number)); + ++dao.validatorCount; + _dao = dao; + } + + require(!_liquidatable(group.balance, group.validatorCount, operators), "account liquidatable"); + + _groups[msg.sender][newGroupId] = group; + } + + emit ValidatorAdded(validatorPK, newGroupId); + } + // function removeValidator(validatorPK) function deposit(uint64 amount) public { From 0367a16f90413db5de29d109c6863f6ae6321d77 Mon Sep 17 00:00:00 2001 From: Vadim Date: Wed, 10 Aug 2022 09:20:26 +0200 Subject: [PATCH 006/149] remove & update & tests --- contracts/SSVRegistry.sol | 51 +++++++++++++++++++++++++++++++++------ test/unit/ssv-registry.js | 33 ++++++++++++++++++++++++- 2 files changed, 76 insertions(+), 8 deletions(-) diff --git a/contracts/SSVRegistry.sol b/contracts/SSVRegistry.sol index 66458193..9d1c8d76 100644 --- a/contracts/SSVRegistry.sol +++ b/contracts/SSVRegistry.sol @@ -47,6 +47,8 @@ contract SSVRegistryNew { event OperatorAdded(uint64 operatorId, address indexed owner, bytes encryptionPK); event OperatorRemoved(uint64 operatorId); event ValidatorAdded(bytes validatorPK, bytes32 groupId); + event ValidatorUpdated(bytes validatorPK, bytes32 groupId); + event ValidatorRemoved(bytes validatorPK, bytes32 groupId); // global vars Counters.Counter private lastOperatorId; @@ -77,7 +79,6 @@ contract SSVRegistryNew { lastOperatorId.increment(); operatorId = uint64(lastOperatorId.current()); _operators[operatorId] = Operator({ owner: msg.sender, earnings: Snapshot({ block: uint64(block.number), index: 0}), validatorCount: 0, fee: fee, earnRate: 0 }); - emit OperatorAdded(operatorId, msg.sender, encryptionPK); } @@ -150,8 +151,8 @@ contract SSVRegistryNew { function updateValidator( uint64[] memory operatorIds, - bytes32 currentGroupId, bytes calldata validatorPK, + bytes32 currentGroupId, uint64 amount ) external { { @@ -175,8 +176,8 @@ contract SSVRegistryNew { } if (!found) { operators[i].earnings = _updateOperatorEarnings(operators[i], currentBlock); - operators[i].earnRate -= operators[i].fee; - --operators[i].validatorCount; + // operators[i].earnRate -= operators[i].fee; + // --operators[i].validatorCount; } } @@ -221,7 +222,6 @@ contract SSVRegistryNew { // // update DAO earnings DAO memory dao = _dao; dao = _updateDAOEarnings(dao, uint64(block.number)); - ++dao.validatorCount; _dao = dao; } @@ -230,7 +230,45 @@ contract SSVRegistryNew { _groups[msg.sender][newGroupId] = group; } - emit ValidatorAdded(validatorPK, newGroupId); + emit ValidatorUpdated(validatorPK, newGroupId); + } + + function removeValidator( + bytes calldata validatorPK, + bytes32 groupId + ) external { + { + Group memory group = _groups[msg.sender][groupId]; + OperatorCollection memory operatorCollection = _operatorCollections[groupId]; + Operator[] memory operators = _extractOperators(operatorCollection.operatorIds); + + uint64 groupIndex = _groupCurrentIndex(operators); + group.balance = _ownerGroupBalance(group, groupIndex); + group.lastIndex = groupIndex; + --group.validatorCount; + + uint64 currentBlock = uint64(block.number); + + for (uint64 i = 0; i < operators.length; ++i) { + operators[i].earnings = _updateOperatorEarnings(operators[i], currentBlock); + // operators[i].earnRate -= operators[i].fee; + // --operators[i].validatorCount; + } + + { + // // update DAO earnings + DAO memory dao = _dao; + dao = _updateDAOEarnings(dao, uint64(block.number)); + --dao.validatorCount; + _dao = dao; + } + } + + emit ValidatorRemoved(validatorPK, groupId); + } + + function test_getOperatorsByGroupId(bytes32 groupId) external view returns (uint64[] memory) { + return _operatorCollections[groupId].operatorIds; } // function removeValidator(validatorPK) @@ -296,7 +334,6 @@ contract SSVRegistryNew { for (uint64 i = 0; i < operatorIds.length; ++i) { operators[i] = _operators[operatorIds[i]]; } - return operators; } diff --git a/test/unit/ssv-registry.js b/test/unit/ssv-registry.js index c40d67ce..1c7829b2 100644 --- a/test/unit/ssv-registry.js +++ b/test/unit/ssv-registry.js @@ -8,7 +8,7 @@ async function mineNBlocks(n) { } } -const operatorsIndexes = Array.from(Array(4).keys()).map(k => k + 1); +const operatorsIndexes = Array.from(Array(5).keys()).map(k => k + 1); describe("Validators", () => { @@ -62,6 +62,37 @@ describe("Validators", () => { .to.emit(deployedRegistryContract, 'ValidatorAdded') .withArgs(validatorPK); + + const resultRegister = (await (await deployedRegistryContract.registerValidator( + [1,2,3,4], + validatorPK, + sharePKs.slice(0, 4), + encryptedShares.slice(0, 4), + '10000' + )).wait()).logs[0]; + const interfaceRegister = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId)']); + const outputRegister = interfaceRegister.decodeEventLog('ValidatorAdded', resultRegister.data, resultRegister.topics); + console.log("register ---->", outputRegister.validatorPK, outputRegister.groupId); + console.log("operatorIdsAfterRegister ---->", await deployedRegistryContract.test_getOperatorsByGroupId(outputRegister.groupId)); + + const resultUpdate = (await (await deployedRegistryContract.updateValidator( + [2,3,4,5], + validatorPK, + outputRegister.groupId, + '10000' + )).wait()).logs[0];; + const interfaceUpdate = new ethers.utils.Interface(['event ValidatorUpdated(bytes validatorPK, bytes32 groupId)']); + const outputUpdate = interfaceUpdate.decodeEventLog('ValidatorUpdated', resultUpdate.data, resultUpdate.topics); + console.log("update ---->", outputUpdate.validatorPK, outputUpdate.groupId); + console.log("operatorIdsAfterUpdate ---->", await deployedRegistryContract.test_getOperatorsByGroupId(outputUpdate.groupId)); + + expect(await deployedRegistryContract.removeValidator( + validatorPK, + outputUpdate.groupId + )) + .to.emit(deployedRegistryContract, 'ValidatorRemoved') + .withArgs(validatorPK, outputUpdate.groupId); + // await deployedRegistryContract.liquidate("0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", "0x392791df626408017a264f53fde61065d5a93a32b60171df9d8a46afdf82992d"); }); }); From 4f782908ad1498400dba9c70b827d7a6a207c78c Mon Sep 17 00:00:00 2001 From: Vadim Date: Wed, 10 Aug 2022 09:33:29 +0200 Subject: [PATCH 007/149] fix tests --- test/unit/ssv-registry.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/unit/ssv-registry.js b/test/unit/ssv-registry.js index 1c7829b2..6dbc411a 100644 --- a/test/unit/ssv-registry.js +++ b/test/unit/ssv-registry.js @@ -41,7 +41,7 @@ describe("Validators", () => { await deployedRegistryContract.deposit("100000000000"); // validator 1 - expect(await deployedRegistryContract.registerValidator( + await expect(await deployedRegistryContract.registerValidator( [1,2,3,4], validatorPK, sharePKs.slice(0, 4), @@ -52,7 +52,7 @@ describe("Validators", () => { .withArgs(validatorPK); // validator 2 - expect(await deployedRegistryContract.registerValidator( + await expect(await deployedRegistryContract.registerValidator( [1,2,3,4], validatorPK, sharePKs.slice(0, 4), @@ -86,7 +86,7 @@ describe("Validators", () => { console.log("update ---->", outputUpdate.validatorPK, outputUpdate.groupId); console.log("operatorIdsAfterUpdate ---->", await deployedRegistryContract.test_getOperatorsByGroupId(outputUpdate.groupId)); - expect(await deployedRegistryContract.removeValidator( + await expect(await deployedRegistryContract.removeValidator( validatorPK, outputUpdate.groupId )) From b90da20bb6c1da5af657723916755eb80505cd03 Mon Sep 17 00:00:00 2001 From: Vadim Date: Wed, 10 Aug 2022 09:37:15 +0200 Subject: [PATCH 008/149] wip improve tests --- test/unit/ssv-registry.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/test/unit/ssv-registry.js b/test/unit/ssv-registry.js index 6dbc411a..a9ec8770 100644 --- a/test/unit/ssv-registry.js +++ b/test/unit/ssv-registry.js @@ -48,8 +48,8 @@ describe("Validators", () => { encryptedShares.slice(0, 4), "10000" )) - .to.emit(deployedRegistryContract, 'ValidatorAdded') - .withArgs(validatorPK); + .to.emit(deployedRegistryContract, 'ValidatorAdded'); + //.withArgs(validatorPK); // validator 2 await expect(await deployedRegistryContract.registerValidator( @@ -59,8 +59,8 @@ describe("Validators", () => { encryptedShares.slice(0, 4), "10000" )) - .to.emit(deployedRegistryContract, 'ValidatorAdded') - .withArgs(validatorPK); + .to.emit(deployedRegistryContract, 'ValidatorAdded'); + // .withArgs(validatorPK); const resultRegister = (await (await deployedRegistryContract.registerValidator( @@ -72,6 +72,8 @@ describe("Validators", () => { )).wait()).logs[0]; const interfaceRegister = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId)']); const outputRegister = interfaceRegister.decodeEventLog('ValidatorAdded', resultRegister.data, resultRegister.topics); + expect(outputRegister.validatorPK).to.equal(validatorPK); + console.log("register ---->", outputRegister.validatorPK, outputRegister.groupId); console.log("operatorIdsAfterRegister ---->", await deployedRegistryContract.test_getOperatorsByGroupId(outputRegister.groupId)); @@ -83,6 +85,9 @@ describe("Validators", () => { )).wait()).logs[0];; const interfaceUpdate = new ethers.utils.Interface(['event ValidatorUpdated(bytes validatorPK, bytes32 groupId)']); const outputUpdate = interfaceUpdate.decodeEventLog('ValidatorUpdated', resultUpdate.data, resultUpdate.topics); + expect(outputRegister.groupId).not.equal(outputUpdate.groupId); + expect(outputRegister.validatorPK).to.equal(outputUpdate.validatorPK); + console.log("update ---->", outputUpdate.validatorPK, outputUpdate.groupId); console.log("operatorIdsAfterUpdate ---->", await deployedRegistryContract.test_getOperatorsByGroupId(outputUpdate.groupId)); From cc06aaae99d4e0593bb15b2ce609957809f57049 Mon Sep 17 00:00:00 2001 From: Vadim Date: Wed, 10 Aug 2022 15:36:23 +0200 Subject: [PATCH 009/149] wip --- contracts/SSVRegistry.sol | 66 ++++++++++++++++++++++----------------- 1 file changed, 38 insertions(+), 28 deletions(-) diff --git a/contracts/SSVRegistry.sol b/contracts/SSVRegistry.sol index 9d1c8d76..4ff7526a 100644 --- a/contracts/SSVRegistry.sol +++ b/contracts/SSVRegistry.sol @@ -108,13 +108,11 @@ contract SSVRegistryNew { Operator[] memory operators; { groupId = _getOrCreateOperatorCollection(operatorIds); - operators = _extractOperators(operatorIds); } Group memory group; { - uint64 groupIndex = _groupCurrentIndex(operators); - + uint64 groupIndex = _groupCurrentIndex(operatorIds); _availableBalances[msg.sender] -= amount; group = _groups[msg.sender][groupId]; @@ -126,10 +124,10 @@ contract SSVRegistryNew { uint64 currentBlock = uint64(block.number); { - for (uint64 i = 0; i < operators.length; ++i) { - operators[i].earnings = _updateOperatorEarnings(operators[i], currentBlock); - operators[i].earnRate += operators[i].fee; - ++operators[i].validatorCount; + for (uint64 i = 0; i < operatorIds.length; ++i) { + _operators[operatorIds[i]].earnings = _updateOperatorEarnings(_operators[operatorIds[i]], currentBlock); + _operators[operatorIds[i]].earnRate += _operators[operatorIds[i]].fee; + ++_operators[operatorIds[i]].validatorCount; } } @@ -158,13 +156,15 @@ contract SSVRegistryNew { { Group memory group = _groups[msg.sender][currentGroupId]; OperatorCollection memory operatorCollection = _operatorCollections[currentGroupId]; - Operator[] memory operators = _extractOperators(operatorCollection.operatorIds); - uint64 groupIndex = _groupCurrentIndex(operators); - group.balance = _ownerGroupBalance(group, groupIndex); + uint64 groupIndex = _groupCurrentIndex(operatorCollection.operatorIds); group.lastIndex = groupIndex; --group.validatorCount; + if (group.validatorCount == 0) { + // _availableBalances[msg.sender] += _ownerGroupBalance(group, groupIndex); + // group.balance -= _ownerGroupBalance(group, groupIndex); + } uint64 currentBlock = uint64(block.number); for (uint64 i = 0; i < operatorCollection.operatorIds.length; ++i) { @@ -175,9 +175,10 @@ contract SSVRegistryNew { } } if (!found) { - operators[i].earnings = _updateOperatorEarnings(operators[i], currentBlock); - // operators[i].earnRate -= operators[i].fee; - // --operators[i].validatorCount; + uint64 id = operatorCollection.operatorIds[i]; + _operators[id].earnings = _updateOperatorEarnings(_operators[id], currentBlock); + _operators[id].earnRate -= _operators[id].fee; + --_operators[id].validatorCount; } } @@ -189,12 +190,13 @@ contract SSVRegistryNew { } } if (!found) { - Operator memory operator = _operators[operatorIds[i]]; - operator.earnings = _updateOperatorEarnings(operator, currentBlock); - operator.earnRate += operators[i].fee; - ++operator.validatorCount; + uint64 id = operatorIds[i]; + _operators[id].earnings = _updateOperatorEarnings(_operators[id], currentBlock); + _operators[id].earnRate += _operators[id].fee; + ++_operators[id].validatorCount; } } + _groups[msg.sender][currentGroupId] = group; } bytes32 newGroupId; @@ -207,7 +209,7 @@ contract SSVRegistryNew { Group memory group; { - uint64 groupIndex = _groupCurrentIndex(operators); + uint64 groupIndex = _groupCurrentIndex(operatorIds); _availableBalances[msg.sender] -= amount; @@ -240,19 +242,24 @@ contract SSVRegistryNew { { Group memory group = _groups[msg.sender][groupId]; OperatorCollection memory operatorCollection = _operatorCollections[groupId]; - Operator[] memory operators = _extractOperators(operatorCollection.operatorIds); - uint64 groupIndex = _groupCurrentIndex(operators); + uint64 groupIndex = _groupCurrentIndex(operatorCollection.operatorIds); group.balance = _ownerGroupBalance(group, groupIndex); group.lastIndex = groupIndex; --group.validatorCount; + if (group.validatorCount == 0) { + // _availableBalances[msg.sender] += _ownerGroupBalance(group, groupIndex); + // group.balance -= _ownerGroupBalance(group, groupIndex); + } + uint64 currentBlock = uint64(block.number); - for (uint64 i = 0; i < operators.length; ++i) { - operators[i].earnings = _updateOperatorEarnings(operators[i], currentBlock); - // operators[i].earnRate -= operators[i].fee; - // --operators[i].validatorCount; + for (uint64 i = 0; i < operatorCollection.operatorIds.length; ++i) { + uint64 id = operatorCollection.operatorIds[i]; + _operators[id].earnings = _updateOperatorEarnings(_operators[id], currentBlock); + _operators[id].earnRate -= _operators[id].fee; + --_operators[id].validatorCount; } { @@ -262,6 +269,8 @@ contract SSVRegistryNew { --dao.validatorCount; _dao = dao; } + + _groups[msg.sender][groupId] = group; } emit ValidatorRemoved(validatorPK, groupId); @@ -345,9 +354,9 @@ contract SSVRegistryNew { return _networkTotalEarnings(dao, currentBlock) - dao.withdrawn; } - function _groupCurrentIndex(Operator[] memory operators) private view returns (uint64 groupIndex) { - for (uint64 i = 0; i < operators.length; ++i) { - groupIndex += _operatorCurrentIndex(operators[i]); + function _groupCurrentIndex(uint64[] memory operatorIds) private view returns (uint64 groupIndex) { + for (uint64 i = 0; i < operatorIds.length; ++i) { + groupIndex += _operatorCurrentIndex(_operators[operatorIds[i]]); } } @@ -368,7 +377,7 @@ contract SSVRegistryNew { function _liquidatable(uint64 balance, uint64 validatorCount, Operator[] memory operators) private view returns (bool) { return balance < LIQUIDATION_MIN_BLOCKS * (_burnRatePerValidator(operators) + _networkFee) * validatorCount; } - + /* function liquidate(address owner, bytes32 groupId) external { OperatorCollection memory operatorCollection = _operatorCollections[groupId]; Operator[] memory operators = new Operator[](operatorCollection.operatorIds.length); @@ -389,6 +398,7 @@ contract SSVRegistryNew { } } } + */ // function addOperatorToValidator( // function _validateRegistryState( From ab0f45d967854bd8b505fa395fa5bc14131b172f Mon Sep 17 00:00:00 2001 From: Vadim Date: Wed, 10 Aug 2022 18:39:21 +0200 Subject: [PATCH 010/149] wip --- contracts/SSVRegistry.sol | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/contracts/SSVRegistry.sol b/contracts/SSVRegistry.sol index 4ff7526a..d2c825bf 100644 --- a/contracts/SSVRegistry.sol +++ b/contracts/SSVRegistry.sol @@ -116,7 +116,7 @@ contract SSVRegistryNew { _availableBalances[msg.sender] -= amount; group = _groups[msg.sender][groupId]; - + console.log(amount, groupIndex); group.balance = _ownerGroupBalance(group, groupIndex) + amount; group.lastIndex = groupIndex; ++group.validatorCount; @@ -364,7 +364,8 @@ contract SSVRegistryNew { return operator.earnings.index + (uint64(block.number) - operator.earnings.block) * operator.fee; } - function _ownerGroupBalance(Group memory group, uint64 currentGroupIndex) private pure returns (uint64) { + function _ownerGroupBalance(Group memory group, uint64 currentGroupIndex) private view returns (uint64) { + console.log(currentGroupIndex, group.lastIndex); return group.balance - (currentGroupIndex - group.lastIndex) * group.validatorCount; } From b85dbbf873da04c8d687780d617bd961b1b62342 Mon Sep 17 00:00:00 2001 From: Vadim Date: Mon, 15 Aug 2022 00:36:10 +0200 Subject: [PATCH 011/149] wip logic math --- contracts/SSVRegistry.sol | 81 +++++++++++++++++++++++++++++++-------- test/unit/ssv-registry.js | 64 +++++++++++++++++++++++-------- 2 files changed, 113 insertions(+), 32 deletions(-) diff --git a/contracts/SSVRegistry.sol b/contracts/SSVRegistry.sol index d2c825bf..065a1705 100644 --- a/contracts/SSVRegistry.sol +++ b/contracts/SSVRegistry.sol @@ -15,7 +15,7 @@ contract SSVRegistryNew { // index is the last index calculated by index += (currentBlock - block) * fee uint64 index; // accumulated is all the accumulated earnings, calculated by accumulated + lastIndex * validatorCount - // uint64 accumulated; + uint64 balance; } struct Operator { @@ -42,6 +42,8 @@ contract SSVRegistryNew { uint64 balance; uint64 validatorCount; uint64 lastIndex; + + Snapshot usage; } event OperatorAdded(uint64 operatorId, address indexed owner, bytes encryptionPK); @@ -78,7 +80,7 @@ contract SSVRegistryNew { lastOperatorId.increment(); operatorId = uint64(lastOperatorId.current()); - _operators[operatorId] = Operator({ owner: msg.sender, earnings: Snapshot({ block: uint64(block.number), index: 0}), validatorCount: 0, fee: fee, earnRate: 0 }); + _operators[operatorId] = Operator({ owner: msg.sender, earnings: Snapshot({ block: uint64(block.number), index: 0, balance: 0}), validatorCount: 0, fee: fee, earnRate: 0 }); emit OperatorAdded(operatorId, msg.sender, encryptionPK); } @@ -90,7 +92,7 @@ contract SSVRegistryNew { operator.earnings = _updateOperatorEarnings(operator, currentBlock); operator.earnRate -= operator.fee * operator.validatorCount; - _operators[operatorId] = _setFee(operator, 0, currentBlock); // TODO vadim, remove _setFee output + _operators[operatorId] = _setFee(operator, 0, currentBlock); operator.validatorCount = 0; emit OperatorRemoved(operatorId); @@ -111,18 +113,20 @@ contract SSVRegistryNew { } Group memory group; + uint64 currentBlock = uint64(block.number); { - uint64 groupIndex = _groupCurrentIndex(operatorIds); + uint64 groupIndex = _groupCurrentIndex(groupId); _availableBalances[msg.sender] -= amount; group = _groups[msg.sender][groupId]; console.log(amount, groupIndex); group.balance = _ownerGroupBalance(group, groupIndex) + amount; - group.lastIndex = groupIndex; + //group.lastIndex = groupIndex; + // group.usage = _updateGroupUsage(group, currentBlock); + ++group.validatorCount; } - uint64 currentBlock = uint64(block.number); { for (uint64 i = 0; i < operatorIds.length; ++i) { _operators[operatorIds[i]].earnings = _updateOperatorEarnings(_operators[operatorIds[i]], currentBlock); @@ -147,6 +151,7 @@ contract SSVRegistryNew { emit ValidatorAdded(validatorPK, groupId); } + /* function updateValidator( uint64[] memory operatorIds, bytes calldata validatorPK, @@ -275,11 +280,32 @@ contract SSVRegistryNew { emit ValidatorRemoved(validatorPK, groupId); } - + */ function test_getOperatorsByGroupId(bytes32 groupId) external view returns (uint64[] memory) { return _operatorCollections[groupId].operatorIds; } + function test_getOperatorBalance(uint64 operatorId) external view returns (uint64) { + return _operatorCurrentEarnings(_operators[operatorId], uint64(block.number)); + } + + function test_operatorCurrentIndex(uint64 operatorId) external view returns (uint64) { + return _operatorCurrentIndex(_operators[operatorId]); + } + + function test_groupCurrentIndex(bytes32 groupId) external view returns (uint64) { + return _groupCurrentIndex(groupId); + } + + function test_groupCurrentUsage(bytes32 groupId) external view returns (uint64) { + return _groupCurrentUsage(groupId); + } + + function test_groupBalance(bytes32 groupId) external view returns (uint64) { + Group memory group = _groups[msg.sender][groupId]; + return group.balance - _groupCurrentUsage(groupId); + } + // function removeValidator(validatorPK) function deposit(uint64 amount) public { @@ -295,15 +321,17 @@ contract SSVRegistryNew { } function _setFee(Operator memory operator, uint64 fee, uint64 currentBlock) private returns (Operator memory) { - operator.earnings = _updateOperatorIndex(operator, currentBlock); + // operator.earnings = _updateOperatorIndex(operator, currentBlock); operator.fee = fee; return operator; } + /* function _updateOperatorIndex(Operator memory operator, uint64 currentBlock) private returns (Snapshot memory) { return Snapshot({ index: _operatorCurrentIndex(operator), block: currentBlock }); } + */ function _getOrCreateOperatorCollection(uint64[] memory operatorIds) private returns (bytes32) { // , OperatorCollection memory for (uint64 i = 0; i < operatorIds.length - 1;) { @@ -321,21 +349,40 @@ contract SSVRegistryNew { } function _updateOperatorEarnings(Operator memory operator, uint64 currentBlock) private returns (Snapshot memory) { - operator.earnings.index = _operatorCurrentEarnings(operator, currentBlock); + operator.earnings.balance = _operatorCurrentEarnings(operator, currentBlock); operator.earnings.block = currentBlock; return operator.earnings; } function _updateDAOEarnings(DAO memory dao, uint64 currentBlock) private returns (DAO memory) { - dao.earnings.index = _networkTotalEarnings(dao, currentBlock); + dao.earnings.balance = _networkTotalEarnings(dao, currentBlock); dao.earnings.block = currentBlock; return dao; } - function _operatorCurrentEarnings(Operator memory operator, uint64 currentBlock) private returns (uint64) { - return operator.earnings.index + (currentBlock - operator.earnings.block) * operator.earnRate; + /* + function _updateGroupUsage(Group memory group, uint64 currentBlock) private returns (Snapshot memory) { + group.usage.index = _groupCurrentUsage(group, currentBlock); + group.usage.block = currentBlock; + return group.usage; + } + */ + + function _operatorCurrentEarnings(Operator memory operator, uint64 currentBlock) private view returns (uint64) { + return operator.earnings.balance + (currentBlock - operator.earnings.block) * operator.earnRate; + } + + /* + function _groupCurrentUsage(Group memory group, uint64 currentBlock) private view returns (uint64) { + return group.usage.index + (currentBlock - group.usage.block) * group.validatorCount; + } + */ + + function _groupCurrentUsage(bytes32 groupId) private view returns (uint64) { + Group memory group = _groups[msg.sender][groupId]; + return _groupCurrentIndex(groupId) - group.usage.index; } function _extractOperators(uint64[] memory operatorIds) private view returns (Operator[] memory) { @@ -347,16 +394,18 @@ contract SSVRegistryNew { } function _networkTotalEarnings(DAO memory dao, uint64 currentBlock) private view returns (uint64) { - return dao.earnings.index + (currentBlock - dao.earnings.block) * _networkFee * dao.validatorCount; + return dao.earnings.balance + (currentBlock - dao.earnings.block) * _networkFee * dao.validatorCount; } function _networkBalance(DAO memory dao, uint64 currentBlock) private view returns (uint64) { return _networkTotalEarnings(dao, currentBlock) - dao.withdrawn; } - function _groupCurrentIndex(uint64[] memory operatorIds) private view returns (uint64 groupIndex) { - for (uint64 i = 0; i < operatorIds.length; ++i) { - groupIndex += _operatorCurrentIndex(_operators[operatorIds[i]]); + function _groupCurrentIndex(bytes32 groupId) private view returns (uint64 groupIndex) { + OperatorCollection memory operatorCollection = _operatorCollections[groupId]; + for (uint64 i = 0; i < operatorCollection.operatorIds.length; ++i) { + console.log("+", operatorCollection.operatorIds[i], _operatorCurrentIndex(_operators[operatorCollection.operatorIds[i]])); + groupIndex += _operatorCurrentIndex(_operators[operatorCollection.operatorIds[i]]); } } diff --git a/test/unit/ssv-registry.js b/test/unit/ssv-registry.js index a9ec8770..1db30e2a 100644 --- a/test/unit/ssv-registry.js +++ b/test/unit/ssv-registry.js @@ -1,4 +1,5 @@ const { expect } = require("chai"); +const { progressBlocks, blockNumber } = require('./utils'); const operator_fee_block = 1; @@ -18,17 +19,16 @@ describe("Validators", () => { deployedRegistryContract = await Registry.deploy(); await deployedRegistryContract.deployed(); - for (let i = 0; i < operatorsIndexes.length; i++) { + await progressBlocks(99); + for (let i = 0; i < 2; i++) { // operatorsIndexes.length + console.log(`[BLOCK] ${await blockNumber()}`) + console.log('> register operator', i); var encryptionPK = "0x123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123451"; - await deployedRegistryContract.registerOperator(encryptionPK, operator_fee_block); + await (await deployedRegistryContract.registerOperator(encryptionPK, operator_fee_block)).wait(); } // await deployedRegistryContract.addOperatorToValidator([], operatorsIndexes, []); }) - it("should create group", async () => { - // await deployedRegistryContract.createGroup([1,2,3,4]); - }) - it("should register validator", async () => { const validatorPK = "0x987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987651"; const sharePKs = Array.from(Array(10).keys()).map(k => `0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765${k}`); @@ -38,19 +38,50 @@ describe("Validators", () => { // await deployedRegistryContract.createGroup([1,2,3,4]); // await deployedRegistryContract.createGroup([1,2,3,4]); + console.log(`[BLOCK] ${await blockNumber()}`) + console.log('> deposit'); await deployedRegistryContract.deposit("100000000000"); + console.log(`[BLOCK] ${await blockNumber()}`) + console.log('> 1 operator balance', await deployedRegistryContract.test_getOperatorBalance(1), 'index', await deployedRegistryContract.test_operatorCurrentIndex(1)); + console.log('> 2 operator balance', await deployedRegistryContract.test_getOperatorBalance(2), 'index', await deployedRegistryContract.test_operatorCurrentIndex(2)); + // console.log('> 3 operator balance', await deployedRegistryContract.test_getOperatorBalance(3), 'index', await deployedRegistryContract.test_operatorCurrentIndex(3)); + // console.log('> 4 operator balance', await deployedRegistryContract.test_getOperatorBalance(4), 'index', await deployedRegistryContract.test_operatorCurrentIndex(4)); // validator 1 - await expect(await deployedRegistryContract.registerValidator( - [1,2,3,4], - validatorPK, - sharePKs.slice(0, 4), - encryptedShares.slice(0, 4), - "10000" - )) - .to.emit(deployedRegistryContract, 'ValidatorAdded'); - //.withArgs(validatorPK); - + const resultRegister = (await (await deployedRegistryContract.registerValidator( + [1,2], + validatorPK, + sharePKs.slice(0, 4), + encryptedShares.slice(0, 4), + "10000" + )).wait()).logs[0]; + const interfaceRegister = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId)']); + const outputRegister = interfaceRegister.decodeEventLog('ValidatorAdded', resultRegister.data, resultRegister.topics); + console.log(`[BLOCK] ${await blockNumber()}`) + console.log("> register validator", outputRegister.validatorPK, outputRegister.groupId); + await progressBlocks(1); + console.log(`[BLOCK] ${await blockNumber()}`) + console.log("> 1 operator balance", await deployedRegistryContract.test_getOperatorBalance(1)); + console.log("> 2 operator balance", await deployedRegistryContract.test_getOperatorBalance(2)); + console.log("> group index", await deployedRegistryContract.test_groupCurrentIndex(outputRegister.groupId)); + console.log("> group usage", await deployedRegistryContract.test_groupCurrentUsage(outputRegister.groupId)); + console.log("> group balance", await deployedRegistryContract.test_groupBalance(outputRegister.groupId)); + await progressBlocks(1); + console.log(`[BLOCK] ${await blockNumber()}`) + console.log("> 1 operator balance", await deployedRegistryContract.test_getOperatorBalance(1)); + console.log("> 2 operator balance", await deployedRegistryContract.test_getOperatorBalance(2)); + console.log("> group index", await deployedRegistryContract.test_groupCurrentIndex(outputRegister.groupId)); + console.log("> group usage", await deployedRegistryContract.test_groupCurrentUsage(outputRegister.groupId)); + console.log("> group balance", await deployedRegistryContract.test_groupBalance(outputRegister.groupId)); + await progressBlocks(1); + console.log(`[BLOCK] ${await blockNumber()}`) + console.log("> 1 operator balance", await deployedRegistryContract.test_getOperatorBalance(1)); + console.log("> 2 operator balance", await deployedRegistryContract.test_getOperatorBalance(2)); + console.log("> group index", await deployedRegistryContract.test_groupCurrentIndex(outputRegister.groupId)); + console.log("> group usage", await deployedRegistryContract.test_groupCurrentUsage(outputRegister.groupId)); + console.log("> group balance", await deployedRegistryContract.test_groupBalance(outputRegister.groupId)); + + /* // validator 2 await expect(await deployedRegistryContract.registerValidator( [1,2,3,4], @@ -98,6 +129,7 @@ describe("Validators", () => { .to.emit(deployedRegistryContract, 'ValidatorRemoved') .withArgs(validatorPK, outputUpdate.groupId); + */ // await deployedRegistryContract.liquidate("0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", "0x392791df626408017a264f53fde61065d5a93a32b60171df9d8a46afdf82992d"); }); }); From af6941784cf697aa5ec20de484ad00ddb66a4eca Mon Sep 17 00:00:00 2001 From: Vadim Date: Mon, 15 Aug 2022 08:32:15 +0200 Subject: [PATCH 012/149] wip logic math --- contracts/SSVRegistry.sol | 51 +++++++++++++++------------ test/unit/ssv-registry.js | 46 +++++++++++++++++++------ test/unit/utils.ts | 72 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 137 insertions(+), 32 deletions(-) create mode 100644 test/unit/utils.ts diff --git a/contracts/SSVRegistry.sol b/contracts/SSVRegistry.sol index 065a1705..484f6b9b 100644 --- a/contracts/SSVRegistry.sol +++ b/contracts/SSVRegistry.sol @@ -48,6 +48,7 @@ contract SSVRegistryNew { event OperatorAdded(uint64 operatorId, address indexed owner, bytes encryptionPK); event OperatorRemoved(uint64 operatorId); + event OperatorFeeUpdated(uint64 operatorId, uint64 fee); event ValidatorAdded(bytes validatorPK, bytes32 groupId); event ValidatorUpdated(bytes validatorPK, bytes32 groupId); event ValidatorRemoved(bytes validatorPK, bytes32 groupId); @@ -98,6 +99,17 @@ contract SSVRegistryNew { emit OperatorRemoved(operatorId); } + function updateOperatorFee(uint64 operatorId, uint64 fee) external { + Operator memory operator = _operators[operatorId]; + require(operator.owner == msg.sender, "not owner"); + + uint64 currentBlock = uint64(block.number); + + _operators[operatorId] = _setFee(operator, fee, currentBlock); + + emit OperatorFeeUpdated(operatorId, fee); + } + function registerValidator( uint64[] memory operatorIds, bytes calldata validatorPK, @@ -115,14 +127,15 @@ contract SSVRegistryNew { Group memory group; uint64 currentBlock = uint64(block.number); { - uint64 groupIndex = _groupCurrentIndex(groupId); _availableBalances[msg.sender] -= amount; group = _groups[msg.sender][groupId]; - console.log(amount, groupIndex); - group.balance = _ownerGroupBalance(group, groupIndex) + amount; + // console.log(amount, groupIndex); //group.lastIndex = groupIndex; - // group.usage = _updateGroupUsage(group, currentBlock); + uint64 groupIndex = _groupCurrentIndex(groupId); + group.balance = _ownerGroupBalance(group, groupIndex) + amount; + group.usage.index = groupIndex; + group.usage.block = currentBlock; ++group.validatorCount; } @@ -281,6 +294,15 @@ contract SSVRegistryNew { emit ValidatorRemoved(validatorPK, groupId); } */ + + function _setFee(Operator memory operator, uint64 fee, uint64 currentBlock) private returns (Operator memory) { + operator.earnings = _updateOperatorEarnings(operator, currentBlock); + operator.earnRate = operator.validatorCount * fee; + operator.fee = fee; + + return operator; + } + function test_getOperatorsByGroupId(bytes32 groupId) external view returns (uint64[] memory) { return _operatorCollections[groupId].operatorIds; } @@ -320,16 +342,9 @@ contract SSVRegistryNew { _operatorCollections[keccak256(abi.encodePacked(operators))] = OperatorCollection({ operatorIds: operators }); } - function _setFee(Operator memory operator, uint64 fee, uint64 currentBlock) private returns (Operator memory) { - // operator.earnings = _updateOperatorIndex(operator, currentBlock); - operator.fee = fee; - - return operator; - } - /* function _updateOperatorIndex(Operator memory operator, uint64 currentBlock) private returns (Snapshot memory) { - return Snapshot({ index: _operatorCurrentIndex(operator), block: currentBlock }); + return Snapshot({ index: _operatorCurrentIndex(operator), block: currentBlock, balance: }); } */ @@ -349,6 +364,7 @@ contract SSVRegistryNew { } function _updateOperatorEarnings(Operator memory operator, uint64 currentBlock) private returns (Snapshot memory) { + operator.earnings.index = _operatorCurrentIndex(operator); operator.earnings.balance = _operatorCurrentEarnings(operator, currentBlock); operator.earnings.block = currentBlock; @@ -362,14 +378,6 @@ contract SSVRegistryNew { return dao; } - /* - function _updateGroupUsage(Group memory group, uint64 currentBlock) private returns (Snapshot memory) { - group.usage.index = _groupCurrentUsage(group, currentBlock); - group.usage.block = currentBlock; - return group.usage; - } - */ - function _operatorCurrentEarnings(Operator memory operator, uint64 currentBlock) private view returns (uint64) { return operator.earnings.balance + (currentBlock - operator.earnings.block) * operator.earnRate; } @@ -414,8 +422,7 @@ contract SSVRegistryNew { } function _ownerGroupBalance(Group memory group, uint64 currentGroupIndex) private view returns (uint64) { - console.log(currentGroupIndex, group.lastIndex); - return group.balance - (currentGroupIndex - group.lastIndex) * group.validatorCount; + return group.balance - (currentGroupIndex - group.usage.index) * group.validatorCount; } function _burnRatePerValidator(Operator[] memory operators) private pure returns (uint64 rate) { diff --git a/test/unit/ssv-registry.js b/test/unit/ssv-registry.js index 1db30e2a..c705ed63 100644 --- a/test/unit/ssv-registry.js +++ b/test/unit/ssv-registry.js @@ -20,11 +20,11 @@ describe("Validators", () => { await deployedRegistryContract.deployed(); await progressBlocks(99); - for (let i = 0; i < 2; i++) { // operatorsIndexes.length - console.log(`[BLOCK] ${await blockNumber()}`) - console.log('> register operator', i); + for (let i = 0; i < 1; i++) { // operatorsIndexes.length var encryptionPK = "0x123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123451"; await (await deployedRegistryContract.registerOperator(encryptionPK, operator_fee_block)).wait(); + console.log(`[BLOCK] ${await blockNumber()}`) + console.log('> register operator', i); } // await deployedRegistryContract.addOperatorToValidator([], operatorsIndexes, []); }) @@ -38,18 +38,17 @@ describe("Validators", () => { // await deployedRegistryContract.createGroup([1,2,3,4]); // await deployedRegistryContract.createGroup([1,2,3,4]); - console.log(`[BLOCK] ${await blockNumber()}`) - console.log('> deposit'); await deployedRegistryContract.deposit("100000000000"); - console.log(`[BLOCK] ${await blockNumber()}`) + console.log('> deposit'); console.log('> 1 operator balance', await deployedRegistryContract.test_getOperatorBalance(1), 'index', await deployedRegistryContract.test_operatorCurrentIndex(1)); console.log('> 2 operator balance', await deployedRegistryContract.test_getOperatorBalance(2), 'index', await deployedRegistryContract.test_operatorCurrentIndex(2)); // console.log('> 3 operator balance', await deployedRegistryContract.test_getOperatorBalance(3), 'index', await deployedRegistryContract.test_operatorCurrentIndex(3)); // console.log('> 4 operator balance', await deployedRegistryContract.test_getOperatorBalance(4), 'index', await deployedRegistryContract.test_operatorCurrentIndex(4)); // validator 1 + await progressBlocks(97); const resultRegister = (await (await deployedRegistryContract.registerValidator( - [1,2], + [1], validatorPK, sharePKs.slice(0, 4), encryptedShares.slice(0, 4), @@ -58,28 +57,55 @@ describe("Validators", () => { const interfaceRegister = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId)']); const outputRegister = interfaceRegister.decodeEventLog('ValidatorAdded', resultRegister.data, resultRegister.topics); console.log(`[BLOCK] ${await blockNumber()}`) + console.log('> 1 operator balance', await deployedRegistryContract.test_getOperatorBalance(1), 'index', await deployedRegistryContract.test_operatorCurrentIndex(1)); console.log("> register validator", outputRegister.validatorPK, outputRegister.groupId); await progressBlocks(1); console.log(`[BLOCK] ${await blockNumber()}`) - console.log("> 1 operator balance", await deployedRegistryContract.test_getOperatorBalance(1)); + console.log('> 1 operator balance', await deployedRegistryContract.test_getOperatorBalance(1), 'index', await deployedRegistryContract.test_operatorCurrentIndex(1)); console.log("> 2 operator balance", await deployedRegistryContract.test_getOperatorBalance(2)); console.log("> group index", await deployedRegistryContract.test_groupCurrentIndex(outputRegister.groupId)); console.log("> group usage", await deployedRegistryContract.test_groupCurrentUsage(outputRegister.groupId)); console.log("> group balance", await deployedRegistryContract.test_groupBalance(outputRegister.groupId)); await progressBlocks(1); console.log(`[BLOCK] ${await blockNumber()}`) - console.log("> 1 operator balance", await deployedRegistryContract.test_getOperatorBalance(1)); + console.log('> 1 operator balance', await deployedRegistryContract.test_getOperatorBalance(1), 'index', await deployedRegistryContract.test_operatorCurrentIndex(1)); console.log("> 2 operator balance", await deployedRegistryContract.test_getOperatorBalance(2)); console.log("> group index", await deployedRegistryContract.test_groupCurrentIndex(outputRegister.groupId)); console.log("> group usage", await deployedRegistryContract.test_groupCurrentUsage(outputRegister.groupId)); console.log("> group balance", await deployedRegistryContract.test_groupBalance(outputRegister.groupId)); await progressBlocks(1); console.log(`[BLOCK] ${await blockNumber()}`) - console.log("> 1 operator balance", await deployedRegistryContract.test_getOperatorBalance(1)); + console.log('> 1 operator balance', await deployedRegistryContract.test_getOperatorBalance(1), 'index', await deployedRegistryContract.test_operatorCurrentIndex(1)); console.log("> 2 operator balance", await deployedRegistryContract.test_getOperatorBalance(2)); console.log("> group index", await deployedRegistryContract.test_groupCurrentIndex(outputRegister.groupId)); console.log("> group usage", await deployedRegistryContract.test_groupCurrentUsage(outputRegister.groupId)); console.log("> group balance", await deployedRegistryContract.test_groupBalance(outputRegister.groupId)); + await (await deployedRegistryContract.updateOperatorFee( + 1, + 2 + )).wait(); + console.log(`[BLOCK] ${await blockNumber()}`) + console.log("> 1 operator fee updated to", 2); + console.log('> 1 operator balance', await deployedRegistryContract.test_getOperatorBalance(1), 'index', await deployedRegistryContract.test_operatorCurrentIndex(1)); + console.log("> 2 operator balance", await deployedRegistryContract.test_getOperatorBalance(2)); + console.log("> group index", await deployedRegistryContract.test_groupCurrentIndex(outputRegister.groupId)); + console.log("> group usage", await deployedRegistryContract.test_groupCurrentUsage(outputRegister.groupId)); + console.log("> group balance", await deployedRegistryContract.test_groupBalance(outputRegister.groupId)); + await progressBlocks(1); + console.log(`[BLOCK] ${await blockNumber()}`) + console.log('> 1 operator balance', await deployedRegistryContract.test_getOperatorBalance(1), 'index', await deployedRegistryContract.test_operatorCurrentIndex(1)); + console.log("> 2 operator balance", await deployedRegistryContract.test_getOperatorBalance(2)); + console.log("> group index", await deployedRegistryContract.test_groupCurrentIndex(outputRegister.groupId)); + console.log("> group usage", await deployedRegistryContract.test_groupCurrentUsage(outputRegister.groupId)); + console.log("> group balance", await deployedRegistryContract.test_groupBalance(outputRegister.groupId)); + await progressBlocks(1); + console.log(`[BLOCK] ${await blockNumber()}`) + console.log('> 1 operator balance', await deployedRegistryContract.test_getOperatorBalance(1), 'index', await deployedRegistryContract.test_operatorCurrentIndex(1)); + console.log("> 2 operator balance", await deployedRegistryContract.test_getOperatorBalance(2)); + console.log("> group index", await deployedRegistryContract.test_groupCurrentIndex(outputRegister.groupId)); + console.log("> group usage", await deployedRegistryContract.test_groupCurrentUsage(outputRegister.groupId)); + console.log("> group balance", await deployedRegistryContract.test_groupBalance(outputRegister.groupId)); + /* // validator 2 diff --git a/test/unit/utils.ts b/test/unit/utils.ts new file mode 100644 index 00000000..f0d29165 --- /dev/null +++ b/test/unit/utils.ts @@ -0,0 +1,72 @@ +declare var network: any; +declare var ethers: any; + +//@ts-ignore +export const strToHex = str => `0x${Buffer.from(str, 'utf8').toString('hex')}`; +//@ts-ignore +export const asciiToHex = str => { + var arr1 = []; + for (var n = 0, l = str.length; n < l; n ++) { + var hex = Number(str.charCodeAt(n)).toString(16); + arr1.push(hex); + } + return arr1.join(''); +} +//@ts-ignore +export const blockNumber = async function() { + return await ethers.provider.getBlockNumber(); +} +//@ts-ignore +export const progress = async function(time, blocks, func = null) { + let snapshot; + + if (func) { + snapshot = await network.provider.send("evm_snapshot"); + } + + if (time) { + await network.provider.send("evm_increaseTime", [time]); + if (!blocks) { + await network.provider.send("evm_mine", []); + } + } + + for (let index = 0; index < blocks; ++index) { + await network.provider.send("evm_mine", []); + } + + if (func) { + //@ts-ignore + await func(); + await network.provider.send("evm_revert", [snapshot]); + } +} +//@ts-ignore +export const progressTime = async function(time, func = null) { + return progress(time, 1, func); +} +//@ts-ignore +export const progressBlocks = async function(blocks, func = null) { + return progress(0, blocks, func); +} +//@ts-ignore +export const snapshot = async function(func) { + return progress(0, 0, func); +} + +export const mineOneBlock = async () => network.provider.send("evm_mine", []); + +export const mineChunk = async (amount: number) => + Promise.all( + Array.from({ length: amount }, () => mineOneBlock()) + ) as unknown as Promise; + +export const mine = async (amount: number) => { + if (amount < 0) throw new Error('mine cannot be called with a negative value'); + const MAX_PARALLEL_CALLS = 1000; + // Do it on parallel but do not overflow connections + for (let i = 0; i < Math.floor(amount / MAX_PARALLEL_CALLS); i++) { + await mineChunk(MAX_PARALLEL_CALLS); + } + return mineChunk(amount % MAX_PARALLEL_CALLS); +}; \ No newline at end of file From ba67f75a9d0746caeb874fff98f7971f8d919ba7 Mon Sep 17 00:00:00 2001 From: Vadim Date: Mon, 15 Aug 2022 08:32:57 +0200 Subject: [PATCH 013/149] mixed up values IO1-990 --- contracts/SSVRegistry.sol | 1 - 1 file changed, 1 deletion(-) diff --git a/contracts/SSVRegistry.sol b/contracts/SSVRegistry.sol index 484f6b9b..50904e14 100644 --- a/contracts/SSVRegistry.sol +++ b/contracts/SSVRegistry.sol @@ -412,7 +412,6 @@ contract SSVRegistryNew { function _groupCurrentIndex(bytes32 groupId) private view returns (uint64 groupIndex) { OperatorCollection memory operatorCollection = _operatorCollections[groupId]; for (uint64 i = 0; i < operatorCollection.operatorIds.length; ++i) { - console.log("+", operatorCollection.operatorIds[i], _operatorCurrentIndex(_operators[operatorCollection.operatorIds[i]])); groupIndex += _operatorCurrentIndex(_operators[operatorCollection.operatorIds[i]]); } } From 025cca2c7fac952cf99eebdeb4e5be1af5de2ab0 Mon Sep 17 00:00:00 2001 From: Vadim Date: Mon, 15 Aug 2022 08:36:29 +0200 Subject: [PATCH 014/149] update tests --- test/unit/ssv-registry.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/unit/ssv-registry.js b/test/unit/ssv-registry.js index c705ed63..21c3e31e 100644 --- a/test/unit/ssv-registry.js +++ b/test/unit/ssv-registry.js @@ -20,7 +20,7 @@ describe("Validators", () => { await deployedRegistryContract.deployed(); await progressBlocks(99); - for (let i = 0; i < 1; i++) { // operatorsIndexes.length + for (let i = 0; i < 2; i++) { // operatorsIndexes.length var encryptionPK = "0x123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123451"; await (await deployedRegistryContract.registerOperator(encryptionPK, operator_fee_block)).wait(); console.log(`[BLOCK] ${await blockNumber()}`) @@ -48,7 +48,7 @@ describe("Validators", () => { // validator 1 await progressBlocks(97); const resultRegister = (await (await deployedRegistryContract.registerValidator( - [1], + [1, 2], validatorPK, sharePKs.slice(0, 4), encryptedShares.slice(0, 4), From f854a34e288e6e0d1bb3d2a51604ee8115e8b27e Mon Sep 17 00:00:00 2001 From: Vadim Date: Tue, 16 Aug 2022 11:50:24 +0200 Subject: [PATCH 015/149] logs improvements, fix math issues --- contracts/SSVRegistry.sol | 22 +++--- test/unit/ssv-registry.js | 153 +++++++++++++++++++++++++------------- 2 files changed, 115 insertions(+), 60 deletions(-) diff --git a/contracts/SSVRegistry.sol b/contracts/SSVRegistry.sol index 50904e14..29cdde90 100644 --- a/contracts/SSVRegistry.sol +++ b/contracts/SSVRegistry.sol @@ -120,20 +120,18 @@ contract SSVRegistryNew { bytes32 groupId; { Operator[] memory operators; + uint64 currentBlock = uint64(block.number); { groupId = _getOrCreateOperatorCollection(operatorIds); } Group memory group; - uint64 currentBlock = uint64(block.number); { _availableBalances[msg.sender] -= amount; group = _groups[msg.sender][groupId]; - // console.log(amount, groupIndex); - //group.lastIndex = groupIndex; uint64 groupIndex = _groupCurrentIndex(groupId); - group.balance = _ownerGroupBalance(group, groupIndex) + amount; + group.balance = group.balance + amount - _groupCurrentUsage(groupId); group.usage.index = groupIndex; group.usage.block = currentBlock; @@ -252,6 +250,7 @@ contract SSVRegistryNew { emit ValidatorUpdated(validatorPK, newGroupId); } + */ function removeValidator( bytes calldata validatorPK, @@ -260,19 +259,25 @@ contract SSVRegistryNew { { Group memory group = _groups[msg.sender][groupId]; OperatorCollection memory operatorCollection = _operatorCollections[groupId]; + uint64 currentBlock = uint64(block.number); + uint64 groupIndex = _groupCurrentIndex(groupId); + group.balance = group.balance - _groupCurrentUsage(groupId); + group.usage.index = groupIndex; + group.usage.block = currentBlock; + --group.validatorCount; + + /* uint64 groupIndex = _groupCurrentIndex(operatorCollection.operatorIds); group.balance = _ownerGroupBalance(group, groupIndex); group.lastIndex = groupIndex; --group.validatorCount; - + */ if (group.validatorCount == 0) { // _availableBalances[msg.sender] += _ownerGroupBalance(group, groupIndex); // group.balance -= _ownerGroupBalance(group, groupIndex); } - uint64 currentBlock = uint64(block.number); - for (uint64 i = 0; i < operatorCollection.operatorIds.length; ++i) { uint64 id = operatorCollection.operatorIds[i]; _operators[id].earnings = _updateOperatorEarnings(_operators[id], currentBlock); @@ -293,7 +298,6 @@ contract SSVRegistryNew { emit ValidatorRemoved(validatorPK, groupId); } - */ function _setFee(Operator memory operator, uint64 fee, uint64 currentBlock) private returns (Operator memory) { operator.earnings = _updateOperatorEarnings(operator, currentBlock); @@ -390,7 +394,7 @@ contract SSVRegistryNew { function _groupCurrentUsage(bytes32 groupId) private view returns (uint64) { Group memory group = _groups[msg.sender][groupId]; - return _groupCurrentIndex(groupId) - group.usage.index; + return (_groupCurrentIndex(groupId) - group.usage.index) * group.validatorCount; } function _extractOperators(uint64[] memory operatorIds) private view returns (Operator[] memory) { diff --git a/test/unit/ssv-registry.js b/test/unit/ssv-registry.js index 21c3e31e..3aa21af8 100644 --- a/test/unit/ssv-registry.js +++ b/test/unit/ssv-registry.js @@ -10,10 +10,35 @@ async function mineNBlocks(n) { } const operatorsIndexes = Array.from(Array(5).keys()).map(k => k + 1); +let deployedRegistryContract; +async function log({ action='', operatorIds = [], groupIds = [] }) { + console.log(`[BLOCK] ${await blockNumber()}`) + if (action) { + console.log(`> ${action}`); + } + if (operatorIds.length) { + for (const id of operatorIds) { + console.log( + `> operator #${id}`, + 'balance', await deployedRegistryContract.test_getOperatorBalance(id), + 'index', await deployedRegistryContract.test_operatorCurrentIndex(id), + ); + } + } + if (groupIds.length) { + for (const id of groupIds) { + console.log( + `> group #$${id}`, + 'balance', await deployedRegistryContract.test_groupBalance(id), + 'usage', await deployedRegistryContract.test_groupCurrentUsage(id), + 'index', await deployedRegistryContract.test_groupCurrentIndex(id), + ); + } + } +} describe("Validators", () => { - var deployedRegistryContract beforeEach(async () => { const Registry = await ethers.getContractFactory("SSVRegistryNew"); deployedRegistryContract = await Registry.deploy(); @@ -23,8 +48,7 @@ describe("Validators", () => { for (let i = 0; i < 2; i++) { // operatorsIndexes.length var encryptionPK = "0x123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123451"; await (await deployedRegistryContract.registerOperator(encryptionPK, operator_fee_block)).wait(); - console.log(`[BLOCK] ${await blockNumber()}`) - console.log('> register operator', i); + await log({ action: `register operator #${i+1}` }); } // await deployedRegistryContract.addOperatorToValidator([], operatorsIndexes, []); }) @@ -39,12 +63,10 @@ describe("Validators", () => { // await deployedRegistryContract.createGroup([1,2,3,4]); await deployedRegistryContract.deposit("100000000000"); - console.log(`[BLOCK] ${await blockNumber()}`) - console.log('> deposit'); - console.log('> 1 operator balance', await deployedRegistryContract.test_getOperatorBalance(1), 'index', await deployedRegistryContract.test_operatorCurrentIndex(1)); - console.log('> 2 operator balance', await deployedRegistryContract.test_getOperatorBalance(2), 'index', await deployedRegistryContract.test_operatorCurrentIndex(2)); - // console.log('> 3 operator balance', await deployedRegistryContract.test_getOperatorBalance(3), 'index', await deployedRegistryContract.test_operatorCurrentIndex(3)); - // console.log('> 4 operator balance', await deployedRegistryContract.test_getOperatorBalance(4), 'index', await deployedRegistryContract.test_operatorCurrentIndex(4)); + await log({ + action: 'deposit', + operatorIds: [1, 2] + }); // validator 1 await progressBlocks(97); const resultRegister = (await (await deployedRegistryContract.registerValidator( @@ -52,60 +74,89 @@ describe("Validators", () => { validatorPK, sharePKs.slice(0, 4), encryptedShares.slice(0, 4), - "10000" + '10000' )).wait()).logs[0]; const interfaceRegister = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId)']); const outputRegister = interfaceRegister.decodeEventLog('ValidatorAdded', resultRegister.data, resultRegister.topics); - console.log(`[BLOCK] ${await blockNumber()}`) - console.log('> 1 operator balance', await deployedRegistryContract.test_getOperatorBalance(1), 'index', await deployedRegistryContract.test_operatorCurrentIndex(1)); - console.log("> register validator", outputRegister.validatorPK, outputRegister.groupId); + await log({ + action: `register validator #1: ${outputRegister.validatorPK} : ${outputRegister.groupId}`, + operatorIds: [1, 2] + }); await progressBlocks(1); - console.log(`[BLOCK] ${await blockNumber()}`) - console.log('> 1 operator balance', await deployedRegistryContract.test_getOperatorBalance(1), 'index', await deployedRegistryContract.test_operatorCurrentIndex(1)); - console.log("> 2 operator balance", await deployedRegistryContract.test_getOperatorBalance(2)); - console.log("> group index", await deployedRegistryContract.test_groupCurrentIndex(outputRegister.groupId)); - console.log("> group usage", await deployedRegistryContract.test_groupCurrentUsage(outputRegister.groupId)); - console.log("> group balance", await deployedRegistryContract.test_groupBalance(outputRegister.groupId)); + await log({ + operatorIds: [1, 2], + groupIds: [outputRegister.groupId] + }); await progressBlocks(1); - console.log(`[BLOCK] ${await blockNumber()}`) - console.log('> 1 operator balance', await deployedRegistryContract.test_getOperatorBalance(1), 'index', await deployedRegistryContract.test_operatorCurrentIndex(1)); - console.log("> 2 operator balance", await deployedRegistryContract.test_getOperatorBalance(2)); - console.log("> group index", await deployedRegistryContract.test_groupCurrentIndex(outputRegister.groupId)); - console.log("> group usage", await deployedRegistryContract.test_groupCurrentUsage(outputRegister.groupId)); - console.log("> group balance", await deployedRegistryContract.test_groupBalance(outputRegister.groupId)); + await log({ + operatorIds: [1, 2], + groupIds: [outputRegister.groupId] + }); await progressBlocks(1); - console.log(`[BLOCK] ${await blockNumber()}`) - console.log('> 1 operator balance', await deployedRegistryContract.test_getOperatorBalance(1), 'index', await deployedRegistryContract.test_operatorCurrentIndex(1)); - console.log("> 2 operator balance", await deployedRegistryContract.test_getOperatorBalance(2)); - console.log("> group index", await deployedRegistryContract.test_groupCurrentIndex(outputRegister.groupId)); - console.log("> group usage", await deployedRegistryContract.test_groupCurrentUsage(outputRegister.groupId)); - console.log("> group balance", await deployedRegistryContract.test_groupBalance(outputRegister.groupId)); + await log({ + operatorIds: [1, 2], + groupIds: [outputRegister.groupId] + }); + const resultRegister2 = (await (await deployedRegistryContract.registerValidator( + [1, 2], + validatorPK, + sharePKs.slice(0, 4), + encryptedShares.slice(0, 4), + "0" + )).wait()).logs[0]; + const interfaceRegister2 = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId)']); + const outputRegister2 = interfaceRegister2.decodeEventLog('ValidatorAdded', resultRegister2.data, resultRegister2.topics); + await log({ + action: `register validator #2: ${outputRegister2.validatorPK} : ${outputRegister2.groupId}`, + operatorIds: [1, 2], + groupIds: [outputRegister.groupId] + }); + await progressBlocks(1); + await log({ + operatorIds: [1, 2], + groupIds: [outputRegister.groupId] + }); + await progressBlocks(1); + await log({ + operatorIds: [1, 2], + groupIds: [outputRegister.groupId] + }); await (await deployedRegistryContract.updateOperatorFee( 1, 2 )).wait(); - console.log(`[BLOCK] ${await blockNumber()}`) - console.log("> 1 operator fee updated to", 2); - console.log('> 1 operator balance', await deployedRegistryContract.test_getOperatorBalance(1), 'index', await deployedRegistryContract.test_operatorCurrentIndex(1)); - console.log("> 2 operator balance", await deployedRegistryContract.test_getOperatorBalance(2)); - console.log("> group index", await deployedRegistryContract.test_groupCurrentIndex(outputRegister.groupId)); - console.log("> group usage", await deployedRegistryContract.test_groupCurrentUsage(outputRegister.groupId)); - console.log("> group balance", await deployedRegistryContract.test_groupBalance(outputRegister.groupId)); + await log({ + action: 'operator #1 fee updated 2', + operatorIds: [1, 2], + groupIds: [outputRegister.groupId] + }); await progressBlocks(1); - console.log(`[BLOCK] ${await blockNumber()}`) - console.log('> 1 operator balance', await deployedRegistryContract.test_getOperatorBalance(1), 'index', await deployedRegistryContract.test_operatorCurrentIndex(1)); - console.log("> 2 operator balance", await deployedRegistryContract.test_getOperatorBalance(2)); - console.log("> group index", await deployedRegistryContract.test_groupCurrentIndex(outputRegister.groupId)); - console.log("> group usage", await deployedRegistryContract.test_groupCurrentUsage(outputRegister.groupId)); - console.log("> group balance", await deployedRegistryContract.test_groupBalance(outputRegister.groupId)); + await log({ + operatorIds: [1, 2], + groupIds: [outputRegister.groupId] + }); await progressBlocks(1); - console.log(`[BLOCK] ${await blockNumber()}`) - console.log('> 1 operator balance', await deployedRegistryContract.test_getOperatorBalance(1), 'index', await deployedRegistryContract.test_operatorCurrentIndex(1)); - console.log("> 2 operator balance", await deployedRegistryContract.test_getOperatorBalance(2)); - console.log("> group index", await deployedRegistryContract.test_groupCurrentIndex(outputRegister.groupId)); - console.log("> group usage", await deployedRegistryContract.test_groupCurrentUsage(outputRegister.groupId)); - console.log("> group balance", await deployedRegistryContract.test_groupBalance(outputRegister.groupId)); - + await log({ + operatorIds: [1, 2], + groupIds: [outputRegister.groupId] + }); + await (await deployedRegistryContract.removeValidator(outputRegister2.validatorPK, outputRegister2.groupId)).wait(); + await log({ + action: 'remove validator #1', + operatorIds: [1, 2], + groupIds: [outputRegister.groupId] + }); + await progressBlocks(1); + await log({ + operatorIds: [1, 2], + groupIds: [outputRegister.groupId] + }); + await progressBlocks(1); + await log({ + operatorIds: [1, 2], + groupIds: [outputRegister.groupId] + }); + /* // validator 2 From c8a784fbd996b4b4a1e8840926ee9d54afac9d37 Mon Sep 17 00:00:00 2001 From: Vadim Date: Tue, 16 Aug 2022 11:57:03 +0200 Subject: [PATCH 016/149] extend logs --- test/unit/ssv-registry.js | 44 +++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/test/unit/ssv-registry.js b/test/unit/ssv-registry.js index 3aa21af8..1a1405e3 100644 --- a/test/unit/ssv-registry.js +++ b/test/unit/ssv-registry.js @@ -45,7 +45,7 @@ describe("Validators", () => { await deployedRegistryContract.deployed(); await progressBlocks(99); - for (let i = 0; i < 2; i++) { // operatorsIndexes.length + for (let i = 0; i < 4; i++) { // operatorsIndexes.length var encryptionPK = "0x123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123451"; await (await deployedRegistryContract.registerOperator(encryptionPK, operator_fee_block)).wait(); await log({ action: `register operator #${i+1}` }); @@ -98,28 +98,28 @@ describe("Validators", () => { groupIds: [outputRegister.groupId] }); const resultRegister2 = (await (await deployedRegistryContract.registerValidator( - [1, 2], + [3, 4], validatorPK, sharePKs.slice(0, 4), encryptedShares.slice(0, 4), - "0" + "1000" )).wait()).logs[0]; const interfaceRegister2 = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId)']); const outputRegister2 = interfaceRegister2.decodeEventLog('ValidatorAdded', resultRegister2.data, resultRegister2.topics); await log({ action: `register validator #2: ${outputRegister2.validatorPK} : ${outputRegister2.groupId}`, - operatorIds: [1, 2], - groupIds: [outputRegister.groupId] + operatorIds: [1, 2, 3, 4], + groupIds: [outputRegister.groupId, outputRegister2.groupId] }); await progressBlocks(1); await log({ - operatorIds: [1, 2], - groupIds: [outputRegister.groupId] + operatorIds: [1, 2, 3, 4], + groupIds: [outputRegister.groupId, outputRegister2.groupId] }); await progressBlocks(1); await log({ - operatorIds: [1, 2], - groupIds: [outputRegister.groupId] + operatorIds: [1, 2, 3, 4], + groupIds: [outputRegister.groupId, outputRegister2.groupId] }); await (await deployedRegistryContract.updateOperatorFee( 1, @@ -127,34 +127,34 @@ describe("Validators", () => { )).wait(); await log({ action: 'operator #1 fee updated 2', - operatorIds: [1, 2], - groupIds: [outputRegister.groupId] + operatorIds: [1, 2, 3, 4], + groupIds: [outputRegister.groupId, outputRegister2.groupId] }); await progressBlocks(1); await log({ - operatorIds: [1, 2], - groupIds: [outputRegister.groupId] + operatorIds: [1, 2, 3, 4], + groupIds: [outputRegister.groupId, outputRegister2.groupId] }); await progressBlocks(1); await log({ - operatorIds: [1, 2], - groupIds: [outputRegister.groupId] + operatorIds: [1, 2, 3, 4], + groupIds: [outputRegister.groupId, outputRegister2.groupId] }); await (await deployedRegistryContract.removeValidator(outputRegister2.validatorPK, outputRegister2.groupId)).wait(); await log({ - action: 'remove validator #1', - operatorIds: [1, 2], - groupIds: [outputRegister.groupId] + action: 'remove validator #2', + operatorIds: [1, 2, 3, 4], + groupIds: [outputRegister.groupId, outputRegister2.groupId] }); await progressBlocks(1); await log({ - operatorIds: [1, 2], - groupIds: [outputRegister.groupId] + operatorIds: [1, 2, 3, 4], + groupIds: [outputRegister.groupId, outputRegister2.groupId] }); await progressBlocks(1); await log({ - operatorIds: [1, 2], - groupIds: [outputRegister.groupId] + operatorIds: [1, 2, 3, 4], + groupIds: [outputRegister.groupId, outputRegister2.groupId] }); From f888cfd7cc3a33c5503f1d32663d4f7bdd92f9fd Mon Sep 17 00:00:00 2001 From: Vadim Date: Wed, 17 Aug 2022 09:14:01 +0200 Subject: [PATCH 017/149] update validator etc --- contracts/SSVRegistry.sol | 151 ++++++++++++++++++++++---------------- test/unit/ssv-registry.js | 87 +++++++++++++++------- 2 files changed, 149 insertions(+), 89 deletions(-) diff --git a/contracts/SSVRegistry.sol b/contracts/SSVRegistry.sol index 29cdde90..1b8e3f6b 100644 --- a/contracts/SSVRegistry.sol +++ b/contracts/SSVRegistry.sol @@ -41,7 +41,6 @@ contract SSVRegistryNew { struct Group { uint64 balance; uint64 validatorCount; - uint64 lastIndex; Snapshot usage; } @@ -67,6 +66,15 @@ contract SSVRegistryNew { uint64 constant LIQUIDATION_MIN_BLOCKS = 50; // uint64 constant NETWORK_FEE_PER_BLOCK = 1; + + error ExceedRegisteredOperatorsByAccountLimit(); + error OperatorDeleted(); + error ValidatorAlreadyExists(); + error ExceedValidatorLimit(); + error OperatorNotFound(); + error InvalidPublicKeyLength(); + error OessDataStructureInvalid(); + DAO private _dao; IERC20 private _token; @@ -113,10 +121,17 @@ contract SSVRegistryNew { function registerValidator( uint64[] memory operatorIds, bytes calldata validatorPK, + bytes[] calldata sharesPublicKeys, bytes[] calldata encryptedShares, - bytes[] calldata sharesPK, uint64 amount ) external { + _validateValidatorParams( + validatorPK, + operatorIds, + sharesPublicKeys, + encryptedShares + ); + bytes32 groupId; { Operator[] memory operators; @@ -131,7 +146,7 @@ contract SSVRegistryNew { group = _groups[msg.sender][groupId]; uint64 groupIndex = _groupCurrentIndex(groupId); - group.balance = group.balance + amount - _groupCurrentUsage(groupId); + group.balance = _ownerGroupBalance(group, groupIndex) + amount; group.usage.index = groupIndex; group.usage.block = currentBlock; @@ -162,54 +177,60 @@ contract SSVRegistryNew { emit ValidatorAdded(validatorPK, groupId); } - /* function updateValidator( uint64[] memory operatorIds, bytes calldata validatorPK, bytes32 currentGroupId, uint64 amount ) external { + uint64 currentBlock = uint64(block.number); { - Group memory group = _groups[msg.sender][currentGroupId]; - OperatorCollection memory operatorCollection = _operatorCollections[currentGroupId]; + Group memory group; + { + group = _groups[msg.sender][currentGroupId]; - uint64 groupIndex = _groupCurrentIndex(operatorCollection.operatorIds); - group.lastIndex = groupIndex; - --group.validatorCount; + uint64 groupIndex = _groupCurrentIndex(currentGroupId); + group.balance = _ownerGroupBalance(group, groupIndex); + group.usage.index = groupIndex; + group.usage.block = currentBlock; + --group.validatorCount; - if (group.validatorCount == 0) { - // _availableBalances[msg.sender] += _ownerGroupBalance(group, groupIndex); - // group.balance -= _ownerGroupBalance(group, groupIndex); + if (group.validatorCount == 0) { + // _availableBalances[msg.sender] += _ownerGroupBalance(group, groupIndex); + // group.balance -= _ownerGroupBalance(group, groupIndex); + } } - uint64 currentBlock = uint64(block.number); - for (uint64 i = 0; i < operatorCollection.operatorIds.length; ++i) { - bool found; - for (uint64 j = 0; j < operatorIds.length; ++j) { - if (operatorCollection.operatorIds[i] == operatorIds[j]) { - found = true; + OperatorCollection memory operatorCollection = _operatorCollections[currentGroupId]; + { + for (uint64 i = 0; i < operatorCollection.operatorIds.length; ++i) { + bool found; + for (uint64 j = 0; j < operatorIds.length; ++j) { + if (operatorCollection.operatorIds[i] == operatorIds[j]) { + found = true; + } + } + if (!found) { + uint64 id = operatorCollection.operatorIds[i]; + _operators[id].earnings = _updateOperatorEarnings(_operators[id], currentBlock); + _operators[id].earnRate -= _operators[id].fee; + --_operators[id].validatorCount; } } - if (!found) { - uint64 id = operatorCollection.operatorIds[i]; - _operators[id].earnings = _updateOperatorEarnings(_operators[id], currentBlock); - _operators[id].earnRate -= _operators[id].fee; - --_operators[id].validatorCount; - } - } - for (uint64 i = 0; i < operatorIds.length; ++i) { - bool found; - for (uint64 j = 0; j < operatorCollection.operatorIds.length; ++j) { - if (operatorIds[i] == operatorCollection.operatorIds[j]) { - found = true; + for (uint64 i = 0; i < operatorIds.length; ++i) { + bool found; + for (uint64 j = 0; j < operatorCollection.operatorIds.length; ++j) { + if (operatorIds[i] == operatorCollection.operatorIds[j]) { + found = true; + } + } + if (!found) { + uint64 id = operatorIds[i]; + _operators[id].earnings = _updateOperatorEarnings(_operators[id], currentBlock); + _operators[id].earnRate += _operators[id].fee; + ++_operators[id].validatorCount; } - } - if (!found) { - uint64 id = operatorIds[i]; - _operators[id].earnings = _updateOperatorEarnings(_operators[id], currentBlock); - _operators[id].earnRate += _operators[id].fee; - ++_operators[id].validatorCount; } } _groups[msg.sender][currentGroupId] = group; @@ -225,14 +246,15 @@ contract SSVRegistryNew { Group memory group; { - uint64 groupIndex = _groupCurrentIndex(operatorIds); + uint64 groupIndex = _groupCurrentIndex(newGroupId); _availableBalances[msg.sender] -= amount; group = _groups[msg.sender][newGroupId]; - group.balance = _ownerGroupBalance(group, groupIndex) + amount; - group.lastIndex = groupIndex; + group.usage.index = groupIndex; + group.usage.block = currentBlock; + ++group.validatorCount; } @@ -250,7 +272,6 @@ contract SSVRegistryNew { emit ValidatorUpdated(validatorPK, newGroupId); } - */ function removeValidator( bytes calldata validatorPK, @@ -262,17 +283,11 @@ contract SSVRegistryNew { uint64 currentBlock = uint64(block.number); uint64 groupIndex = _groupCurrentIndex(groupId); - group.balance = group.balance - _groupCurrentUsage(groupId); + group.balance = _ownerGroupBalance(group, groupIndex); group.usage.index = groupIndex; group.usage.block = currentBlock; --group.validatorCount; - /* - uint64 groupIndex = _groupCurrentIndex(operatorCollection.operatorIds); - group.balance = _ownerGroupBalance(group, groupIndex); - group.lastIndex = groupIndex; - --group.validatorCount; - */ if (group.validatorCount == 0) { // _availableBalances[msg.sender] += _ownerGroupBalance(group, groupIndex); // group.balance -= _ownerGroupBalance(group, groupIndex); @@ -323,13 +338,34 @@ contract SSVRegistryNew { return _groupCurrentIndex(groupId); } - function test_groupCurrentUsage(bytes32 groupId) external view returns (uint64) { - return _groupCurrentUsage(groupId); - } - function test_groupBalance(bytes32 groupId) external view returns (uint64) { Group memory group = _groups[msg.sender][groupId]; - return group.balance - _groupCurrentUsage(groupId); + return _ownerGroupBalance(group, _groupCurrentIndex(groupId)); + } + + /** + * @dev Validates the paramss for a validator. + * @param publicKey Validator public key. + * @param operatorIds Operator operatorIds. + * @param sharesPublicKeys Shares public keys. + * @param encryptedKeys Encrypted private keys. + */ + function _validateValidatorParams( + bytes memory publicKey, + uint64[] memory operatorIds, + bytes[] memory sharesPublicKeys, + bytes[] memory encryptedKeys + ) private pure { + if (publicKey.length != 48) { + revert InvalidPublicKeyLength(); + } + if ( + operatorIds.length != sharesPublicKeys.length || + operatorIds.length != encryptedKeys.length || + operatorIds.length < 4 || operatorIds.length % 3 != 1 + ) { + revert OessDataStructureInvalid(); + } } // function removeValidator(validatorPK) @@ -386,17 +422,6 @@ contract SSVRegistryNew { return operator.earnings.balance + (currentBlock - operator.earnings.block) * operator.earnRate; } - /* - function _groupCurrentUsage(Group memory group, uint64 currentBlock) private view returns (uint64) { - return group.usage.index + (currentBlock - group.usage.block) * group.validatorCount; - } - */ - - function _groupCurrentUsage(bytes32 groupId) private view returns (uint64) { - Group memory group = _groups[msg.sender][groupId]; - return (_groupCurrentIndex(groupId) - group.usage.index) * group.validatorCount; - } - function _extractOperators(uint64[] memory operatorIds) private view returns (Operator[] memory) { Operator[] memory operators = new Operator[](operatorIds.length); for (uint64 i = 0; i < operatorIds.length; ++i) { diff --git a/test/unit/ssv-registry.js b/test/unit/ssv-registry.js index 1a1405e3..de358219 100644 --- a/test/unit/ssv-registry.js +++ b/test/unit/ssv-registry.js @@ -31,7 +31,6 @@ async function log({ action='', operatorIds = [], groupIds = [] }) { console.log( `> group #$${id}`, 'balance', await deployedRegistryContract.test_groupBalance(id), - 'usage', await deployedRegistryContract.test_groupCurrentUsage(id), 'index', await deployedRegistryContract.test_groupCurrentIndex(id), ); } @@ -45,7 +44,7 @@ describe("Validators", () => { await deployedRegistryContract.deployed(); await progressBlocks(99); - for (let i = 0; i < 4; i++) { // operatorsIndexes.length + for (let i = 0; i < 8; i++) { // operatorsIndexes.length var encryptionPK = "0x123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123451"; await (await deployedRegistryContract.registerOperator(encryptionPK, operator_fee_block)).wait(); await log({ action: `register operator #${i+1}` }); @@ -55,7 +54,7 @@ describe("Validators", () => { it("should register validator", async () => { const validatorPK = "0x987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987651"; - const sharePKs = Array.from(Array(10).keys()).map(k => `0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765${k}`); + const sharePKs = Array.from(Array(10).keys()).map(k => `0x12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345${k}`); const encryptedShares = Array.from(Array(10).keys()).map(k => `0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765${k}98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765${k}`); // const operatorsIndexes = Array.from(Array(10).keys()).map(k => k + 1); @@ -65,40 +64,77 @@ describe("Validators", () => { await deployedRegistryContract.deposit("100000000000"); await log({ action: 'deposit', - operatorIds: [1, 2] + operatorIds: [1, 2, 3, 4] }); // validator 1 await progressBlocks(97); - const resultRegister = (await (await deployedRegistryContract.registerValidator( - [1, 2], + let resultRegister = (await (await deployedRegistryContract.registerValidator( + [1,2,3,4], validatorPK, sharePKs.slice(0, 4), - encryptedShares.slice(0, 4), + sharePKs.slice(0, 4), '10000' )).wait()).logs[0]; - const interfaceRegister = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId)']); - const outputRegister = interfaceRegister.decodeEventLog('ValidatorAdded', resultRegister.data, resultRegister.topics); + let interfaceRegister = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId)']); + let outputRegister = interfaceRegister.decodeEventLog('ValidatorAdded', resultRegister.data, resultRegister.topics); await log({ action: `register validator #1: ${outputRegister.validatorPK} : ${outputRegister.groupId}`, - operatorIds: [1, 2] + operatorIds: [1, 2, 3, 4] }); await progressBlocks(1); await log({ - operatorIds: [1, 2], + operatorIds: [1, 2, 3, 4], groupIds: [outputRegister.groupId] }); + + let resultUpdate = (await (await deployedRegistryContract.updateValidator( + [4,5,6,7], + validatorPK, + outputRegister.groupId, + '10000' + )).wait()).logs[0];; + let interfaceUpdate = new ethers.utils.Interface(['event ValidatorUpdated(bytes validatorPK, bytes32 groupId)']); + let outputUpdate = interfaceUpdate.decodeEventLog('ValidatorUpdated', resultUpdate.data, resultUpdate.topics); + expect(outputRegister.groupId).not.equal(outputUpdate.groupId); + expect(outputRegister.validatorPK).to.equal(outputUpdate.validatorPK); + + await log({ + action: `update validator #1: ${outputUpdate.validatorPK} : ${outputUpdate.groupId}`, + operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], + groupIds: [outputRegister.groupId, outputUpdate.groupId] + }); await progressBlocks(1); await log({ - operatorIds: [1, 2], - groupIds: [outputRegister.groupId] + operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], + groupIds: [outputRegister.groupId, outputUpdate.groupId] }); await progressBlocks(1); await log({ - operatorIds: [1, 2], - groupIds: [outputRegister.groupId] + operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], + groupIds: [outputRegister.groupId, outputUpdate.groupId] + }); + + // move back validator 1 to group 1 + resultRegister = (await (await deployedRegistryContract.updateValidator( + [1,2,3,4], + validatorPK, + outputUpdate.groupId, + '10000' + )).wait()).logs[0];; + interfaceRegister = new ethers.utils.Interface(['event ValidatorUpdated(bytes validatorPK, bytes32 groupId)']); + outputRegister = interfaceUpdate.decodeEventLog('ValidatorUpdated', resultRegister.data, resultRegister.topics); + await log({ + action: `update validator #1: ${outputRegister.validatorPK} : ${outputRegister.groupId}`, + operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], + groupIds: [outputRegister.groupId, outputUpdate.groupId] + }); + await progressBlocks(1); + await log({ + operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], + groupIds: [outputRegister.groupId, outputUpdate.groupId] }); const resultRegister2 = (await (await deployedRegistryContract.registerValidator( - [3, 4], + [5,6,7,8], validatorPK, sharePKs.slice(0, 4), encryptedShares.slice(0, 4), @@ -108,17 +144,17 @@ describe("Validators", () => { const outputRegister2 = interfaceRegister2.decodeEventLog('ValidatorAdded', resultRegister2.data, resultRegister2.topics); await log({ action: `register validator #2: ${outputRegister2.validatorPK} : ${outputRegister2.groupId}`, - operatorIds: [1, 2, 3, 4], + operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], groupIds: [outputRegister.groupId, outputRegister2.groupId] }); await progressBlocks(1); await log({ - operatorIds: [1, 2, 3, 4], + operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], groupIds: [outputRegister.groupId, outputRegister2.groupId] }); await progressBlocks(1); await log({ - operatorIds: [1, 2, 3, 4], + operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], groupIds: [outputRegister.groupId, outputRegister2.groupId] }); await (await deployedRegistryContract.updateOperatorFee( @@ -127,36 +163,35 @@ describe("Validators", () => { )).wait(); await log({ action: 'operator #1 fee updated 2', - operatorIds: [1, 2, 3, 4], + operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], groupIds: [outputRegister.groupId, outputRegister2.groupId] }); await progressBlocks(1); await log({ - operatorIds: [1, 2, 3, 4], + operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], groupIds: [outputRegister.groupId, outputRegister2.groupId] }); await progressBlocks(1); await log({ - operatorIds: [1, 2, 3, 4], + operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], groupIds: [outputRegister.groupId, outputRegister2.groupId] }); await (await deployedRegistryContract.removeValidator(outputRegister2.validatorPK, outputRegister2.groupId)).wait(); await log({ action: 'remove validator #2', - operatorIds: [1, 2, 3, 4], + operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], groupIds: [outputRegister.groupId, outputRegister2.groupId] }); await progressBlocks(1); await log({ - operatorIds: [1, 2, 3, 4], + operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], groupIds: [outputRegister.groupId, outputRegister2.groupId] }); await progressBlocks(1); await log({ - operatorIds: [1, 2, 3, 4], + operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], groupIds: [outputRegister.groupId, outputRegister2.groupId] }); - /* // validator 2 From 78663ed3d31dcc0678386a7ecd6d25df4cd481eb Mon Sep 17 00:00:00 2001 From: Vadim Date: Sun, 21 Aug 2022 11:28:35 +0200 Subject: [PATCH 018/149] gas issues, validatorpk, extended operator logic --- contracts/SSVRegistry.sol | 47 ++++++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/contracts/SSVRegistry.sol b/contracts/SSVRegistry.sol index 1b8e3f6b..69b74f5a 100644 --- a/contracts/SSVRegistry.sol +++ b/contracts/SSVRegistry.sol @@ -41,7 +41,7 @@ contract SSVRegistryNew { struct Group { uint64 balance; uint64 validatorCount; - + bytes[] validatorPKs; Snapshot usage; } @@ -100,9 +100,10 @@ contract SSVRegistryNew { uint64 currentBlock = uint64(block.number); operator.earnings = _updateOperatorEarnings(operator, currentBlock); - operator.earnRate -= operator.fee * operator.validatorCount; - _operators[operatorId] = _setFee(operator, 0, currentBlock); + operator.earnRate = 0; + operator.fee = 0; operator.validatorCount = 0; + _operators[operatorId] = operator; emit OperatorRemoved(operatorId); } @@ -132,12 +133,13 @@ contract SSVRegistryNew { encryptedShares ); + // Operator[] memory operators; bytes32 groupId; { - Operator[] memory operators; uint64 currentBlock = uint64(block.number); { groupId = _getOrCreateOperatorCollection(operatorIds); + // operators = _extractOperators(operatorIds); } Group memory group; @@ -151,13 +153,28 @@ contract SSVRegistryNew { group.usage.block = currentBlock; ++group.validatorCount; + + // TODO + // gas issues + // without: 352641 max, 336957 avg, 321272 min + // with that: 442985 max, 427300 avg, 411615 min + /* + bytes[] memory extendedGroup = new bytes[](group.validatorCount); + for (uint64 i = 0; i < group.validatorPKs.length; ++i) { + extendedGroup[i] = group.validatorPKs[i]; + } + extendedGroup[group.validatorCount - 1] = validatorPK; + group.validatorPKs = extendedGroup; + */ } { for (uint64 i = 0; i < operatorIds.length; ++i) { - _operators[operatorIds[i]].earnings = _updateOperatorEarnings(_operators[operatorIds[i]], currentBlock); - _operators[operatorIds[i]].earnRate += _operators[operatorIds[i]].fee; - ++_operators[operatorIds[i]].validatorCount; + Operator memory operator = _operators[operatorIds[i]]; + operator.earnings = _updateOperatorEarnings(operator, currentBlock); + operator.earnRate += operator.fee; + ++operator.validatorCount; + _operators[operatorIds[i]] = operator; } } @@ -169,7 +186,11 @@ contract SSVRegistryNew { _dao = dao; } - require(!_liquidatable(group.balance, group.validatorCount, operators), "account liquidatable"); + // TODO + // require(!_liquidatable(group.balance, group.validatorCount, _extractOperators(operatorIds)), "account liquidatable"); + // list of operators here makes the gas higher + // without: 352641 max, 336957 avg, 321272 min + // with that: 364550 max, 348866 avg, 333181 min _groups[msg.sender][groupId] = group; } @@ -238,10 +259,10 @@ contract SSVRegistryNew { bytes32 newGroupId; { - Operator[] memory operators; + // Operator[] memory newOperators; { newGroupId = _getOrCreateOperatorCollection(operatorIds); - operators = _extractOperators(operatorIds); + // newOperators = _extractOperators(operatorIds); } Group memory group; @@ -265,7 +286,11 @@ contract SSVRegistryNew { _dao = dao; } - require(!_liquidatable(group.balance, group.validatorCount, operators), "account liquidatable"); + // TODO + // require(!_liquidatable(group.balance, group.validatorCount, newOperators), "account liquidatable"); + // list of operators here makes the gas higher + // without: 353107 max, 315041 avg, 276974 min + // with that: 365039 max, 326973 avg, 288906 min _groups[msg.sender][newGroupId] = group; } From b4c7164b2495d891c37b0ce7c04a1dde8c738f8c Mon Sep 17 00:00:00 2001 From: Vadim Date: Sun, 21 Aug 2022 12:19:05 +0200 Subject: [PATCH 019/149] update encrypted and shares keys logic --- contracts/SSVRegistry.sol | 10 ++++++---- test/unit/ssv-registry.js | 14 +++++++++----- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/contracts/SSVRegistry.sol b/contracts/SSVRegistry.sol index 69b74f5a..18ca5fb7 100644 --- a/contracts/SSVRegistry.sol +++ b/contracts/SSVRegistry.sol @@ -48,8 +48,8 @@ contract SSVRegistryNew { event OperatorAdded(uint64 operatorId, address indexed owner, bytes encryptionPK); event OperatorRemoved(uint64 operatorId); event OperatorFeeUpdated(uint64 operatorId, uint64 fee); - event ValidatorAdded(bytes validatorPK, bytes32 groupId); - event ValidatorUpdated(bytes validatorPK, bytes32 groupId); + event ValidatorAdded(bytes validatorPK, bytes32 groupId, bytes[] sharesPublicKeys, bytes[] encryptedShares); + event ValidatorUpdated(bytes validatorPK, bytes32 groupId, bytes[] sharesPublicKeys, bytes[] encryptedShares); event ValidatorRemoved(bytes validatorPK, bytes32 groupId); // global vars @@ -195,13 +195,15 @@ contract SSVRegistryNew { _groups[msg.sender][groupId] = group; } - emit ValidatorAdded(validatorPK, groupId); + emit ValidatorAdded(validatorPK, groupId, sharesPublicKeys, encryptedShares); } function updateValidator( uint64[] memory operatorIds, bytes calldata validatorPK, bytes32 currentGroupId, + bytes[] calldata sharesPublicKeys, + bytes[] calldata encryptedShares, uint64 amount ) external { uint64 currentBlock = uint64(block.number); @@ -295,7 +297,7 @@ contract SSVRegistryNew { _groups[msg.sender][newGroupId] = group; } - emit ValidatorUpdated(validatorPK, newGroupId); + emit ValidatorUpdated(validatorPK, newGroupId, sharesPublicKeys, encryptedShares); } function removeValidator( diff --git a/test/unit/ssv-registry.js b/test/unit/ssv-registry.js index de358219..f4ffb8cb 100644 --- a/test/unit/ssv-registry.js +++ b/test/unit/ssv-registry.js @@ -72,10 +72,10 @@ describe("Validators", () => { [1,2,3,4], validatorPK, sharePKs.slice(0, 4), - sharePKs.slice(0, 4), + encryptedShares.slice(0, 4), '10000' )).wait()).logs[0]; - let interfaceRegister = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId)']); + let interfaceRegister = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId, bytes[] sharesPublicKeys, bytes[] encryptedShares)']); let outputRegister = interfaceRegister.decodeEventLog('ValidatorAdded', resultRegister.data, resultRegister.topics); await log({ action: `register validator #1: ${outputRegister.validatorPK} : ${outputRegister.groupId}`, @@ -91,9 +91,11 @@ describe("Validators", () => { [4,5,6,7], validatorPK, outputRegister.groupId, + sharePKs.slice(0, 4), + encryptedShares.slice(0, 4), '10000' )).wait()).logs[0];; - let interfaceUpdate = new ethers.utils.Interface(['event ValidatorUpdated(bytes validatorPK, bytes32 groupId)']); + let interfaceUpdate = new ethers.utils.Interface(['event ValidatorUpdated(bytes validatorPK, bytes32 groupId, bytes[] sharesPublicKeys, bytes[] encryptedShares)']); let outputUpdate = interfaceUpdate.decodeEventLog('ValidatorUpdated', resultUpdate.data, resultUpdate.topics); expect(outputRegister.groupId).not.equal(outputUpdate.groupId); expect(outputRegister.validatorPK).to.equal(outputUpdate.validatorPK); @@ -119,9 +121,11 @@ describe("Validators", () => { [1,2,3,4], validatorPK, outputUpdate.groupId, + sharePKs.slice(0, 4), + encryptedShares.slice(0, 4), '10000' )).wait()).logs[0];; - interfaceRegister = new ethers.utils.Interface(['event ValidatorUpdated(bytes validatorPK, bytes32 groupId)']); + interfaceRegister = new ethers.utils.Interface(['event ValidatorUpdated(bytes validatorPK, bytes32 groupId, bytes[] sharesPublicKeys, bytes[] encryptedShares)']); outputRegister = interfaceUpdate.decodeEventLog('ValidatorUpdated', resultRegister.data, resultRegister.topics); await log({ action: `update validator #1: ${outputRegister.validatorPK} : ${outputRegister.groupId}`, @@ -140,7 +144,7 @@ describe("Validators", () => { encryptedShares.slice(0, 4), "1000" )).wait()).logs[0]; - const interfaceRegister2 = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId)']); + const interfaceRegister2 = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId, bytes[] sharesPublicKeys, bytes[] encryptedShares)']); const outputRegister2 = interfaceRegister2.decodeEventLog('ValidatorAdded', resultRegister2.data, resultRegister2.topics); await log({ action: `register validator #2: ${outputRegister2.validatorPK} : ${outputRegister2.groupId}`, From c9141d2d0c88748c3542d0baa062e849546cb23e Mon Sep 17 00:00:00 2001 From: Vadim Date: Sun, 21 Aug 2022 12:58:32 +0200 Subject: [PATCH 020/149] fix group balance --- contracts/SSVRegistry.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/SSVRegistry.sol b/contracts/SSVRegistry.sol index 18ca5fb7..c20de713 100644 --- a/contracts/SSVRegistry.sol +++ b/contracts/SSVRegistry.sol @@ -477,7 +477,7 @@ contract SSVRegistryNew { } function _ownerGroupBalance(Group memory group, uint64 currentGroupIndex) private view returns (uint64) { - return group.balance - (currentGroupIndex - group.usage.index) * group.validatorCount; + return group.balance - ((currentGroupIndex - group.usage.index) + _networkFee) * group.validatorCount; } function _burnRatePerValidator(Operator[] memory operators) private pure returns (uint64 rate) { From 74753090180ec923edc8ffcf0cf6c156db8cbf91 Mon Sep 17 00:00:00 2001 From: Vadim Date: Sun, 21 Aug 2022 15:18:03 +0200 Subject: [PATCH 021/149] tmp --- contracts/SSVRegistry.sol | 19 ++++++------------- test/unit/ssv-registry.js | 16 ++++++++-------- 2 files changed, 14 insertions(+), 21 deletions(-) diff --git a/contracts/SSVRegistry.sol b/contracts/SSVRegistry.sol index c20de713..d76be1b8 100644 --- a/contracts/SSVRegistry.sol +++ b/contracts/SSVRegistry.sol @@ -48,8 +48,8 @@ contract SSVRegistryNew { event OperatorAdded(uint64 operatorId, address indexed owner, bytes encryptionPK); event OperatorRemoved(uint64 operatorId); event OperatorFeeUpdated(uint64 operatorId, uint64 fee); - event ValidatorAdded(bytes validatorPK, bytes32 groupId, bytes[] sharesPublicKeys, bytes[] encryptedShares); - event ValidatorUpdated(bytes validatorPK, bytes32 groupId, bytes[] sharesPublicKeys, bytes[] encryptedShares); + event ValidatorAdded(bytes validatorPK, bytes32 groupId); // , bytes[] sharesPublicKeys, bytes[] encryptedShares); + event ValidatorUpdated(bytes validatorPK, bytes32 groupId); // , bytes[] sharesPublicKeys, bytes[] encryptedShares); event ValidatorRemoved(bytes validatorPK, bytes32 groupId); // global vars @@ -66,15 +66,6 @@ contract SSVRegistryNew { uint64 constant LIQUIDATION_MIN_BLOCKS = 50; // uint64 constant NETWORK_FEE_PER_BLOCK = 1; - - error ExceedRegisteredOperatorsByAccountLimit(); - error OperatorDeleted(); - error ValidatorAlreadyExists(); - error ExceedValidatorLimit(); - error OperatorNotFound(); - error InvalidPublicKeyLength(); - error OessDataStructureInvalid(); - DAO private _dao; IERC20 private _token; @@ -195,7 +186,7 @@ contract SSVRegistryNew { _groups[msg.sender][groupId] = group; } - emit ValidatorAdded(validatorPK, groupId, sharesPublicKeys, encryptedShares); + emit ValidatorAdded(validatorPK, groupId); // , sharesPublicKeys, encryptedShares); } function updateValidator( @@ -297,7 +288,7 @@ contract SSVRegistryNew { _groups[msg.sender][newGroupId] = group; } - emit ValidatorUpdated(validatorPK, newGroupId, sharesPublicKeys, encryptedShares); + emit ValidatorUpdated(validatorPK, newGroupId); //, sharesPublicKeys, encryptedShares); } function removeValidator( @@ -383,6 +374,7 @@ contract SSVRegistryNew { bytes[] memory sharesPublicKeys, bytes[] memory encryptedKeys ) private pure { + /* if (publicKey.length != 48) { revert InvalidPublicKeyLength(); } @@ -393,6 +385,7 @@ contract SSVRegistryNew { ) { revert OessDataStructureInvalid(); } + */ } // function removeValidator(validatorPK) diff --git a/test/unit/ssv-registry.js b/test/unit/ssv-registry.js index f4ffb8cb..f1e10caa 100644 --- a/test/unit/ssv-registry.js +++ b/test/unit/ssv-registry.js @@ -71,11 +71,11 @@ describe("Validators", () => { let resultRegister = (await (await deployedRegistryContract.registerValidator( [1,2,3,4], validatorPK, - sharePKs.slice(0, 4), - encryptedShares.slice(0, 4), + // sharePKs.slice(0, 4), + // encryptedShares.slice(0, 4), '10000' )).wait()).logs[0]; - let interfaceRegister = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId, bytes[] sharesPublicKeys, bytes[] encryptedShares)']); + let interfaceRegister = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId)']); // , bytes[] sharesPublicKeys, bytes[] encryptedShares let outputRegister = interfaceRegister.decodeEventLog('ValidatorAdded', resultRegister.data, resultRegister.topics); await log({ action: `register validator #1: ${outputRegister.validatorPK} : ${outputRegister.groupId}`, @@ -91,11 +91,11 @@ describe("Validators", () => { [4,5,6,7], validatorPK, outputRegister.groupId, - sharePKs.slice(0, 4), - encryptedShares.slice(0, 4), + // sharePKs.slice(0, 4), + // encryptedShares.slice(0, 4), '10000' )).wait()).logs[0];; - let interfaceUpdate = new ethers.utils.Interface(['event ValidatorUpdated(bytes validatorPK, bytes32 groupId, bytes[] sharesPublicKeys, bytes[] encryptedShares)']); + let interfaceUpdate = new ethers.utils.Interface(['event ValidatorUpdated(bytes validatorPK, bytes32 groupId)']); // , bytes[] sharesPublicKeys, bytes[] encryptedShares let outputUpdate = interfaceUpdate.decodeEventLog('ValidatorUpdated', resultUpdate.data, resultUpdate.topics); expect(outputRegister.groupId).not.equal(outputUpdate.groupId); expect(outputRegister.validatorPK).to.equal(outputUpdate.validatorPK); @@ -125,7 +125,7 @@ describe("Validators", () => { encryptedShares.slice(0, 4), '10000' )).wait()).logs[0];; - interfaceRegister = new ethers.utils.Interface(['event ValidatorUpdated(bytes validatorPK, bytes32 groupId, bytes[] sharesPublicKeys, bytes[] encryptedShares)']); + interfaceRegister = new ethers.utils.Interface(['event ValidatorUpdated(bytes validatorPK, bytes32 groupId)']); // , bytes[] sharesPublicKeys, bytes[] encryptedShares outputRegister = interfaceUpdate.decodeEventLog('ValidatorUpdated', resultRegister.data, resultRegister.topics); await log({ action: `update validator #1: ${outputRegister.validatorPK} : ${outputRegister.groupId}`, @@ -144,7 +144,7 @@ describe("Validators", () => { encryptedShares.slice(0, 4), "1000" )).wait()).logs[0]; - const interfaceRegister2 = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId, bytes[] sharesPublicKeys, bytes[] encryptedShares)']); + const interfaceRegister2 = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId)']); // , bytes[] sharesPublicKeys, bytes[] encryptedShares const outputRegister2 = interfaceRegister2.decodeEventLog('ValidatorAdded', resultRegister2.data, resultRegister2.topics); await log({ action: `register validator #2: ${outputRegister2.validatorPK} : ${outputRegister2.groupId}`, From 786d50a8bbf3ba778186aaaafe79232ae164b3f2 Mon Sep 17 00:00:00 2001 From: Vadim Date: Sun, 21 Aug 2022 16:27:01 +0200 Subject: [PATCH 022/149] Revert "fix group balance" This reverts commit c9141d2d0c88748c3542d0baa062e849546cb23e. --- contracts/SSVRegistry.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/SSVRegistry.sol b/contracts/SSVRegistry.sol index d76be1b8..09d98aa0 100644 --- a/contracts/SSVRegistry.sol +++ b/contracts/SSVRegistry.sol @@ -470,7 +470,7 @@ contract SSVRegistryNew { } function _ownerGroupBalance(Group memory group, uint64 currentGroupIndex) private view returns (uint64) { - return group.balance - ((currentGroupIndex - group.usage.index) + _networkFee) * group.validatorCount; + return group.balance - (currentGroupIndex - group.usage.index) * group.validatorCount; } function _burnRatePerValidator(Operator[] memory operators) private pure returns (uint64 rate) { From 7d4904cd39df5e179396cfa3af8b0251744d53ce Mon Sep 17 00:00:00 2001 From: Vadim Date: Sun, 21 Aug 2022 16:28:47 +0200 Subject: [PATCH 023/149] fix tests --- test/unit/ssv-registry.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/unit/ssv-registry.js b/test/unit/ssv-registry.js index f1e10caa..0f414e5b 100644 --- a/test/unit/ssv-registry.js +++ b/test/unit/ssv-registry.js @@ -71,8 +71,8 @@ describe("Validators", () => { let resultRegister = (await (await deployedRegistryContract.registerValidator( [1,2,3,4], validatorPK, - // sharePKs.slice(0, 4), - // encryptedShares.slice(0, 4), + sharePKs.slice(0, 4), + encryptedShares.slice(0, 4), '10000' )).wait()).logs[0]; let interfaceRegister = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId)']); // , bytes[] sharesPublicKeys, bytes[] encryptedShares @@ -91,8 +91,8 @@ describe("Validators", () => { [4,5,6,7], validatorPK, outputRegister.groupId, - // sharePKs.slice(0, 4), - // encryptedShares.slice(0, 4), + sharePKs.slice(0, 4), + encryptedShares.slice(0, 4), '10000' )).wait()).logs[0];; let interfaceUpdate = new ethers.utils.Interface(['event ValidatorUpdated(bytes validatorPK, bytes32 groupId)']); // , bytes[] sharesPublicKeys, bytes[] encryptedShares From 2a209ce2ba5c419af195630d9e09f89257b5c876 Mon Sep 17 00:00:00 2001 From: AndrewBlox Date: Sun, 21 Aug 2022 17:29:53 +0300 Subject: [PATCH 024/149] push stress test --- test/unit/stress.js | 80 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 test/unit/stress.js diff --git a/test/unit/stress.js b/test/unit/stress.js new file mode 100644 index 00000000..b0651b35 --- /dev/null +++ b/test/unit/stress.js @@ -0,0 +1,80 @@ +const { expect } = require("chai"); +const operator_fee_block = 1; + +const operatorsIndexes = Array.from(Array(1000).keys()).map(k => k + 1); +let sharePKs, encryptedShares +let validatorData = [] + +describe("Stress Test", () => { + var deployedRegistryContract + beforeEach(async () => { + const Registry = await ethers.getContractFactory("SSVRegistryNew"); + deployedRegistryContract = await Registry.deploy(); + await deployedRegistryContract.deployed(); + validatorData = [] + + // Create 1000 operators + for (let i = 0; i < operatorsIndexes.length; i++) { + const encryptionPK = "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002644c5330744c5331435255644a54694253553045675546564354456c4449457446575330744c533074436b314a53554a4a616b464f516d64726357687261556335647a424351564646526b464254304e425554684254556c4a516b4e6e53304e42555556424e5756554e557777563068365a54647954575a506232787456484d4b64577449513245344b336474625577324f54464a5131527052454531556b4a31546b787153565132576b4530597a4d78635652495933464256486c3565566b774c7a6b3352336c4b5a32646f596e6c465232526f5a516f76616c6836615756544f584a325279744a56474631516a684d566c686b656b78475956517857455a5765466c6e4e327832546c42344f5552504c315a6f526b686b5757786e54334932643052745633466a52476f33436c68575557464f57454674526e67334e6a56514e546c584e585a7a564752585657464852577858536d3933536b5a4b646e6332556c5249536b5a315456686a537a5a5661574a3063555a4d536d4a774f57356b6455674b516a6c4c537a4e57636d59725a6d744a4f5752425a327478524446484f456c785130744b4d566c33626a557965477878625452434e69744f4f475a555a45314d53314a75635770465a6d527a563164774d46567a4d51704c54573976535863796333426f6158417a5546704e596e4a61615530774e6a4a325a556f3055336f76596a424f62576450546e685464304a4a546e4e7863473534516a68465556517853544e6a4e6b6c714e586868436d35525355524255554643436930744c5330745255354549464a545153425156554a4d53554d675330565a4c5330744c53304b00000000000000000000000000000000000000000000000000000000"; + await deployedRegistryContract.registerOperator(encryptionPK, operator_fee_block); + } + sharePKs = Array.from(Array(10).keys()).map(k => `0xa20a622ecbc816c89896f92a18214905a57beedbe8df6120ba644453a7e35672a365c3b73ce35b8738eeb5dade9107d${k}`); + encryptedShares = Array.from(Array(10).keys()).map(k => `0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000158513741566f733037584a4537767275644b366c7a647a76634143313563636b5152492b6143766f31617a374979787a517233506a4361632b545745394d45307a4f6d49${k}36947472f46312f38613556786d71383948366e6b71436130415573782b37326c43306f686a4b3874396853746953746732596e2b304d2f4e3732744c6d5951394c325976654c56564a35556c586a425777${k}4377a5537732f3142435653727862415431376f2f704858474c46644170697a4c5332704b48354b71746545786e3033566b4a4244527538596c5055334634656c554937697a667a474444626d49677536484862305777344669743745543745422f357056457a547279445a5179516753336a4858714d63637359396e52494250724f2f2f367370544736646e5831304e4872356b716a305136464b64684d6a4162644d43773966527274672b72766979584e6674464945445478304768314f513d3d0000000000000000`); + + // Deposit to the account + await deployedRegistryContract.deposit("100000000000") + + // Register 1000 validators + for (let i = 1000; i < 2000; i++) { + const randomOperator = Math.floor(Math.random() * 995) + const validatorPK = `0xa7ae1ea93b860ca0269ccca776b4526977395aa194e5820a00dedbf1cd63e7a898eec9a12f539f733ea4df9c651f${i}` + + const registerResult = (await (await deployedRegistryContract.registerValidator( + [randomOperator, randomOperator + 1, randomOperator + 2, randomOperator + 3], + validatorPK, + sharePKs.slice(0, 4), + encryptedShares.slice(0, 4), + "10000" + )).wait()).logs[0] + + // Save validator group id emits + const interfaceRegister = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId)']); + const outputRegister = interfaceRegister.decodeEventLog('ValidatorAdded', registerResult.data, registerResult.topics); + validatorData.push({ publicKey: validatorPK, groupId: outputRegister.groupId }) + } + }) + + it("Update 1000 operators", async () => { + for (let i = 0; i < operatorsIndexes.length; i++) { + await deployedRegistryContract.updateOperatorFee(operatorsIndexes[i], 10) + } + }) + + it("Update 30 validators", async () => { + for (let i = 1000; i < 1030; i++) { + const randomOperator = Math.floor(Math.random() * 995) + const validatorPK = `0xa7ae1ea93b860ca0269ccca776b4526977395aa194e5820a00dedbf1cd63e7a898eec9a12f539f733ea4df9c651f${i}` + await deployedRegistryContract.updateValidator( + [randomOperator, randomOperator + 1, randomOperator + 2, randomOperator + 3], + validatorPK, + validatorData[i - 1000].groupId, + sharePKs.slice(0, 4), + encryptedShares.slice(0, 4), + "10" + ) + } + }) + + it("Remove 1000 operators", async () => { + for (let i = 0; i < operatorsIndexes.length; i++) { + await deployedRegistryContract.removeOperator(operatorsIndexes[i]) + } + }) + + it("Remove 1000 validators", async () => { + for (let i = 0; i < validatorData.length; i++) { + await deployedRegistryContract.removeValidator(validatorData[i].publicKey, validatorData[i].groupId) + } + }) + +}); From 518f7cc50cfe0c7b56c14c3dad8c182fccf1a7bc Mon Sep 17 00:00:00 2001 From: Vadim Date: Mon, 22 Aug 2022 11:56:20 +0200 Subject: [PATCH 025/149] mapping for transfer --- contracts/SSVRegistry.sol | 28 ++++++++++++++++++++++++++-- hardhat.config.ts | 3 +++ test/unit/ssv-registry.js | 16 +++++++++++++--- test/unit/stress.js | 6 +++++- 4 files changed, 47 insertions(+), 6 deletions(-) diff --git a/contracts/SSVRegistry.sol b/contracts/SSVRegistry.sol index 09d98aa0..17cf8cfd 100644 --- a/contracts/SSVRegistry.sol +++ b/contracts/SSVRegistry.sol @@ -41,7 +41,7 @@ contract SSVRegistryNew { struct Group { uint64 balance; uint64 validatorCount; - bytes[] validatorPKs; + // bytes[] validatorPKs; Snapshot usage; } @@ -49,6 +49,7 @@ contract SSVRegistryNew { event OperatorRemoved(uint64 operatorId); event OperatorFeeUpdated(uint64 operatorId, uint64 fee); event ValidatorAdded(bytes validatorPK, bytes32 groupId); // , bytes[] sharesPublicKeys, bytes[] encryptedShares); + event ValidatorTransfered(bytes32 ipfsHash, bytes32 groupId); // , bytes[] sharesPublicKeys, bytes[] encryptedShares); event ValidatorUpdated(bytes validatorPK, bytes32 groupId); // , bytes[] sharesPublicKeys, bytes[] encryptedShares); event ValidatorRemoved(bytes validatorPK, bytes32 groupId); @@ -61,6 +62,7 @@ contract SSVRegistryNew { mapping(bytes32 => OperatorCollection) private _operatorCollections; mapping(address => mapping(bytes32 => Group)) private _groups; mapping(address => uint64) _availableBalances; + mapping(bytes32 => mapping(bytes => uint16)) private _validatorPKs; uint64 private _networkFee; uint64 constant LIQUIDATION_MIN_BLOCKS = 50; @@ -110,6 +112,19 @@ contract SSVRegistryNew { emit OperatorFeeUpdated(operatorId, fee); } + function transferValidator( + // bytes calldata validatorPK, + bytes32 ipfsHash, + bytes32 groupId + // bytes[] calldata sharesPublicKeys, + // bytes[] calldata encryptedShares + ) external { + for (uint64 i = 0; i < 100; ++i) { + emit ValidatorTransfered(ipfsHash, groupId); + // _validatorPKs[msg.sender][validatorPK] = groupId; + } + } + function registerValidator( uint64[] memory operatorIds, bytes calldata validatorPK, @@ -157,6 +172,15 @@ contract SSVRegistryNew { extendedGroup[group.validatorCount - 1] = validatorPK; group.validatorPKs = extendedGroup; */ + // group.validatorPKs[validatorPK] = 1; + // _validatorPKs[msg.sender][validatorPK] = groupId; + /* + bytes32[] memory data = new bytes32[](2); + data[0] = bytes32(abi.encodePacked(msg.sender)); + data[1] = groupId; + bytes32 key = keccak256(abi.encodePacked(data)); + _validatorPKs[key][validatorPK] = 1; + */ } { @@ -178,7 +202,7 @@ contract SSVRegistryNew { } // TODO - // require(!_liquidatable(group.balance, group.validatorCount, _extractOperators(operatorIds)), "account liquidatable"); + require(!_liquidatable(group.balance, group.validatorCount, _extractOperators(operatorIds)), "account liquidatable"); // list of operators here makes the gas higher // without: 352641 max, 336957 avg, 321272 min // with that: 364550 max, 348866 avg, 333181 min diff --git a/hardhat.config.ts b/hardhat.config.ts index 85c5c3fe..58ea9a19 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -12,6 +12,9 @@ import '@nomiclabs/hardhat-solhint'; const config: HardhatUserConfig = { // Your type-safe config goes here + mocha: { + timeout: 40000000000000000 + }, solidity: { compilers: [ { diff --git a/test/unit/ssv-registry.js b/test/unit/ssv-registry.js index 0f414e5b..47c49bf2 100644 --- a/test/unit/ssv-registry.js +++ b/test/unit/ssv-registry.js @@ -124,7 +124,7 @@ describe("Validators", () => { sharePKs.slice(0, 4), encryptedShares.slice(0, 4), '10000' - )).wait()).logs[0];; + )).wait()).logs[0]; interfaceRegister = new ethers.utils.Interface(['event ValidatorUpdated(bytes validatorPK, bytes32 groupId)']); // , bytes[] sharesPublicKeys, bytes[] encryptedShares outputRegister = interfaceUpdate.decodeEventLog('ValidatorUpdated', resultRegister.data, resultRegister.topics); await log({ @@ -138,7 +138,7 @@ describe("Validators", () => { groupIds: [outputRegister.groupId, outputUpdate.groupId] }); const resultRegister2 = (await (await deployedRegistryContract.registerValidator( - [5,6,7,8], + [1,2,3,4], validatorPK, sharePKs.slice(0, 4), encryptedShares.slice(0, 4), @@ -196,7 +196,17 @@ describe("Validators", () => { operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], groupIds: [outputRegister.groupId, outputRegister2.groupId] }); - + await progressBlocks(1); + (await (await deployedRegistryContract.transferValidator( + outputRegister.groupId, + outputRegister.groupId, + )).wait()).logs[0];; + await log({ + action: 'transfer', + operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], + groupIds: [outputRegister.groupId, outputRegister2.groupId] + }); + /* // validator 2 await expect(await deployedRegistryContract.registerValidator( diff --git a/test/unit/stress.js b/test/unit/stress.js index b0651b35..44b665f7 100644 --- a/test/unit/stress.js +++ b/test/unit/stress.js @@ -1,4 +1,5 @@ const { expect } = require("chai"); +const { progressBlocks } = require('./utils'); const operator_fee_block = 1; const operatorsIndexes = Array.from(Array(1000).keys()).map(k => k + 1); @@ -23,7 +24,9 @@ describe("Stress Test", () => { // Deposit to the account await deployedRegistryContract.deposit("100000000000") + }) + it("Register 1000 validators", async () => { // Register 1000 validators for (let i = 1000; i < 2000; i++) { const randomOperator = Math.floor(Math.random() * 995) @@ -44,6 +47,7 @@ describe("Stress Test", () => { } }) + /* it("Update 1000 operators", async () => { for (let i = 0; i < operatorsIndexes.length; i++) { await deployedRegistryContract.updateOperatorFee(operatorsIndexes[i], 10) @@ -76,5 +80,5 @@ describe("Stress Test", () => { await deployedRegistryContract.removeValidator(validatorData[i].publicKey, validatorData[i].groupId) } }) - + */ }); From 5a856a516e97b7d5d828c65e6b01b5ecc8a161dc Mon Sep 17 00:00:00 2001 From: Lior Rutenberg Date: Tue, 23 Aug 2022 13:29:33 +0300 Subject: [PATCH 026/149] fixed to correct events --- contracts/SSVRegistry.sol | 9 +- test/unit/ssv-registry.js | 6 +- test/unit/stress.js | 168 +++++++++++++++++++------------------- 3 files changed, 91 insertions(+), 92 deletions(-) diff --git a/contracts/SSVRegistry.sol b/contracts/SSVRegistry.sol index 17cf8cfd..8b4ebf7f 100644 --- a/contracts/SSVRegistry.sol +++ b/contracts/SSVRegistry.sol @@ -41,16 +41,15 @@ contract SSVRegistryNew { struct Group { uint64 balance; uint64 validatorCount; - // bytes[] validatorPKs; Snapshot usage; } event OperatorAdded(uint64 operatorId, address indexed owner, bytes encryptionPK); event OperatorRemoved(uint64 operatorId); event OperatorFeeUpdated(uint64 operatorId, uint64 fee); - event ValidatorAdded(bytes validatorPK, bytes32 groupId); // , bytes[] sharesPublicKeys, bytes[] encryptedShares); + event ValidatorAdded(bytes validatorPK, bytes32 groupId,bytes[] sharesPublicKeys, bytes[] encryptedShares); event ValidatorTransfered(bytes32 ipfsHash, bytes32 groupId); // , bytes[] sharesPublicKeys, bytes[] encryptedShares); - event ValidatorUpdated(bytes validatorPK, bytes32 groupId); // , bytes[] sharesPublicKeys, bytes[] encryptedShares); + event ValidatorUpdated(bytes validatorPK, bytes32 groupId, bytes[] sharesPublicKeys, bytes[] encryptedShares); event ValidatorRemoved(bytes validatorPK, bytes32 groupId); // global vars @@ -210,7 +209,7 @@ contract SSVRegistryNew { _groups[msg.sender][groupId] = group; } - emit ValidatorAdded(validatorPK, groupId); // , sharesPublicKeys, encryptedShares); + emit ValidatorAdded(validatorPK, groupId, sharesPublicKeys, encryptedShares); } function updateValidator( @@ -312,7 +311,7 @@ contract SSVRegistryNew { _groups[msg.sender][newGroupId] = group; } - emit ValidatorUpdated(validatorPK, newGroupId); //, sharesPublicKeys, encryptedShares); + emit ValidatorUpdated(validatorPK, newGroupId, sharesPublicKeys, encryptedShares); } function removeValidator( diff --git a/test/unit/ssv-registry.js b/test/unit/ssv-registry.js index 47c49bf2..b2adce69 100644 --- a/test/unit/ssv-registry.js +++ b/test/unit/ssv-registry.js @@ -75,7 +75,7 @@ describe("Validators", () => { encryptedShares.slice(0, 4), '10000' )).wait()).logs[0]; - let interfaceRegister = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId)']); // , bytes[] sharesPublicKeys, bytes[] encryptedShares + let interfaceRegister = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId, bytes[] sharesPublicKeys, bytes[] encryptedShares)']); let outputRegister = interfaceRegister.decodeEventLog('ValidatorAdded', resultRegister.data, resultRegister.topics); await log({ action: `register validator #1: ${outputRegister.validatorPK} : ${outputRegister.groupId}`, @@ -95,7 +95,7 @@ describe("Validators", () => { encryptedShares.slice(0, 4), '10000' )).wait()).logs[0];; - let interfaceUpdate = new ethers.utils.Interface(['event ValidatorUpdated(bytes validatorPK, bytes32 groupId)']); // , bytes[] sharesPublicKeys, bytes[] encryptedShares + let interfaceUpdate = new ethers.utils.Interface(['event ValidatorUpdated(bytes validatorPK, bytes32 groupId, bytes[] sharesPublicKeys, bytes[] encryptedShares)']); let outputUpdate = interfaceUpdate.decodeEventLog('ValidatorUpdated', resultUpdate.data, resultUpdate.topics); expect(outputRegister.groupId).not.equal(outputUpdate.groupId); expect(outputRegister.validatorPK).to.equal(outputUpdate.validatorPK); @@ -144,7 +144,7 @@ describe("Validators", () => { encryptedShares.slice(0, 4), "1000" )).wait()).logs[0]; - const interfaceRegister2 = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId)']); // , bytes[] sharesPublicKeys, bytes[] encryptedShares + const interfaceRegister2 = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId, bytes[] sharesPublicKeys, bytes[] encryptedShares)']); const outputRegister2 = interfaceRegister2.decodeEventLog('ValidatorAdded', resultRegister2.data, resultRegister2.topics); await log({ action: `register validator #2: ${outputRegister2.validatorPK} : ${outputRegister2.groupId}`, diff --git a/test/unit/stress.js b/test/unit/stress.js index 44b665f7..4019bed0 100644 --- a/test/unit/stress.js +++ b/test/unit/stress.js @@ -1,84 +1,84 @@ -const { expect } = require("chai"); -const { progressBlocks } = require('./utils'); -const operator_fee_block = 1; - -const operatorsIndexes = Array.from(Array(1000).keys()).map(k => k + 1); -let sharePKs, encryptedShares -let validatorData = [] - -describe("Stress Test", () => { - var deployedRegistryContract - beforeEach(async () => { - const Registry = await ethers.getContractFactory("SSVRegistryNew"); - deployedRegistryContract = await Registry.deploy(); - await deployedRegistryContract.deployed(); - validatorData = [] - - // Create 1000 operators - for (let i = 0; i < operatorsIndexes.length; i++) { - const encryptionPK = "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002644c5330744c5331435255644a54694253553045675546564354456c4449457446575330744c533074436b314a53554a4a616b464f516d64726357687261556335647a424351564646526b464254304e425554684254556c4a516b4e6e53304e42555556424e5756554e557777563068365a54647954575a506232787456484d4b64577449513245344b336474625577324f54464a5131527052454531556b4a31546b787153565132576b4530597a4d78635652495933464256486c3565566b774c7a6b3352336c4b5a32646f596e6c465232526f5a516f76616c6836615756544f584a325279744a56474631516a684d566c686b656b78475956517857455a5765466c6e4e327832546c42344f5552504c315a6f526b686b5757786e54334932643052745633466a52476f33436c68575557464f57454674526e67334e6a56514e546c584e585a7a564752585657464852577858536d3933536b5a4b646e6332556c5249536b5a315456686a537a5a5661574a3063555a4d536d4a774f57356b6455674b516a6c4c537a4e57636d59725a6d744a4f5752425a327478524446484f456c785130744b4d566c33626a557965477878625452434e69744f4f475a555a45314d53314a75635770465a6d527a563164774d46567a4d51704c54573976535863796333426f6158417a5546704e596e4a61615530774e6a4a325a556f3055336f76596a424f62576450546e685464304a4a546e4e7863473534516a68465556517853544e6a4e6b6c714e586868436d35525355524255554643436930744c5330745255354549464a545153425156554a4d53554d675330565a4c5330744c53304b00000000000000000000000000000000000000000000000000000000"; - await deployedRegistryContract.registerOperator(encryptionPK, operator_fee_block); - } - sharePKs = Array.from(Array(10).keys()).map(k => `0xa20a622ecbc816c89896f92a18214905a57beedbe8df6120ba644453a7e35672a365c3b73ce35b8738eeb5dade9107d${k}`); - encryptedShares = Array.from(Array(10).keys()).map(k => `0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000158513741566f733037584a4537767275644b366c7a647a76634143313563636b5152492b6143766f31617a374979787a517233506a4361632b545745394d45307a4f6d49${k}36947472f46312f38613556786d71383948366e6b71436130415573782b37326c43306f686a4b3874396853746953746732596e2b304d2f4e3732744c6d5951394c325976654c56564a35556c586a425777${k}4377a5537732f3142435653727862415431376f2f704858474c46644170697a4c5332704b48354b71746545786e3033566b4a4244527538596c5055334634656c554937697a667a474444626d49677536484862305777344669743745543745422f357056457a547279445a5179516753336a4858714d63637359396e52494250724f2f2f367370544736646e5831304e4872356b716a305136464b64684d6a4162644d43773966527274672b72766979584e6674464945445478304768314f513d3d0000000000000000`); - - // Deposit to the account - await deployedRegistryContract.deposit("100000000000") - }) - - it("Register 1000 validators", async () => { - // Register 1000 validators - for (let i = 1000; i < 2000; i++) { - const randomOperator = Math.floor(Math.random() * 995) - const validatorPK = `0xa7ae1ea93b860ca0269ccca776b4526977395aa194e5820a00dedbf1cd63e7a898eec9a12f539f733ea4df9c651f${i}` - - const registerResult = (await (await deployedRegistryContract.registerValidator( - [randomOperator, randomOperator + 1, randomOperator + 2, randomOperator + 3], - validatorPK, - sharePKs.slice(0, 4), - encryptedShares.slice(0, 4), - "10000" - )).wait()).logs[0] - - // Save validator group id emits - const interfaceRegister = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId)']); - const outputRegister = interfaceRegister.decodeEventLog('ValidatorAdded', registerResult.data, registerResult.topics); - validatorData.push({ publicKey: validatorPK, groupId: outputRegister.groupId }) - } - }) - - /* - it("Update 1000 operators", async () => { - for (let i = 0; i < operatorsIndexes.length; i++) { - await deployedRegistryContract.updateOperatorFee(operatorsIndexes[i], 10) - } - }) - - it("Update 30 validators", async () => { - for (let i = 1000; i < 1030; i++) { - const randomOperator = Math.floor(Math.random() * 995) - const validatorPK = `0xa7ae1ea93b860ca0269ccca776b4526977395aa194e5820a00dedbf1cd63e7a898eec9a12f539f733ea4df9c651f${i}` - await deployedRegistryContract.updateValidator( - [randomOperator, randomOperator + 1, randomOperator + 2, randomOperator + 3], - validatorPK, - validatorData[i - 1000].groupId, - sharePKs.slice(0, 4), - encryptedShares.slice(0, 4), - "10" - ) - } - }) - - it("Remove 1000 operators", async () => { - for (let i = 0; i < operatorsIndexes.length; i++) { - await deployedRegistryContract.removeOperator(operatorsIndexes[i]) - } - }) - - it("Remove 1000 validators", async () => { - for (let i = 0; i < validatorData.length; i++) { - await deployedRegistryContract.removeValidator(validatorData[i].publicKey, validatorData[i].groupId) - } - }) - */ -}); +// const { expect } = require("chai"); +// const { progressBlocks } = require('./utils'); +// const operator_fee_block = 1; +// +// const operatorsIndexes = Array.from(Array(1000).keys()).map(k => k + 1); +// let sharePKs, encryptedShares +// let validatorData = [] +// +// describe("Stress Test", () => { +// var deployedRegistryContract +// beforeEach(async () => { +// const Registry = await ethers.getContractFactory("SSVRegistryNew"); +// deployedRegistryContract = await Registry.deploy(); +// await deployedRegistryContract.deployed(); +// validatorData = [] +// +// // Create 1000 operators +// for (let i = 0; i < operatorsIndexes.length; i++) { +// const encryptionPK = "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002644c5330744c5331435255644a54694253553045675546564354456c4449457446575330744c533074436b314a53554a4a616b464f516d64726357687261556335647a424351564646526b464254304e425554684254556c4a516b4e6e53304e42555556424e5756554e557777563068365a54647954575a506232787456484d4b64577449513245344b336474625577324f54464a5131527052454531556b4a31546b787153565132576b4530597a4d78635652495933464256486c3565566b774c7a6b3352336c4b5a32646f596e6c465232526f5a516f76616c6836615756544f584a325279744a56474631516a684d566c686b656b78475956517857455a5765466c6e4e327832546c42344f5552504c315a6f526b686b5757786e54334932643052745633466a52476f33436c68575557464f57454674526e67334e6a56514e546c584e585a7a564752585657464852577858536d3933536b5a4b646e6332556c5249536b5a315456686a537a5a5661574a3063555a4d536d4a774f57356b6455674b516a6c4c537a4e57636d59725a6d744a4f5752425a327478524446484f456c785130744b4d566c33626a557965477878625452434e69744f4f475a555a45314d53314a75635770465a6d527a563164774d46567a4d51704c54573976535863796333426f6158417a5546704e596e4a61615530774e6a4a325a556f3055336f76596a424f62576450546e685464304a4a546e4e7863473534516a68465556517853544e6a4e6b6c714e586868436d35525355524255554643436930744c5330745255354549464a545153425156554a4d53554d675330565a4c5330744c53304b00000000000000000000000000000000000000000000000000000000"; +// await deployedRegistryContract.registerOperator(encryptionPK, operator_fee_block); +// } +// sharePKs = Array.from(Array(10).keys()).map(k => `0xa20a622ecbc816c89896f92a18214905a57beedbe8df6120ba644453a7e35672a365c3b73ce35b8738eeb5dade9107d${k}`); +// encryptedShares = Array.from(Array(10).keys()).map(k => `0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000158513741566f733037584a4537767275644b366c7a647a76634143313563636b5152492b6143766f31617a374979787a517233506a4361632b545745394d45307a4f6d49${k}36947472f46312f38613556786d71383948366e6b71436130415573782b37326c43306f686a4b3874396853746953746732596e2b304d2f4e3732744c6d5951394c325976654c56564a35556c586a425777${k}4377a5537732f3142435653727862415431376f2f704858474c46644170697a4c5332704b48354b71746545786e3033566b4a4244527538596c5055334634656c554937697a667a474444626d49677536484862305777344669743745543745422f357056457a547279445a5179516753336a4858714d63637359396e52494250724f2f2f367370544736646e5831304e4872356b716a305136464b64684d6a4162644d43773966527274672b72766979584e6674464945445478304768314f513d3d0000000000000000`); +// +// // Deposit to the account +// await deployedRegistryContract.deposit("100000000000") +// }) +// +// it("Register 1000 validators", async () => { +// // Register 1000 validators +// for (let i = 1000; i < 2000; i++) { +// const randomOperator = Math.floor(Math.random() * 995) +// const validatorPK = `0xa7ae1ea93b860ca0269ccca776b4526977395aa194e5820a00dedbf1cd63e7a898eec9a12f539f733ea4df9c651f${i}` +// +// const registerResult = (await (await deployedRegistryContract.registerValidator( +// [randomOperator, randomOperator + 1, randomOperator + 2, randomOperator + 3], +// validatorPK, +// sharePKs.slice(0, 4), +// encryptedShares.slice(0, 4), +// "10000" +// )).wait()).logs[0] +// +// // Save validator group id emits +// const interfaceRegister = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId)']); +// const outputRegister = interfaceRegister.decodeEventLog('ValidatorAdded', registerResult.data, registerResult.topics); +// validatorData.push({ publicKey: validatorPK, groupId: outputRegister.groupId }) +// } +// }) +// +// /* +// it("Update 1000 operators", async () => { +// for (let i = 0; i < operatorsIndexes.length; i++) { +// await deployedRegistryContract.updateOperatorFee(operatorsIndexes[i], 10) +// } +// }) +// +// it("Update 30 validators", async () => { +// for (let i = 1000; i < 1030; i++) { +// const randomOperator = Math.floor(Math.random() * 995) +// const validatorPK = `0xa7ae1ea93b860ca0269ccca776b4526977395aa194e5820a00dedbf1cd63e7a898eec9a12f539f733ea4df9c651f${i}` +// await deployedRegistryContract.updateValidator( +// [randomOperator, randomOperator + 1, randomOperator + 2, randomOperator + 3], +// validatorPK, +// validatorData[i - 1000].groupId, +// sharePKs.slice(0, 4), +// encryptedShares.slice(0, 4), +// "10" +// ) +// } +// }) +// +// it("Remove 1000 operators", async () => { +// for (let i = 0; i < operatorsIndexes.length; i++) { +// await deployedRegistryContract.removeOperator(operatorsIndexes[i]) +// } +// }) +// +// it("Remove 1000 validators", async () => { +// for (let i = 0; i < validatorData.length; i++) { +// await deployedRegistryContract.removeValidator(validatorData[i].publicKey, validatorData[i].groupId) +// } +// }) +// */ +// }); From 7a3c9bfdef9f83621616c3e4937fda9e514d15cf Mon Sep 17 00:00:00 2001 From: Vadim Date: Tue, 23 Aug 2022 17:14:40 +0200 Subject: [PATCH 027/149] wip cleanup the code --- contracts/SSVRegistry.sol | 213 +++++++++++++------------------------- test/unit/ssv-registry.js | 2 + 2 files changed, 76 insertions(+), 139 deletions(-) diff --git a/contracts/SSVRegistry.sol b/contracts/SSVRegistry.sol index 8b4ebf7f..4a9ebfde 100644 --- a/contracts/SSVRegistry.sol +++ b/contracts/SSVRegistry.sol @@ -61,12 +61,17 @@ contract SSVRegistryNew { mapping(bytes32 => OperatorCollection) private _operatorCollections; mapping(address => mapping(bytes32 => Group)) private _groups; mapping(address => uint64) _availableBalances; - mapping(bytes32 => mapping(bytes => uint16)) private _validatorPKs; + mapping(address => mapping(bytes => bytes32)) private _validatorPKs; uint64 private _networkFee; uint64 constant LIQUIDATION_MIN_BLOCKS = 50; // uint64 constant NETWORK_FEE_PER_BLOCK = 1; + /** errors */ + error InvalidPublicKeyLength(); + error OessDataStructureInvalid(); + error ValidatorNotExistInGroup(); + DAO private _dao; IERC20 private _token; @@ -111,6 +116,7 @@ contract SSVRegistryNew { emit OperatorFeeUpdated(operatorId, fee); } + /* function transferValidator( // bytes calldata validatorPK, bytes32 ipfsHash, @@ -123,6 +129,7 @@ contract SSVRegistryNew { // _validatorPKs[msg.sender][validatorPK] = groupId; } } + */ function registerValidator( uint64[] memory operatorIds, @@ -138,74 +145,28 @@ contract SSVRegistryNew { encryptedShares ); - // Operator[] memory operators; - bytes32 groupId; - { - uint64 currentBlock = uint64(block.number); - { - groupId = _getOrCreateOperatorCollection(operatorIds); - // operators = _extractOperators(operatorIds); - } + bytes32 groupId = _getOrCreateOperatorCollection(operatorIds); + { Group memory group; { _availableBalances[msg.sender] -= amount; - - group = _groups[msg.sender][groupId]; - uint64 groupIndex = _groupCurrentIndex(groupId); - group.balance = _ownerGroupBalance(group, groupIndex) + amount; - group.usage.index = groupIndex; - group.usage.block = currentBlock; - - ++group.validatorCount; - - // TODO - // gas issues - // without: 352641 max, 336957 avg, 321272 min - // with that: 442985 max, 427300 avg, 411615 min - /* - bytes[] memory extendedGroup = new bytes[](group.validatorCount); - for (uint64 i = 0; i < group.validatorPKs.length; ++i) { - extendedGroup[i] = group.validatorPKs[i]; - } - extendedGroup[group.validatorCount - 1] = validatorPK; - group.validatorPKs = extendedGroup; - */ - // group.validatorPKs[validatorPK] = 1; - // _validatorPKs[msg.sender][validatorPK] = groupId; - /* - bytes32[] memory data = new bytes32[](2); - data[0] = bytes32(abi.encodePacked(msg.sender)); - data[1] = groupId; - bytes32 key = keccak256(abi.encodePacked(data)); - _validatorPKs[key][validatorPK] = 1; - */ + group = _updateGroupData(groupId, amount, true); + _validatorPKs[msg.sender][validatorPK] = groupId; } { - for (uint64 i = 0; i < operatorIds.length; ++i) { - Operator memory operator = _operators[operatorIds[i]]; - operator.earnings = _updateOperatorEarnings(operator, currentBlock); - operator.earnRate += operator.fee; - ++operator.validatorCount; - _operators[operatorIds[i]] = operator; - } + _updateOperatorsData(operatorIds, true); } { - // // update DAO earnings DAO memory dao = _dao; dao = _updateDAOEarnings(dao, uint64(block.number)); ++dao.validatorCount; _dao = dao; } - // TODO - require(!_liquidatable(group.balance, group.validatorCount, _extractOperators(operatorIds)), "account liquidatable"); - // list of operators here makes the gas higher - // without: 352641 max, 336957 avg, 321272 min - // with that: 364550 max, 348866 avg, 333181 min - + require(!_liquidatable(group.balance, group.validatorCount, operatorIds), "account liquidatable"); _groups[msg.sender][groupId] = group; } @@ -215,99 +176,41 @@ contract SSVRegistryNew { function updateValidator( uint64[] memory operatorIds, bytes calldata validatorPK, - bytes32 currentGroupId, + bytes32 groupId, bytes[] calldata sharesPublicKeys, bytes[] calldata encryptedShares, uint64 amount ) external { - uint64 currentBlock = uint64(block.number); - { - Group memory group; - { - group = _groups[msg.sender][currentGroupId]; - - uint64 groupIndex = _groupCurrentIndex(currentGroupId); - group.balance = _ownerGroupBalance(group, groupIndex); - group.usage.index = groupIndex; - group.usage.block = currentBlock; - --group.validatorCount; - - if (group.validatorCount == 0) { - // _availableBalances[msg.sender] += _ownerGroupBalance(group, groupIndex); - // group.balance -= _ownerGroupBalance(group, groupIndex); - } - } - OperatorCollection memory operatorCollection = _operatorCollections[currentGroupId]; - { - for (uint64 i = 0; i < operatorCollection.operatorIds.length; ++i) { - bool found; - for (uint64 j = 0; j < operatorIds.length; ++j) { - if (operatorCollection.operatorIds[i] == operatorIds[j]) { - found = true; - } - } - if (!found) { - uint64 id = operatorCollection.operatorIds[i]; - _operators[id].earnings = _updateOperatorEarnings(_operators[id], currentBlock); - _operators[id].earnRate -= _operators[id].fee; - --_operators[id].validatorCount; - } - } - - for (uint64 i = 0; i < operatorIds.length; ++i) { - bool found; - for (uint64 j = 0; j < operatorCollection.operatorIds.length; ++j) { - if (operatorIds[i] == operatorCollection.operatorIds[j]) { - found = true; - } - } - if (!found) { - uint64 id = operatorIds[i]; - _operators[id].earnings = _updateOperatorEarnings(_operators[id], currentBlock); - _operators[id].earnRate += _operators[id].fee; - ++_operators[id].validatorCount; - } - } - } - _groups[msg.sender][currentGroupId] = group; + if (_validatorPKs[msg.sender][validatorPK] != groupId) { + revert ValidatorNotExistInGroup(); } - bytes32 newGroupId; + _groups[msg.sender][groupId] = _updateGroupData(groupId, 0, false); + { - // Operator[] memory newOperators; - { - newGroupId = _getOrCreateOperatorCollection(operatorIds); - // newOperators = _extractOperators(operatorIds); - } + OperatorCollection memory operatorCollection = _operatorCollections[groupId]; + _updateOperatorsData(operatorCollection.operatorIds, false); + _updateOperatorsData(operatorIds, true); + } + + bytes32 newGroupId = _getOrCreateOperatorCollection(operatorIds); + { Group memory group; { - uint64 groupIndex = _groupCurrentIndex(newGroupId); - _availableBalances[msg.sender] -= amount; - - group = _groups[msg.sender][newGroupId]; - group.balance = _ownerGroupBalance(group, groupIndex) + amount; - group.usage.index = groupIndex; - group.usage.block = currentBlock; - - ++group.validatorCount; + group = _updateGroupData(newGroupId, amount, true); + _validatorPKs[msg.sender][validatorPK] = newGroupId; } { - // // update DAO earnings DAO memory dao = _dao; dao = _updateDAOEarnings(dao, uint64(block.number)); _dao = dao; } - // TODO - // require(!_liquidatable(group.balance, group.validatorCount, newOperators), "account liquidatable"); - // list of operators here makes the gas higher - // without: 353107 max, 315041 avg, 276974 min - // with that: 365039 max, 326973 avg, 288906 min - + require(!_liquidatable(group.balance, group.validatorCount, operatorIds), "account liquidatable"); _groups[msg.sender][newGroupId] = group; } @@ -318,6 +221,10 @@ contract SSVRegistryNew { bytes calldata validatorPK, bytes32 groupId ) external { + if (_validatorPKs[msg.sender][validatorPK] != groupId) { + revert ValidatorNotExistInGroup(); + } + { Group memory group = _groups[msg.sender][groupId]; OperatorCollection memory operatorCollection = _operatorCollections[groupId]; @@ -363,6 +270,43 @@ contract SSVRegistryNew { return operator; } + function _updateOperatorsData(uint64[] memory operatorIds, bool increase) private { + uint64 currentBlock = uint64(block.number); + for (uint64 i = 0; i < operatorIds.length; ++i) { + Operator memory operator = _operators[operatorIds[i]]; + operator.earnings = _updateOperatorEarnings(operator, currentBlock); + if (increase) { + operator.earnRate += operator.fee; + ++operator.validatorCount; + } else { + operator.earnRate -= operator.fee; + --operator.validatorCount; + } + _operators[operatorIds[i]] = operator; + } + } + + function _updateGroupData(bytes32 groupId, uint64 amount, bool increase) private returns (Group memory) { + Group memory group = _groups[msg.sender][groupId]; + uint64 currentBlock = uint64(block.number); + uint64 groupIndex = _groupCurrentIndex(groupId); + group.balance = _ownerGroupBalance(group, groupIndex) + amount; + group.usage.index = groupIndex; + group.usage.block = currentBlock; + if (increase) { + ++group.validatorCount; + } else { + --group.validatorCount; + } + + if (group.validatorCount == 0) { + // _availableBalances[msg.sender] += _ownerGroupBalance(group, groupIndex); + // group.balance -= _ownerGroupBalance(group, groupIndex); + } + return group; + } + + function test_getOperatorsByGroupId(bytes32 groupId) external view returns (uint64[] memory) { return _operatorCollections[groupId].operatorIds; } @@ -397,7 +341,6 @@ contract SSVRegistryNew { bytes[] memory sharesPublicKeys, bytes[] memory encryptedKeys ) private pure { - /* if (publicKey.length != 48) { revert InvalidPublicKeyLength(); } @@ -408,11 +351,8 @@ contract SSVRegistryNew { ) { revert OessDataStructureInvalid(); } - */ } - // function removeValidator(validatorPK) - function deposit(uint64 amount) public { _availableBalances[msg.sender] += amount; } @@ -425,12 +365,6 @@ contract SSVRegistryNew { _operatorCollections[keccak256(abi.encodePacked(operators))] = OperatorCollection({ operatorIds: operators }); } - /* - function _updateOperatorIndex(Operator memory operator, uint64 currentBlock) private returns (Snapshot memory) { - return Snapshot({ index: _operatorCurrentIndex(operator), block: currentBlock, balance: }); - } - */ - function _getOrCreateOperatorCollection(uint64[] memory operatorIds) private returns (bytes32) { // , OperatorCollection memory for (uint64 i = 0; i < operatorIds.length - 1;) { require(operatorIds[i] <= operatorIds[++i]); @@ -443,7 +377,7 @@ contract SSVRegistryNew { operatorCollection.operatorIds = operatorIds; } - return key; // (key, operatorCollection); + return key; } function _updateOperatorEarnings(Operator memory operator, uint64 currentBlock) private returns (Snapshot memory) { @@ -502,9 +436,10 @@ contract SSVRegistryNew { } } - function _liquidatable(uint64 balance, uint64 validatorCount, Operator[] memory operators) private view returns (bool) { - return balance < LIQUIDATION_MIN_BLOCKS * (_burnRatePerValidator(operators) + _networkFee) * validatorCount; + function _liquidatable(uint64 balance, uint64 validatorCount, uint64[] memory operatorIds) private view returns (bool) { + return balance < LIQUIDATION_MIN_BLOCKS * (_burnRatePerValidator(_extractOperators(operatorIds)) + _networkFee) * validatorCount; } + /* function liquidate(address owner, bytes32 groupId) external { OperatorCollection memory operatorCollection = _operatorCollections[groupId]; diff --git a/test/unit/ssv-registry.js b/test/unit/ssv-registry.js index b2adce69..1d77f0f2 100644 --- a/test/unit/ssv-registry.js +++ b/test/unit/ssv-registry.js @@ -196,6 +196,7 @@ describe("Validators", () => { operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], groupIds: [outputRegister.groupId, outputRegister2.groupId] }); + /* await progressBlocks(1); (await (await deployedRegistryContract.transferValidator( outputRegister.groupId, @@ -206,6 +207,7 @@ describe("Validators", () => { operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], groupIds: [outputRegister.groupId, outputRegister2.groupId] }); + */ /* // validator 2 From f1d5a1d2e0b92bf4feffe5f9e2f4d9609f1472cd Mon Sep 17 00:00:00 2001 From: Adam Zigdon Date: Tue, 23 Aug 2022 18:32:26 +0300 Subject: [PATCH 028/149] transfer tests #1 --- contracts/SSVRegistry.sol | 235 ++++++++++++++++++++++---------------- test/unit/ssv-registry.js | 41 +++++-- 2 files changed, 168 insertions(+), 108 deletions(-) diff --git a/contracts/SSVRegistry.sol b/contracts/SSVRegistry.sol index 8b4ebf7f..43d624d1 100644 --- a/contracts/SSVRegistry.sol +++ b/contracts/SSVRegistry.sol @@ -22,7 +22,6 @@ contract SSVRegistryNew { address owner; uint64 fee; uint64 validatorCount; - uint64 earnRate; Snapshot earnings; } @@ -44,11 +43,18 @@ contract SSVRegistryNew { Snapshot usage; } + struct Validator { + bytes32 operatorCollectionId; + address owner; + bool active; + } + event OperatorAdded(uint64 operatorId, address indexed owner, bytes encryptionPK); event OperatorRemoved(uint64 operatorId); event OperatorFeeUpdated(uint64 operatorId, uint64 fee); event ValidatorAdded(bytes validatorPK, bytes32 groupId,bytes[] sharesPublicKeys, bytes[] encryptedShares); - event ValidatorTransfered(bytes32 ipfsHash, bytes32 groupId); // , bytes[] sharesPublicKeys, bytes[] encryptedShares); + event ValidatorTransfered(bytes32 validatorPK, bytes32 groupId,bytes[] sharesPublicKeys, bytes[] encryptedShares); + event ValidatorTransferedArr(bytes32[] validatorPK, bytes32 groupId,bytes sharesPublicKeys, bytes encryptedShares); event ValidatorUpdated(bytes validatorPK, bytes32 groupId, bytes[] sharesPublicKeys, bytes[] encryptedShares); event ValidatorRemoved(bytes validatorPK, bytes32 groupId); @@ -59,9 +65,9 @@ contract SSVRegistryNew { // operator vars mapping(uint64 => Operator) private _operators; mapping(bytes32 => OperatorCollection) private _operatorCollections; - mapping(address => mapping(bytes32 => Group)) private _groups; + mapping(bytes32 => Group) private _groups; mapping(address => uint64) _availableBalances; - mapping(bytes32 => mapping(bytes => uint16)) private _validatorPKs; + mapping(bytes32 => Validator) _validatorPKs; uint64 private _networkFee; uint64 constant LIQUIDATION_MIN_BLOCKS = 50; @@ -81,7 +87,7 @@ contract SSVRegistryNew { lastOperatorId.increment(); operatorId = uint64(lastOperatorId.current()); - _operators[operatorId] = Operator({ owner: msg.sender, earnings: Snapshot({ block: uint64(block.number), index: 0, balance: 0}), validatorCount: 0, fee: fee, earnRate: 0 }); + _operators[operatorId] = Operator({ owner: msg.sender, earnings: Snapshot({ block: uint64(block.number), index: 0, balance: 0}), validatorCount: 0, fee: fee}); emit OperatorAdded(operatorId, msg.sender, encryptionPK); } @@ -91,8 +97,7 @@ contract SSVRegistryNew { uint64 currentBlock = uint64(block.number); - operator.earnings = _updateOperatorEarnings(operator, currentBlock); - operator.earnRate = 0; + operator.earnings = _updateOperatorEarnings(operator); operator.fee = 0; operator.validatorCount = 0; _operators[operatorId] = operator; @@ -104,24 +109,48 @@ contract SSVRegistryNew { Operator memory operator = _operators[operatorId]; require(operator.owner == msg.sender, "not owner"); - uint64 currentBlock = uint64(block.number); - - _operators[operatorId] = _setFee(operator, fee, currentBlock); + _operators[operatorId] = _setFee(operator, fee); emit OperatorFeeUpdated(operatorId, fee); } - function transferValidator( - // bytes calldata validatorPK, - bytes32 ipfsHash, - bytes32 groupId - // bytes[] calldata sharesPublicKeys, - // bytes[] calldata encryptedShares + function transferValidators( + bytes32[] calldata validatorPK, + bytes32 fromGroupId, + bytes32 toGroupId, + bytes calldata sharesPublicKeys, + bytes calldata encryptedShares ) external { - for (uint64 i = 0; i < 100; ++i) { - emit ValidatorTransfered(ipfsHash, groupId); - // _validatorPKs[msg.sender][validatorPK] = groupId; + // _validateValidatorParams + uint64 activeValidatorCount = 0; + + for (uint64 index = 0; index < validatorPK.length; ++index) { + Validator memory validator = _validatorPKs[validatorPK[index]]; + validator.operatorCollectionId = toGroupId; + _validatorPKs[validatorPK[index]] = validator; + + if (validator.active) { + ++activeValidatorCount; + } + // Changing to a single event reducing by 15K gas } + emit ValidatorTransferedArr(validatorPK, toGroupId, sharesPublicKeys, encryptedShares); + + uint64[] memory newOperatorIds = _operatorCollections[toGroupId].operatorIds; + + _updateOperatorsValidatorMove(_operatorCollections[fromGroupId].operatorIds, newOperatorIds, activeValidatorCount); + + Group memory group = _groups[keccak256(abi.encodePacked(msg.sender, fromGroupId))]; + group.usage.index = _groupCurrentIndex(fromGroupId); + group.usage.block = uint64(block.number); + group.validatorCount -= activeValidatorCount; + + group = _groups[keccak256(abi.encodePacked(msg.sender, toGroupId))]; + group.usage.index = _groupCurrentIndex(toGroupId); + group.usage.block = uint64(block.number); + group.validatorCount += activeValidatorCount; + + require(!_liquidatable(group.balance, group.validatorCount, _extractOperators(newOperatorIds)), "account liquidatable"); } function registerValidator( @@ -133,17 +162,15 @@ contract SSVRegistryNew { ) external { _validateValidatorParams( validatorPK, - operatorIds, sharesPublicKeys, encryptedShares ); // Operator[] memory operators; - bytes32 groupId; + bytes32 operatorCollectionId; { - uint64 currentBlock = uint64(block.number); { - groupId = _getOrCreateOperatorCollection(operatorIds); + operatorCollectionId = getOrCreateOperatorCollection(operatorIds); // operators = _extractOperators(operatorIds); } @@ -151,11 +178,11 @@ contract SSVRegistryNew { { _availableBalances[msg.sender] -= amount; - group = _groups[msg.sender][groupId]; - uint64 groupIndex = _groupCurrentIndex(groupId); + group = _groups[keccak256(abi.encodePacked(msg.sender, operatorCollectionId))]; + uint64 groupIndex = _groupCurrentIndex(operatorCollectionId); group.balance = _ownerGroupBalance(group, groupIndex) + amount; group.usage.index = groupIndex; - group.usage.block = currentBlock; + group.usage.block = uint64(block.number); ++group.validatorCount; @@ -172,11 +199,11 @@ contract SSVRegistryNew { group.validatorPKs = extendedGroup; */ // group.validatorPKs[validatorPK] = 1; - // _validatorPKs[msg.sender][validatorPK] = groupId; + // _validatorPKs[msg.sender][validatorPK] = operatorCollectionId; /* bytes32[] memory data = new bytes32[](2); data[0] = bytes32(abi.encodePacked(msg.sender)); - data[1] = groupId; + data[1] = operatorCollectionId; bytes32 key = keccak256(abi.encodePacked(data)); _validatorPKs[key][validatorPK] = 1; */ @@ -185,8 +212,7 @@ contract SSVRegistryNew { { for (uint64 i = 0; i < operatorIds.length; ++i) { Operator memory operator = _operators[operatorIds[i]]; - operator.earnings = _updateOperatorEarnings(operator, currentBlock); - operator.earnRate += operator.fee; + operator.earnings = _updateOperatorEarnings(operator); ++operator.validatorCount; _operators[operatorIds[i]] = operator; } @@ -195,7 +221,7 @@ contract SSVRegistryNew { { // // update DAO earnings DAO memory dao = _dao; - dao = _updateDAOEarnings(dao, uint64(block.number)); + dao = _updateDAOEarnings(dao); ++dao.validatorCount; _dao = dao; } @@ -206,10 +232,56 @@ contract SSVRegistryNew { // without: 352641 max, 336957 avg, 321272 min // with that: 364550 max, 348866 avg, 333181 min - _groups[msg.sender][groupId] = group; + _groups[keccak256(abi.encodePacked(msg.sender, operatorCollectionId))] = group; } - emit ValidatorAdded(validatorPK, groupId, sharesPublicKeys, encryptedShares); + _validatorPKs[keccak256(validatorPK)] = Validator({ owner: msg.sender, operatorCollectionId: operatorCollectionId, active: true}); + + emit ValidatorAdded(validatorPK, operatorCollectionId, sharesPublicKeys, encryptedShares); + } + + function _updateOperatorsValidatorMove( + uint64[] memory oldOperatorIds, + uint64[] memory newOperatorIds, + uint64 validatorCount + ) private { + uint64 oldIndex; + uint64 newIndex; + + while (oldIndex < oldOperatorIds.length && newIndex < newOperatorIds.length) { + if (oldOperatorIds[oldIndex] < newOperatorIds[newIndex]) { + Operator memory operator = _operators[oldOperatorIds[oldIndex]]; + operator.earnings = _updateOperatorEarnings(operator); + operator.validatorCount -= validatorCount; + _operators[oldOperatorIds[oldIndex]] = operator; + ++oldIndex; + } else if (newOperatorIds[newIndex] < oldOperatorIds[oldIndex]) { + Operator memory operator = _operators[newOperatorIds[newIndex]]; + operator.earnings = _updateOperatorEarnings(operator); + operator.validatorCount += validatorCount; + _operators[newOperatorIds[newIndex]] = operator; + ++newIndex; + } else { + ++oldIndex; + ++newIndex; + } + } + + while (oldIndex < oldOperatorIds.length) { + Operator memory operator = _operators[oldOperatorIds[oldIndex]]; + operator.earnings = _updateOperatorEarnings(operator); + operator.validatorCount -= validatorCount; + _operators[oldOperatorIds[oldIndex]] = operator; + ++oldIndex; + } + + while (newIndex < newOperatorIds.length) { + Operator memory operator = _operators[newOperatorIds[newIndex]]; + operator.earnings = _updateOperatorEarnings(operator); + operator.validatorCount += validatorCount; + _operators[newOperatorIds[newIndex]] = operator; + ++newIndex; + } } function updateValidator( @@ -224,7 +296,7 @@ contract SSVRegistryNew { { Group memory group; { - group = _groups[msg.sender][currentGroupId]; + group = _groups[keccak256(abi.encodePacked(msg.sender, currentGroupId))]; uint64 groupIndex = _groupCurrentIndex(currentGroupId); group.balance = _ownerGroupBalance(group, groupIndex); @@ -239,45 +311,15 @@ contract SSVRegistryNew { } OperatorCollection memory operatorCollection = _operatorCollections[currentGroupId]; - { - for (uint64 i = 0; i < operatorCollection.operatorIds.length; ++i) { - bool found; - for (uint64 j = 0; j < operatorIds.length; ++j) { - if (operatorCollection.operatorIds[i] == operatorIds[j]) { - found = true; - } - } - if (!found) { - uint64 id = operatorCollection.operatorIds[i]; - _operators[id].earnings = _updateOperatorEarnings(_operators[id], currentBlock); - _operators[id].earnRate -= _operators[id].fee; - --_operators[id].validatorCount; - } - } - - for (uint64 i = 0; i < operatorIds.length; ++i) { - bool found; - for (uint64 j = 0; j < operatorCollection.operatorIds.length; ++j) { - if (operatorIds[i] == operatorCollection.operatorIds[j]) { - found = true; - } - } - if (!found) { - uint64 id = operatorIds[i]; - _operators[id].earnings = _updateOperatorEarnings(_operators[id], currentBlock); - _operators[id].earnRate += _operators[id].fee; - ++_operators[id].validatorCount; - } - } - } - _groups[msg.sender][currentGroupId] = group; + _updateOperatorsValidatorMove(operatorCollection.operatorIds, operatorIds, 1); + _groups[keccak256(abi.encodePacked(msg.sender, currentGroupId))] = group; } bytes32 newGroupId; { // Operator[] memory newOperators; { - newGroupId = _getOrCreateOperatorCollection(operatorIds); + newGroupId = getOrCreateOperatorCollection(operatorIds); // newOperators = _extractOperators(operatorIds); } @@ -287,7 +329,7 @@ contract SSVRegistryNew { _availableBalances[msg.sender] -= amount; - group = _groups[msg.sender][newGroupId]; + group = _groups[keccak256(abi.encodePacked(msg.sender, newGroupId))]; group.balance = _ownerGroupBalance(group, groupIndex) + amount; group.usage.index = groupIndex; group.usage.block = currentBlock; @@ -298,7 +340,7 @@ contract SSVRegistryNew { { // // update DAO earnings DAO memory dao = _dao; - dao = _updateDAOEarnings(dao, uint64(block.number)); + dao = _updateDAOEarnings(dao); _dao = dao; } @@ -308,18 +350,18 @@ contract SSVRegistryNew { // without: 353107 max, 315041 avg, 276974 min // with that: 365039 max, 326973 avg, 288906 min - _groups[msg.sender][newGroupId] = group; + _groups[keccak256(abi.encodePacked(msg.sender, newGroupId))] = group; } emit ValidatorUpdated(validatorPK, newGroupId, sharesPublicKeys, encryptedShares); } function removeValidator( - bytes calldata validatorPK, - bytes32 groupId - ) external { + bytes calldata validatorPK + ) public { + bytes32 groupId = _validatorPKs[keccak256(validatorPK)].operatorCollectionId; { - Group memory group = _groups[msg.sender][groupId]; + Group memory group = _groups[keccak256(abi.encodePacked(msg.sender, groupId))]; OperatorCollection memory operatorCollection = _operatorCollections[groupId]; uint64 currentBlock = uint64(block.number); @@ -334,30 +376,29 @@ contract SSVRegistryNew { // group.balance -= _ownerGroupBalance(group, groupIndex); } + for (uint64 i = 0; i < operatorCollection.operatorIds.length; ++i) { uint64 id = operatorCollection.operatorIds[i]; - _operators[id].earnings = _updateOperatorEarnings(_operators[id], currentBlock); - _operators[id].earnRate -= _operators[id].fee; + _operators[id].earnings = _updateOperatorEarnings(_operators[id]); --_operators[id].validatorCount; } { // // update DAO earnings DAO memory dao = _dao; - dao = _updateDAOEarnings(dao, uint64(block.number)); + dao = _updateDAOEarnings(dao); --dao.validatorCount; _dao = dao; } - _groups[msg.sender][groupId] = group; + _groups[keccak256(abi.encodePacked(msg.sender, groupId))] = group; } emit ValidatorRemoved(validatorPK, groupId); } - function _setFee(Operator memory operator, uint64 fee, uint64 currentBlock) private returns (Operator memory) { - operator.earnings = _updateOperatorEarnings(operator, currentBlock); - operator.earnRate = operator.validatorCount * fee; + function _setFee(Operator memory operator, uint64 fee) private returns (Operator memory) { + operator.earnings = _updateOperatorEarnings(operator); operator.fee = fee; return operator; @@ -368,7 +409,7 @@ contract SSVRegistryNew { } function test_getOperatorBalance(uint64 operatorId) external view returns (uint64) { - return _operatorCurrentEarnings(_operators[operatorId], uint64(block.number)); + return _operatorCurrentEarnings(_operators[operatorId]); } function test_operatorCurrentIndex(uint64 operatorId) external view returns (uint64) { @@ -380,20 +421,18 @@ contract SSVRegistryNew { } function test_groupBalance(bytes32 groupId) external view returns (uint64) { - Group memory group = _groups[msg.sender][groupId]; + Group memory group = _groups[keccak256(abi.encodePacked(msg.sender, groupId))]; return _ownerGroupBalance(group, _groupCurrentIndex(groupId)); } /** * @dev Validates the paramss for a validator. * @param publicKey Validator public key. - * @param operatorIds Operator operatorIds. * @param sharesPublicKeys Shares public keys. * @param encryptedKeys Encrypted private keys. */ function _validateValidatorParams( bytes memory publicKey, - uint64[] memory operatorIds, bytes[] memory sharesPublicKeys, bytes[] memory encryptedKeys ) private pure { @@ -431,7 +470,7 @@ contract SSVRegistryNew { } */ - function _getOrCreateOperatorCollection(uint64[] memory operatorIds) private returns (bytes32) { // , OperatorCollection memory + function getOrCreateOperatorCollection(uint64[] memory operatorIds) public returns (bytes32) { // , OperatorCollection memory for (uint64 i = 0; i < operatorIds.length - 1;) { require(operatorIds[i] <= operatorIds[++i]); } @@ -446,23 +485,23 @@ contract SSVRegistryNew { return key; // (key, operatorCollection); } - function _updateOperatorEarnings(Operator memory operator, uint64 currentBlock) private returns (Snapshot memory) { + function _updateOperatorEarnings(Operator memory operator) private returns (Snapshot memory) { operator.earnings.index = _operatorCurrentIndex(operator); - operator.earnings.balance = _operatorCurrentEarnings(operator, currentBlock); - operator.earnings.block = currentBlock; + operator.earnings.balance = _operatorCurrentEarnings(operator); + operator.earnings.block = uint64(block.number); return operator.earnings; } - function _updateDAOEarnings(DAO memory dao, uint64 currentBlock) private returns (DAO memory) { - dao.earnings.balance = _networkTotalEarnings(dao, currentBlock); - dao.earnings.block = currentBlock; + function _updateDAOEarnings(DAO memory dao) private returns (DAO memory) { + dao.earnings.balance = _networkTotalEarnings(dao); + dao.earnings.block = uint64(block.number); return dao; } - function _operatorCurrentEarnings(Operator memory operator, uint64 currentBlock) private view returns (uint64) { - return operator.earnings.balance + (currentBlock - operator.earnings.block) * operator.earnRate; + function _operatorCurrentEarnings(Operator memory operator) private view returns (uint64) { + return operator.earnings.balance + (uint64(block.number) - operator.earnings.block) * operator.validatorCount * operator.fee; } function _extractOperators(uint64[] memory operatorIds) private view returns (Operator[] memory) { @@ -473,12 +512,12 @@ contract SSVRegistryNew { return operators; } - function _networkTotalEarnings(DAO memory dao, uint64 currentBlock) private view returns (uint64) { - return dao.earnings.balance + (currentBlock - dao.earnings.block) * _networkFee * dao.validatorCount; + function _networkTotalEarnings(DAO memory dao) private view returns (uint64) { + return dao.earnings.balance + (uint64(block.number) - dao.earnings.block) * _networkFee * dao.validatorCount; } - function _networkBalance(DAO memory dao, uint64 currentBlock) private view returns (uint64) { - return _networkTotalEarnings(dao, currentBlock) - dao.withdrawn; + function _networkBalance(DAO memory dao) private view returns (uint64) { + return _networkTotalEarnings(dao) - dao.withdrawn; } function _groupCurrentIndex(bytes32 groupId) private view returns (uint64 groupIndex) { diff --git a/test/unit/ssv-registry.js b/test/unit/ssv-registry.js index b2adce69..1a562d3e 100644 --- a/test/unit/ssv-registry.js +++ b/test/unit/ssv-registry.js @@ -2,7 +2,6 @@ const { expect } = require("chai"); const { progressBlocks, blockNumber } = require('./utils'); const operator_fee_block = 1; - async function mineNBlocks(n) { for (let index = 0; index < n; index++) { await ethers.provider.send('evm_mine'); @@ -53,7 +52,7 @@ describe("Validators", () => { }) it("should register validator", async () => { - const validatorPK = "0x987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987651"; + const validatorPK = "0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765"; const sharePKs = Array.from(Array(10).keys()).map(k => `0x12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345${k}`); const encryptedShares = Array.from(Array(10).keys()).map(k => `0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765${k}98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765${k}`); // const operatorsIndexes = Array.from(Array(10).keys()).map(k => k + 1); @@ -70,7 +69,7 @@ describe("Validators", () => { await progressBlocks(97); let resultRegister = (await (await deployedRegistryContract.registerValidator( [1,2,3,4], - validatorPK, + validatorPK + "f", sharePKs.slice(0, 4), encryptedShares.slice(0, 4), '10000' @@ -89,7 +88,7 @@ describe("Validators", () => { let resultUpdate = (await (await deployedRegistryContract.updateValidator( [4,5,6,7], - validatorPK, + validatorPK + "f", outputRegister.groupId, sharePKs.slice(0, 4), encryptedShares.slice(0, 4), @@ -119,7 +118,7 @@ describe("Validators", () => { // move back validator 1 to group 1 resultRegister = (await (await deployedRegistryContract.updateValidator( [1,2,3,4], - validatorPK, + validatorPK + "f", outputUpdate.groupId, sharePKs.slice(0, 4), encryptedShares.slice(0, 4), @@ -139,7 +138,7 @@ describe("Validators", () => { }); const resultRegister2 = (await (await deployedRegistryContract.registerValidator( [1,2,3,4], - validatorPK, + validatorPK + "f", sharePKs.slice(0, 4), encryptedShares.slice(0, 4), "1000" @@ -180,7 +179,7 @@ describe("Validators", () => { operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], groupIds: [outputRegister.groupId, outputRegister2.groupId] }); - await (await deployedRegistryContract.removeValidator(outputRegister2.validatorPK, outputRegister2.groupId)).wait(); + await (await deployedRegistryContract.removeValidator(outputRegister2.validatorPK)).wait(); await log({ action: 'remove validator #2', operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], @@ -197,10 +196,32 @@ describe("Validators", () => { groupIds: [outputRegister.groupId, outputRegister2.groupId] }); await progressBlocks(1); - (await (await deployedRegistryContract.transferValidator( - outputRegister.groupId, + + let results = [] + for (let i = 0; i < 20; ++i) { + let resultRegister = (await (await deployedRegistryContract.registerValidator( + [1,2,3,4], + validatorPK + i % 10, + sharePKs.slice(0, 4), + encryptedShares.slice(0, 4), + '10000' + )).wait()).logs[0]; + + const interfaceRegister = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId, bytes[] sharesPublicKeys, bytes[] encryptedShares)']); + const outputRegister = interfaceRegister.decodeEventLog('ValidatorAdded', resultRegister.data, resultRegister.topics); + + results.push(outputRegister); + } + + const transferLogs = (await (await deployedRegistryContract.transferValidators( + results.map(r => ethers.utils.keccak256(r.validatorPK)), outputRegister.groupId, - )).wait()).logs[0];; + outputRegister2.groupId, + results.map(r => sharePKs.slice(0,4)).flat().reduce((a,b) => a.concat(b.slice(2))), + results.map(r => encryptedShares.slice(0,4)).flat().reduce((a,b) => a.concat(b.slice(2))) + )).wait()).logs; + + console.log(transferLogs); await log({ action: 'transfer', operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], From 0fd9085fcbe9d6fd4f99beb82fa38f2cac1766cb Mon Sep 17 00:00:00 2001 From: Vadim Date: Wed, 24 Aug 2022 13:24:25 +0200 Subject: [PATCH 029/149] small code fixes --- contracts/SSVRegistry.sol | 43 ++++++--------------------------------- 1 file changed, 6 insertions(+), 37 deletions(-) diff --git a/contracts/SSVRegistry.sol b/contracts/SSVRegistry.sol index 77bab0e7..54d72499 100644 --- a/contracts/SSVRegistry.sol +++ b/contracts/SSVRegistry.sol @@ -184,28 +184,6 @@ contract SSVRegistryNew { _availableBalances[msg.sender] -= amount; group = _updateGroupData(operatorCollectionId, amount, true); - // TODO - // gas issues - // without: 352641 max, 336957 avg, 321272 min - // with that: 442985 max, 427300 avg, 411615 min - /* - bytes[] memory extendedGroup = new bytes[](group.validatorCount); - for (uint64 i = 0; i < group.validatorPKs.length; ++i) { - extendedGroup[i] = group.validatorPKs[i]; - } - extendedGroup[group.validatorCount - 1] = validatorPK; - group.validatorPKs = extendedGroup; - */ - // group.validatorPKs[validatorPK] = 1; - // _validatorPKs[msg.sender][validatorPK] = operatorCollectionId; - /* - bytes32[] memory data = new bytes32[](2); - data[0] = bytes32(abi.encodePacked(msg.sender)); - data[1] = operatorCollectionId; - bytes32 key = keccak256(abi.encodePacked(data)); - _validatorPKs[key][validatorPK] = 1; - */ - { for (uint64 i = 0; i < operatorIds.length; ++i) { Operator memory operator = _operators[operatorIds[i]]; @@ -224,9 +202,6 @@ contract SSVRegistryNew { // TODO require(!_liquidatable(group.balance, group.validatorCount, operatorIds), "account liquidatable"); - // list of operators here makes the gas higher - // without: 352641 max, 336957 avg, 321272 min - // with that: 364550 max, 348866 avg, 333181 min _groups[keccak256(abi.encodePacked(msg.sender, operatorCollectionId))] = group; } @@ -326,12 +301,6 @@ contract SSVRegistryNew { _dao = dao; } - // TODO - // require(!_liquidatable(group.balance, group.validatorCount, newOperators), "account liquidatable"); - // list of operators here makes the gas higher - // without: 353107 max, 315041 avg, 276974 min - // with that: 365039 max, 326973 avg, 288906 min - require(!_liquidatable(group.balance, group.validatorCount, operatorIds), "account liquidatable"); } @@ -346,14 +315,14 @@ contract SSVRegistryNew { revert ValidatorNotOwned(); } - bytes32 groupId = _validatorPKs[keccak256(validatorPK)].operatorCollectionId; + bytes32 operatorCollectionId = _validatorPKs[keccak256(validatorPK)].operatorCollectionId; { - Group memory group = _groups[keccak256(abi.encodePacked(msg.sender, groupId))]; - OperatorCollection memory operatorCollection = _operatorCollections[groupId]; + Group memory group = _groups[keccak256(abi.encodePacked(msg.sender, operatorCollectionId))]; + OperatorCollection memory operatorCollection = _operatorCollections[operatorCollectionId]; uint64 currentBlock = uint64(block.number); - uint64 groupIndex = _operatorCollectionCurrentIndex(groupId); + uint64 groupIndex = _operatorCollectionCurrentIndex(operatorCollectionId); group.balance = _ownerGroupBalance(group, groupIndex); group.usage.index = groupIndex; group.usage.block = currentBlock; @@ -379,10 +348,10 @@ contract SSVRegistryNew { _dao = dao; } - _groups[keccak256(abi.encodePacked(msg.sender, groupId))] = group; + _groups[keccak256(abi.encodePacked(msg.sender, operatorCollectionId))] = group; } - emit ValidatorRemoved(validatorPK, groupId); + emit ValidatorRemoved(validatorPK, operatorCollectionId); } function _setFee(Operator memory operator, uint64 fee) private returns (Operator memory) { From ffa038e2c21537360fb601384a750b65801c5e81 Mon Sep 17 00:00:00 2001 From: Vadim Date: Wed, 24 Aug 2022 13:59:16 +0200 Subject: [PATCH 030/149] add balanceOf --- contracts/SSVRegistry.sol | 9 ++++----- test/unit/ssv-registry.js | 4 +++- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/contracts/SSVRegistry.sol b/contracts/SSVRegistry.sol index 54d72499..3f5ae560 100644 --- a/contracts/SSVRegistry.sol +++ b/contracts/SSVRegistry.sol @@ -394,6 +394,10 @@ contract SSVRegistryNew { return group; } + function balanceOf(address owner, bytes32 operatorCollectionId) external view returns (uint64) { + Group memory group = _groups[keccak256(abi.encodePacked(owner, operatorCollectionId))]; + return _ownerGroupBalance(group, _operatorCollectionCurrentIndex(operatorCollectionId)); + } function test_getOperatorsByGroupId(bytes32 groupId) external view returns (uint64[] memory) { return _operatorCollections[groupId].operatorIds; @@ -411,11 +415,6 @@ contract SSVRegistryNew { return _operatorCollectionCurrentIndex(groupId); } - function test_groupBalance(bytes32 groupId) external view returns (uint64) { - Group memory group = _groups[keccak256(abi.encodePacked(msg.sender, groupId))]; - return _ownerGroupBalance(group, _operatorCollectionCurrentIndex(groupId)); - } - /** * @dev Validates the paramss for a validator. * @param publicKey Validator public key. diff --git a/test/unit/ssv-registry.js b/test/unit/ssv-registry.js index a4443856..7ced52a0 100644 --- a/test/unit/ssv-registry.js +++ b/test/unit/ssv-registry.js @@ -10,6 +10,7 @@ async function mineNBlocks(n) { const operatorsIndexes = Array.from(Array(5).keys()).map(k => k + 1); let deployedRegistryContract; +let owner; async function log({ action='', operatorIds = [], groupIds = [] }) { console.log(`[BLOCK] ${await blockNumber()}`) @@ -29,7 +30,7 @@ async function log({ action='', operatorIds = [], groupIds = [] }) { for (const id of groupIds) { console.log( `> group #$${id}`, - 'balance', await deployedRegistryContract.test_groupBalance(id), + 'balance', await deployedRegistryContract.balanceOf(owner.address, id), 'index', await deployedRegistryContract.test_operatorCollectionCurrentIndex(id), ); } @@ -38,6 +39,7 @@ async function log({ action='', operatorIds = [], groupIds = [] }) { describe("Validators", () => { beforeEach(async () => { + [ owner ] = await ethers.getSigners(); const Registry = await ethers.getContractFactory("SSVRegistryNew"); deployedRegistryContract = await Registry.deploy(); await deployedRegistryContract.deployed(); From 0c3c3d7917f7e5f3702cc890fe2b42f70ee5a4ad Mon Sep 17 00:00:00 2001 From: Vadim Date: Wed, 24 Aug 2022 14:34:13 +0200 Subject: [PATCH 031/149] remove test functions --- contracts/SSVRegistry.sol | 18 ++++-------------- test/unit/ssv-registry.js | 6 ++---- 2 files changed, 6 insertions(+), 18 deletions(-) diff --git a/contracts/SSVRegistry.sol b/contracts/SSVRegistry.sol index 3f5ae560..8ba6477e 100644 --- a/contracts/SSVRegistry.sol +++ b/contracts/SSVRegistry.sol @@ -394,27 +394,15 @@ contract SSVRegistryNew { return group; } - function balanceOf(address owner, bytes32 operatorCollectionId) external view returns (uint64) { + function groupBalanceOf(address owner, bytes32 operatorCollectionId) external view returns (uint64) { Group memory group = _groups[keccak256(abi.encodePacked(owner, operatorCollectionId))]; return _ownerGroupBalance(group, _operatorCollectionCurrentIndex(operatorCollectionId)); } - function test_getOperatorsByGroupId(bytes32 groupId) external view returns (uint64[] memory) { - return _operatorCollections[groupId].operatorIds; - } - - function test_getOperatorBalance(uint64 operatorId) external view returns (uint64) { + function operatorEarningsOf(uint64 operatorId) external view returns (uint64) { return _operatorCurrentEarnings(_operators[operatorId]); } - function test_operatorCurrentIndex(uint64 operatorId) external view returns (uint64) { - return _operatorCurrentIndex(_operators[operatorId]); - } - - function test_operatorCollectionCurrentIndex(bytes32 groupId) external view returns (uint64) { - return _operatorCollectionCurrentIndex(groupId); - } - /** * @dev Validates the paramss for a validator. * @param publicKey Validator public key. @@ -481,6 +469,8 @@ contract SSVRegistryNew { return dao; } + // TODO + // no connection with owner address function _operatorCurrentEarnings(Operator memory operator) private view returns (uint64) { return operator.earnings.balance + (uint64(block.number) - operator.earnings.block) * operator.validatorCount * operator.fee; } diff --git a/test/unit/ssv-registry.js b/test/unit/ssv-registry.js index 7ced52a0..8acb2411 100644 --- a/test/unit/ssv-registry.js +++ b/test/unit/ssv-registry.js @@ -21,8 +21,7 @@ async function log({ action='', operatorIds = [], groupIds = [] }) { for (const id of operatorIds) { console.log( `> operator #${id}`, - 'balance', await deployedRegistryContract.test_getOperatorBalance(id), - 'index', await deployedRegistryContract.test_operatorCurrentIndex(id), + 'balance', await deployedRegistryContract.operatorEarningsOf(id), ); } } @@ -30,8 +29,7 @@ async function log({ action='', operatorIds = [], groupIds = [] }) { for (const id of groupIds) { console.log( `> group #$${id}`, - 'balance', await deployedRegistryContract.balanceOf(owner.address, id), - 'index', await deployedRegistryContract.test_operatorCollectionCurrentIndex(id), + 'balance', await deployedRegistryContract.groupBalanceOf(owner.address, id), ); } } From 90eb1c9e7f736eca8f9c907b418cfdfa7748dedc Mon Sep 17 00:00:00 2001 From: Lior Rutenberg Date: Wed, 24 Aug 2022 15:38:25 +0300 Subject: [PATCH 032/149] integrated compressed shares --- contracts/SSVRegistry.sol | 42 ++++++++++----------------- test/unit/ssv-registry.js | 60 +++++++++++++++++++++++++-------------- 2 files changed, 54 insertions(+), 48 deletions(-) diff --git a/contracts/SSVRegistry.sol b/contracts/SSVRegistry.sol index 77bab0e7..596fba6e 100644 --- a/contracts/SSVRegistry.sol +++ b/contracts/SSVRegistry.sol @@ -10,11 +10,11 @@ contract SSVRegistryNew { using Counters for Counters.Counter; struct Snapshot { - // block is the last block in which last index was set + /// @dev block is the last block in which last index was set uint64 block; - // index is the last index calculated by index += (currentBlock - block) * fee + /// @dev index is the last index calculated by index += (currentBlock - block) * fee uint64 index; - // accumulated is all the accumulated earnings, calculated by accumulated + lastIndex * validatorCount + /// @dev accumulated is all the accumulated earnings, calculated by accumulated + lastIndex * validatorCount uint64 balance; } @@ -52,10 +52,9 @@ contract SSVRegistryNew { event OperatorAdded(uint64 operatorId, address indexed owner, bytes encryptionPK); event OperatorRemoved(uint64 operatorId); event OperatorFeeUpdated(uint64 operatorId, uint64 fee); - event ValidatorAdded(bytes validatorPK, bytes32 groupId,bytes[] sharesPublicKeys, bytes[] encryptedShares); - event ValidatorTransfered(bytes32 validatorPK, bytes32 groupId,bytes[] sharesPublicKeys, bytes[] encryptedShares); - event ValidatorTransferedArr(bytes[] validatorPK, bytes32 groupId,bytes sharesPublicKeys, bytes encryptedShares); - event ValidatorUpdated(bytes validatorPK, bytes32 groupId, bytes[] sharesPublicKeys, bytes[] encryptedShares); + event ValidatorAdded(bytes validatorPK, bytes32 groupId,bytes shares); + event ValidatorTransferedArr(bytes[] validatorPK, bytes32 groupId,bytes[] shares); + event ValidatorUpdated(bytes validatorPK, bytes32 groupId, bytes shares); event ValidatorRemoved(bytes validatorPK, bytes32 groupId); // global vars @@ -123,8 +122,7 @@ contract SSVRegistryNew { bytes[] calldata validatorPK, bytes32 fromGroupId, bytes32 toGroupId, - bytes calldata sharesPublicKeys, - bytes calldata encryptedShares + bytes[] calldata shares ) external { // _validateValidatorParams uint64 activeValidatorCount = 0; @@ -144,7 +142,7 @@ contract SSVRegistryNew { } // Changing to a single event reducing by 15K gas } - emit ValidatorTransferedArr(validatorPK, toGroupId, sharesPublicKeys, encryptedShares); + emit ValidatorTransferedArr(validatorPK, toGroupId, shares); uint64[] memory newOperatorIds = _operatorCollections[toGroupId].operatorIds; @@ -166,15 +164,12 @@ contract SSVRegistryNew { function registerValidator( uint64[] memory operatorIds, bytes calldata validatorPK, - bytes[] calldata sharesPublicKeys, - bytes[] calldata encryptedShares, + bytes calldata shares, uint64 amount ) external { _validateValidatorParams( operatorIds, - validatorPK, - sharesPublicKeys, - encryptedShares + validatorPK ); // Operator[] memory operators; @@ -233,7 +228,7 @@ contract SSVRegistryNew { _validatorPKs[keccak256(validatorPK)] = Validator({ owner: msg.sender, operatorCollectionId: operatorCollectionId, active: true}); - emit ValidatorAdded(validatorPK, operatorCollectionId, sharesPublicKeys, encryptedShares); + emit ValidatorAdded(validatorPK, operatorCollectionId, shares); } function _updateOperatorsValidatorMove( @@ -283,8 +278,7 @@ contract SSVRegistryNew { function updateValidator( uint64[] memory operatorIds, bytes calldata validatorPK, - bytes[] calldata sharesPublicKeys, - bytes[] calldata encryptedShares, + bytes calldata shares, uint64 amount ) external { uint64 currentBlock = uint64(block.number); @@ -335,7 +329,7 @@ contract SSVRegistryNew { require(!_liquidatable(group.balance, group.validatorCount, operatorIds), "account liquidatable"); } - emit ValidatorUpdated(validatorPK, newOperatorCollectionId, sharesPublicKeys, encryptedShares); + emit ValidatorUpdated(validatorPK, newOperatorCollectionId, shares); } } @@ -448,23 +442,17 @@ contract SSVRegistryNew { } /** - * @dev Validates the paramss for a validator. + * @dev Validates the params for a validator. * @param publicKey Validator public key. - * @param sharesPublicKeys Shares public keys. - * @param encryptedKeys Encrypted private keys. */ function _validateValidatorParams( uint64[] memory operatorIds, - bytes memory publicKey, - bytes[] memory sharesPublicKeys, - bytes[] memory encryptedKeys + bytes memory publicKey ) private pure { if (publicKey.length != 48) { revert InvalidPublicKeyLength(); } if ( - operatorIds.length != sharesPublicKeys.length || - operatorIds.length != encryptedKeys.length || operatorIds.length < 4 || operatorIds.length % 3 != 1 ) { revert OessDataStructureInvalid(); diff --git a/test/unit/ssv-registry.js b/test/unit/ssv-registry.js index a4443856..9b4b71c8 100644 --- a/test/unit/ssv-registry.js +++ b/test/unit/ssv-registry.js @@ -53,7 +53,7 @@ describe("Validators", () => { it("should register validator", async () => { const validatorPK = "0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765"; - const sharePKs = Array.from(Array(10).keys()).map(k => `0x12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345${k}`); + const sharePKs = Array.from(Array(10).keys()).map(k => `0xe0096008000000b4010000040000001000000076000000dc000000420d142c307831323334353637383930fe0a00520a000031017afe66008266000032fe66009266000033fe66009266000034016621ac28d60000009c01000062020025c02c307839383736353433323130fe0a00520a000031fe560052560019b0003101dafec60082c6000032fec6007ac6004d6ca666000033ceb401fe8c017e8c014dcca6c6004d7a0035b23200fec6007ec6000034${k}${k}`); const encryptedShares = Array.from(Array(10).keys()).map(k => `0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765${k}98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765${k}`); // const operatorsIndexes = Array.from(Array(10).keys()).map(k => k + 1); @@ -70,11 +70,10 @@ describe("Validators", () => { let resultRegister = (await (await deployedRegistryContract.registerValidator( [1,2,3,4], validatorPK + "f", - sharePKs.slice(0, 4), - encryptedShares.slice(0, 4), + sharePKs[0], '10000' )).wait()).logs[0]; - let interfaceRegister = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId, bytes[] sharesPublicKeys, bytes[] encryptedShares)']); + let interfaceRegister = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId, bytes shares)']); let outputRegister = interfaceRegister.decodeEventLog('ValidatorAdded', resultRegister.data, resultRegister.topics); await log({ action: `register validator #1: ${outputRegister.validatorPK} : ${outputRegister.groupId}`, @@ -89,11 +88,10 @@ describe("Validators", () => { let resultUpdate = (await (await deployedRegistryContract.updateValidator( [4,5,6,7], validatorPK + "f", - sharePKs.slice(0, 4), - encryptedShares.slice(0, 4), + sharePKs[2], '10000' )).wait()).logs[0];; - let interfaceUpdate = new ethers.utils.Interface(['event ValidatorUpdated(bytes validatorPK, bytes32 groupId, bytes[] sharesPublicKeys, bytes[] encryptedShares)']); + let interfaceUpdate = new ethers.utils.Interface(['event ValidatorUpdated(bytes validatorPK, bytes32 groupId, bytes shares)']); let outputUpdate = interfaceUpdate.decodeEventLog('ValidatorUpdated', resultUpdate.data, resultUpdate.topics); expect(outputRegister.groupId).not.equal(outputUpdate.groupId); expect(outputRegister.validatorPK).to.equal(outputUpdate.validatorPK); @@ -118,8 +116,7 @@ describe("Validators", () => { resultRegister = (await (await deployedRegistryContract.updateValidator( [1,2,3,4], validatorPK + "f", - sharePKs.slice(0, 4), - encryptedShares.slice(0, 4), + sharePKs[1], '10000' )).wait()).logs[0]; interfaceRegister = new ethers.utils.Interface(['event ValidatorUpdated(bytes validatorPK, bytes32 groupId)']); // , bytes[] sharesPublicKeys, bytes[] encryptedShares @@ -134,20 +131,40 @@ describe("Validators", () => { operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], groupIds: [outputRegister.groupId, outputUpdate.groupId] }); - const resultRegister2 = (await (await deployedRegistryContract.registerValidator( + + const resultRegister2 = (await (await deployedRegistryContract.registerValidator( [1,2,3,4], validatorPK + "f", - sharePKs.slice(0, 4), - encryptedShares.slice(0, 4), + sharePKs[1], "1000" )).wait()).logs[0]; - const interfaceRegister2 = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId, bytes[] sharesPublicKeys, bytes[] encryptedShares)']); + + const interfaceRegister2 = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId, bytes shares)']); const outputRegister2 = interfaceRegister2.decodeEventLog('ValidatorAdded', resultRegister2.data, resultRegister2.topics); await log({ action: `register validator #2: ${outputRegister2.validatorPK} : ${outputRegister2.groupId}`, operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], groupIds: [outputRegister.groupId, outputRegister2.groupId] }); + + + const resultRegister3 = (await (await deployedRegistryContract.registerValidator( + [5,6,7,8], + validatorPK + "f", + sharePKs[1], + "1000000" + )).wait()).logs[0]; + + const interfaceRegister3 = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId, bytes shares)']); + const outputRegister3 = interfaceRegister3.decodeEventLog('ValidatorAdded', resultRegister3.data, resultRegister3.topics); + await log({ + action: `register validator #3: ${resultRegister3.validatorPK} : ${resultRegister3.groupId}`, + operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], + groupIds: [outputRegister.groupId, outputRegister2.groupId] + }); + + + await progressBlocks(1); await log({ operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], @@ -200,29 +217,30 @@ describe("Validators", () => { let resultRegister = (await (await deployedRegistryContract.registerValidator( [1,2,3,4], validatorPK + i % 10, - sharePKs.slice(0, 4), - encryptedShares.slice(0, 4), + sharePKs[2], '10000' )).wait()).logs[0]; - const interfaceRegister = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId, bytes[] sharesPublicKeys, bytes[] encryptedShares)']); + const interfaceRegister = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId, bytes shares)']); const outputRegister = interfaceRegister.decodeEventLog('ValidatorAdded', resultRegister.data, resultRegister.topics); results.push(outputRegister); } + console.log("outputRegister.groupId,outputRegister2.groupId") + console.log(outputRegister.groupId,outputRegister3.groupId) const transferLogs = (await (await deployedRegistryContract.transferValidators( results.map(r => r.validatorPK), outputRegister.groupId, - outputRegister2.groupId, - results.map(r => sharePKs.slice(0,4)).flat().reduce((a,b) => a.concat(b.slice(2))), - results.map(r => encryptedShares.slice(0,4)).flat().reduce((a,b) => a.concat(b.slice(2))) - )).wait()).logs; + outputRegister3.groupId, + results.map(r => sharePKs[4]) + )).wait()).logs; + return; await log({ action: 'transfer', operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], - groupIds: [outputRegister.groupId, outputRegister2.groupId] + groupIds: [outputRegister.groupId, resultRegister3.groupId] }); /* From a7aef9f6ed14aed09ff67c63ff037b33eef6cae2 Mon Sep 17 00:00:00 2001 From: andrew-blox <102898824+andrew-blox@users.noreply.github.com> Date: Wed, 24 Aug 2022 17:16:18 +0300 Subject: [PATCH 033/149] update testing structure (#85) Co-authored-by: Vadim --- test/unit/stress.js | 84 ----------- tests/account/deposit.js | 38 +++++ tests/account/withdraw.js | 38 +++++ tests/dao/networkFeeChange.js | 38 +++++ tests/dao/networkFeeWithdraw.js | 38 +++++ {test/unit => tests/helpers}/utils.ts | 0 tests/liquidate/liquidate.js | 42 ++++++ tests/liquidate/liquidationThreshold.js | 42 ++++++ tests/operators/register.js | 83 +++++++++++ tests/operators/remove.js | 38 +++++ tests/operators/update.js | 38 +++++ tests/sanity/balances.js | 139 ++++++++++++++++++ tests/sanity/stress.js | 80 ++++++++++ .../ssv-registry.js => tests/vadimToUpdate.js | 6 +- tests/validators/register.js | 90 ++++++++++++ tests/validators/remove.js | 38 +++++ tests/validators/update.js | 38 +++++ 17 files changed, 782 insertions(+), 88 deletions(-) delete mode 100644 test/unit/stress.js create mode 100644 tests/account/deposit.js create mode 100644 tests/account/withdraw.js create mode 100644 tests/dao/networkFeeChange.js create mode 100644 tests/dao/networkFeeWithdraw.js rename {test/unit => tests/helpers}/utils.ts (100%) create mode 100644 tests/liquidate/liquidate.js create mode 100644 tests/liquidate/liquidationThreshold.js create mode 100644 tests/operators/register.js create mode 100644 tests/operators/remove.js create mode 100644 tests/operators/update.js create mode 100644 tests/sanity/balances.js create mode 100644 tests/sanity/stress.js rename test/unit/ssv-registry.js => tests/vadimToUpdate.js (99%) create mode 100644 tests/validators/register.js create mode 100644 tests/validators/remove.js create mode 100644 tests/validators/update.js diff --git a/test/unit/stress.js b/test/unit/stress.js deleted file mode 100644 index 4019bed0..00000000 --- a/test/unit/stress.js +++ /dev/null @@ -1,84 +0,0 @@ -// const { expect } = require("chai"); -// const { progressBlocks } = require('./utils'); -// const operator_fee_block = 1; -// -// const operatorsIndexes = Array.from(Array(1000).keys()).map(k => k + 1); -// let sharePKs, encryptedShares -// let validatorData = [] -// -// describe("Stress Test", () => { -// var deployedRegistryContract -// beforeEach(async () => { -// const Registry = await ethers.getContractFactory("SSVRegistryNew"); -// deployedRegistryContract = await Registry.deploy(); -// await deployedRegistryContract.deployed(); -// validatorData = [] -// -// // Create 1000 operators -// for (let i = 0; i < operatorsIndexes.length; i++) { -// const encryptionPK = "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002644c5330744c5331435255644a54694253553045675546564354456c4449457446575330744c533074436b314a53554a4a616b464f516d64726357687261556335647a424351564646526b464254304e425554684254556c4a516b4e6e53304e42555556424e5756554e557777563068365a54647954575a506232787456484d4b64577449513245344b336474625577324f54464a5131527052454531556b4a31546b787153565132576b4530597a4d78635652495933464256486c3565566b774c7a6b3352336c4b5a32646f596e6c465232526f5a516f76616c6836615756544f584a325279744a56474631516a684d566c686b656b78475956517857455a5765466c6e4e327832546c42344f5552504c315a6f526b686b5757786e54334932643052745633466a52476f33436c68575557464f57454674526e67334e6a56514e546c584e585a7a564752585657464852577858536d3933536b5a4b646e6332556c5249536b5a315456686a537a5a5661574a3063555a4d536d4a774f57356b6455674b516a6c4c537a4e57636d59725a6d744a4f5752425a327478524446484f456c785130744b4d566c33626a557965477878625452434e69744f4f475a555a45314d53314a75635770465a6d527a563164774d46567a4d51704c54573976535863796333426f6158417a5546704e596e4a61615530774e6a4a325a556f3055336f76596a424f62576450546e685464304a4a546e4e7863473534516a68465556517853544e6a4e6b6c714e586868436d35525355524255554643436930744c5330745255354549464a545153425156554a4d53554d675330565a4c5330744c53304b00000000000000000000000000000000000000000000000000000000"; -// await deployedRegistryContract.registerOperator(encryptionPK, operator_fee_block); -// } -// sharePKs = Array.from(Array(10).keys()).map(k => `0xa20a622ecbc816c89896f92a18214905a57beedbe8df6120ba644453a7e35672a365c3b73ce35b8738eeb5dade9107d${k}`); -// encryptedShares = Array.from(Array(10).keys()).map(k => `0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000158513741566f733037584a4537767275644b366c7a647a76634143313563636b5152492b6143766f31617a374979787a517233506a4361632b545745394d45307a4f6d49${k}36947472f46312f38613556786d71383948366e6b71436130415573782b37326c43306f686a4b3874396853746953746732596e2b304d2f4e3732744c6d5951394c325976654c56564a35556c586a425777${k}4377a5537732f3142435653727862415431376f2f704858474c46644170697a4c5332704b48354b71746545786e3033566b4a4244527538596c5055334634656c554937697a667a474444626d49677536484862305777344669743745543745422f357056457a547279445a5179516753336a4858714d63637359396e52494250724f2f2f367370544736646e5831304e4872356b716a305136464b64684d6a4162644d43773966527274672b72766979584e6674464945445478304768314f513d3d0000000000000000`); -// -// // Deposit to the account -// await deployedRegistryContract.deposit("100000000000") -// }) -// -// it("Register 1000 validators", async () => { -// // Register 1000 validators -// for (let i = 1000; i < 2000; i++) { -// const randomOperator = Math.floor(Math.random() * 995) -// const validatorPK = `0xa7ae1ea93b860ca0269ccca776b4526977395aa194e5820a00dedbf1cd63e7a898eec9a12f539f733ea4df9c651f${i}` -// -// const registerResult = (await (await deployedRegistryContract.registerValidator( -// [randomOperator, randomOperator + 1, randomOperator + 2, randomOperator + 3], -// validatorPK, -// sharePKs.slice(0, 4), -// encryptedShares.slice(0, 4), -// "10000" -// )).wait()).logs[0] -// -// // Save validator group id emits -// const interfaceRegister = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId)']); -// const outputRegister = interfaceRegister.decodeEventLog('ValidatorAdded', registerResult.data, registerResult.topics); -// validatorData.push({ publicKey: validatorPK, groupId: outputRegister.groupId }) -// } -// }) -// -// /* -// it("Update 1000 operators", async () => { -// for (let i = 0; i < operatorsIndexes.length; i++) { -// await deployedRegistryContract.updateOperatorFee(operatorsIndexes[i], 10) -// } -// }) -// -// it("Update 30 validators", async () => { -// for (let i = 1000; i < 1030; i++) { -// const randomOperator = Math.floor(Math.random() * 995) -// const validatorPK = `0xa7ae1ea93b860ca0269ccca776b4526977395aa194e5820a00dedbf1cd63e7a898eec9a12f539f733ea4df9c651f${i}` -// await deployedRegistryContract.updateValidator( -// [randomOperator, randomOperator + 1, randomOperator + 2, randomOperator + 3], -// validatorPK, -// validatorData[i - 1000].groupId, -// sharePKs.slice(0, 4), -// encryptedShares.slice(0, 4), -// "10" -// ) -// } -// }) -// -// it("Remove 1000 operators", async () => { -// for (let i = 0; i < operatorsIndexes.length; i++) { -// await deployedRegistryContract.removeOperator(operatorsIndexes[i]) -// } -// }) -// -// it("Remove 1000 validators", async () => { -// for (let i = 0; i < validatorData.length; i++) { -// await deployedRegistryContract.removeValidator(validatorData[i].publicKey, validatorData[i].groupId) -// } -// }) -// */ -// }); diff --git a/tests/account/deposit.js b/tests/account/deposit.js new file mode 100644 index 00000000..44b10e6d --- /dev/null +++ b/tests/account/deposit.js @@ -0,0 +1,38 @@ +const { expect } = require("chai"); +const operator_fee_block = 1; + +const operatorsIndexes = Array.from(Array(8).keys()).map(k => k + 1); +let sharePKs, encryptedShares + +describe("Deposit Test", () => { + var deployedRegistryContract + beforeEach(async () => { + const Registry = await ethers.getContractFactory("SSVRegistryNew"); + deployedRegistryContract = await Registry.deploy(); + await deployedRegistryContract.deployed(); + + // Create 4 operators + for (let i = 0; i < operatorsIndexes.length; i++) { + const encryptionPK = "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002644c5330744c5331435255644a54694253553045675546564354456c4449457446575330744c533074436b314a53554a4a616b464f516d64726357687261556335647a424351564646526b464254304e425554684254556c4a516b4e6e53304e42555556424e5756554e557777563068365a54647954575a506232787456484d4b64577449513245344b336474625577324f54464a5131527052454531556b4a31546b787153565132576b4530597a4d78635652495933464256486c3565566b774c7a6b3352336c4b5a32646f596e6c465232526f5a516f76616c6836615756544f584a325279744a56474631516a684d566c686b656b78475956517857455a5765466c6e4e327832546c42344f5552504c315a6f526b686b5757786e54334932643052745633466a52476f33436c68575557464f57454674526e67334e6a56514e546c584e585a7a564752585657464852577858536d3933536b5a4b646e6332556c5249536b5a315456686a537a5a5661574a3063555a4d536d4a774f57356b6455674b516a6c4c537a4e57636d59725a6d744a4f5752425a327478524446484f456c785130744b4d566c33626a557965477878625452434e69744f4f475a555a45314d53314a75635770465a6d527a563164774d46567a4d51704c54573976535863796333426f6158417a5546704e596e4a61615530774e6a4a325a556f3055336f76596a424f62576450546e685464304a4a546e4e7863473534516a68465556517853544e6a4e6b6c714e586868436d35525355524255554643436930744c5330745255354549464a545153425156554a4d53554d675330565a4c5330744c53304b00000000000000000000000000000000000000000000000000000000"; + await deployedRegistryContract.registerOperator(encryptionPK, operator_fee_block); + } + sharePKs = Array.from(Array(10).keys()).map(k => `0xa20a622ecbc816c89896f92a18214905a57beedbe8df6120ba644453a7e35672a365c3b73ce35b8738eeb5dade9107d${k}`); + encryptedShares = Array.from(Array(10).keys()).map(k => `0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000158513741566f733037584a4537767275644b366c7a647a76634143313563636b5152492b6143766f31617a374979787a517233506a4361632b545745394d45307a4f6d49${k}36947472f46312f38613556786d71383948366e6b71436130415573782b37326c43306f686a4b3874396853746953746732596e2b304d2f4e3732744c6d5951394c325976654c56564a35556c586a425777${k}4377a5537732f3142435653727862415431376f2f704858474c46644170697a4c5332704b48354b71746545786e3033566b4a4244527538596c5055334634656c554937697a667a474444626d49677536484862305777344669743745543745422f357056457a547279445a5179516753336a4858714d63637359396e52494250724f2f2f367370544736646e5831304e4872356b716a305136464b64684d6a4162644d43773966527274672b72766979584e6674464945445478304768314f513d3d0000000000000000`); + + await deployedRegistryContract.deposit("100000000000") + + }) + + it("Deposit", async () => { + + }) + + it("Deposit errors", async () => { + + }) + + it("Deposit gas limits", async () => { + + }) + +}); diff --git a/tests/account/withdraw.js b/tests/account/withdraw.js new file mode 100644 index 00000000..c3601d1d --- /dev/null +++ b/tests/account/withdraw.js @@ -0,0 +1,38 @@ +const { expect } = require("chai"); +const operator_fee_block = 1; + +const operatorsIndexes = Array.from(Array(8).keys()).map(k => k + 1); +let sharePKs, encryptedShares + +describe("Withdraw Test", () => { + var deployedRegistryContract + beforeEach(async () => { + const Registry = await ethers.getContractFactory("SSVRegistryNew"); + deployedRegistryContract = await Registry.deploy(); + await deployedRegistryContract.deployed(); + + // Create 4 operators + for (let i = 0; i < operatorsIndexes.length; i++) { + const encryptionPK = "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002644c5330744c5331435255644a54694253553045675546564354456c4449457446575330744c533074436b314a53554a4a616b464f516d64726357687261556335647a424351564646526b464254304e425554684254556c4a516b4e6e53304e42555556424e5756554e557777563068365a54647954575a506232787456484d4b64577449513245344b336474625577324f54464a5131527052454531556b4a31546b787153565132576b4530597a4d78635652495933464256486c3565566b774c7a6b3352336c4b5a32646f596e6c465232526f5a516f76616c6836615756544f584a325279744a56474631516a684d566c686b656b78475956517857455a5765466c6e4e327832546c42344f5552504c315a6f526b686b5757786e54334932643052745633466a52476f33436c68575557464f57454674526e67334e6a56514e546c584e585a7a564752585657464852577858536d3933536b5a4b646e6332556c5249536b5a315456686a537a5a5661574a3063555a4d536d4a774f57356b6455674b516a6c4c537a4e57636d59725a6d744a4f5752425a327478524446484f456c785130744b4d566c33626a557965477878625452434e69744f4f475a555a45314d53314a75635770465a6d527a563164774d46567a4d51704c54573976535863796333426f6158417a5546704e596e4a61615530774e6a4a325a556f3055336f76596a424f62576450546e685464304a4a546e4e7863473534516a68465556517853544e6a4e6b6c714e586868436d35525355524255554643436930744c5330745255354549464a545153425156554a4d53554d675330565a4c5330744c53304b00000000000000000000000000000000000000000000000000000000"; + await deployedRegistryContract.registerOperator(encryptionPK, operator_fee_block); + } + sharePKs = Array.from(Array(10).keys()).map(k => `0xa20a622ecbc816c89896f92a18214905a57beedbe8df6120ba644453a7e35672a365c3b73ce35b8738eeb5dade9107d${k}`); + encryptedShares = Array.from(Array(10).keys()).map(k => `0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000158513741566f733037584a4537767275644b366c7a647a76634143313563636b5152492b6143766f31617a374979787a517233506a4361632b545745394d45307a4f6d49${k}36947472f46312f38613556786d71383948366e6b71436130415573782b37326c43306f686a4b3874396853746953746732596e2b304d2f4e3732744c6d5951394c325976654c56564a35556c586a425777${k}4377a5537732f3142435653727862415431376f2f704858474c46644170697a4c5332704b48354b71746545786e3033566b4a4244527538596c5055334634656c554937697a667a474444626d49677536484862305777344669743745543745422f357056457a547279445a5179516753336a4858714d63637359396e52494250724f2f2f367370544736646e5831304e4872356b716a305136464b64684d6a4162644d43773966527274672b72766979584e6674464945445478304768314f513d3d0000000000000000`); + + await deployedRegistryContract.deposit("100000000000") + + }) + + it("Withdraw", async () => { + + }) + + it("Withdraw errors", async () => { + + }) + + it("Withdraw gas limits", async () => { + + }) + +}); diff --git a/tests/dao/networkFeeChange.js b/tests/dao/networkFeeChange.js new file mode 100644 index 00000000..70f45b66 --- /dev/null +++ b/tests/dao/networkFeeChange.js @@ -0,0 +1,38 @@ +const { expect } = require("chai"); +const operator_fee_block = 1; + +const operatorsIndexes = Array.from(Array(8).keys()).map(k => k + 1); +let sharePKs, encryptedShares + +describe("Change Network Fee Test", () => { + var deployedRegistryContract + beforeEach(async () => { + const Registry = await ethers.getContractFactory("SSVRegistryNew"); + deployedRegistryContract = await Registry.deploy(); + await deployedRegistryContract.deployed(); + + // Create 4 operators + for (let i = 0; i < operatorsIndexes.length; i++) { + const encryptionPK = "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002644c5330744c5331435255644a54694253553045675546564354456c4449457446575330744c533074436b314a53554a4a616b464f516d64726357687261556335647a424351564646526b464254304e425554684254556c4a516b4e6e53304e42555556424e5756554e557777563068365a54647954575a506232787456484d4b64577449513245344b336474625577324f54464a5131527052454531556b4a31546b787153565132576b4530597a4d78635652495933464256486c3565566b774c7a6b3352336c4b5a32646f596e6c465232526f5a516f76616c6836615756544f584a325279744a56474631516a684d566c686b656b78475956517857455a5765466c6e4e327832546c42344f5552504c315a6f526b686b5757786e54334932643052745633466a52476f33436c68575557464f57454674526e67334e6a56514e546c584e585a7a564752585657464852577858536d3933536b5a4b646e6332556c5249536b5a315456686a537a5a5661574a3063555a4d536d4a774f57356b6455674b516a6c4c537a4e57636d59725a6d744a4f5752425a327478524446484f456c785130744b4d566c33626a557965477878625452434e69744f4f475a555a45314d53314a75635770465a6d527a563164774d46567a4d51704c54573976535863796333426f6158417a5546704e596e4a61615530774e6a4a325a556f3055336f76596a424f62576450546e685464304a4a546e4e7863473534516a68465556517853544e6a4e6b6c714e586868436d35525355524255554643436930744c5330745255354549464a545153425156554a4d53554d675330565a4c5330744c53304b00000000000000000000000000000000000000000000000000000000"; + await deployedRegistryContract.registerOperator(encryptionPK, operator_fee_block); + } + sharePKs = Array.from(Array(10).keys()).map(k => `0xa20a622ecbc816c89896f92a18214905a57beedbe8df6120ba644453a7e35672a365c3b73ce35b8738eeb5dade9107d${k}`); + encryptedShares = Array.from(Array(10).keys()).map(k => `0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000158513741566f733037584a4537767275644b366c7a647a76634143313563636b5152492b6143766f31617a374979787a517233506a4361632b545745394d45307a4f6d49${k}36947472f46312f38613556786d71383948366e6b71436130415573782b37326c43306f686a4b3874396853746953746732596e2b304d2f4e3732744c6d5951394c325976654c56564a35556c586a425777${k}4377a5537732f3142435653727862415431376f2f704858474c46644170697a4c5332704b48354b71746545786e3033566b4a4244527538596c5055334634656c554937697a667a474444626d49677536484862305777344669743745543745422f357056457a547279445a5179516753336a4858714d63637359396e52494250724f2f2f367370544736646e5831304e4872356b716a305136464b64684d6a4162644d43773966527274672b72766979584e6674464945445478304768314f513d3d0000000000000000`); + + await deployedRegistryContract.deposit("100000000000") + + }) + + it("Get network fee", async () => { + + }) + + it("Change network fee", async () => { + + }) + + it("Change network fee errors", async () => { + + }) + +}); diff --git a/tests/dao/networkFeeWithdraw.js b/tests/dao/networkFeeWithdraw.js new file mode 100644 index 00000000..bff431aa --- /dev/null +++ b/tests/dao/networkFeeWithdraw.js @@ -0,0 +1,38 @@ +const { expect } = require("chai"); +const operator_fee_block = 1; + +const operatorsIndexes = Array.from(Array(8).keys()).map(k => k + 1); +let sharePKs, encryptedShares + +describe("Withdraw Network Fee Test", () => { + var deployedRegistryContract + beforeEach(async () => { + const Registry = await ethers.getContractFactory("SSVRegistryNew"); + deployedRegistryContract = await Registry.deploy(); + await deployedRegistryContract.deployed(); + + // Create 4 operators + for (let i = 0; i < operatorsIndexes.length; i++) { + const encryptionPK = "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002644c5330744c5331435255644a54694253553045675546564354456c4449457446575330744c533074436b314a53554a4a616b464f516d64726357687261556335647a424351564646526b464254304e425554684254556c4a516b4e6e53304e42555556424e5756554e557777563068365a54647954575a506232787456484d4b64577449513245344b336474625577324f54464a5131527052454531556b4a31546b787153565132576b4530597a4d78635652495933464256486c3565566b774c7a6b3352336c4b5a32646f596e6c465232526f5a516f76616c6836615756544f584a325279744a56474631516a684d566c686b656b78475956517857455a5765466c6e4e327832546c42344f5552504c315a6f526b686b5757786e54334932643052745633466a52476f33436c68575557464f57454674526e67334e6a56514e546c584e585a7a564752585657464852577858536d3933536b5a4b646e6332556c5249536b5a315456686a537a5a5661574a3063555a4d536d4a774f57356b6455674b516a6c4c537a4e57636d59725a6d744a4f5752425a327478524446484f456c785130744b4d566c33626a557965477878625452434e69744f4f475a555a45314d53314a75635770465a6d527a563164774d46567a4d51704c54573976535863796333426f6158417a5546704e596e4a61615530774e6a4a325a556f3055336f76596a424f62576450546e685464304a4a546e4e7863473534516a68465556517853544e6a4e6b6c714e586868436d35525355524255554643436930744c5330745255354549464a545153425156554a4d53554d675330565a4c5330744c53304b00000000000000000000000000000000000000000000000000000000"; + await deployedRegistryContract.registerOperator(encryptionPK, operator_fee_block); + } + sharePKs = Array.from(Array(10).keys()).map(k => `0xa20a622ecbc816c89896f92a18214905a57beedbe8df6120ba644453a7e35672a365c3b73ce35b8738eeb5dade9107d${k}`); + encryptedShares = Array.from(Array(10).keys()).map(k => `0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000158513741566f733037584a4537767275644b366c7a647a76634143313563636b5152492b6143766f31617a374979787a517233506a4361632b545745394d45307a4f6d49${k}36947472f46312f38613556786d71383948366e6b71436130415573782b37326c43306f686a4b3874396853746953746732596e2b304d2f4e3732744c6d5951394c325976654c56564a35556c586a425777${k}4377a5537732f3142435653727862415431376f2f704858474c46644170697a4c5332704b48354b71746545786e3033566b4a4244527538596c5055334634656c554937697a667a474444626d49677536484862305777344669743745543745422f357056457a547279445a5179516753336a4858714d63637359396e52494250724f2f2f367370544736646e5831304e4872356b716a305136464b64684d6a4162644d43773966527274672b72766979584e6674464945445478304768314f513d3d0000000000000000`); + + await deployedRegistryContract.deposit("100000000000") + + }) + + it("Get withdrawable network fee amount", async () => { + + }) + + it("Withdraw network fee", async () => { + + }) + + it("Withdraw network fee errors", async () => { + + }) + +}); diff --git a/test/unit/utils.ts b/tests/helpers/utils.ts similarity index 100% rename from test/unit/utils.ts rename to tests/helpers/utils.ts diff --git a/tests/liquidate/liquidate.js b/tests/liquidate/liquidate.js new file mode 100644 index 00000000..6d73cecc --- /dev/null +++ b/tests/liquidate/liquidate.js @@ -0,0 +1,42 @@ +const { expect } = require("chai"); +const operator_fee_block = 1; + +const operatorsIndexes = Array.from(Array(8).keys()).map(k => k + 1); +let sharePKs, encryptedShares + +describe("Liquidate Test", () => { + var deployedRegistryContract + beforeEach(async () => { + const Registry = await ethers.getContractFactory("SSVRegistryNew"); + deployedRegistryContract = await Registry.deploy(); + await deployedRegistryContract.deployed(); + + // Create 4 operators + for (let i = 0; i < operatorsIndexes.length; i++) { + const encryptionPK = "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002644c5330744c5331435255644a54694253553045675546564354456c4449457446575330744c533074436b314a53554a4a616b464f516d64726357687261556335647a424351564646526b464254304e425554684254556c4a516b4e6e53304e42555556424e5756554e557777563068365a54647954575a506232787456484d4b64577449513245344b336474625577324f54464a5131527052454531556b4a31546b787153565132576b4530597a4d78635652495933464256486c3565566b774c7a6b3352336c4b5a32646f596e6c465232526f5a516f76616c6836615756544f584a325279744a56474631516a684d566c686b656b78475956517857455a5765466c6e4e327832546c42344f5552504c315a6f526b686b5757786e54334932643052745633466a52476f33436c68575557464f57454674526e67334e6a56514e546c584e585a7a564752585657464852577858536d3933536b5a4b646e6332556c5249536b5a315456686a537a5a5661574a3063555a4d536d4a774f57356b6455674b516a6c4c537a4e57636d59725a6d744a4f5752425a327478524446484f456c785130744b4d566c33626a557965477878625452434e69744f4f475a555a45314d53314a75635770465a6d527a563164774d46567a4d51704c54573976535863796333426f6158417a5546704e596e4a61615530774e6a4a325a556f3055336f76596a424f62576450546e685464304a4a546e4e7863473534516a68465556517853544e6a4e6b6c714e586868436d35525355524255554643436930744c5330745255354549464a545153425156554a4d53554d675330565a4c5330744c53304b00000000000000000000000000000000000000000000000000000000"; + await deployedRegistryContract.registerOperator(encryptionPK, operator_fee_block); + } + sharePKs = Array.from(Array(10).keys()).map(k => `0xa20a622ecbc816c89896f92a18214905a57beedbe8df6120ba644453a7e35672a365c3b73ce35b8738eeb5dade9107d${k}`); + encryptedShares = Array.from(Array(10).keys()).map(k => `0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000158513741566f733037584a4537767275644b366c7a647a76634143313563636b5152492b6143766f31617a374979787a517233506a4361632b545745394d45307a4f6d49${k}36947472f46312f38613556786d71383948366e6b71436130415573782b37326c43306f686a4b3874396853746953746732596e2b304d2f4e3732744c6d5951394c325976654c56564a35556c586a425777${k}4377a5537732f3142435653727862415431376f2f704858474c46644170697a4c5332704b48354b71746545786e3033566b4a4244527538596c5055334634656c554937697a667a474444626d49677536484862305777344669743745543745422f357056457a547279445a5179516753336a4858714d63637359396e52494250724f2f2f367370544736646e5831304e4872356b716a305136464b64684d6a4162644d43773966527274672b72766979584e6674464945445478304768314f513d3d0000000000000000`); + + await deployedRegistryContract.deposit("100000000000") + + }) + + it("Liquidatable", async () => { + + }) + + it("Liquidate", async () => { + + }) + + it("Liquidate errors", async () => { + + }) + + it("Liquidate gas limits", async () => { + + }) + +}); diff --git a/tests/liquidate/liquidationThreshold.js b/tests/liquidate/liquidationThreshold.js new file mode 100644 index 00000000..54dfdfd7 --- /dev/null +++ b/tests/liquidate/liquidationThreshold.js @@ -0,0 +1,42 @@ +const { expect } = require("chai"); +const operator_fee_block = 1; + +const operatorsIndexes = Array.from(Array(8).keys()).map(k => k + 1); +let sharePKs, encryptedShares + +describe("Liquidation Threshold Test", () => { + var deployedRegistryContract + beforeEach(async () => { + const Registry = await ethers.getContractFactory("SSVRegistryNew"); + deployedRegistryContract = await Registry.deploy(); + await deployedRegistryContract.deployed(); + + // Create 4 operators + for (let i = 0; i < operatorsIndexes.length; i++) { + const encryptionPK = "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002644c5330744c5331435255644a54694253553045675546564354456c4449457446575330744c533074436b314a53554a4a616b464f516d64726357687261556335647a424351564646526b464254304e425554684254556c4a516b4e6e53304e42555556424e5756554e557777563068365a54647954575a506232787456484d4b64577449513245344b336474625577324f54464a5131527052454531556b4a31546b787153565132576b4530597a4d78635652495933464256486c3565566b774c7a6b3352336c4b5a32646f596e6c465232526f5a516f76616c6836615756544f584a325279744a56474631516a684d566c686b656b78475956517857455a5765466c6e4e327832546c42344f5552504c315a6f526b686b5757786e54334932643052745633466a52476f33436c68575557464f57454674526e67334e6a56514e546c584e585a7a564752585657464852577858536d3933536b5a4b646e6332556c5249536b5a315456686a537a5a5661574a3063555a4d536d4a774f57356b6455674b516a6c4c537a4e57636d59725a6d744a4f5752425a327478524446484f456c785130744b4d566c33626a557965477878625452434e69744f4f475a555a45314d53314a75635770465a6d527a563164774d46567a4d51704c54573976535863796333426f6158417a5546704e596e4a61615530774e6a4a325a556f3055336f76596a424f62576450546e685464304a4a546e4e7863473534516a68465556517853544e6a4e6b6c714e586868436d35525355524255554643436930744c5330745255354549464a545153425156554a4d53554d675330565a4c5330744c53304b00000000000000000000000000000000000000000000000000000000"; + await deployedRegistryContract.registerOperator(encryptionPK, operator_fee_block); + } + sharePKs = Array.from(Array(10).keys()).map(k => `0xa20a622ecbc816c89896f92a18214905a57beedbe8df6120ba644453a7e35672a365c3b73ce35b8738eeb5dade9107d${k}`); + encryptedShares = Array.from(Array(10).keys()).map(k => `0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000158513741566f733037584a4537767275644b366c7a647a76634143313563636b5152492b6143766f31617a374979787a517233506a4361632b545745394d45307a4f6d49${k}36947472f46312f38613556786d71383948366e6b71436130415573782b37326c43306f686a4b3874396853746953746732596e2b304d2f4e3732744c6d5951394c325976654c56564a35556c586a425777${k}4377a5537732f3142435653727862415431376f2f704858474c46644170697a4c5332704b48354b71746545786e3033566b4a4244527538596c5055334634656c554937697a667a474444626d49677536484862305777344669743745543745422f357056457a547279445a5179516753336a4858714d63637359396e52494250724f2f2f367370544736646e5831304e4872356b716a305136464b64684d6a4162644d43773966527274672b72766979584e6674464945445478304768314f513d3d0000000000000000`); + + await deployedRegistryContract.deposit("100000000000") + + }) + + it("Get liquidation threshold", async () => { + + }) + + it("Change liquidation threshold", async () => { + + }) + + it("Change liquidation threshold errors", async () => { + + }) + + it("Liquidation threshold gas limits", async () => { + + }) + +}); diff --git a/tests/operators/register.js b/tests/operators/register.js new file mode 100644 index 00000000..2a2ea826 --- /dev/null +++ b/tests/operators/register.js @@ -0,0 +1,83 @@ +const { expect } = require("chai"); +const operator_fee_block = 1; + +const operatorsIndexes = Array.from(Array(8).keys()).map(k => k + 1); +let sharePKs, encryptedShares + +describe("Register Operator Test", () => { + var deployedRegistryContract + beforeEach(async () => { + const Registry = await ethers.getContractFactory("SSVRegistryNew"); + deployedRegistryContract = await Registry.deploy(); + await deployedRegistryContract.deployed(); + + // Create 4 operators + for (let i = 0; i < operatorsIndexes.length; i++) { + const encryptionPK = "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002644c5330744c5331435255644a54694253553045675546564354456c4449457446575330744c533074436b314a53554a4a616b464f516d64726357687261556335647a424351564646526b464254304e425554684254556c4a516b4e6e53304e42555556424e5756554e557777563068365a54647954575a506232787456484d4b64577449513245344b336474625577324f54464a5131527052454531556b4a31546b787153565132576b4530597a4d78635652495933464256486c3565566b774c7a6b3352336c4b5a32646f596e6c465232526f5a516f76616c6836615756544f584a325279744a56474631516a684d566c686b656b78475956517857455a5765466c6e4e327832546c42344f5552504c315a6f526b686b5757786e54334932643052745633466a52476f33436c68575557464f57454674526e67334e6a56514e546c584e585a7a564752585657464852577858536d3933536b5a4b646e6332556c5249536b5a315456686a537a5a5661574a3063555a4d536d4a774f57356b6455674b516a6c4c537a4e57636d59725a6d744a4f5752425a327478524446484f456c785130744b4d566c33626a557965477878625452434e69744f4f475a555a45314d53314a75635770465a6d527a563164774d46567a4d51704c54573976535863796333426f6158417a5546704e596e4a61615530774e6a4a325a556f3055336f76596a424f62576450546e685464304a4a546e4e7863473534516a68465556517853544e6a4e6b6c714e586868436d35525355524255554643436930744c5330745255354549464a545153425156554a4d53554d675330565a4c5330744c53304b00000000000000000000000000000000000000000000000000000000"; + await deployedRegistryContract.registerOperator(encryptionPK, operator_fee_block); + } + sharePKs = Array.from(Array(10).keys()).map(k => `0xa20a622ecbc816c89896f92a18214905a57beedbe8df6120ba644453a7e35672a365c3b73ce35b8738eeb5dade9107d${k}`); + encryptedShares = Array.from(Array(10).keys()).map(k => `0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000158513741566f733037584a4537767275644b366c7a647a76634143313563636b5152492b6143766f31617a374979787a517233506a4361632b545745394d45307a4f6d49${k}36947472f46312f38613556786d71383948366e6b71436130415573782b37326c43306f686a4b3874396853746953746732596e2b304d2f4e3732744c6d5951394c325976654c56564a35556c586a425777${k}4377a5537732f3142435653727862415431376f2f704858474c46644170697a4c5332704b48354b71746545786e3033566b4a4244527538596c5055334634656c554937697a667a474444626d49677536484862305777344669743745543745422f357056457a547279445a5179516753336a4858714d63637359396e52494250724f2f2f367370544736646e5831304e4872356b716a305136464b64684d6a4162644d43773966527274672b72766979584e6674464945445478304768314f513d3d0000000000000000`); + + await deployedRegistryContract.deposit("100000000000") + + }) + + it("Register operator", async () => { + + }) + + it("Register operator errors", async () => { + + }) + + it("Register operator gas limits", async () => { + const validatorPK = `0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100` + + // Cost: 364101 + await deployedRegistryContract.registerValidator( + [1, 2, 3, 4], + `${validatorPK}0`, + sharePKs.slice(0, 4), + encryptedShares.slice(0, 4), + "10000" + ) + + // // Cost: 185380 + // await deployedRegistryContract.registerValidator( + // [1, 2, 3, 4], + // `${validatorPK}1`, + // sharePKs.slice(0, 4), + // encryptedShares.slice(0, 4), + // "10000" + // ) + + // Cost: 295713 + await deployedRegistryContract.registerValidator( + [1, 2, 5, 6], + `${validatorPK}1`, + sharePKs.slice(0, 4), + encryptedShares.slice(0, 4), + "10000" + ) + + // // Cost: 312813 + // await deployedRegistryContract.registerValidator( + // [1, 5, 6, 7], + // `${validatorPK}2`, + // sharePKs.slice(0, 4), + // encryptedShares.slice(0, 4), + // "10000" + // ) + + // // Cost: 329901 + // await deployedRegistryContract.registerValidator( + // [5, 6, 7, 8], + // `${validatorPK}0`, + // sharePKs.slice(0, 4), + // encryptedShares.slice(0, 4), + // "10000" + // ) + }) + +}); diff --git a/tests/operators/remove.js b/tests/operators/remove.js new file mode 100644 index 00000000..30aab00d --- /dev/null +++ b/tests/operators/remove.js @@ -0,0 +1,38 @@ +const { expect } = require("chai"); +const operator_fee_block = 1; + +const operatorsIndexes = Array.from(Array(8).keys()).map(k => k + 1); +let sharePKs, encryptedShares + +describe("Remove Operator Test", () => { + var deployedRegistryContract + beforeEach(async () => { + const Registry = await ethers.getContractFactory("SSVRegistryNew"); + deployedRegistryContract = await Registry.deploy(); + await deployedRegistryContract.deployed(); + + // Create 4 operators + for (let i = 0; i < operatorsIndexes.length; i++) { + const encryptionPK = "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002644c5330744c5331435255644a54694253553045675546564354456c4449457446575330744c533074436b314a53554a4a616b464f516d64726357687261556335647a424351564646526b464254304e425554684254556c4a516b4e6e53304e42555556424e5756554e557777563068365a54647954575a506232787456484d4b64577449513245344b336474625577324f54464a5131527052454531556b4a31546b787153565132576b4530597a4d78635652495933464256486c3565566b774c7a6b3352336c4b5a32646f596e6c465232526f5a516f76616c6836615756544f584a325279744a56474631516a684d566c686b656b78475956517857455a5765466c6e4e327832546c42344f5552504c315a6f526b686b5757786e54334932643052745633466a52476f33436c68575557464f57454674526e67334e6a56514e546c584e585a7a564752585657464852577858536d3933536b5a4b646e6332556c5249536b5a315456686a537a5a5661574a3063555a4d536d4a774f57356b6455674b516a6c4c537a4e57636d59725a6d744a4f5752425a327478524446484f456c785130744b4d566c33626a557965477878625452434e69744f4f475a555a45314d53314a75635770465a6d527a563164774d46567a4d51704c54573976535863796333426f6158417a5546704e596e4a61615530774e6a4a325a556f3055336f76596a424f62576450546e685464304a4a546e4e7863473534516a68465556517853544e6a4e6b6c714e586868436d35525355524255554643436930744c5330745255354549464a545153425156554a4d53554d675330565a4c5330744c53304b00000000000000000000000000000000000000000000000000000000"; + await deployedRegistryContract.registerOperator(encryptionPK, operator_fee_block); + } + sharePKs = Array.from(Array(10).keys()).map(k => `0xa20a622ecbc816c89896f92a18214905a57beedbe8df6120ba644453a7e35672a365c3b73ce35b8738eeb5dade9107d${k}`); + encryptedShares = Array.from(Array(10).keys()).map(k => `0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000158513741566f733037584a4537767275644b366c7a647a76634143313563636b5152492b6143766f31617a374979787a517233506a4361632b545745394d45307a4f6d49${k}36947472f46312f38613556786d71383948366e6b71436130415573782b37326c43306f686a4b3874396853746953746732596e2b304d2f4e3732744c6d5951394c325976654c56564a35556c586a425777${k}4377a5537732f3142435653727862415431376f2f704858474c46644170697a4c5332704b48354b71746545786e3033566b4a4244527538596c5055334634656c554937697a667a474444626d49677536484862305777344669743745543745422f357056457a547279445a5179516753336a4858714d63637359396e52494250724f2f2f367370544736646e5831304e4872356b716a305136464b64684d6a4162644d43773966527274672b72766979584e6674464945445478304768314f513d3d0000000000000000`); + + await deployedRegistryContract.deposit("100000000000") + + }) + + it("Remove operator", async () => { + + }) + + it("Remove operator errors", async () => { + + }) + + it("Remove operator gas limits", async () => { + + }) + +}); diff --git a/tests/operators/update.js b/tests/operators/update.js new file mode 100644 index 00000000..487c76b6 --- /dev/null +++ b/tests/operators/update.js @@ -0,0 +1,38 @@ +const { expect } = require("chai"); +const operator_fee_block = 1; + +const operatorsIndexes = Array.from(Array(8).keys()).map(k => k + 1); +let sharePKs, encryptedShares + +describe("Remove Operator Test", () => { + var deployedRegistryContract + beforeEach(async () => { + const Registry = await ethers.getContractFactory("SSVRegistryNew"); + deployedRegistryContract = await Registry.deploy(); + await deployedRegistryContract.deployed(); + + // Create 4 operators + for (let i = 0; i < operatorsIndexes.length; i++) { + const encryptionPK = "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002644c5330744c5331435255644a54694253553045675546564354456c4449457446575330744c533074436b314a53554a4a616b464f516d64726357687261556335647a424351564646526b464254304e425554684254556c4a516b4e6e53304e42555556424e5756554e557777563068365a54647954575a506232787456484d4b64577449513245344b336474625577324f54464a5131527052454531556b4a31546b787153565132576b4530597a4d78635652495933464256486c3565566b774c7a6b3352336c4b5a32646f596e6c465232526f5a516f76616c6836615756544f584a325279744a56474631516a684d566c686b656b78475956517857455a5765466c6e4e327832546c42344f5552504c315a6f526b686b5757786e54334932643052745633466a52476f33436c68575557464f57454674526e67334e6a56514e546c584e585a7a564752585657464852577858536d3933536b5a4b646e6332556c5249536b5a315456686a537a5a5661574a3063555a4d536d4a774f57356b6455674b516a6c4c537a4e57636d59725a6d744a4f5752425a327478524446484f456c785130744b4d566c33626a557965477878625452434e69744f4f475a555a45314d53314a75635770465a6d527a563164774d46567a4d51704c54573976535863796333426f6158417a5546704e596e4a61615530774e6a4a325a556f3055336f76596a424f62576450546e685464304a4a546e4e7863473534516a68465556517853544e6a4e6b6c714e586868436d35525355524255554643436930744c5330745255354549464a545153425156554a4d53554d675330565a4c5330744c53304b00000000000000000000000000000000000000000000000000000000"; + await deployedRegistryContract.registerOperator(encryptionPK, operator_fee_block); + } + sharePKs = Array.from(Array(10).keys()).map(k => `0xa20a622ecbc816c89896f92a18214905a57beedbe8df6120ba644453a7e35672a365c3b73ce35b8738eeb5dade9107d${k}`); + encryptedShares = Array.from(Array(10).keys()).map(k => `0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000158513741566f733037584a4537767275644b366c7a647a76634143313563636b5152492b6143766f31617a374979787a517233506a4361632b545745394d45307a4f6d49${k}36947472f46312f38613556786d71383948366e6b71436130415573782b37326c43306f686a4b3874396853746953746732596e2b304d2f4e3732744c6d5951394c325976654c56564a35556c586a425777${k}4377a5537732f3142435653727862415431376f2f704858474c46644170697a4c5332704b48354b71746545786e3033566b4a4244527538596c5055334634656c554937697a667a474444626d49677536484862305777344669743745543745422f357056457a547279445a5179516753336a4858714d63637359396e52494250724f2f2f367370544736646e5831304e4872356b716a305136464b64684d6a4162644d43773966527274672b72766979584e6674464945445478304768314f513d3d0000000000000000`); + + await deployedRegistryContract.deposit("100000000000") + + }) + + it("Update operator", async () => { + + }) + + it("Update operator errors", async () => { + + }) + + it("Update operator gas limits", async () => { + + }) + +}); diff --git a/tests/sanity/balances.js b/tests/sanity/balances.js new file mode 100644 index 00000000..d968b0cc --- /dev/null +++ b/tests/sanity/balances.js @@ -0,0 +1,139 @@ +const { expect } = require("chai"); +const operator_fee_block = 1; +const { progressBlocks } = require('../helpers/utils'); + +const operatorsIndexes = Array.from(Array(8).keys()).map(k => k + 1); +let sharePKs, encryptedShares +const validatorBalance = 100000000000 + +describe("Balance Test", () => { + var deployedRegistryContract + beforeEach(async () => { + const Registry = await ethers.getContractFactory("SSVRegistryNew"); + deployedRegistryContract = await Registry.deploy(); + await deployedRegistryContract.deployed(); + + // Register 4 operators + for (let i = 0; i < operatorsIndexes.length; i++) { + const encryptionPK = "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002644c5330744c5331435255644a54694253553045675546564354456c4449457446575330744c533074436b314a53554a4a616b464f516d64726357687261556335647a424351564646526b464254304e425554684254556c4a516b4e6e53304e42555556424e5756554e557777563068365a54647954575a506232787456484d4b64577449513245344b336474625577324f54464a5131527052454531556b4a31546b787153565132576b4530597a4d78635652495933464256486c3565566b774c7a6b3352336c4b5a32646f596e6c465232526f5a516f76616c6836615756544f584a325279744a56474631516a684d566c686b656b78475956517857455a5765466c6e4e327832546c42344f5552504c315a6f526b686b5757786e54334932643052745633466a52476f33436c68575557464f57454674526e67334e6a56514e546c584e585a7a564752585657464852577858536d3933536b5a4b646e6332556c5249536b5a315456686a537a5a5661574a3063555a4d536d4a774f57356b6455674b516a6c4c537a4e57636d59725a6d744a4f5752425a327478524446484f456c785130744b4d566c33626a557965477878625452434e69744f4f475a555a45314d53314a75635770465a6d527a563164774d46567a4d51704c54573976535863796333426f6158417a5546704e596e4a61615530774e6a4a325a556f3055336f76596a424f62576450546e685464304a4a546e4e7863473534516a68465556517853544e6a4e6b6c714e586868436d35525355524255554643436930744c5330745255354549464a545153425156554a4d53554d675330565a4c5330744c53304b00000000000000000000000000000000000000000000000000000000"; + await deployedRegistryContract.registerOperator(encryptionPK, i !== 4 ? operator_fee_block : 100); + } + sharePKs = Array.from(Array(10).keys()).map(k => `0xa20a622ecbc816c89896f92a18214905a57beedbe8df6120ba644453a7e35672a365c3b73ce35b8738eeb5dade9107d${k}`); + encryptedShares = Array.from(Array(10).keys()).map(k => `0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000158513741566f733037584a4537767275644b366c7a647a76634143313563636b5152492b6143766f31617a374979787a517233506a4361632b545745394d45307a4f6d49${k}36947472f46312f38613556786d71383948366e6b71436130415573782b37326c43306f686a4b3874396853746953746732596e2b304d2f4e3732744c6d5951394c325976654c56564a35556c586a425777${k}4377a5537732f3142435653727862415431376f2f704858474c46644170697a4c5332704b48354b71746545786e3033566b4a4244527538596c5055334634656c554937697a667a474444626d49677536484862305777344669743745543745422f357056457a547279445a5179516753336a4858714d63637359396e52494250724f2f2f367370544736646e5831304e4872356b716a305136464b64684d6a4162644d43773966527274672b72766979584e6674464945445478304768314f513d3d0000000000000000`); + + await deployedRegistryContract.deposit(validatorBalance.toString()) + + }) + + it("Check balances", async () => { + // Register 1000 validators + const validatorPK = `0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100` + + expect(await deployedRegistryContract.test_getOperatorBalance(1)).to.equal('0') + + // Register a validator + const validator1 = (await (await deployedRegistryContract.registerValidator( + [1, 2, 3, 4], + `${validatorPK}0`, + sharePKs.slice(0, 4), + encryptedShares.slice(0, 4), + "10000" + )).wait()).logs[0] + const interfaceRegister = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId)']); + const outputRegister = interfaceRegister.decodeEventLog('ValidatorAdded', validator1.data, validator1.topics); + + // Progress 50 blocks and check operator balances and group balance + await progressBlocks(50) + expect(await deployedRegistryContract.test_getOperatorBalance(1)).to.equal('50') + expect(await deployedRegistryContract.test_getOperatorBalance(2)).to.equal('50') + expect(await deployedRegistryContract.test_getOperatorBalance(3)).to.equal('50') + expect(await deployedRegistryContract.test_getOperatorBalance(4)).to.equal('50') + expect(await deployedRegistryContract.test_groupBalance(outputRegister.groupId)).to.equal(10000 - 150) + + // Update one of the operator fees + await deployedRegistryContract.updateOperatorFee(1, 10) + + // Progress 50 blocks and check operator balances and group balance + await progressBlocks(50) + expect(await deployedRegistryContract.test_getOperatorBalance(1)).to.equal('551') + expect(await deployedRegistryContract.test_getOperatorBalance(2)).to.equal('101') + expect(await deployedRegistryContract.test_getOperatorBalance(3)).to.equal('101') + expect(await deployedRegistryContract.test_getOperatorBalance(4)).to.equal('101') + expect(await deployedRegistryContract.test_groupBalance(outputRegister.groupId)).to.equal(10000 - 904) + + // Update 3 operator fees + await deployedRegistryContract.updateOperatorFee(2, 20) + await deployedRegistryContract.updateOperatorFee(3, 20) + await deployedRegistryContract.updateOperatorFee(4, 20) + + // Progress 50 blocks and check operator balances and group balance + await progressBlocks(50) + expect(await deployedRegistryContract.test_getOperatorBalance(1)).to.equal('1081') + expect(await deployedRegistryContract.test_getOperatorBalance(2)).to.equal('1142') + expect(await deployedRegistryContract.test_getOperatorBalance(3)).to.equal('1123') + expect(await deployedRegistryContract.test_getOperatorBalance(4)).to.equal('1104') + expect(await deployedRegistryContract.test_groupBalance(outputRegister.groupId)).to.equal(10000 - 4500) + + // Add another validator + await deployedRegistryContract.registerValidator( + [1, 2, 3, 5], + `${validatorPK}1`, + sharePKs.slice(0, 4), + encryptedShares.slice(0, 4), + "10000" + ) + + // Progress 50 blocks and check operator balances and group balance + await progressBlocks(50) + expect(await deployedRegistryContract.test_getOperatorBalance(1)).to.equal('2091') + expect(await deployedRegistryContract.test_getOperatorBalance(2)).to.equal('3162') + expect(await deployedRegistryContract.test_getOperatorBalance(3)).to.equal('3143') + expect(await deployedRegistryContract.test_getOperatorBalance(4)).to.equal('2124') + expect(await deployedRegistryContract.test_getOperatorBalance(5)).to.equal('5000') + expect(await deployedRegistryContract.test_groupBalance(outputRegister.groupId)).to.equal(10000 - 4500) + + // Remove an operator + await deployedRegistryContract.removeOperator(1) + + // Progress 50 blocks and check operator balances and group balance + await progressBlocks(50) + expect(await deployedRegistryContract.test_getOperatorBalance(1)).to.equal('2091') + expect(await deployedRegistryContract.test_getOperatorBalance(2)).to.equal('3162') + expect(await deployedRegistryContract.test_getOperatorBalance(3)).to.equal('3143') + expect(await deployedRegistryContract.test_getOperatorBalance(4)).to.equal('2124') + expect(await deployedRegistryContract.test_getOperatorBalance(5)).to.equal('5000') + expect(await deployedRegistryContract.test_groupBalance(outputRegister.groupId)).to.equal(10000 - 4500) + + // Update a validator + await deployedRegistryContract.updateValidator( + [1, 2, 3, 5], + `${validatorPK}0`, + outputRegister.groupId, + sharePKs.slice(0, 4), + encryptedShares.slice(0, 4), + "10" + ) + + // Progress 50 blocks and check operator balances and group balance + await progressBlocks(50) + expect(await deployedRegistryContract.test_getOperatorBalance(1)).to.equal('2091') + expect(await deployedRegistryContract.test_getOperatorBalance(2)).to.equal('3162') + expect(await deployedRegistryContract.test_getOperatorBalance(3)).to.equal('3143') + expect(await deployedRegistryContract.test_getOperatorBalance(4)).to.equal('2124') + expect(await deployedRegistryContract.test_getOperatorBalance(5)).to.equal('5000') + expect(await deployedRegistryContract.test_groupBalance(outputRegister.groupId)).to.equal(10000 - 4500) + + // Remove a validator + await deployedRegistryContract.removeValidator(`${validatorPK}0`, outputRegister.groupId) + + // Progress 50 blocks and check operator balances and group balance + await progressBlocks(50) + expect(await deployedRegistryContract.test_getOperatorBalance(1)).to.equal('2091') + expect(await deployedRegistryContract.test_getOperatorBalance(2)).to.equal('3162') + expect(await deployedRegistryContract.test_getOperatorBalance(3)).to.equal('3143') + expect(await deployedRegistryContract.test_getOperatorBalance(4)).to.equal('2124') + expect(await deployedRegistryContract.test_getOperatorBalance(5)).to.equal('5000') + expect(await deployedRegistryContract.test_groupBalance(outputRegister.groupId)).to.equal(10000 - 4500) + }) + +}); diff --git a/tests/sanity/stress.js b/tests/sanity/stress.js new file mode 100644 index 00000000..b0651b35 --- /dev/null +++ b/tests/sanity/stress.js @@ -0,0 +1,80 @@ +const { expect } = require("chai"); +const operator_fee_block = 1; + +const operatorsIndexes = Array.from(Array(1000).keys()).map(k => k + 1); +let sharePKs, encryptedShares +let validatorData = [] + +describe("Stress Test", () => { + var deployedRegistryContract + beforeEach(async () => { + const Registry = await ethers.getContractFactory("SSVRegistryNew"); + deployedRegistryContract = await Registry.deploy(); + await deployedRegistryContract.deployed(); + validatorData = [] + + // Create 1000 operators + for (let i = 0; i < operatorsIndexes.length; i++) { + const encryptionPK = "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002644c5330744c5331435255644a54694253553045675546564354456c4449457446575330744c533074436b314a53554a4a616b464f516d64726357687261556335647a424351564646526b464254304e425554684254556c4a516b4e6e53304e42555556424e5756554e557777563068365a54647954575a506232787456484d4b64577449513245344b336474625577324f54464a5131527052454531556b4a31546b787153565132576b4530597a4d78635652495933464256486c3565566b774c7a6b3352336c4b5a32646f596e6c465232526f5a516f76616c6836615756544f584a325279744a56474631516a684d566c686b656b78475956517857455a5765466c6e4e327832546c42344f5552504c315a6f526b686b5757786e54334932643052745633466a52476f33436c68575557464f57454674526e67334e6a56514e546c584e585a7a564752585657464852577858536d3933536b5a4b646e6332556c5249536b5a315456686a537a5a5661574a3063555a4d536d4a774f57356b6455674b516a6c4c537a4e57636d59725a6d744a4f5752425a327478524446484f456c785130744b4d566c33626a557965477878625452434e69744f4f475a555a45314d53314a75635770465a6d527a563164774d46567a4d51704c54573976535863796333426f6158417a5546704e596e4a61615530774e6a4a325a556f3055336f76596a424f62576450546e685464304a4a546e4e7863473534516a68465556517853544e6a4e6b6c714e586868436d35525355524255554643436930744c5330745255354549464a545153425156554a4d53554d675330565a4c5330744c53304b00000000000000000000000000000000000000000000000000000000"; + await deployedRegistryContract.registerOperator(encryptionPK, operator_fee_block); + } + sharePKs = Array.from(Array(10).keys()).map(k => `0xa20a622ecbc816c89896f92a18214905a57beedbe8df6120ba644453a7e35672a365c3b73ce35b8738eeb5dade9107d${k}`); + encryptedShares = Array.from(Array(10).keys()).map(k => `0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000158513741566f733037584a4537767275644b366c7a647a76634143313563636b5152492b6143766f31617a374979787a517233506a4361632b545745394d45307a4f6d49${k}36947472f46312f38613556786d71383948366e6b71436130415573782b37326c43306f686a4b3874396853746953746732596e2b304d2f4e3732744c6d5951394c325976654c56564a35556c586a425777${k}4377a5537732f3142435653727862415431376f2f704858474c46644170697a4c5332704b48354b71746545786e3033566b4a4244527538596c5055334634656c554937697a667a474444626d49677536484862305777344669743745543745422f357056457a547279445a5179516753336a4858714d63637359396e52494250724f2f2f367370544736646e5831304e4872356b716a305136464b64684d6a4162644d43773966527274672b72766979584e6674464945445478304768314f513d3d0000000000000000`); + + // Deposit to the account + await deployedRegistryContract.deposit("100000000000") + + // Register 1000 validators + for (let i = 1000; i < 2000; i++) { + const randomOperator = Math.floor(Math.random() * 995) + const validatorPK = `0xa7ae1ea93b860ca0269ccca776b4526977395aa194e5820a00dedbf1cd63e7a898eec9a12f539f733ea4df9c651f${i}` + + const registerResult = (await (await deployedRegistryContract.registerValidator( + [randomOperator, randomOperator + 1, randomOperator + 2, randomOperator + 3], + validatorPK, + sharePKs.slice(0, 4), + encryptedShares.slice(0, 4), + "10000" + )).wait()).logs[0] + + // Save validator group id emits + const interfaceRegister = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId)']); + const outputRegister = interfaceRegister.decodeEventLog('ValidatorAdded', registerResult.data, registerResult.topics); + validatorData.push({ publicKey: validatorPK, groupId: outputRegister.groupId }) + } + }) + + it("Update 1000 operators", async () => { + for (let i = 0; i < operatorsIndexes.length; i++) { + await deployedRegistryContract.updateOperatorFee(operatorsIndexes[i], 10) + } + }) + + it("Update 30 validators", async () => { + for (let i = 1000; i < 1030; i++) { + const randomOperator = Math.floor(Math.random() * 995) + const validatorPK = `0xa7ae1ea93b860ca0269ccca776b4526977395aa194e5820a00dedbf1cd63e7a898eec9a12f539f733ea4df9c651f${i}` + await deployedRegistryContract.updateValidator( + [randomOperator, randomOperator + 1, randomOperator + 2, randomOperator + 3], + validatorPK, + validatorData[i - 1000].groupId, + sharePKs.slice(0, 4), + encryptedShares.slice(0, 4), + "10" + ) + } + }) + + it("Remove 1000 operators", async () => { + for (let i = 0; i < operatorsIndexes.length; i++) { + await deployedRegistryContract.removeOperator(operatorsIndexes[i]) + } + }) + + it("Remove 1000 validators", async () => { + for (let i = 0; i < validatorData.length; i++) { + await deployedRegistryContract.removeValidator(validatorData[i].publicKey, validatorData[i].groupId) + } + }) + +}); diff --git a/test/unit/ssv-registry.js b/tests/vadimToUpdate.js similarity index 99% rename from test/unit/ssv-registry.js rename to tests/vadimToUpdate.js index 4c2e4412..75966d6b 100644 --- a/test/unit/ssv-registry.js +++ b/tests/vadimToUpdate.js @@ -2,6 +2,7 @@ const { expect } = require("chai"); const { progressBlocks, blockNumber } = require('./utils'); const operator_fee_block = 1; + async function mineNBlocks(n) { for (let index = 0; index < n; index++) { await ethers.provider.send('evm_mine'); @@ -10,7 +11,6 @@ async function mineNBlocks(n) { const operatorsIndexes = Array.from(Array(5).keys()).map(k => k + 1); let deployedRegistryContract; -let owner; async function log({ action='', operatorIds = [], groupIds = [] }) { console.log(`[BLOCK] ${await blockNumber()}`) @@ -37,7 +37,6 @@ async function log({ action='', operatorIds = [], groupIds = [] }) { describe("Validators", () => { beforeEach(async () => { - [ owner ] = await ethers.getSigners(); const Registry = await ethers.getContractFactory("SSVRegistryNew"); deployedRegistryContract = await Registry.deploy(); await deployedRegistryContract.deployed(); @@ -194,7 +193,7 @@ describe("Validators", () => { operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], groupIds: [outputRegister.groupId, outputRegister2.groupId] }); - await (await deployedRegistryContract.removeValidator(outputRegister2.validatorPK)).wait(); + await (await deployedRegistryContract.removeValidator(outputRegister2.validatorPK, outputRegister2.groupId)).wait(); await log({ action: 'remove validator #2', operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], @@ -211,7 +210,6 @@ describe("Validators", () => { groupIds: [outputRegister.groupId, outputRegister2.groupId] }); await progressBlocks(1); - let results = [] for (let i = 0; i < 20; ++i) { let resultRegister = (await (await deployedRegistryContract.registerValidator( diff --git a/tests/validators/register.js b/tests/validators/register.js new file mode 100644 index 00000000..7cc9b4b9 --- /dev/null +++ b/tests/validators/register.js @@ -0,0 +1,90 @@ +const { expect } = require("chai"); +const operator_fee_block = 1; + +const operatorsIndexes = Array.from(Array(8).keys()).map(k => k + 1); +let sharePKs, encryptedShares + +describe("Register Validator Test", () => { + var deployedRegistryContract + beforeEach(async () => { + const Registry = await ethers.getContractFactory("SSVRegistryNew"); + deployedRegistryContract = await Registry.deploy(); + await deployedRegistryContract.deployed(); + + // Create 4 operators + for (let i = 0; i < operatorsIndexes.length; i++) { + const encryptionPK = "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002644c5330744c5331435255644a54694253553045675546564354456c4449457446575330744c533074436b314a53554a4a616b464f516d64726357687261556335647a424351564646526b464254304e425554684254556c4a516b4e6e53304e42555556424e5756554e557777563068365a54647954575a506232787456484d4b64577449513245344b336474625577324f54464a5131527052454531556b4a31546b787153565132576b4530597a4d78635652495933464256486c3565566b774c7a6b3352336c4b5a32646f596e6c465232526f5a516f76616c6836615756544f584a325279744a56474631516a684d566c686b656b78475956517857455a5765466c6e4e327832546c42344f5552504c315a6f526b686b5757786e54334932643052745633466a52476f33436c68575557464f57454674526e67334e6a56514e546c584e585a7a564752585657464852577858536d3933536b5a4b646e6332556c5249536b5a315456686a537a5a5661574a3063555a4d536d4a774f57356b6455674b516a6c4c537a4e57636d59725a6d744a4f5752425a327478524446484f456c785130744b4d566c33626a557965477878625452434e69744f4f475a555a45314d53314a75635770465a6d527a563164774d46567a4d51704c54573976535863796333426f6158417a5546704e596e4a61615530774e6a4a325a556f3055336f76596a424f62576450546e685464304a4a546e4e7863473534516a68465556517853544e6a4e6b6c714e586868436d35525355524255554643436930744c5330745255354549464a545153425156554a4d53554d675330565a4c5330744c53304b00000000000000000000000000000000000000000000000000000000"; + await deployedRegistryContract.registerOperator(encryptionPK, operator_fee_block); + } + sharePKs = Array.from(Array(10).keys()).map(k => `0xa20a622ecbc816c89896f92a18214905a57beedbe8df6120ba644453a7e35672a365c3b73ce35b8738eeb5dade9107d${k}`); + encryptedShares = Array.from(Array(10).keys()).map(k => `0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000158513741566f733037584a4537767275644b366c7a647a76634143313563636b5152492b6143766f31617a374979787a517233506a4361632b545745394d45307a4f6d49${k}36947472f46312f38613556786d71383948366e6b71436130415573782b37326c43306f686a4b3874396853746953746732596e2b304d2f4e3732744c6d5951394c325976654c56564a35556c586a425777${k}4377a5537732f3142435653727862415431376f2f704858474c46644170697a4c5332704b48354b71746545786e3033566b4a4244527538596c5055334634656c554937697a667a474444626d49677536484862305777344669743745543745422f357056457a547279445a5179516753336a4858714d63637359396e52494250724f2f2f367370544736646e5831304e4872356b716a305136464b64684d6a4162644d43773966527274672b72766979584e6674464945445478304768314f513d3d0000000000000000`); + + await deployedRegistryContract.deposit("100000000000") + + }) + + it("Register validator", async () => { + const validatorPK = `0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100` + await deployedRegistryContract.registerValidator( + [1, 2, 3, 4], + `${validatorPK}0`, + sharePKs.slice(0, 4), + encryptedShares.slice(0, 4), + "10000" + ) + }) + + it("Register validator errors", async () => { + + }) + + it("Register validator gas limits", async () => { + const validatorPK = `0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100` + + // Cost: 364101 + await deployedRegistryContract.registerValidator( + [1, 2, 3, 4], + `${validatorPK}0`, + sharePKs.slice(0, 4), + encryptedShares.slice(0, 4), + "10000" + ) + + // // Cost: 185380 + // await deployedRegistryContract.registerValidator( + // [1, 2, 3, 4], + // `${validatorPK}1`, + // sharePKs.slice(0, 4), + // encryptedShares.slice(0, 4), + // "10000" + // ) + + // Cost: 295713 + await deployedRegistryContract.registerValidator( + [1, 2, 5, 6], + `${validatorPK}1`, + sharePKs.slice(0, 4), + encryptedShares.slice(0, 4), + "10000" + ) + + // // Cost: 312813 + // await deployedRegistryContract.registerValidator( + // [1, 5, 6, 7], + // `${validatorPK}2`, + // sharePKs.slice(0, 4), + // encryptedShares.slice(0, 4), + // "10000" + // ) + + // // Cost: 329901 + // await deployedRegistryContract.registerValidator( + // [5, 6, 7, 8], + // `${validatorPK}0`, + // sharePKs.slice(0, 4), + // encryptedShares.slice(0, 4), + // "10000" + // ) + }) + +}); diff --git a/tests/validators/remove.js b/tests/validators/remove.js new file mode 100644 index 00000000..7478b5bf --- /dev/null +++ b/tests/validators/remove.js @@ -0,0 +1,38 @@ +const { expect } = require("chai"); +const operator_fee_block = 1; + +const operatorsIndexes = Array.from(Array(8).keys()).map(k => k + 1); +let sharePKs, encryptedShares + +describe("Remove Validator Test", () => { + var deployedRegistryContract + beforeEach(async () => { + const Registry = await ethers.getContractFactory("SSVRegistryNew"); + deployedRegistryContract = await Registry.deploy(); + await deployedRegistryContract.deployed(); + + // Create 4 operators + for (let i = 0; i < operatorsIndexes.length; i++) { + const encryptionPK = "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002644c5330744c5331435255644a54694253553045675546564354456c4449457446575330744c533074436b314a53554a4a616b464f516d64726357687261556335647a424351564646526b464254304e425554684254556c4a516b4e6e53304e42555556424e5756554e557777563068365a54647954575a506232787456484d4b64577449513245344b336474625577324f54464a5131527052454531556b4a31546b787153565132576b4530597a4d78635652495933464256486c3565566b774c7a6b3352336c4b5a32646f596e6c465232526f5a516f76616c6836615756544f584a325279744a56474631516a684d566c686b656b78475956517857455a5765466c6e4e327832546c42344f5552504c315a6f526b686b5757786e54334932643052745633466a52476f33436c68575557464f57454674526e67334e6a56514e546c584e585a7a564752585657464852577858536d3933536b5a4b646e6332556c5249536b5a315456686a537a5a5661574a3063555a4d536d4a774f57356b6455674b516a6c4c537a4e57636d59725a6d744a4f5752425a327478524446484f456c785130744b4d566c33626a557965477878625452434e69744f4f475a555a45314d53314a75635770465a6d527a563164774d46567a4d51704c54573976535863796333426f6158417a5546704e596e4a61615530774e6a4a325a556f3055336f76596a424f62576450546e685464304a4a546e4e7863473534516a68465556517853544e6a4e6b6c714e586868436d35525355524255554643436930744c5330745255354549464a545153425156554a4d53554d675330565a4c5330744c53304b00000000000000000000000000000000000000000000000000000000"; + await deployedRegistryContract.registerOperator(encryptionPK, operator_fee_block); + } + sharePKs = Array.from(Array(10).keys()).map(k => `0xa20a622ecbc816c89896f92a18214905a57beedbe8df6120ba644453a7e35672a365c3b73ce35b8738eeb5dade9107d${k}`); + encryptedShares = Array.from(Array(10).keys()).map(k => `0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000158513741566f733037584a4537767275644b366c7a647a76634143313563636b5152492b6143766f31617a374979787a517233506a4361632b545745394d45307a4f6d49${k}36947472f46312f38613556786d71383948366e6b71436130415573782b37326c43306f686a4b3874396853746953746732596e2b304d2f4e3732744c6d5951394c325976654c56564a35556c586a425777${k}4377a5537732f3142435653727862415431376f2f704858474c46644170697a4c5332704b48354b71746545786e3033566b4a4244527538596c5055334634656c554937697a667a474444626d49677536484862305777344669743745543745422f357056457a547279445a5179516753336a4858714d63637359396e52494250724f2f2f367370544736646e5831304e4872356b716a305136464b64684d6a4162644d43773966527274672b72766979584e6674464945445478304768314f513d3d0000000000000000`); + + await deployedRegistryContract.deposit("100000000000") + + }) + + it("Remove validator", async () => { + + }) + + it("Remove validator errors", async () => { + + }) + + it("Remove Validator gas limits", async () => { + + }) + +}); diff --git a/tests/validators/update.js b/tests/validators/update.js new file mode 100644 index 00000000..3ee078e7 --- /dev/null +++ b/tests/validators/update.js @@ -0,0 +1,38 @@ +const { expect } = require("chai"); +const operator_fee_block = 1; + +const operatorsIndexes = Array.from(Array(8).keys()).map(k => k + 1); +let sharePKs, encryptedShares + +describe("Remove Validator Test", () => { + var deployedRegistryContract + beforeEach(async () => { + const Registry = await ethers.getContractFactory("SSVRegistryNew"); + deployedRegistryContract = await Registry.deploy(); + await deployedRegistryContract.deployed(); + + // Create 4 operators + for (let i = 0; i < operatorsIndexes.length; i++) { + const encryptionPK = "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002644c5330744c5331435255644a54694253553045675546564354456c4449457446575330744c533074436b314a53554a4a616b464f516d64726357687261556335647a424351564646526b464254304e425554684254556c4a516b4e6e53304e42555556424e5756554e557777563068365a54647954575a506232787456484d4b64577449513245344b336474625577324f54464a5131527052454531556b4a31546b787153565132576b4530597a4d78635652495933464256486c3565566b774c7a6b3352336c4b5a32646f596e6c465232526f5a516f76616c6836615756544f584a325279744a56474631516a684d566c686b656b78475956517857455a5765466c6e4e327832546c42344f5552504c315a6f526b686b5757786e54334932643052745633466a52476f33436c68575557464f57454674526e67334e6a56514e546c584e585a7a564752585657464852577858536d3933536b5a4b646e6332556c5249536b5a315456686a537a5a5661574a3063555a4d536d4a774f57356b6455674b516a6c4c537a4e57636d59725a6d744a4f5752425a327478524446484f456c785130744b4d566c33626a557965477878625452434e69744f4f475a555a45314d53314a75635770465a6d527a563164774d46567a4d51704c54573976535863796333426f6158417a5546704e596e4a61615530774e6a4a325a556f3055336f76596a424f62576450546e685464304a4a546e4e7863473534516a68465556517853544e6a4e6b6c714e586868436d35525355524255554643436930744c5330745255354549464a545153425156554a4d53554d675330565a4c5330744c53304b00000000000000000000000000000000000000000000000000000000"; + await deployedRegistryContract.registerOperator(encryptionPK, operator_fee_block); + } + sharePKs = Array.from(Array(10).keys()).map(k => `0xa20a622ecbc816c89896f92a18214905a57beedbe8df6120ba644453a7e35672a365c3b73ce35b8738eeb5dade9107d${k}`); + encryptedShares = Array.from(Array(10).keys()).map(k => `0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000158513741566f733037584a4537767275644b366c7a647a76634143313563636b5152492b6143766f31617a374979787a517233506a4361632b545745394d45307a4f6d49${k}36947472f46312f38613556786d71383948366e6b71436130415573782b37326c43306f686a4b3874396853746953746732596e2b304d2f4e3732744c6d5951394c325976654c56564a35556c586a425777${k}4377a5537732f3142435653727862415431376f2f704858474c46644170697a4c5332704b48354b71746545786e3033566b4a4244527538596c5055334634656c554937697a667a474444626d49677536484862305777344669743745543745422f357056457a547279445a5179516753336a4858714d63637359396e52494250724f2f2f367370544736646e5831304e4872356b716a305136464b64684d6a4162644d43773966527274672b72766979584e6674464945445478304768314f513d3d0000000000000000`); + + await deployedRegistryContract.deposit("100000000000") + + }) + + it("Update validator", async () => { + + }) + + it("Update validator errors", async () => { + + }) + + it("Update Validator gas limits", async () => { + + }) + +}); From 6c2356ccf40b1669dd5ba6a50f9cd867e9a1b96f Mon Sep 17 00:00:00 2001 From: Lior Rutenberg Date: Wed, 24 Aug 2022 17:40:24 +0300 Subject: [PATCH 034/149] fixed vadim test --- tests/vadimToUpdate.js | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/tests/vadimToUpdate.js b/tests/vadimToUpdate.js index 75966d6b..e60c3f1d 100644 --- a/tests/vadimToUpdate.js +++ b/tests/vadimToUpdate.js @@ -1,5 +1,5 @@ const { expect } = require("chai"); -const { progressBlocks, blockNumber } = require('./utils'); +const { progressBlocks, blockNumber } = require('./helpers/utils'); const operator_fee_block = 1; @@ -26,6 +26,7 @@ async function log({ action='', operatorIds = [], groupIds = [] }) { } } if (groupIds.length) { + const [owner] = await ethers.getSigners(); for (const id of groupIds) { console.log( `> group #$${id}`, @@ -72,6 +73,7 @@ describe("Validators", () => { sharePKs[0], '10000' )).wait()).logs[0]; + let interfaceRegister = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId, bytes shares)']); let outputRegister = interfaceRegister.decodeEventLog('ValidatorAdded', resultRegister.data, resultRegister.topics); await log({ @@ -89,7 +91,8 @@ describe("Validators", () => { validatorPK + "f", sharePKs[2], '10000' - )).wait()).logs[0];; + )).wait()).logs[0]; + let interfaceUpdate = new ethers.utils.Interface(['event ValidatorUpdated(bytes validatorPK, bytes32 groupId, bytes shares)']); let outputUpdate = interfaceUpdate.decodeEventLog('ValidatorUpdated', resultUpdate.data, resultUpdate.topics); expect(outputRegister.groupId).not.equal(outputUpdate.groupId); @@ -133,7 +136,7 @@ describe("Validators", () => { const resultRegister2 = (await (await deployedRegistryContract.registerValidator( [1,2,3,4], - validatorPK + "f", + validatorPK + "a", sharePKs[1], "1000" )).wait()).logs[0]; @@ -149,7 +152,7 @@ describe("Validators", () => { const resultRegister3 = (await (await deployedRegistryContract.registerValidator( [5,6,7,8], - validatorPK + "f", + validatorPK + "b", sharePKs[1], "1000000" )).wait()).logs[0]; @@ -193,12 +196,15 @@ describe("Validators", () => { operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], groupIds: [outputRegister.groupId, outputRegister2.groupId] }); - await (await deployedRegistryContract.removeValidator(outputRegister2.validatorPK, outputRegister2.groupId)).wait(); + + + await (await deployedRegistryContract.removeValidator(outputRegister2.validatorPK)).wait(); await log({ action: 'remove validator #2', operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], groupIds: [outputRegister.groupId, outputRegister2.groupId] }); + await progressBlocks(1); await log({ operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], From bafb7a0fd571da66e5eeaa67f6d9fcdadd0c6b10 Mon Sep 17 00:00:00 2001 From: AndrewBlox Date: Thu, 25 Aug 2022 14:13:10 +0300 Subject: [PATCH 035/149] clean contract tests --- test/account/deposit.ts | 28 ++++ test/account/withdraw.ts | 28 ++++ test/dao/network-fee-change.ts | 28 ++++ test/dao/network-fee-withdraw.ts | 28 ++++ test/helpers/contract-helpers.ts | 57 ++++++++ {tests => test}/helpers/utils.ts | 0 test/liquidate/liquidate.ts | 32 +++++ test/liquidate/liquidation-threshold.ts | 32 +++++ test/operators/register.ts | 71 ++++++++++ test/operators/remove.ts | 28 ++++ test/operators/update.ts | 28 ++++ test/sanity/balances.ts | 126 ++++++++++++++++++ test/sanity/stress.ts | 51 +++++++ {tests => test}/vadimToUpdate.js | 0 test/validators/gas/1-operator-different.ts | 34 +++++ test/validators/gas/2-operator-different.ts | 34 +++++ test/validators/gas/3-operator-different.ts | 34 +++++ test/validators/gas/4-operator-different.ts | 34 +++++ test/validators/gas/different-group.ts | 34 +++++ test/validators/gas/same-group.ts | 34 +++++ test/validators/register.ts | 29 ++++ test/validators/remove.ts | 28 ++++ test/validators/update.ts | 28 ++++ tests/account/deposit.js | 38 ------ tests/account/withdraw.js | 38 ------ tests/dao/networkFeeChange.js | 38 ------ tests/dao/networkFeeWithdraw.js | 38 ------ tests/liquidate/liquidate.js | 42 ------ tests/liquidate/liquidationThreshold.js | 42 ------ tests/operators/register.js | 83 ------------ tests/operators/remove.js | 38 ------ tests/operators/update.js | 38 ------ tests/sanity/balances.js | 139 -------------------- tests/sanity/stress.js | 80 ----------- tests/validators/register.js | 90 ------------- tests/validators/remove.js | 38 ------ tests/validators/update.js | 38 ------ 37 files changed, 826 insertions(+), 780 deletions(-) create mode 100644 test/account/deposit.ts create mode 100644 test/account/withdraw.ts create mode 100644 test/dao/network-fee-change.ts create mode 100644 test/dao/network-fee-withdraw.ts create mode 100644 test/helpers/contract-helpers.ts rename {tests => test}/helpers/utils.ts (100%) create mode 100644 test/liquidate/liquidate.ts create mode 100644 test/liquidate/liquidation-threshold.ts create mode 100644 test/operators/register.ts create mode 100644 test/operators/remove.ts create mode 100644 test/operators/update.ts create mode 100644 test/sanity/balances.ts create mode 100644 test/sanity/stress.ts rename {tests => test}/vadimToUpdate.js (100%) create mode 100644 test/validators/gas/1-operator-different.ts create mode 100644 test/validators/gas/2-operator-different.ts create mode 100644 test/validators/gas/3-operator-different.ts create mode 100644 test/validators/gas/4-operator-different.ts create mode 100644 test/validators/gas/different-group.ts create mode 100644 test/validators/gas/same-group.ts create mode 100644 test/validators/register.ts create mode 100644 test/validators/remove.ts create mode 100644 test/validators/update.ts delete mode 100644 tests/account/deposit.js delete mode 100644 tests/account/withdraw.js delete mode 100644 tests/dao/networkFeeChange.js delete mode 100644 tests/dao/networkFeeWithdraw.js delete mode 100644 tests/liquidate/liquidate.js delete mode 100644 tests/liquidate/liquidationThreshold.js delete mode 100644 tests/operators/register.js delete mode 100644 tests/operators/remove.js delete mode 100644 tests/operators/update.js delete mode 100644 tests/sanity/balances.js delete mode 100644 tests/sanity/stress.js delete mode 100644 tests/validators/register.js delete mode 100644 tests/validators/remove.js delete mode 100644 tests/validators/update.js diff --git a/test/account/deposit.ts b/test/account/deposit.ts new file mode 100644 index 00000000..1174f98b --- /dev/null +++ b/test/account/deposit.ts @@ -0,0 +1,28 @@ +const { expect } = require("chai"); + +import * as helpers from "../helpers/contract-helpers" +let registryContract: any, operatorIDs: any, shares: any, owner: any +const numberOfOperators = 4 +const operatorFee = 4 + +describe("Deposit Tests", () => { + beforeEach(async () => { + const contractData = await helpers.initializeContract(numberOfOperators, operatorFee) + registryContract = contractData.contract + operatorIDs = contractData.operatorIDs + shares = contractData.shares + }) + + it("Deposit", async () => { + + }) + + it("Deposit errors", async () => { + + }) + + it("Deposit gas limits", async () => { + + }) + +}); diff --git a/test/account/withdraw.ts b/test/account/withdraw.ts new file mode 100644 index 00000000..04140e46 --- /dev/null +++ b/test/account/withdraw.ts @@ -0,0 +1,28 @@ +const { expect } = require("chai"); + +import * as helpers from "../helpers/contract-helpers" +let registryContract: any, operatorIDs: any, shares: any, owner: any +const numberOfOperators = 4 +const operatorFee = 4 + +describe("Withdraw Tests", () => { + beforeEach(async () => { + const contractData = await helpers.initializeContract(numberOfOperators, operatorFee) + registryContract = contractData.contract + operatorIDs = contractData.operatorIDs + shares = contractData.shares + }) + + it("Withdraw", async () => { + + }) + + it("Withdraw errors", async () => { + + }) + + it("Withdraw gas limits", async () => { + + }) + +}); diff --git a/test/dao/network-fee-change.ts b/test/dao/network-fee-change.ts new file mode 100644 index 00000000..bd9d8dba --- /dev/null +++ b/test/dao/network-fee-change.ts @@ -0,0 +1,28 @@ +const { expect } = require("chai"); + +import * as helpers from "../helpers/contract-helpers" +let registryContract: any, operatorIDs: any, shares: any, owner: any +const numberOfOperators = 4 +const operatorFee = 4 + +describe("DAO Network Fee Change Tests", () => { + beforeEach(async () => { + const contractData = await helpers.initializeContract(numberOfOperators, operatorFee) + registryContract = contractData.contract + operatorIDs = contractData.operatorIDs + shares = contractData.shares + }) + + it("Get network fee", async () => { + + }) + + it("Change network fee", async () => { + + }) + + it("Change network fee errors", async () => { + + }) + +}); diff --git a/test/dao/network-fee-withdraw.ts b/test/dao/network-fee-withdraw.ts new file mode 100644 index 00000000..53ef288a --- /dev/null +++ b/test/dao/network-fee-withdraw.ts @@ -0,0 +1,28 @@ +const { expect } = require("chai"); + +import * as helpers from "../helpers/contract-helpers" +let registryContract: any, operatorIDs: any, shares: any, owner: any +const numberOfOperators = 4 +const operatorFee = 4 + +describe("DAO Network Fee Withdraw Tests", () => { + beforeEach(async () => { + const contractData = await helpers.initializeContract(numberOfOperators, operatorFee) + registryContract = contractData.contract + operatorIDs = contractData.operatorIDs + shares = contractData.shares + }) + + it("Get withdrawable network fee amount", async () => { + + }) + + it("Withdraw network fee", async () => { + + }) + + it("Withdraw network fee errors", async () => { + + }) + +}); diff --git a/test/helpers/contract-helpers.ts b/test/helpers/contract-helpers.ts new file mode 100644 index 00000000..c115393f --- /dev/null +++ b/test/helpers/contract-helpers.ts @@ -0,0 +1,57 @@ +// Imports +declare const ethers: any + +// Generate shares +const shares = Array.from(Array(10).keys()).map(k => `0xe0096008000000b4010000040000001000000076000000dc000000420d142c307831323334353637383930fe0a00520a000031017afe66008266000032fe66009266000033fe66009266000034016621ac28d60000009c01000062020025c02c307839383736353433323130fe0a00520a000031fe560052560019b0003101dafec60082c6000032fec6007ac6004d6ca666000033ceb401fe8c017e8c014dcca6c6004d7a0035b23200fec6007ec6000034${k}${k}`) + +export const initializeContract = async (numberOfOperators: number, fee: number) => { + // Define accounts + const [owner] = await ethers.getSigners(); + + // Initialize contract + const registry = await ethers.getContractFactory("SSVRegistryNew") + const deployedRegistryContract = await registry.deploy() + await deployedRegistryContract.deployed(); + + // Register Operators + for (let i = 0; i < numberOfOperators; i++) { + const encodedABI = "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002644c5330744c5331435255644a54694253553045675546564354456c4449457446575330744c533074436b314a53554a4a616b464f516d64726357687261556335647a424351564646526b464254304e425554684254556c4a516b4e6e53304e42555556424e5756554e557777563068365a54647954575a506232787456484d4b64577449513245344b336474625577324f54464a5131527052454531556b4a31546b787153565132576b4530597a4d78635652495933464256486c3565566b774c7a6b3352336c4b5a32646f596e6c465232526f5a516f76616c6836615756544f584a325279744a56474631516a684d566c686b656b78475956517857455a5765466c6e4e327832546c42344f5552504c315a6f526b686b5757786e54334932643052745633466a52476f33436c68575557464f57454674526e67334e6a56514e546c584e585a7a564752585657464852577858536d3933536b5a4b646e6332556c5249536b5a315456686a537a5a5661574a3063555a4d536d4a774f57356b6455674b516a6c4c537a4e57636d59725a6d744a4f5752425a327478524446484f456c785130744b4d566c33626a557965477878625452434e69744f4f475a555a45314d53314a75635770465a6d527a563164774d46567a4d51704c54573976535863796333426f6158417a5546704e596e4a61615530774e6a4a325a556f3055336f76596a424f62576450546e685464304a4a546e4e7863473534516a68465556517853544e6a4e6b6c714e586868436d35525355524255554643436930744c5330745255354549464a545153425156554a4d53554d675330565a4c5330744c53304b00000000000000000000000000000000000000000000000000000000"; + await deployedRegistryContract.registerOperator(encodedABI, fee); + } + + // Generate Operator IDs + const operatorIDs = Array.from(Array(numberOfOperators).keys()).map(k => k + 1) + + // Deposit to the contract + await deployedRegistryContract.deposit("9000000000000000000") + + return { contract: deployedRegistryContract, operatorIDs: operatorIDs, shares: shares, owner: owner } +} + +export const registerValidators = async (numberOfValidators: number, amount: string, operatorAmount: number, contract: any) => { + let validatorData: any = [] + const validatorsToRegister = 1000 + numberOfValidators + + // Register validators to contract + for (let i = 1000; i < validatorsToRegister; i++) { + const randomOperator = Math.floor(Math.random() * (operatorAmount - 4)) + const validatorPK = `0xa7ae1ea93b860ca0269ccca776b4526977395aa194e5820a00dedbf1cd63e7a898eec9a12f539f733ea4df9c651f${i}` + + const registerResult = (await (await contract.registerValidator( + [randomOperator, randomOperator + 1, randomOperator + 2, randomOperator + 3], + validatorPK, + shares[0], + amount, + )).wait()).logs[0] + + // Save validator group id emits + let interfaceRegister = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId, bytes shares)']); + const outputRegister = interfaceRegister.decodeEventLog('ValidatorAdded', registerResult.data, registerResult.topics); + + // Save the validator emit + validatorData.push({ publicKey: validatorPK, groupId: outputRegister.groupId }) + } + + return validatorData + +} \ No newline at end of file diff --git a/tests/helpers/utils.ts b/test/helpers/utils.ts similarity index 100% rename from tests/helpers/utils.ts rename to test/helpers/utils.ts diff --git a/test/liquidate/liquidate.ts b/test/liquidate/liquidate.ts new file mode 100644 index 00000000..a6778fa2 --- /dev/null +++ b/test/liquidate/liquidate.ts @@ -0,0 +1,32 @@ +const { expect } = require("chai"); + +import * as helpers from "../helpers/contract-helpers" +let registryContract: any, operatorIDs: any, shares: any, owner: any +const numberOfOperators = 4 +const operatorFee = 4 + +describe("Liquidate Tests", () => { + beforeEach(async () => { + const contractData = await helpers.initializeContract(numberOfOperators, operatorFee) + registryContract = contractData.contract + operatorIDs = contractData.operatorIDs + shares = contractData.shares + }) + + it("Liquidatable", async () => { + + }) + + it("Liquidate", async () => { + + }) + + it("Liquidate errors", async () => { + + }) + + it("Liquidate gas limits", async () => { + + }) + +}); diff --git a/test/liquidate/liquidation-threshold.ts b/test/liquidate/liquidation-threshold.ts new file mode 100644 index 00000000..63c46436 --- /dev/null +++ b/test/liquidate/liquidation-threshold.ts @@ -0,0 +1,32 @@ +const { expect } = require("chai"); + +import * as helpers from "../helpers/contract-helpers" +let registryContract: any, operatorIDs: any, shares: any, owner: any +const numberOfOperators = 4 +const operatorFee = 4 + +describe("Liquidation Threshold Tests", () => { + beforeEach(async () => { + const contractData = await helpers.initializeContract(numberOfOperators, operatorFee) + registryContract = contractData.contract + operatorIDs = contractData.operatorIDs + shares = contractData.shares + }) + + it("Get liquidation threshold", async () => { + + }) + + it("Change liquidation threshold", async () => { + + }) + + it("Change liquidation threshold errors", async () => { + + }) + + it("Liquidation threshold gas limits", async () => { + + }) + +}); diff --git a/test/operators/register.ts b/test/operators/register.ts new file mode 100644 index 00000000..f1d7f46e --- /dev/null +++ b/test/operators/register.ts @@ -0,0 +1,71 @@ +const { expect } = require("chai"); + +import * as helpers from "../helpers/contract-helpers" +let registryContract: any, operatorIDs: any, shares: any, owner: any +const numberOfOperators = 4 +const operatorFee = 4 + +describe("Register Operator Tests", () => { + beforeEach(async () => { + const contractData = await helpers.initializeContract(numberOfOperators, operatorFee) + registryContract = contractData.contract + operatorIDs = contractData.operatorIDs + shares = contractData.shares + }) + + it("Register operator", async () => { + + }) + + it("Register operator errors", async () => { + + }) + + it("Register operator gas limits", async () => { + const validatorPK = `0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100` + + // Cost: 364101 + await registryContract.registerValidator( + [1, 2, 3, 4], + `${validatorPK}0`, + shares[0], + "10000" + ) + + // // Cost: 185380 + // await deployedRegistryContract.registerValidator( + // [1, 2, 3, 4], + // `${validatorPK}1`, + // sharePKs.slice(0, 4), + // encryptedShares.slice(0, 4), + // "10000" + // ) + + // Cost: 295713 + await registryContract.registerValidator( + [1, 2, 5, 6], + `${validatorPK}1`, + shares[1], + "10000" + ) + + // // Cost: 312813 + // await deployedRegistryContract.registerValidator( + // [1, 5, 6, 7], + // `${validatorPK}2`, + // sharePKs.slice(0, 4), + // encryptedShares.slice(0, 4), + // "10000" + // ) + + // // Cost: 329901 + // await deployedRegistryContract.registerValidator( + // [5, 6, 7, 8], + // `${validatorPK}0`, + // sharePKs.slice(0, 4), + // encryptedShares.slice(0, 4), + // "10000" + // ) + }) + +}); diff --git a/test/operators/remove.ts b/test/operators/remove.ts new file mode 100644 index 00000000..09b21f34 --- /dev/null +++ b/test/operators/remove.ts @@ -0,0 +1,28 @@ +const { expect } = require("chai"); + +import * as helpers from "../helpers/contract-helpers" +let registryContract: any, operatorIDs: any, shares: any, owner: any +const numberOfOperators = 4 +const operatorFee = 4 + +describe("Remove Operator Tests", () => { + beforeEach(async () => { + const contractData = await helpers.initializeContract(numberOfOperators, operatorFee) + registryContract = contractData.contract + operatorIDs = contractData.operatorIDs + shares = contractData.shares + }) + + it("Remove operator", async () => { + + }) + + it("Remove operator errors", async () => { + + }) + + it("Remove operator gas limits", async () => { + + }) + +}); diff --git a/test/operators/update.ts b/test/operators/update.ts new file mode 100644 index 00000000..ef4e3f4b --- /dev/null +++ b/test/operators/update.ts @@ -0,0 +1,28 @@ +const { expect } = require("chai"); + +import * as helpers from "../helpers/contract-helpers" +let registryContract: any, operatorIDs: any, shares: any, owner: any +const numberOfOperators = 4 +const operatorFee = 4 + +describe("Update Operator Tests", () => { + beforeEach(async () => { + const contractData = await helpers.initializeContract(numberOfOperators, operatorFee) + registryContract = contractData.contract + operatorIDs = contractData.operatorIDs + shares = contractData.shares + }) + + it("Update operator", async () => { + + }) + + it("Update operator errors", async () => { + + }) + + it("Update operator gas limits", async () => { + + }) + +}); diff --git a/test/sanity/balances.ts b/test/sanity/balances.ts new file mode 100644 index 00000000..895e89ff --- /dev/null +++ b/test/sanity/balances.ts @@ -0,0 +1,126 @@ +const { expect } = require("chai"); +declare const ethers: any + +import * as helpers from "../helpers/contract-helpers" +import * as utils from "../helpers/utils" +let registryContract: any, operatorIDs: any, shares: any, owner: any +const numberOfOperators = 6 +const operatorFee = 1 + +describe("Balance Tests", () => { + beforeEach(async () => { + const contractData = await helpers.initializeContract(numberOfOperators, operatorFee) + registryContract = contractData.contract + operatorIDs = contractData.operatorIDs + shares = contractData.shares + owner = contractData.owner + }) + + it("Check balances", async () => { + // // Register 1000 validators + // const validatorPK = `0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100` + + // expect(await registryContract.operatorEarningsOf(1)).to.equal('0') + + // // Register a validator + // const validator1 = (await (await registryContract.registerValidator( + // [1, 2, 3, 4], + // `${validatorPK}0`, + // shares[0], + // "10000" + // )).wait()).logs[0] + // let interfaceRegister = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId, bytes shares)']); + // const outputRegister = interfaceRegister.decodeEventLog('ValidatorAdded', validator1.data, validator1.topics); + + // // Progress 50 blocks and check operator balances and group balance + // await utils.progressBlocks(50) + // expect(await registryContract.operatorEarningsOf(1)).to.equal('50') + // expect(await registryContract.operatorEarningsOf(2)).to.equal('50') + // expect(await registryContract.operatorEarningsOf(3)).to.equal('50') + // expect(await registryContract.operatorEarningsOf(4)).to.equal('50') + // expect(await registryContract.groupBalanceOf(owner.address, outputRegister.groupId)).to.equal(10000 - 150) + + // // Update one of the operator fees + // await registryContract.updateOperatorFee(1, 10) + + // // Progress 50 blocks and check operator balances and group balance + // await utils.progressBlocks(50) + // expect(await registryContract.operatorEarningsOf(1)).to.equal('551') + // expect(await registryContract.operatorEarningsOf(2)).to.equal('101') + // expect(await registryContract.operatorEarningsOf(3)).to.equal('101') + // expect(await registryContract.operatorEarningsOf(4)).to.equal('101') + // expect(await registryContract.groupBalanceOf(owner.address, outputRegister.groupId)).to.equal(10000 - 904) + + // // Update 3 operator fees + // await registryContract.updateOperatorFee(2, 20) + // await registryContract.updateOperatorFee(3, 20) + // await registryContract.updateOperatorFee(4, 20) + + // // Progress 50 blocks and check operator balances and group balance + // await utils.progressBlocks(50) + // expect(await registryContract.operatorEarningsOf(1)).to.equal('1081') + // expect(await registryContract.operatorEarningsOf(2)).to.equal('1142') + // expect(await registryContract.operatorEarningsOf(3)).to.equal('1123') + // expect(await registryContract.operatorEarningsOf(4)).to.equal('1104') + // expect(await registryContract.groupBalanceOf(owner.address, outputRegister.groupId)).to.equal(10000 - 4500) + + // // Add another validator + // await registryContract.registerValidator( + // [1, 2, 3, 5], + // `${validatorPK}1`, + // shares[1], + // "10000" + // ) + + // // Progress 50 blocks and check operator balances and group balance + // await utils.progressBlocks(50) + // expect(await registryContract.operatorEarningsOf(1)).to.equal('2091') + // expect(await registryContract.operatorEarningsOf(2)).to.equal('3162') + // expect(await registryContract.operatorEarningsOf(3)).to.equal('3143') + // expect(await registryContract.operatorEarningsOf(4)).to.equal('2124') + // expect(await registryContract.operatorEarningsOf(5)).to.equal('5000') + // expect(await registryContract.groupBalanceOf(owner.address, outputRegister.groupId)).to.equal(10000 - 4500) + + // // Remove an operator + // await registryContract.removeOperator(1) + + // // Progress 50 blocks and check operator balances and group balance + // await utils.progressBlocks(50) + // expect(await registryContract.operatorEarningsOf(1)).to.equal('2091') + // expect(await registryContract.operatorEarningsOf(2)).to.equal('3162') + // expect(await registryContract.operatorEarningsOf(3)).to.equal('3143') + // expect(await registryContract.operatorEarningsOf(4)).to.equal('2124') + // expect(await registryContract.operatorEarningsOf(5)).to.equal('5000') + // expect(await registryContract.groupBalanceOf(owner.address, outputRegister.groupId)).to.equal(10000 - 4500) + + // // Update a validator + // await registryContract.updateValidator( + // [1, 2, 3, 5], + // `${validatorPK}0`, + // shares[1], + // "10" + // ) + + // // Progress 50 blocks and check operator balances and group balance + // await utils.progressBlocks(50) + // expect(await registryContract.operatorEarningsOf(1)).to.equal('2091') + // expect(await registryContract.operatorEarningsOf(2)).to.equal('3162') + // expect(await registryContract.operatorEarningsOf(3)).to.equal('3143') + // expect(await registryContract.operatorEarningsOf(4)).to.equal('2124') + // expect(await registryContract.operatorEarningsOf(5)).to.equal('5000') + // expect(await registryContract.groupBalanceOf(owner.address, outputRegister.groupId)).to.equal(10000 - 4500) + + // // Remove a validator + // await registryContract.removeValidator(`${validatorPK}0`, outputRegister.groupId) + + // // Progress 50 blocks and check operator balances and group balance + // await utils.progressBlocks(50) + // expect(await registryContract.operatorEarningsOf(1)).to.equal('2091') + // expect(await registryContract.operatorEarningsOf(2)).to.equal('3162') + // expect(await registryContract.operatorEarningsOf(3)).to.equal('3143') + // expect(await registryContract.operatorEarningsOf(4)).to.equal('2124') + // expect(await registryContract.operatorEarningsOf(5)).to.equal('5000') + // expect(await registryContract.groupBalanceOf(owner.address, outputRegister.groupId)).to.equal(10000 - 4500) + }) + +}); diff --git a/test/sanity/stress.ts b/test/sanity/stress.ts new file mode 100644 index 00000000..d7ff8879 --- /dev/null +++ b/test/sanity/stress.ts @@ -0,0 +1,51 @@ +const { expect } = require("chai"); +declare const ethers: any + +import * as helpers from "../helpers/contract-helpers" +let registryContract: any, operatorIDs: any, shares: any +const numberOfOperators = 1000 +const operatorFee = 1 +let validatorData: any = [] + +describe("Stress Tests", () => { + beforeEach(async () => { + const contractData = await helpers.initializeContract(numberOfOperators, operatorFee) + registryContract = contractData.contract + operatorIDs = contractData.operatorIDs + shares = contractData.shares + + // Register 1000 validators + validatorData = await helpers.registerValidators(1000, '10000', numberOfOperators, registryContract) + }) + + it("Update 1000 operators", async () => { + for (let i = 0; i < operatorIDs.length; i++) { + await registryContract.updateOperatorFee(operatorIDs[i], 10) + } + }) + + it("Update 1000 validators", async () => { + for (let i = 1000; i < (validatorData.length + 1000); i++) { + const randomOperator = Math.floor(Math.random() * (numberOfOperators - 4)) + await registryContract.updateValidator( + [randomOperator, randomOperator + 1, randomOperator + 2, randomOperator + 3], + validatorData[i-1000].publicKey, + shares[1], + "10001" + ) + } + }) + + it("Remove 1000 operators", async () => { + for (let i = 0; i < operatorIDs.length; i++) { + await registryContract.removeOperator(operatorIDs[i]) + } + }) + + it("Remove 1000 validators", async () => { + for (let i = 0; i < validatorData.length; i++) { + await registryContract.removeValidator(validatorData[i].publicKey) + } + }) + +}); \ No newline at end of file diff --git a/tests/vadimToUpdate.js b/test/vadimToUpdate.js similarity index 100% rename from tests/vadimToUpdate.js rename to test/vadimToUpdate.js diff --git a/test/validators/gas/1-operator-different.ts b/test/validators/gas/1-operator-different.ts new file mode 100644 index 00000000..64ac80df --- /dev/null +++ b/test/validators/gas/1-operator-different.ts @@ -0,0 +1,34 @@ +const { expect } = require("chai"); + +import * as helpers from "../../helpers/contract-helpers" +let registryContract: any, operatorIDs: any, shares: any, owner: any +const numberOfOperators = 4 +const operatorFee = 4 + +describe("Register Validator Gas Tests 1 Operator Different", () => { + beforeEach(async () => { + const contractData = await helpers.initializeContract(numberOfOperators, operatorFee) + registryContract = contractData.contract + operatorIDs = contractData.operatorIDs + shares = contractData.shares + }) + + it("1 Operator Different", async () => { + const validatorPK = `0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100` + + await registryContract.registerValidator( + [1, 2, 3, 4], + `${validatorPK}0`, + shares[0], + "10000" + ) + + await registryContract.registerValidator( + [1, 2, 3, 5], + `${validatorPK}1`, + shares[1], + "10000" + ) + }) + +}); diff --git a/test/validators/gas/2-operator-different.ts b/test/validators/gas/2-operator-different.ts new file mode 100644 index 00000000..8719fc1b --- /dev/null +++ b/test/validators/gas/2-operator-different.ts @@ -0,0 +1,34 @@ +const { expect } = require("chai"); + +import * as helpers from "../../helpers/contract-helpers" +let registryContract: any, operatorIDs: any, shares: any, owner: any +const numberOfOperators = 4 +const operatorFee = 4 + +describe("Register Validator Gas Tests 2 Operator Different", () => { + beforeEach(async () => { + const contractData = await helpers.initializeContract(numberOfOperators, operatorFee) + registryContract = contractData.contract + operatorIDs = contractData.operatorIDs + shares = contractData.shares + }) + + it("2 Operator Different", async () => { + const validatorPK = `0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100` + + await registryContract.registerValidator( + [1, 2, 3, 4], + `${validatorPK}0`, + shares[0], + "10000" + ) + + await registryContract.registerValidator( + [1, 2, 5, 6], + `${validatorPK}1`, + shares[1], + "10000" + ) + }) + +}); diff --git a/test/validators/gas/3-operator-different.ts b/test/validators/gas/3-operator-different.ts new file mode 100644 index 00000000..a2e30c48 --- /dev/null +++ b/test/validators/gas/3-operator-different.ts @@ -0,0 +1,34 @@ +const { expect } = require("chai"); + +import * as helpers from "../../helpers/contract-helpers" +let registryContract: any, operatorIDs: any, shares: any, owner: any +const numberOfOperators = 4 +const operatorFee = 4 + +describe("Register Validator Gas Tests 3 Operator Different", () => { + beforeEach(async () => { + const contractData = await helpers.initializeContract(numberOfOperators, operatorFee) + registryContract = contractData.contract + operatorIDs = contractData.operatorIDs + shares = contractData.shares + }) + + it("3 Operator Different", async () => { + const validatorPK = `0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100` + + await registryContract.registerValidator( + [1, 2, 3, 4], + `${validatorPK}0`, + shares[0], + "10000" + ) + + await registryContract.registerValidator( + [1, 5, 6, 7], + `${validatorPK}1`, + shares[1], + "10000" + ) + }) + +}); diff --git a/test/validators/gas/4-operator-different.ts b/test/validators/gas/4-operator-different.ts new file mode 100644 index 00000000..a779d42e --- /dev/null +++ b/test/validators/gas/4-operator-different.ts @@ -0,0 +1,34 @@ +const { expect } = require("chai"); + +import * as helpers from "../../helpers/contract-helpers" +let registryContract: any, operatorIDs: any, shares: any, owner: any +const numberOfOperators = 4 +const operatorFee = 4 + +describe("Register Validator Gas Tests 3 Operator Different", () => { + beforeEach(async () => { + const contractData = await helpers.initializeContract(numberOfOperators, operatorFee) + registryContract = contractData.contract + operatorIDs = contractData.operatorIDs + shares = contractData.shares + }) + + it("3 Operator Different", async () => { + const validatorPK = `0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100` + + await registryContract.registerValidator( + [1, 2, 3, 4], + `${validatorPK}0`, + shares[0], + "10000" + ) + + await registryContract.registerValidator( + [5, 6, 7, 8], + `${validatorPK}1`, + shares[1], + "10000" + ) + }) + +}); diff --git a/test/validators/gas/different-group.ts b/test/validators/gas/different-group.ts new file mode 100644 index 00000000..2919d7c5 --- /dev/null +++ b/test/validators/gas/different-group.ts @@ -0,0 +1,34 @@ +const { expect } = require("chai"); + +import * as helpers from "../../helpers/contract-helpers" +let registryContract: any, operatorIDs: any, shares: any, owner: any +const numberOfOperators = 4 +const operatorFee = 4 + +describe("Register Validator Gas Tests Different Group", () => { + beforeEach(async () => { + const contractData = await helpers.initializeContract(numberOfOperators, operatorFee) + registryContract = contractData.contract + operatorIDs = contractData.operatorIDs + shares = contractData.shares + }) + + it("Different group", async () => { + const validatorPK = `0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100` + + await registryContract.registerValidator( + [1, 2, 3, 4], + `${validatorPK}0`, + shares[0], + "10000" + ) + + await registryContract.registerValidator( + [5, 6, 7, 8], + `${validatorPK}1`, + shares[1], + "10000" + ) + }) + +}); diff --git a/test/validators/gas/same-group.ts b/test/validators/gas/same-group.ts new file mode 100644 index 00000000..44f1166d --- /dev/null +++ b/test/validators/gas/same-group.ts @@ -0,0 +1,34 @@ +const { expect } = require("chai"); + +import * as helpers from "../../helpers/contract-helpers" +let registryContract: any, operatorIDs: any, shares: any, owner: any +const numberOfOperators = 4 +const operatorFee = 4 + +describe("Register Validator Gas Tests Same Group", () => { + beforeEach(async () => { + const contractData = await helpers.initializeContract(numberOfOperators, operatorFee) + registryContract = contractData.contract + operatorIDs = contractData.operatorIDs + shares = contractData.shares + }) + + it("Same group", async () => { + const validatorPK = `0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100` + + await registryContract.registerValidator( + [1, 2, 3, 4], + `${validatorPK}0`, + shares[0], + "10000" + ) + + await registryContract.registerValidator( + [1, 2, 3, 4], + `${validatorPK}1`, + shares[1], + "10000" + ) + }) + +}); diff --git a/test/validators/register.ts b/test/validators/register.ts new file mode 100644 index 00000000..040b7a07 --- /dev/null +++ b/test/validators/register.ts @@ -0,0 +1,29 @@ +const { expect } = require("chai"); + +import * as helpers from "../helpers/contract-helpers" +let registryContract: any, operatorIDs: any, shares: any, owner: any +const numberOfOperators = 4 +const operatorFee = 4 + +describe("Register Validator Tests", () => { + beforeEach(async () => { + const contractData = await helpers.initializeContract(numberOfOperators, operatorFee) + registryContract = contractData.contract + operatorIDs = contractData.operatorIDs + shares = contractData.shares + }) + + it("Register validator", async () => { + const validatorPK = `0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100` + await registryContract.registerValidator( + [1, 2, 3, 4], + `${validatorPK}0`, + shares[0], + "10000" + ) + }) + + it("Register validator errors", async () => { + + }) +}); \ No newline at end of file diff --git a/test/validators/remove.ts b/test/validators/remove.ts new file mode 100644 index 00000000..ccffbdc3 --- /dev/null +++ b/test/validators/remove.ts @@ -0,0 +1,28 @@ +const { expect } = require("chai"); + +import * as helpers from "../helpers/contract-helpers" +let registryContract: any, operatorIDs: any, shares: any, owner: any +const numberOfOperators = 4 +const operatorFee = 4 + +describe("Remove Validator Tests", () => { + beforeEach(async () => { + const contractData = await helpers.initializeContract(numberOfOperators, operatorFee) + registryContract = contractData.contract + operatorIDs = contractData.operatorIDs + shares = contractData.shares + }) + + it("Remove validator", async () => { + + }) + + it("Remove validator errors", async () => { + + }) + + it("Remove Validator gas limits", async () => { + + }) + +}); diff --git a/test/validators/update.ts b/test/validators/update.ts new file mode 100644 index 00000000..72c22082 --- /dev/null +++ b/test/validators/update.ts @@ -0,0 +1,28 @@ +const { expect } = require("chai"); + +import * as helpers from "../helpers/contract-helpers" +let registryContract: any, operatorIDs: any, shares: any, owner: any +const numberOfOperators = 4 +const operatorFee = 4 + +describe("Update Validator Tests", () => { + beforeEach(async () => { + const contractData = await helpers.initializeContract(numberOfOperators, operatorFee) + registryContract = contractData.contract + operatorIDs = contractData.operatorIDs + shares = contractData.shares + }) + + it("Update validator", async () => { + + }) + + it("Update validator errors", async () => { + + }) + + it("Update Validator gas limits", async () => { + + }) + +}); diff --git a/tests/account/deposit.js b/tests/account/deposit.js deleted file mode 100644 index 44b10e6d..00000000 --- a/tests/account/deposit.js +++ /dev/null @@ -1,38 +0,0 @@ -const { expect } = require("chai"); -const operator_fee_block = 1; - -const operatorsIndexes = Array.from(Array(8).keys()).map(k => k + 1); -let sharePKs, encryptedShares - -describe("Deposit Test", () => { - var deployedRegistryContract - beforeEach(async () => { - const Registry = await ethers.getContractFactory("SSVRegistryNew"); - deployedRegistryContract = await Registry.deploy(); - await deployedRegistryContract.deployed(); - - // Create 4 operators - for (let i = 0; i < operatorsIndexes.length; i++) { - const encryptionPK = "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002644c5330744c5331435255644a54694253553045675546564354456c4449457446575330744c533074436b314a53554a4a616b464f516d64726357687261556335647a424351564646526b464254304e425554684254556c4a516b4e6e53304e42555556424e5756554e557777563068365a54647954575a506232787456484d4b64577449513245344b336474625577324f54464a5131527052454531556b4a31546b787153565132576b4530597a4d78635652495933464256486c3565566b774c7a6b3352336c4b5a32646f596e6c465232526f5a516f76616c6836615756544f584a325279744a56474631516a684d566c686b656b78475956517857455a5765466c6e4e327832546c42344f5552504c315a6f526b686b5757786e54334932643052745633466a52476f33436c68575557464f57454674526e67334e6a56514e546c584e585a7a564752585657464852577858536d3933536b5a4b646e6332556c5249536b5a315456686a537a5a5661574a3063555a4d536d4a774f57356b6455674b516a6c4c537a4e57636d59725a6d744a4f5752425a327478524446484f456c785130744b4d566c33626a557965477878625452434e69744f4f475a555a45314d53314a75635770465a6d527a563164774d46567a4d51704c54573976535863796333426f6158417a5546704e596e4a61615530774e6a4a325a556f3055336f76596a424f62576450546e685464304a4a546e4e7863473534516a68465556517853544e6a4e6b6c714e586868436d35525355524255554643436930744c5330745255354549464a545153425156554a4d53554d675330565a4c5330744c53304b00000000000000000000000000000000000000000000000000000000"; - await deployedRegistryContract.registerOperator(encryptionPK, operator_fee_block); - } - sharePKs = Array.from(Array(10).keys()).map(k => `0xa20a622ecbc816c89896f92a18214905a57beedbe8df6120ba644453a7e35672a365c3b73ce35b8738eeb5dade9107d${k}`); - encryptedShares = Array.from(Array(10).keys()).map(k => `0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000158513741566f733037584a4537767275644b366c7a647a76634143313563636b5152492b6143766f31617a374979787a517233506a4361632b545745394d45307a4f6d49${k}36947472f46312f38613556786d71383948366e6b71436130415573782b37326c43306f686a4b3874396853746953746732596e2b304d2f4e3732744c6d5951394c325976654c56564a35556c586a425777${k}4377a5537732f3142435653727862415431376f2f704858474c46644170697a4c5332704b48354b71746545786e3033566b4a4244527538596c5055334634656c554937697a667a474444626d49677536484862305777344669743745543745422f357056457a547279445a5179516753336a4858714d63637359396e52494250724f2f2f367370544736646e5831304e4872356b716a305136464b64684d6a4162644d43773966527274672b72766979584e6674464945445478304768314f513d3d0000000000000000`); - - await deployedRegistryContract.deposit("100000000000") - - }) - - it("Deposit", async () => { - - }) - - it("Deposit errors", async () => { - - }) - - it("Deposit gas limits", async () => { - - }) - -}); diff --git a/tests/account/withdraw.js b/tests/account/withdraw.js deleted file mode 100644 index c3601d1d..00000000 --- a/tests/account/withdraw.js +++ /dev/null @@ -1,38 +0,0 @@ -const { expect } = require("chai"); -const operator_fee_block = 1; - -const operatorsIndexes = Array.from(Array(8).keys()).map(k => k + 1); -let sharePKs, encryptedShares - -describe("Withdraw Test", () => { - var deployedRegistryContract - beforeEach(async () => { - const Registry = await ethers.getContractFactory("SSVRegistryNew"); - deployedRegistryContract = await Registry.deploy(); - await deployedRegistryContract.deployed(); - - // Create 4 operators - for (let i = 0; i < operatorsIndexes.length; i++) { - const encryptionPK = "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002644c5330744c5331435255644a54694253553045675546564354456c4449457446575330744c533074436b314a53554a4a616b464f516d64726357687261556335647a424351564646526b464254304e425554684254556c4a516b4e6e53304e42555556424e5756554e557777563068365a54647954575a506232787456484d4b64577449513245344b336474625577324f54464a5131527052454531556b4a31546b787153565132576b4530597a4d78635652495933464256486c3565566b774c7a6b3352336c4b5a32646f596e6c465232526f5a516f76616c6836615756544f584a325279744a56474631516a684d566c686b656b78475956517857455a5765466c6e4e327832546c42344f5552504c315a6f526b686b5757786e54334932643052745633466a52476f33436c68575557464f57454674526e67334e6a56514e546c584e585a7a564752585657464852577858536d3933536b5a4b646e6332556c5249536b5a315456686a537a5a5661574a3063555a4d536d4a774f57356b6455674b516a6c4c537a4e57636d59725a6d744a4f5752425a327478524446484f456c785130744b4d566c33626a557965477878625452434e69744f4f475a555a45314d53314a75635770465a6d527a563164774d46567a4d51704c54573976535863796333426f6158417a5546704e596e4a61615530774e6a4a325a556f3055336f76596a424f62576450546e685464304a4a546e4e7863473534516a68465556517853544e6a4e6b6c714e586868436d35525355524255554643436930744c5330745255354549464a545153425156554a4d53554d675330565a4c5330744c53304b00000000000000000000000000000000000000000000000000000000"; - await deployedRegistryContract.registerOperator(encryptionPK, operator_fee_block); - } - sharePKs = Array.from(Array(10).keys()).map(k => `0xa20a622ecbc816c89896f92a18214905a57beedbe8df6120ba644453a7e35672a365c3b73ce35b8738eeb5dade9107d${k}`); - encryptedShares = Array.from(Array(10).keys()).map(k => `0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000158513741566f733037584a4537767275644b366c7a647a76634143313563636b5152492b6143766f31617a374979787a517233506a4361632b545745394d45307a4f6d49${k}36947472f46312f38613556786d71383948366e6b71436130415573782b37326c43306f686a4b3874396853746953746732596e2b304d2f4e3732744c6d5951394c325976654c56564a35556c586a425777${k}4377a5537732f3142435653727862415431376f2f704858474c46644170697a4c5332704b48354b71746545786e3033566b4a4244527538596c5055334634656c554937697a667a474444626d49677536484862305777344669743745543745422f357056457a547279445a5179516753336a4858714d63637359396e52494250724f2f2f367370544736646e5831304e4872356b716a305136464b64684d6a4162644d43773966527274672b72766979584e6674464945445478304768314f513d3d0000000000000000`); - - await deployedRegistryContract.deposit("100000000000") - - }) - - it("Withdraw", async () => { - - }) - - it("Withdraw errors", async () => { - - }) - - it("Withdraw gas limits", async () => { - - }) - -}); diff --git a/tests/dao/networkFeeChange.js b/tests/dao/networkFeeChange.js deleted file mode 100644 index 70f45b66..00000000 --- a/tests/dao/networkFeeChange.js +++ /dev/null @@ -1,38 +0,0 @@ -const { expect } = require("chai"); -const operator_fee_block = 1; - -const operatorsIndexes = Array.from(Array(8).keys()).map(k => k + 1); -let sharePKs, encryptedShares - -describe("Change Network Fee Test", () => { - var deployedRegistryContract - beforeEach(async () => { - const Registry = await ethers.getContractFactory("SSVRegistryNew"); - deployedRegistryContract = await Registry.deploy(); - await deployedRegistryContract.deployed(); - - // Create 4 operators - for (let i = 0; i < operatorsIndexes.length; i++) { - const encryptionPK = "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002644c5330744c5331435255644a54694253553045675546564354456c4449457446575330744c533074436b314a53554a4a616b464f516d64726357687261556335647a424351564646526b464254304e425554684254556c4a516b4e6e53304e42555556424e5756554e557777563068365a54647954575a506232787456484d4b64577449513245344b336474625577324f54464a5131527052454531556b4a31546b787153565132576b4530597a4d78635652495933464256486c3565566b774c7a6b3352336c4b5a32646f596e6c465232526f5a516f76616c6836615756544f584a325279744a56474631516a684d566c686b656b78475956517857455a5765466c6e4e327832546c42344f5552504c315a6f526b686b5757786e54334932643052745633466a52476f33436c68575557464f57454674526e67334e6a56514e546c584e585a7a564752585657464852577858536d3933536b5a4b646e6332556c5249536b5a315456686a537a5a5661574a3063555a4d536d4a774f57356b6455674b516a6c4c537a4e57636d59725a6d744a4f5752425a327478524446484f456c785130744b4d566c33626a557965477878625452434e69744f4f475a555a45314d53314a75635770465a6d527a563164774d46567a4d51704c54573976535863796333426f6158417a5546704e596e4a61615530774e6a4a325a556f3055336f76596a424f62576450546e685464304a4a546e4e7863473534516a68465556517853544e6a4e6b6c714e586868436d35525355524255554643436930744c5330745255354549464a545153425156554a4d53554d675330565a4c5330744c53304b00000000000000000000000000000000000000000000000000000000"; - await deployedRegistryContract.registerOperator(encryptionPK, operator_fee_block); - } - sharePKs = Array.from(Array(10).keys()).map(k => `0xa20a622ecbc816c89896f92a18214905a57beedbe8df6120ba644453a7e35672a365c3b73ce35b8738eeb5dade9107d${k}`); - encryptedShares = Array.from(Array(10).keys()).map(k => `0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000158513741566f733037584a4537767275644b366c7a647a76634143313563636b5152492b6143766f31617a374979787a517233506a4361632b545745394d45307a4f6d49${k}36947472f46312f38613556786d71383948366e6b71436130415573782b37326c43306f686a4b3874396853746953746732596e2b304d2f4e3732744c6d5951394c325976654c56564a35556c586a425777${k}4377a5537732f3142435653727862415431376f2f704858474c46644170697a4c5332704b48354b71746545786e3033566b4a4244527538596c5055334634656c554937697a667a474444626d49677536484862305777344669743745543745422f357056457a547279445a5179516753336a4858714d63637359396e52494250724f2f2f367370544736646e5831304e4872356b716a305136464b64684d6a4162644d43773966527274672b72766979584e6674464945445478304768314f513d3d0000000000000000`); - - await deployedRegistryContract.deposit("100000000000") - - }) - - it("Get network fee", async () => { - - }) - - it("Change network fee", async () => { - - }) - - it("Change network fee errors", async () => { - - }) - -}); diff --git a/tests/dao/networkFeeWithdraw.js b/tests/dao/networkFeeWithdraw.js deleted file mode 100644 index bff431aa..00000000 --- a/tests/dao/networkFeeWithdraw.js +++ /dev/null @@ -1,38 +0,0 @@ -const { expect } = require("chai"); -const operator_fee_block = 1; - -const operatorsIndexes = Array.from(Array(8).keys()).map(k => k + 1); -let sharePKs, encryptedShares - -describe("Withdraw Network Fee Test", () => { - var deployedRegistryContract - beforeEach(async () => { - const Registry = await ethers.getContractFactory("SSVRegistryNew"); - deployedRegistryContract = await Registry.deploy(); - await deployedRegistryContract.deployed(); - - // Create 4 operators - for (let i = 0; i < operatorsIndexes.length; i++) { - const encryptionPK = "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002644c5330744c5331435255644a54694253553045675546564354456c4449457446575330744c533074436b314a53554a4a616b464f516d64726357687261556335647a424351564646526b464254304e425554684254556c4a516b4e6e53304e42555556424e5756554e557777563068365a54647954575a506232787456484d4b64577449513245344b336474625577324f54464a5131527052454531556b4a31546b787153565132576b4530597a4d78635652495933464256486c3565566b774c7a6b3352336c4b5a32646f596e6c465232526f5a516f76616c6836615756544f584a325279744a56474631516a684d566c686b656b78475956517857455a5765466c6e4e327832546c42344f5552504c315a6f526b686b5757786e54334932643052745633466a52476f33436c68575557464f57454674526e67334e6a56514e546c584e585a7a564752585657464852577858536d3933536b5a4b646e6332556c5249536b5a315456686a537a5a5661574a3063555a4d536d4a774f57356b6455674b516a6c4c537a4e57636d59725a6d744a4f5752425a327478524446484f456c785130744b4d566c33626a557965477878625452434e69744f4f475a555a45314d53314a75635770465a6d527a563164774d46567a4d51704c54573976535863796333426f6158417a5546704e596e4a61615530774e6a4a325a556f3055336f76596a424f62576450546e685464304a4a546e4e7863473534516a68465556517853544e6a4e6b6c714e586868436d35525355524255554643436930744c5330745255354549464a545153425156554a4d53554d675330565a4c5330744c53304b00000000000000000000000000000000000000000000000000000000"; - await deployedRegistryContract.registerOperator(encryptionPK, operator_fee_block); - } - sharePKs = Array.from(Array(10).keys()).map(k => `0xa20a622ecbc816c89896f92a18214905a57beedbe8df6120ba644453a7e35672a365c3b73ce35b8738eeb5dade9107d${k}`); - encryptedShares = Array.from(Array(10).keys()).map(k => `0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000158513741566f733037584a4537767275644b366c7a647a76634143313563636b5152492b6143766f31617a374979787a517233506a4361632b545745394d45307a4f6d49${k}36947472f46312f38613556786d71383948366e6b71436130415573782b37326c43306f686a4b3874396853746953746732596e2b304d2f4e3732744c6d5951394c325976654c56564a35556c586a425777${k}4377a5537732f3142435653727862415431376f2f704858474c46644170697a4c5332704b48354b71746545786e3033566b4a4244527538596c5055334634656c554937697a667a474444626d49677536484862305777344669743745543745422f357056457a547279445a5179516753336a4858714d63637359396e52494250724f2f2f367370544736646e5831304e4872356b716a305136464b64684d6a4162644d43773966527274672b72766979584e6674464945445478304768314f513d3d0000000000000000`); - - await deployedRegistryContract.deposit("100000000000") - - }) - - it("Get withdrawable network fee amount", async () => { - - }) - - it("Withdraw network fee", async () => { - - }) - - it("Withdraw network fee errors", async () => { - - }) - -}); diff --git a/tests/liquidate/liquidate.js b/tests/liquidate/liquidate.js deleted file mode 100644 index 6d73cecc..00000000 --- a/tests/liquidate/liquidate.js +++ /dev/null @@ -1,42 +0,0 @@ -const { expect } = require("chai"); -const operator_fee_block = 1; - -const operatorsIndexes = Array.from(Array(8).keys()).map(k => k + 1); -let sharePKs, encryptedShares - -describe("Liquidate Test", () => { - var deployedRegistryContract - beforeEach(async () => { - const Registry = await ethers.getContractFactory("SSVRegistryNew"); - deployedRegistryContract = await Registry.deploy(); - await deployedRegistryContract.deployed(); - - // Create 4 operators - for (let i = 0; i < operatorsIndexes.length; i++) { - const encryptionPK = "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002644c5330744c5331435255644a54694253553045675546564354456c4449457446575330744c533074436b314a53554a4a616b464f516d64726357687261556335647a424351564646526b464254304e425554684254556c4a516b4e6e53304e42555556424e5756554e557777563068365a54647954575a506232787456484d4b64577449513245344b336474625577324f54464a5131527052454531556b4a31546b787153565132576b4530597a4d78635652495933464256486c3565566b774c7a6b3352336c4b5a32646f596e6c465232526f5a516f76616c6836615756544f584a325279744a56474631516a684d566c686b656b78475956517857455a5765466c6e4e327832546c42344f5552504c315a6f526b686b5757786e54334932643052745633466a52476f33436c68575557464f57454674526e67334e6a56514e546c584e585a7a564752585657464852577858536d3933536b5a4b646e6332556c5249536b5a315456686a537a5a5661574a3063555a4d536d4a774f57356b6455674b516a6c4c537a4e57636d59725a6d744a4f5752425a327478524446484f456c785130744b4d566c33626a557965477878625452434e69744f4f475a555a45314d53314a75635770465a6d527a563164774d46567a4d51704c54573976535863796333426f6158417a5546704e596e4a61615530774e6a4a325a556f3055336f76596a424f62576450546e685464304a4a546e4e7863473534516a68465556517853544e6a4e6b6c714e586868436d35525355524255554643436930744c5330745255354549464a545153425156554a4d53554d675330565a4c5330744c53304b00000000000000000000000000000000000000000000000000000000"; - await deployedRegistryContract.registerOperator(encryptionPK, operator_fee_block); - } - sharePKs = Array.from(Array(10).keys()).map(k => `0xa20a622ecbc816c89896f92a18214905a57beedbe8df6120ba644453a7e35672a365c3b73ce35b8738eeb5dade9107d${k}`); - encryptedShares = Array.from(Array(10).keys()).map(k => `0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000158513741566f733037584a4537767275644b366c7a647a76634143313563636b5152492b6143766f31617a374979787a517233506a4361632b545745394d45307a4f6d49${k}36947472f46312f38613556786d71383948366e6b71436130415573782b37326c43306f686a4b3874396853746953746732596e2b304d2f4e3732744c6d5951394c325976654c56564a35556c586a425777${k}4377a5537732f3142435653727862415431376f2f704858474c46644170697a4c5332704b48354b71746545786e3033566b4a4244527538596c5055334634656c554937697a667a474444626d49677536484862305777344669743745543745422f357056457a547279445a5179516753336a4858714d63637359396e52494250724f2f2f367370544736646e5831304e4872356b716a305136464b64684d6a4162644d43773966527274672b72766979584e6674464945445478304768314f513d3d0000000000000000`); - - await deployedRegistryContract.deposit("100000000000") - - }) - - it("Liquidatable", async () => { - - }) - - it("Liquidate", async () => { - - }) - - it("Liquidate errors", async () => { - - }) - - it("Liquidate gas limits", async () => { - - }) - -}); diff --git a/tests/liquidate/liquidationThreshold.js b/tests/liquidate/liquidationThreshold.js deleted file mode 100644 index 54dfdfd7..00000000 --- a/tests/liquidate/liquidationThreshold.js +++ /dev/null @@ -1,42 +0,0 @@ -const { expect } = require("chai"); -const operator_fee_block = 1; - -const operatorsIndexes = Array.from(Array(8).keys()).map(k => k + 1); -let sharePKs, encryptedShares - -describe("Liquidation Threshold Test", () => { - var deployedRegistryContract - beforeEach(async () => { - const Registry = await ethers.getContractFactory("SSVRegistryNew"); - deployedRegistryContract = await Registry.deploy(); - await deployedRegistryContract.deployed(); - - // Create 4 operators - for (let i = 0; i < operatorsIndexes.length; i++) { - const encryptionPK = "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002644c5330744c5331435255644a54694253553045675546564354456c4449457446575330744c533074436b314a53554a4a616b464f516d64726357687261556335647a424351564646526b464254304e425554684254556c4a516b4e6e53304e42555556424e5756554e557777563068365a54647954575a506232787456484d4b64577449513245344b336474625577324f54464a5131527052454531556b4a31546b787153565132576b4530597a4d78635652495933464256486c3565566b774c7a6b3352336c4b5a32646f596e6c465232526f5a516f76616c6836615756544f584a325279744a56474631516a684d566c686b656b78475956517857455a5765466c6e4e327832546c42344f5552504c315a6f526b686b5757786e54334932643052745633466a52476f33436c68575557464f57454674526e67334e6a56514e546c584e585a7a564752585657464852577858536d3933536b5a4b646e6332556c5249536b5a315456686a537a5a5661574a3063555a4d536d4a774f57356b6455674b516a6c4c537a4e57636d59725a6d744a4f5752425a327478524446484f456c785130744b4d566c33626a557965477878625452434e69744f4f475a555a45314d53314a75635770465a6d527a563164774d46567a4d51704c54573976535863796333426f6158417a5546704e596e4a61615530774e6a4a325a556f3055336f76596a424f62576450546e685464304a4a546e4e7863473534516a68465556517853544e6a4e6b6c714e586868436d35525355524255554643436930744c5330745255354549464a545153425156554a4d53554d675330565a4c5330744c53304b00000000000000000000000000000000000000000000000000000000"; - await deployedRegistryContract.registerOperator(encryptionPK, operator_fee_block); - } - sharePKs = Array.from(Array(10).keys()).map(k => `0xa20a622ecbc816c89896f92a18214905a57beedbe8df6120ba644453a7e35672a365c3b73ce35b8738eeb5dade9107d${k}`); - encryptedShares = Array.from(Array(10).keys()).map(k => `0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000158513741566f733037584a4537767275644b366c7a647a76634143313563636b5152492b6143766f31617a374979787a517233506a4361632b545745394d45307a4f6d49${k}36947472f46312f38613556786d71383948366e6b71436130415573782b37326c43306f686a4b3874396853746953746732596e2b304d2f4e3732744c6d5951394c325976654c56564a35556c586a425777${k}4377a5537732f3142435653727862415431376f2f704858474c46644170697a4c5332704b48354b71746545786e3033566b4a4244527538596c5055334634656c554937697a667a474444626d49677536484862305777344669743745543745422f357056457a547279445a5179516753336a4858714d63637359396e52494250724f2f2f367370544736646e5831304e4872356b716a305136464b64684d6a4162644d43773966527274672b72766979584e6674464945445478304768314f513d3d0000000000000000`); - - await deployedRegistryContract.deposit("100000000000") - - }) - - it("Get liquidation threshold", async () => { - - }) - - it("Change liquidation threshold", async () => { - - }) - - it("Change liquidation threshold errors", async () => { - - }) - - it("Liquidation threshold gas limits", async () => { - - }) - -}); diff --git a/tests/operators/register.js b/tests/operators/register.js deleted file mode 100644 index 2a2ea826..00000000 --- a/tests/operators/register.js +++ /dev/null @@ -1,83 +0,0 @@ -const { expect } = require("chai"); -const operator_fee_block = 1; - -const operatorsIndexes = Array.from(Array(8).keys()).map(k => k + 1); -let sharePKs, encryptedShares - -describe("Register Operator Test", () => { - var deployedRegistryContract - beforeEach(async () => { - const Registry = await ethers.getContractFactory("SSVRegistryNew"); - deployedRegistryContract = await Registry.deploy(); - await deployedRegistryContract.deployed(); - - // Create 4 operators - for (let i = 0; i < operatorsIndexes.length; i++) { - const encryptionPK = "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002644c5330744c5331435255644a54694253553045675546564354456c4449457446575330744c533074436b314a53554a4a616b464f516d64726357687261556335647a424351564646526b464254304e425554684254556c4a516b4e6e53304e42555556424e5756554e557777563068365a54647954575a506232787456484d4b64577449513245344b336474625577324f54464a5131527052454531556b4a31546b787153565132576b4530597a4d78635652495933464256486c3565566b774c7a6b3352336c4b5a32646f596e6c465232526f5a516f76616c6836615756544f584a325279744a56474631516a684d566c686b656b78475956517857455a5765466c6e4e327832546c42344f5552504c315a6f526b686b5757786e54334932643052745633466a52476f33436c68575557464f57454674526e67334e6a56514e546c584e585a7a564752585657464852577858536d3933536b5a4b646e6332556c5249536b5a315456686a537a5a5661574a3063555a4d536d4a774f57356b6455674b516a6c4c537a4e57636d59725a6d744a4f5752425a327478524446484f456c785130744b4d566c33626a557965477878625452434e69744f4f475a555a45314d53314a75635770465a6d527a563164774d46567a4d51704c54573976535863796333426f6158417a5546704e596e4a61615530774e6a4a325a556f3055336f76596a424f62576450546e685464304a4a546e4e7863473534516a68465556517853544e6a4e6b6c714e586868436d35525355524255554643436930744c5330745255354549464a545153425156554a4d53554d675330565a4c5330744c53304b00000000000000000000000000000000000000000000000000000000"; - await deployedRegistryContract.registerOperator(encryptionPK, operator_fee_block); - } - sharePKs = Array.from(Array(10).keys()).map(k => `0xa20a622ecbc816c89896f92a18214905a57beedbe8df6120ba644453a7e35672a365c3b73ce35b8738eeb5dade9107d${k}`); - encryptedShares = Array.from(Array(10).keys()).map(k => `0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000158513741566f733037584a4537767275644b366c7a647a76634143313563636b5152492b6143766f31617a374979787a517233506a4361632b545745394d45307a4f6d49${k}36947472f46312f38613556786d71383948366e6b71436130415573782b37326c43306f686a4b3874396853746953746732596e2b304d2f4e3732744c6d5951394c325976654c56564a35556c586a425777${k}4377a5537732f3142435653727862415431376f2f704858474c46644170697a4c5332704b48354b71746545786e3033566b4a4244527538596c5055334634656c554937697a667a474444626d49677536484862305777344669743745543745422f357056457a547279445a5179516753336a4858714d63637359396e52494250724f2f2f367370544736646e5831304e4872356b716a305136464b64684d6a4162644d43773966527274672b72766979584e6674464945445478304768314f513d3d0000000000000000`); - - await deployedRegistryContract.deposit("100000000000") - - }) - - it("Register operator", async () => { - - }) - - it("Register operator errors", async () => { - - }) - - it("Register operator gas limits", async () => { - const validatorPK = `0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100` - - // Cost: 364101 - await deployedRegistryContract.registerValidator( - [1, 2, 3, 4], - `${validatorPK}0`, - sharePKs.slice(0, 4), - encryptedShares.slice(0, 4), - "10000" - ) - - // // Cost: 185380 - // await deployedRegistryContract.registerValidator( - // [1, 2, 3, 4], - // `${validatorPK}1`, - // sharePKs.slice(0, 4), - // encryptedShares.slice(0, 4), - // "10000" - // ) - - // Cost: 295713 - await deployedRegistryContract.registerValidator( - [1, 2, 5, 6], - `${validatorPK}1`, - sharePKs.slice(0, 4), - encryptedShares.slice(0, 4), - "10000" - ) - - // // Cost: 312813 - // await deployedRegistryContract.registerValidator( - // [1, 5, 6, 7], - // `${validatorPK}2`, - // sharePKs.slice(0, 4), - // encryptedShares.slice(0, 4), - // "10000" - // ) - - // // Cost: 329901 - // await deployedRegistryContract.registerValidator( - // [5, 6, 7, 8], - // `${validatorPK}0`, - // sharePKs.slice(0, 4), - // encryptedShares.slice(0, 4), - // "10000" - // ) - }) - -}); diff --git a/tests/operators/remove.js b/tests/operators/remove.js deleted file mode 100644 index 30aab00d..00000000 --- a/tests/operators/remove.js +++ /dev/null @@ -1,38 +0,0 @@ -const { expect } = require("chai"); -const operator_fee_block = 1; - -const operatorsIndexes = Array.from(Array(8).keys()).map(k => k + 1); -let sharePKs, encryptedShares - -describe("Remove Operator Test", () => { - var deployedRegistryContract - beforeEach(async () => { - const Registry = await ethers.getContractFactory("SSVRegistryNew"); - deployedRegistryContract = await Registry.deploy(); - await deployedRegistryContract.deployed(); - - // Create 4 operators - for (let i = 0; i < operatorsIndexes.length; i++) { - const encryptionPK = "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002644c5330744c5331435255644a54694253553045675546564354456c4449457446575330744c533074436b314a53554a4a616b464f516d64726357687261556335647a424351564646526b464254304e425554684254556c4a516b4e6e53304e42555556424e5756554e557777563068365a54647954575a506232787456484d4b64577449513245344b336474625577324f54464a5131527052454531556b4a31546b787153565132576b4530597a4d78635652495933464256486c3565566b774c7a6b3352336c4b5a32646f596e6c465232526f5a516f76616c6836615756544f584a325279744a56474631516a684d566c686b656b78475956517857455a5765466c6e4e327832546c42344f5552504c315a6f526b686b5757786e54334932643052745633466a52476f33436c68575557464f57454674526e67334e6a56514e546c584e585a7a564752585657464852577858536d3933536b5a4b646e6332556c5249536b5a315456686a537a5a5661574a3063555a4d536d4a774f57356b6455674b516a6c4c537a4e57636d59725a6d744a4f5752425a327478524446484f456c785130744b4d566c33626a557965477878625452434e69744f4f475a555a45314d53314a75635770465a6d527a563164774d46567a4d51704c54573976535863796333426f6158417a5546704e596e4a61615530774e6a4a325a556f3055336f76596a424f62576450546e685464304a4a546e4e7863473534516a68465556517853544e6a4e6b6c714e586868436d35525355524255554643436930744c5330745255354549464a545153425156554a4d53554d675330565a4c5330744c53304b00000000000000000000000000000000000000000000000000000000"; - await deployedRegistryContract.registerOperator(encryptionPK, operator_fee_block); - } - sharePKs = Array.from(Array(10).keys()).map(k => `0xa20a622ecbc816c89896f92a18214905a57beedbe8df6120ba644453a7e35672a365c3b73ce35b8738eeb5dade9107d${k}`); - encryptedShares = Array.from(Array(10).keys()).map(k => `0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000158513741566f733037584a4537767275644b366c7a647a76634143313563636b5152492b6143766f31617a374979787a517233506a4361632b545745394d45307a4f6d49${k}36947472f46312f38613556786d71383948366e6b71436130415573782b37326c43306f686a4b3874396853746953746732596e2b304d2f4e3732744c6d5951394c325976654c56564a35556c586a425777${k}4377a5537732f3142435653727862415431376f2f704858474c46644170697a4c5332704b48354b71746545786e3033566b4a4244527538596c5055334634656c554937697a667a474444626d49677536484862305777344669743745543745422f357056457a547279445a5179516753336a4858714d63637359396e52494250724f2f2f367370544736646e5831304e4872356b716a305136464b64684d6a4162644d43773966527274672b72766979584e6674464945445478304768314f513d3d0000000000000000`); - - await deployedRegistryContract.deposit("100000000000") - - }) - - it("Remove operator", async () => { - - }) - - it("Remove operator errors", async () => { - - }) - - it("Remove operator gas limits", async () => { - - }) - -}); diff --git a/tests/operators/update.js b/tests/operators/update.js deleted file mode 100644 index 487c76b6..00000000 --- a/tests/operators/update.js +++ /dev/null @@ -1,38 +0,0 @@ -const { expect } = require("chai"); -const operator_fee_block = 1; - -const operatorsIndexes = Array.from(Array(8).keys()).map(k => k + 1); -let sharePKs, encryptedShares - -describe("Remove Operator Test", () => { - var deployedRegistryContract - beforeEach(async () => { - const Registry = await ethers.getContractFactory("SSVRegistryNew"); - deployedRegistryContract = await Registry.deploy(); - await deployedRegistryContract.deployed(); - - // Create 4 operators - for (let i = 0; i < operatorsIndexes.length; i++) { - const encryptionPK = "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002644c5330744c5331435255644a54694253553045675546564354456c4449457446575330744c533074436b314a53554a4a616b464f516d64726357687261556335647a424351564646526b464254304e425554684254556c4a516b4e6e53304e42555556424e5756554e557777563068365a54647954575a506232787456484d4b64577449513245344b336474625577324f54464a5131527052454531556b4a31546b787153565132576b4530597a4d78635652495933464256486c3565566b774c7a6b3352336c4b5a32646f596e6c465232526f5a516f76616c6836615756544f584a325279744a56474631516a684d566c686b656b78475956517857455a5765466c6e4e327832546c42344f5552504c315a6f526b686b5757786e54334932643052745633466a52476f33436c68575557464f57454674526e67334e6a56514e546c584e585a7a564752585657464852577858536d3933536b5a4b646e6332556c5249536b5a315456686a537a5a5661574a3063555a4d536d4a774f57356b6455674b516a6c4c537a4e57636d59725a6d744a4f5752425a327478524446484f456c785130744b4d566c33626a557965477878625452434e69744f4f475a555a45314d53314a75635770465a6d527a563164774d46567a4d51704c54573976535863796333426f6158417a5546704e596e4a61615530774e6a4a325a556f3055336f76596a424f62576450546e685464304a4a546e4e7863473534516a68465556517853544e6a4e6b6c714e586868436d35525355524255554643436930744c5330745255354549464a545153425156554a4d53554d675330565a4c5330744c53304b00000000000000000000000000000000000000000000000000000000"; - await deployedRegistryContract.registerOperator(encryptionPK, operator_fee_block); - } - sharePKs = Array.from(Array(10).keys()).map(k => `0xa20a622ecbc816c89896f92a18214905a57beedbe8df6120ba644453a7e35672a365c3b73ce35b8738eeb5dade9107d${k}`); - encryptedShares = Array.from(Array(10).keys()).map(k => `0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000158513741566f733037584a4537767275644b366c7a647a76634143313563636b5152492b6143766f31617a374979787a517233506a4361632b545745394d45307a4f6d49${k}36947472f46312f38613556786d71383948366e6b71436130415573782b37326c43306f686a4b3874396853746953746732596e2b304d2f4e3732744c6d5951394c325976654c56564a35556c586a425777${k}4377a5537732f3142435653727862415431376f2f704858474c46644170697a4c5332704b48354b71746545786e3033566b4a4244527538596c5055334634656c554937697a667a474444626d49677536484862305777344669743745543745422f357056457a547279445a5179516753336a4858714d63637359396e52494250724f2f2f367370544736646e5831304e4872356b716a305136464b64684d6a4162644d43773966527274672b72766979584e6674464945445478304768314f513d3d0000000000000000`); - - await deployedRegistryContract.deposit("100000000000") - - }) - - it("Update operator", async () => { - - }) - - it("Update operator errors", async () => { - - }) - - it("Update operator gas limits", async () => { - - }) - -}); diff --git a/tests/sanity/balances.js b/tests/sanity/balances.js deleted file mode 100644 index d968b0cc..00000000 --- a/tests/sanity/balances.js +++ /dev/null @@ -1,139 +0,0 @@ -const { expect } = require("chai"); -const operator_fee_block = 1; -const { progressBlocks } = require('../helpers/utils'); - -const operatorsIndexes = Array.from(Array(8).keys()).map(k => k + 1); -let sharePKs, encryptedShares -const validatorBalance = 100000000000 - -describe("Balance Test", () => { - var deployedRegistryContract - beforeEach(async () => { - const Registry = await ethers.getContractFactory("SSVRegistryNew"); - deployedRegistryContract = await Registry.deploy(); - await deployedRegistryContract.deployed(); - - // Register 4 operators - for (let i = 0; i < operatorsIndexes.length; i++) { - const encryptionPK = "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002644c5330744c5331435255644a54694253553045675546564354456c4449457446575330744c533074436b314a53554a4a616b464f516d64726357687261556335647a424351564646526b464254304e425554684254556c4a516b4e6e53304e42555556424e5756554e557777563068365a54647954575a506232787456484d4b64577449513245344b336474625577324f54464a5131527052454531556b4a31546b787153565132576b4530597a4d78635652495933464256486c3565566b774c7a6b3352336c4b5a32646f596e6c465232526f5a516f76616c6836615756544f584a325279744a56474631516a684d566c686b656b78475956517857455a5765466c6e4e327832546c42344f5552504c315a6f526b686b5757786e54334932643052745633466a52476f33436c68575557464f57454674526e67334e6a56514e546c584e585a7a564752585657464852577858536d3933536b5a4b646e6332556c5249536b5a315456686a537a5a5661574a3063555a4d536d4a774f57356b6455674b516a6c4c537a4e57636d59725a6d744a4f5752425a327478524446484f456c785130744b4d566c33626a557965477878625452434e69744f4f475a555a45314d53314a75635770465a6d527a563164774d46567a4d51704c54573976535863796333426f6158417a5546704e596e4a61615530774e6a4a325a556f3055336f76596a424f62576450546e685464304a4a546e4e7863473534516a68465556517853544e6a4e6b6c714e586868436d35525355524255554643436930744c5330745255354549464a545153425156554a4d53554d675330565a4c5330744c53304b00000000000000000000000000000000000000000000000000000000"; - await deployedRegistryContract.registerOperator(encryptionPK, i !== 4 ? operator_fee_block : 100); - } - sharePKs = Array.from(Array(10).keys()).map(k => `0xa20a622ecbc816c89896f92a18214905a57beedbe8df6120ba644453a7e35672a365c3b73ce35b8738eeb5dade9107d${k}`); - encryptedShares = Array.from(Array(10).keys()).map(k => `0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000158513741566f733037584a4537767275644b366c7a647a76634143313563636b5152492b6143766f31617a374979787a517233506a4361632b545745394d45307a4f6d49${k}36947472f46312f38613556786d71383948366e6b71436130415573782b37326c43306f686a4b3874396853746953746732596e2b304d2f4e3732744c6d5951394c325976654c56564a35556c586a425777${k}4377a5537732f3142435653727862415431376f2f704858474c46644170697a4c5332704b48354b71746545786e3033566b4a4244527538596c5055334634656c554937697a667a474444626d49677536484862305777344669743745543745422f357056457a547279445a5179516753336a4858714d63637359396e52494250724f2f2f367370544736646e5831304e4872356b716a305136464b64684d6a4162644d43773966527274672b72766979584e6674464945445478304768314f513d3d0000000000000000`); - - await deployedRegistryContract.deposit(validatorBalance.toString()) - - }) - - it("Check balances", async () => { - // Register 1000 validators - const validatorPK = `0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100` - - expect(await deployedRegistryContract.test_getOperatorBalance(1)).to.equal('0') - - // Register a validator - const validator1 = (await (await deployedRegistryContract.registerValidator( - [1, 2, 3, 4], - `${validatorPK}0`, - sharePKs.slice(0, 4), - encryptedShares.slice(0, 4), - "10000" - )).wait()).logs[0] - const interfaceRegister = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId)']); - const outputRegister = interfaceRegister.decodeEventLog('ValidatorAdded', validator1.data, validator1.topics); - - // Progress 50 blocks and check operator balances and group balance - await progressBlocks(50) - expect(await deployedRegistryContract.test_getOperatorBalance(1)).to.equal('50') - expect(await deployedRegistryContract.test_getOperatorBalance(2)).to.equal('50') - expect(await deployedRegistryContract.test_getOperatorBalance(3)).to.equal('50') - expect(await deployedRegistryContract.test_getOperatorBalance(4)).to.equal('50') - expect(await deployedRegistryContract.test_groupBalance(outputRegister.groupId)).to.equal(10000 - 150) - - // Update one of the operator fees - await deployedRegistryContract.updateOperatorFee(1, 10) - - // Progress 50 blocks and check operator balances and group balance - await progressBlocks(50) - expect(await deployedRegistryContract.test_getOperatorBalance(1)).to.equal('551') - expect(await deployedRegistryContract.test_getOperatorBalance(2)).to.equal('101') - expect(await deployedRegistryContract.test_getOperatorBalance(3)).to.equal('101') - expect(await deployedRegistryContract.test_getOperatorBalance(4)).to.equal('101') - expect(await deployedRegistryContract.test_groupBalance(outputRegister.groupId)).to.equal(10000 - 904) - - // Update 3 operator fees - await deployedRegistryContract.updateOperatorFee(2, 20) - await deployedRegistryContract.updateOperatorFee(3, 20) - await deployedRegistryContract.updateOperatorFee(4, 20) - - // Progress 50 blocks and check operator balances and group balance - await progressBlocks(50) - expect(await deployedRegistryContract.test_getOperatorBalance(1)).to.equal('1081') - expect(await deployedRegistryContract.test_getOperatorBalance(2)).to.equal('1142') - expect(await deployedRegistryContract.test_getOperatorBalance(3)).to.equal('1123') - expect(await deployedRegistryContract.test_getOperatorBalance(4)).to.equal('1104') - expect(await deployedRegistryContract.test_groupBalance(outputRegister.groupId)).to.equal(10000 - 4500) - - // Add another validator - await deployedRegistryContract.registerValidator( - [1, 2, 3, 5], - `${validatorPK}1`, - sharePKs.slice(0, 4), - encryptedShares.slice(0, 4), - "10000" - ) - - // Progress 50 blocks and check operator balances and group balance - await progressBlocks(50) - expect(await deployedRegistryContract.test_getOperatorBalance(1)).to.equal('2091') - expect(await deployedRegistryContract.test_getOperatorBalance(2)).to.equal('3162') - expect(await deployedRegistryContract.test_getOperatorBalance(3)).to.equal('3143') - expect(await deployedRegistryContract.test_getOperatorBalance(4)).to.equal('2124') - expect(await deployedRegistryContract.test_getOperatorBalance(5)).to.equal('5000') - expect(await deployedRegistryContract.test_groupBalance(outputRegister.groupId)).to.equal(10000 - 4500) - - // Remove an operator - await deployedRegistryContract.removeOperator(1) - - // Progress 50 blocks and check operator balances and group balance - await progressBlocks(50) - expect(await deployedRegistryContract.test_getOperatorBalance(1)).to.equal('2091') - expect(await deployedRegistryContract.test_getOperatorBalance(2)).to.equal('3162') - expect(await deployedRegistryContract.test_getOperatorBalance(3)).to.equal('3143') - expect(await deployedRegistryContract.test_getOperatorBalance(4)).to.equal('2124') - expect(await deployedRegistryContract.test_getOperatorBalance(5)).to.equal('5000') - expect(await deployedRegistryContract.test_groupBalance(outputRegister.groupId)).to.equal(10000 - 4500) - - // Update a validator - await deployedRegistryContract.updateValidator( - [1, 2, 3, 5], - `${validatorPK}0`, - outputRegister.groupId, - sharePKs.slice(0, 4), - encryptedShares.slice(0, 4), - "10" - ) - - // Progress 50 blocks and check operator balances and group balance - await progressBlocks(50) - expect(await deployedRegistryContract.test_getOperatorBalance(1)).to.equal('2091') - expect(await deployedRegistryContract.test_getOperatorBalance(2)).to.equal('3162') - expect(await deployedRegistryContract.test_getOperatorBalance(3)).to.equal('3143') - expect(await deployedRegistryContract.test_getOperatorBalance(4)).to.equal('2124') - expect(await deployedRegistryContract.test_getOperatorBalance(5)).to.equal('5000') - expect(await deployedRegistryContract.test_groupBalance(outputRegister.groupId)).to.equal(10000 - 4500) - - // Remove a validator - await deployedRegistryContract.removeValidator(`${validatorPK}0`, outputRegister.groupId) - - // Progress 50 blocks and check operator balances and group balance - await progressBlocks(50) - expect(await deployedRegistryContract.test_getOperatorBalance(1)).to.equal('2091') - expect(await deployedRegistryContract.test_getOperatorBalance(2)).to.equal('3162') - expect(await deployedRegistryContract.test_getOperatorBalance(3)).to.equal('3143') - expect(await deployedRegistryContract.test_getOperatorBalance(4)).to.equal('2124') - expect(await deployedRegistryContract.test_getOperatorBalance(5)).to.equal('5000') - expect(await deployedRegistryContract.test_groupBalance(outputRegister.groupId)).to.equal(10000 - 4500) - }) - -}); diff --git a/tests/sanity/stress.js b/tests/sanity/stress.js deleted file mode 100644 index b0651b35..00000000 --- a/tests/sanity/stress.js +++ /dev/null @@ -1,80 +0,0 @@ -const { expect } = require("chai"); -const operator_fee_block = 1; - -const operatorsIndexes = Array.from(Array(1000).keys()).map(k => k + 1); -let sharePKs, encryptedShares -let validatorData = [] - -describe("Stress Test", () => { - var deployedRegistryContract - beforeEach(async () => { - const Registry = await ethers.getContractFactory("SSVRegistryNew"); - deployedRegistryContract = await Registry.deploy(); - await deployedRegistryContract.deployed(); - validatorData = [] - - // Create 1000 operators - for (let i = 0; i < operatorsIndexes.length; i++) { - const encryptionPK = "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002644c5330744c5331435255644a54694253553045675546564354456c4449457446575330744c533074436b314a53554a4a616b464f516d64726357687261556335647a424351564646526b464254304e425554684254556c4a516b4e6e53304e42555556424e5756554e557777563068365a54647954575a506232787456484d4b64577449513245344b336474625577324f54464a5131527052454531556b4a31546b787153565132576b4530597a4d78635652495933464256486c3565566b774c7a6b3352336c4b5a32646f596e6c465232526f5a516f76616c6836615756544f584a325279744a56474631516a684d566c686b656b78475956517857455a5765466c6e4e327832546c42344f5552504c315a6f526b686b5757786e54334932643052745633466a52476f33436c68575557464f57454674526e67334e6a56514e546c584e585a7a564752585657464852577858536d3933536b5a4b646e6332556c5249536b5a315456686a537a5a5661574a3063555a4d536d4a774f57356b6455674b516a6c4c537a4e57636d59725a6d744a4f5752425a327478524446484f456c785130744b4d566c33626a557965477878625452434e69744f4f475a555a45314d53314a75635770465a6d527a563164774d46567a4d51704c54573976535863796333426f6158417a5546704e596e4a61615530774e6a4a325a556f3055336f76596a424f62576450546e685464304a4a546e4e7863473534516a68465556517853544e6a4e6b6c714e586868436d35525355524255554643436930744c5330745255354549464a545153425156554a4d53554d675330565a4c5330744c53304b00000000000000000000000000000000000000000000000000000000"; - await deployedRegistryContract.registerOperator(encryptionPK, operator_fee_block); - } - sharePKs = Array.from(Array(10).keys()).map(k => `0xa20a622ecbc816c89896f92a18214905a57beedbe8df6120ba644453a7e35672a365c3b73ce35b8738eeb5dade9107d${k}`); - encryptedShares = Array.from(Array(10).keys()).map(k => `0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000158513741566f733037584a4537767275644b366c7a647a76634143313563636b5152492b6143766f31617a374979787a517233506a4361632b545745394d45307a4f6d49${k}36947472f46312f38613556786d71383948366e6b71436130415573782b37326c43306f686a4b3874396853746953746732596e2b304d2f4e3732744c6d5951394c325976654c56564a35556c586a425777${k}4377a5537732f3142435653727862415431376f2f704858474c46644170697a4c5332704b48354b71746545786e3033566b4a4244527538596c5055334634656c554937697a667a474444626d49677536484862305777344669743745543745422f357056457a547279445a5179516753336a4858714d63637359396e52494250724f2f2f367370544736646e5831304e4872356b716a305136464b64684d6a4162644d43773966527274672b72766979584e6674464945445478304768314f513d3d0000000000000000`); - - // Deposit to the account - await deployedRegistryContract.deposit("100000000000") - - // Register 1000 validators - for (let i = 1000; i < 2000; i++) { - const randomOperator = Math.floor(Math.random() * 995) - const validatorPK = `0xa7ae1ea93b860ca0269ccca776b4526977395aa194e5820a00dedbf1cd63e7a898eec9a12f539f733ea4df9c651f${i}` - - const registerResult = (await (await deployedRegistryContract.registerValidator( - [randomOperator, randomOperator + 1, randomOperator + 2, randomOperator + 3], - validatorPK, - sharePKs.slice(0, 4), - encryptedShares.slice(0, 4), - "10000" - )).wait()).logs[0] - - // Save validator group id emits - const interfaceRegister = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId)']); - const outputRegister = interfaceRegister.decodeEventLog('ValidatorAdded', registerResult.data, registerResult.topics); - validatorData.push({ publicKey: validatorPK, groupId: outputRegister.groupId }) - } - }) - - it("Update 1000 operators", async () => { - for (let i = 0; i < operatorsIndexes.length; i++) { - await deployedRegistryContract.updateOperatorFee(operatorsIndexes[i], 10) - } - }) - - it("Update 30 validators", async () => { - for (let i = 1000; i < 1030; i++) { - const randomOperator = Math.floor(Math.random() * 995) - const validatorPK = `0xa7ae1ea93b860ca0269ccca776b4526977395aa194e5820a00dedbf1cd63e7a898eec9a12f539f733ea4df9c651f${i}` - await deployedRegistryContract.updateValidator( - [randomOperator, randomOperator + 1, randomOperator + 2, randomOperator + 3], - validatorPK, - validatorData[i - 1000].groupId, - sharePKs.slice(0, 4), - encryptedShares.slice(0, 4), - "10" - ) - } - }) - - it("Remove 1000 operators", async () => { - for (let i = 0; i < operatorsIndexes.length; i++) { - await deployedRegistryContract.removeOperator(operatorsIndexes[i]) - } - }) - - it("Remove 1000 validators", async () => { - for (let i = 0; i < validatorData.length; i++) { - await deployedRegistryContract.removeValidator(validatorData[i].publicKey, validatorData[i].groupId) - } - }) - -}); diff --git a/tests/validators/register.js b/tests/validators/register.js deleted file mode 100644 index 7cc9b4b9..00000000 --- a/tests/validators/register.js +++ /dev/null @@ -1,90 +0,0 @@ -const { expect } = require("chai"); -const operator_fee_block = 1; - -const operatorsIndexes = Array.from(Array(8).keys()).map(k => k + 1); -let sharePKs, encryptedShares - -describe("Register Validator Test", () => { - var deployedRegistryContract - beforeEach(async () => { - const Registry = await ethers.getContractFactory("SSVRegistryNew"); - deployedRegistryContract = await Registry.deploy(); - await deployedRegistryContract.deployed(); - - // Create 4 operators - for (let i = 0; i < operatorsIndexes.length; i++) { - const encryptionPK = "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002644c5330744c5331435255644a54694253553045675546564354456c4449457446575330744c533074436b314a53554a4a616b464f516d64726357687261556335647a424351564646526b464254304e425554684254556c4a516b4e6e53304e42555556424e5756554e557777563068365a54647954575a506232787456484d4b64577449513245344b336474625577324f54464a5131527052454531556b4a31546b787153565132576b4530597a4d78635652495933464256486c3565566b774c7a6b3352336c4b5a32646f596e6c465232526f5a516f76616c6836615756544f584a325279744a56474631516a684d566c686b656b78475956517857455a5765466c6e4e327832546c42344f5552504c315a6f526b686b5757786e54334932643052745633466a52476f33436c68575557464f57454674526e67334e6a56514e546c584e585a7a564752585657464852577858536d3933536b5a4b646e6332556c5249536b5a315456686a537a5a5661574a3063555a4d536d4a774f57356b6455674b516a6c4c537a4e57636d59725a6d744a4f5752425a327478524446484f456c785130744b4d566c33626a557965477878625452434e69744f4f475a555a45314d53314a75635770465a6d527a563164774d46567a4d51704c54573976535863796333426f6158417a5546704e596e4a61615530774e6a4a325a556f3055336f76596a424f62576450546e685464304a4a546e4e7863473534516a68465556517853544e6a4e6b6c714e586868436d35525355524255554643436930744c5330745255354549464a545153425156554a4d53554d675330565a4c5330744c53304b00000000000000000000000000000000000000000000000000000000"; - await deployedRegistryContract.registerOperator(encryptionPK, operator_fee_block); - } - sharePKs = Array.from(Array(10).keys()).map(k => `0xa20a622ecbc816c89896f92a18214905a57beedbe8df6120ba644453a7e35672a365c3b73ce35b8738eeb5dade9107d${k}`); - encryptedShares = Array.from(Array(10).keys()).map(k => `0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000158513741566f733037584a4537767275644b366c7a647a76634143313563636b5152492b6143766f31617a374979787a517233506a4361632b545745394d45307a4f6d49${k}36947472f46312f38613556786d71383948366e6b71436130415573782b37326c43306f686a4b3874396853746953746732596e2b304d2f4e3732744c6d5951394c325976654c56564a35556c586a425777${k}4377a5537732f3142435653727862415431376f2f704858474c46644170697a4c5332704b48354b71746545786e3033566b4a4244527538596c5055334634656c554937697a667a474444626d49677536484862305777344669743745543745422f357056457a547279445a5179516753336a4858714d63637359396e52494250724f2f2f367370544736646e5831304e4872356b716a305136464b64684d6a4162644d43773966527274672b72766979584e6674464945445478304768314f513d3d0000000000000000`); - - await deployedRegistryContract.deposit("100000000000") - - }) - - it("Register validator", async () => { - const validatorPK = `0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100` - await deployedRegistryContract.registerValidator( - [1, 2, 3, 4], - `${validatorPK}0`, - sharePKs.slice(0, 4), - encryptedShares.slice(0, 4), - "10000" - ) - }) - - it("Register validator errors", async () => { - - }) - - it("Register validator gas limits", async () => { - const validatorPK = `0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100` - - // Cost: 364101 - await deployedRegistryContract.registerValidator( - [1, 2, 3, 4], - `${validatorPK}0`, - sharePKs.slice(0, 4), - encryptedShares.slice(0, 4), - "10000" - ) - - // // Cost: 185380 - // await deployedRegistryContract.registerValidator( - // [1, 2, 3, 4], - // `${validatorPK}1`, - // sharePKs.slice(0, 4), - // encryptedShares.slice(0, 4), - // "10000" - // ) - - // Cost: 295713 - await deployedRegistryContract.registerValidator( - [1, 2, 5, 6], - `${validatorPK}1`, - sharePKs.slice(0, 4), - encryptedShares.slice(0, 4), - "10000" - ) - - // // Cost: 312813 - // await deployedRegistryContract.registerValidator( - // [1, 5, 6, 7], - // `${validatorPK}2`, - // sharePKs.slice(0, 4), - // encryptedShares.slice(0, 4), - // "10000" - // ) - - // // Cost: 329901 - // await deployedRegistryContract.registerValidator( - // [5, 6, 7, 8], - // `${validatorPK}0`, - // sharePKs.slice(0, 4), - // encryptedShares.slice(0, 4), - // "10000" - // ) - }) - -}); diff --git a/tests/validators/remove.js b/tests/validators/remove.js deleted file mode 100644 index 7478b5bf..00000000 --- a/tests/validators/remove.js +++ /dev/null @@ -1,38 +0,0 @@ -const { expect } = require("chai"); -const operator_fee_block = 1; - -const operatorsIndexes = Array.from(Array(8).keys()).map(k => k + 1); -let sharePKs, encryptedShares - -describe("Remove Validator Test", () => { - var deployedRegistryContract - beforeEach(async () => { - const Registry = await ethers.getContractFactory("SSVRegistryNew"); - deployedRegistryContract = await Registry.deploy(); - await deployedRegistryContract.deployed(); - - // Create 4 operators - for (let i = 0; i < operatorsIndexes.length; i++) { - const encryptionPK = "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002644c5330744c5331435255644a54694253553045675546564354456c4449457446575330744c533074436b314a53554a4a616b464f516d64726357687261556335647a424351564646526b464254304e425554684254556c4a516b4e6e53304e42555556424e5756554e557777563068365a54647954575a506232787456484d4b64577449513245344b336474625577324f54464a5131527052454531556b4a31546b787153565132576b4530597a4d78635652495933464256486c3565566b774c7a6b3352336c4b5a32646f596e6c465232526f5a516f76616c6836615756544f584a325279744a56474631516a684d566c686b656b78475956517857455a5765466c6e4e327832546c42344f5552504c315a6f526b686b5757786e54334932643052745633466a52476f33436c68575557464f57454674526e67334e6a56514e546c584e585a7a564752585657464852577858536d3933536b5a4b646e6332556c5249536b5a315456686a537a5a5661574a3063555a4d536d4a774f57356b6455674b516a6c4c537a4e57636d59725a6d744a4f5752425a327478524446484f456c785130744b4d566c33626a557965477878625452434e69744f4f475a555a45314d53314a75635770465a6d527a563164774d46567a4d51704c54573976535863796333426f6158417a5546704e596e4a61615530774e6a4a325a556f3055336f76596a424f62576450546e685464304a4a546e4e7863473534516a68465556517853544e6a4e6b6c714e586868436d35525355524255554643436930744c5330745255354549464a545153425156554a4d53554d675330565a4c5330744c53304b00000000000000000000000000000000000000000000000000000000"; - await deployedRegistryContract.registerOperator(encryptionPK, operator_fee_block); - } - sharePKs = Array.from(Array(10).keys()).map(k => `0xa20a622ecbc816c89896f92a18214905a57beedbe8df6120ba644453a7e35672a365c3b73ce35b8738eeb5dade9107d${k}`); - encryptedShares = Array.from(Array(10).keys()).map(k => `0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000158513741566f733037584a4537767275644b366c7a647a76634143313563636b5152492b6143766f31617a374979787a517233506a4361632b545745394d45307a4f6d49${k}36947472f46312f38613556786d71383948366e6b71436130415573782b37326c43306f686a4b3874396853746953746732596e2b304d2f4e3732744c6d5951394c325976654c56564a35556c586a425777${k}4377a5537732f3142435653727862415431376f2f704858474c46644170697a4c5332704b48354b71746545786e3033566b4a4244527538596c5055334634656c554937697a667a474444626d49677536484862305777344669743745543745422f357056457a547279445a5179516753336a4858714d63637359396e52494250724f2f2f367370544736646e5831304e4872356b716a305136464b64684d6a4162644d43773966527274672b72766979584e6674464945445478304768314f513d3d0000000000000000`); - - await deployedRegistryContract.deposit("100000000000") - - }) - - it("Remove validator", async () => { - - }) - - it("Remove validator errors", async () => { - - }) - - it("Remove Validator gas limits", async () => { - - }) - -}); diff --git a/tests/validators/update.js b/tests/validators/update.js deleted file mode 100644 index 3ee078e7..00000000 --- a/tests/validators/update.js +++ /dev/null @@ -1,38 +0,0 @@ -const { expect } = require("chai"); -const operator_fee_block = 1; - -const operatorsIndexes = Array.from(Array(8).keys()).map(k => k + 1); -let sharePKs, encryptedShares - -describe("Remove Validator Test", () => { - var deployedRegistryContract - beforeEach(async () => { - const Registry = await ethers.getContractFactory("SSVRegistryNew"); - deployedRegistryContract = await Registry.deploy(); - await deployedRegistryContract.deployed(); - - // Create 4 operators - for (let i = 0; i < operatorsIndexes.length; i++) { - const encryptionPK = "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002644c5330744c5331435255644a54694253553045675546564354456c4449457446575330744c533074436b314a53554a4a616b464f516d64726357687261556335647a424351564646526b464254304e425554684254556c4a516b4e6e53304e42555556424e5756554e557777563068365a54647954575a506232787456484d4b64577449513245344b336474625577324f54464a5131527052454531556b4a31546b787153565132576b4530597a4d78635652495933464256486c3565566b774c7a6b3352336c4b5a32646f596e6c465232526f5a516f76616c6836615756544f584a325279744a56474631516a684d566c686b656b78475956517857455a5765466c6e4e327832546c42344f5552504c315a6f526b686b5757786e54334932643052745633466a52476f33436c68575557464f57454674526e67334e6a56514e546c584e585a7a564752585657464852577858536d3933536b5a4b646e6332556c5249536b5a315456686a537a5a5661574a3063555a4d536d4a774f57356b6455674b516a6c4c537a4e57636d59725a6d744a4f5752425a327478524446484f456c785130744b4d566c33626a557965477878625452434e69744f4f475a555a45314d53314a75635770465a6d527a563164774d46567a4d51704c54573976535863796333426f6158417a5546704e596e4a61615530774e6a4a325a556f3055336f76596a424f62576450546e685464304a4a546e4e7863473534516a68465556517853544e6a4e6b6c714e586868436d35525355524255554643436930744c5330745255354549464a545153425156554a4d53554d675330565a4c5330744c53304b00000000000000000000000000000000000000000000000000000000"; - await deployedRegistryContract.registerOperator(encryptionPK, operator_fee_block); - } - sharePKs = Array.from(Array(10).keys()).map(k => `0xa20a622ecbc816c89896f92a18214905a57beedbe8df6120ba644453a7e35672a365c3b73ce35b8738eeb5dade9107d${k}`); - encryptedShares = Array.from(Array(10).keys()).map(k => `0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000158513741566f733037584a4537767275644b366c7a647a76634143313563636b5152492b6143766f31617a374979787a517233506a4361632b545745394d45307a4f6d49${k}36947472f46312f38613556786d71383948366e6b71436130415573782b37326c43306f686a4b3874396853746953746732596e2b304d2f4e3732744c6d5951394c325976654c56564a35556c586a425777${k}4377a5537732f3142435653727862415431376f2f704858474c46644170697a4c5332704b48354b71746545786e3033566b4a4244527538596c5055334634656c554937697a667a474444626d49677536484862305777344669743745543745422f357056457a547279445a5179516753336a4858714d63637359396e52494250724f2f2f367370544736646e5831304e4872356b716a305136464b64684d6a4162644d43773966527274672b72766979584e6674464945445478304768314f513d3d0000000000000000`); - - await deployedRegistryContract.deposit("100000000000") - - }) - - it("Update validator", async () => { - - }) - - it("Update validator errors", async () => { - - }) - - it("Update Validator gas limits", async () => { - - }) - -}); From 9ae41d524d5f92cbb30621640ca9c3e9f0b3dd6a Mon Sep 17 00:00:00 2001 From: Lior Rutenberg Date: Thu, 25 Aug 2022 14:59:11 +0300 Subject: [PATCH 036/149] changed collection name to cluster --- contracts/SSVRegistry.sol | 90 +++++++++++++++++++-------------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/contracts/SSVRegistry.sol b/contracts/SSVRegistry.sol index 2eeb1f8d..9feb0b68 100644 --- a/contracts/SSVRegistry.sol +++ b/contracts/SSVRegistry.sol @@ -33,7 +33,7 @@ contract SSVRegistryNew { Snapshot earnings; } - struct OperatorCollection { + struct Cluster { uint64[] operatorIds; } @@ -44,7 +44,7 @@ contract SSVRegistryNew { } struct Validator { - bytes32 operatorCollectionId; + bytes32 clusterId; address owner; bool active; } @@ -63,7 +63,7 @@ contract SSVRegistryNew { // operator vars mapping(uint64 => Operator) private _operators; - mapping(bytes32 => OperatorCollection) private _operatorCollections; + mapping(bytes32 => Cluster) private _clusters; mapping(bytes32 => Group) private _groups; mapping(address => uint64) _availableBalances; mapping(bytes32 => Validator) _validatorPKs; @@ -134,7 +134,7 @@ contract SSVRegistryNew { revert ValidatorNotOwned(); } - validator.operatorCollectionId = toGroupId; + validator.clusterId = toGroupId; _validatorPKs[keccak256(validatorPK[index])] = validator; if (validator.active) { @@ -144,17 +144,17 @@ contract SSVRegistryNew { } emit ValidatorTransferedArr(validatorPK, toGroupId, shares); - uint64[] memory newOperatorIds = _operatorCollections[toGroupId].operatorIds; + uint64[] memory newOperatorIds = _clusters[toGroupId].operatorIds; - _updateOperatorsValidatorMove(_operatorCollections[fromGroupId].operatorIds, newOperatorIds, activeValidatorCount); + _updateOperatorsValidatorMove(_clusters[fromGroupId].operatorIds, newOperatorIds, activeValidatorCount); Group memory group = _groups[keccak256(abi.encodePacked(msg.sender, fromGroupId))]; - group.usage.index = _operatorCollectionCurrentIndex(fromGroupId); + group.usage.index = _clusterCurrentIndex(fromGroupId); group.usage.block = uint64(block.number); group.validatorCount -= activeValidatorCount; group = _groups[keccak256(abi.encodePacked(msg.sender, toGroupId))]; - group.usage.index = _operatorCollectionCurrentIndex(toGroupId); + group.usage.index = _clusterCurrentIndex(toGroupId); group.usage.block = uint64(block.number); group.validatorCount += activeValidatorCount; @@ -173,11 +173,11 @@ contract SSVRegistryNew { ); // Operator[] memory operators; - bytes32 operatorCollectionId = _getOrCreateOperatorCollection(operatorIds); + bytes32 clusterId = _getOrCreateCluster(operatorIds); { Group memory group; _availableBalances[msg.sender] -= amount; - group = _updateGroupData(operatorCollectionId, amount, true); + group = _updateGroupData(clusterId, amount, true); { for (uint64 i = 0; i < operatorIds.length; ++i) { @@ -198,12 +198,12 @@ contract SSVRegistryNew { // TODO require(!_liquidatable(group.balance, group.validatorCount, operatorIds), "account liquidatable"); - _groups[keccak256(abi.encodePacked(msg.sender, operatorCollectionId))] = group; + _groups[keccak256(abi.encodePacked(msg.sender, clusterId))] = group; } - _validatorPKs[keccak256(validatorPK)] = Validator({ owner: msg.sender, operatorCollectionId: operatorCollectionId, active: true}); + _validatorPKs[keccak256(validatorPK)] = Validator({ owner: msg.sender, clusterId: clusterId, active: true}); - emit ValidatorAdded(validatorPK, operatorCollectionId, shares); + emit ValidatorAdded(validatorPK, clusterId, shares); } function _updateOperatorsValidatorMove( @@ -257,14 +257,14 @@ contract SSVRegistryNew { uint64 amount ) external { uint64 currentBlock = uint64(block.number); - bytes32 operatorCollectionId = _validatorPKs[keccak256(validatorPK)].operatorCollectionId; + bytes32 clusterId = _validatorPKs[keccak256(validatorPK)].clusterId; if (_validatorPKs[keccak256(validatorPK)].owner != msg.sender) { revert ValidatorNotOwned(); } { - _groups[keccak256(abi.encodePacked(msg.sender, operatorCollectionId))] = _updateGroupData(operatorCollectionId, 0, false); + _groups[keccak256(abi.encodePacked(msg.sender, clusterId))] = _updateGroupData(clusterId, 0, false); // if (group.validatorCount == 0) { // _availableBalances[msg.sender] += _ownerGroupBalance(group, groupIndex); // group.balance -= _ownerGroupBalance(group, groupIndex); @@ -272,21 +272,21 @@ contract SSVRegistryNew { } { - OperatorCollection memory operatorCollection = _operatorCollections[operatorCollectionId]; - _updateOperatorsValidatorMove(operatorCollection.operatorIds, operatorIds, 1); + Cluster memory cluster = _clusters[clusterId]; + _updateOperatorsValidatorMove(cluster.operatorIds, operatorIds, 1); } { - bytes32 newOperatorCollectionId = _getOrCreateOperatorCollection(operatorIds); + bytes32 newClusterId = _getOrCreateCluster(operatorIds); { Group memory group; { _availableBalances[msg.sender] -= amount; - _groups[keccak256(abi.encodePacked(msg.sender, newOperatorCollectionId))] = _updateGroupData(newOperatorCollectionId, amount, true); - _validatorPKs[keccak256(validatorPK)].operatorCollectionId = newOperatorCollectionId; + _groups[keccak256(abi.encodePacked(msg.sender, newClusterId))] = _updateGroupData(newClusterId, amount, true); + _validatorPKs[keccak256(validatorPK)].clusterId = newClusterId; } { @@ -298,7 +298,7 @@ contract SSVRegistryNew { require(!_liquidatable(group.balance, group.validatorCount, operatorIds), "account liquidatable"); } - emit ValidatorUpdated(validatorPK, newOperatorCollectionId, shares); + emit ValidatorUpdated(validatorPK, newClusterId, shares); } } @@ -309,14 +309,14 @@ contract SSVRegistryNew { revert ValidatorNotOwned(); } - bytes32 operatorCollectionId = _validatorPKs[keccak256(validatorPK)].operatorCollectionId; + bytes32 clusterId = _validatorPKs[keccak256(validatorPK)].clusterId; { - Group memory group = _groups[keccak256(abi.encodePacked(msg.sender, operatorCollectionId))]; - OperatorCollection memory operatorCollection = _operatorCollections[operatorCollectionId]; + Group memory group = _groups[keccak256(abi.encodePacked(msg.sender, clusterId))]; + Cluster memory cluster = _clusters[clusterId]; uint64 currentBlock = uint64(block.number); - uint64 groupIndex = _operatorCollectionCurrentIndex(operatorCollectionId); + uint64 groupIndex = _clusterCurrentIndex(clusterId); group.balance = _ownerGroupBalance(group, groupIndex); group.usage.index = groupIndex; group.usage.block = currentBlock; @@ -328,8 +328,8 @@ contract SSVRegistryNew { } - for (uint64 i = 0; i < operatorCollection.operatorIds.length; ++i) { - uint64 id = operatorCollection.operatorIds[i]; + for (uint64 i = 0; i < cluster.operatorIds.length; ++i) { + uint64 id = cluster.operatorIds[i]; _operators[id].earnings = _updateOperatorEarnings(_operators[id]); --_operators[id].validatorCount; } @@ -342,10 +342,10 @@ contract SSVRegistryNew { _dao = dao; } - _groups[keccak256(abi.encodePacked(msg.sender, operatorCollectionId))] = group; + _groups[keccak256(abi.encodePacked(msg.sender, clusterId))] = group; } - emit ValidatorRemoved(validatorPK, operatorCollectionId); + emit ValidatorRemoved(validatorPK, clusterId); } function _setFee(Operator memory operator, uint64 fee) private returns (Operator memory) { @@ -369,9 +369,9 @@ contract SSVRegistryNew { } } - function _updateGroupData(bytes32 operatorCollectionId, uint64 amount, bool increase) private returns (Group memory) { - Group memory group = _groups[keccak256(abi.encodePacked(msg.sender, operatorCollectionId))]; - uint64 groupIndex = _operatorCollectionCurrentIndex(operatorCollectionId); + function _updateGroupData(bytes32 clusterId, uint64 amount, bool increase) private returns (Group memory) { + Group memory group = _groups[keccak256(abi.encodePacked(msg.sender, clusterId))]; + uint64 groupIndex = _clusterCurrentIndex(clusterId); group.balance = _ownerGroupBalance(group, groupIndex) + amount; group.usage.index = groupIndex; group.usage.block = uint64(block.number); @@ -388,9 +388,9 @@ contract SSVRegistryNew { return group; } - function groupBalanceOf(address owner, bytes32 operatorCollectionId) external view returns (uint64) { - Group memory group = _groups[keccak256(abi.encodePacked(owner, operatorCollectionId))]; - return _ownerGroupBalance(group, _operatorCollectionCurrentIndex(operatorCollectionId)); + function groupBalanceOf(address owner, bytes32 clusterId) external view returns (uint64) { + Group memory group = _groups[keccak256(abi.encodePacked(owner, clusterId))]; + return _ownerGroupBalance(group, _clusterCurrentIndex(clusterId)); } function operatorEarningsOf(uint64 operatorId) external view returns (uint64) { @@ -419,24 +419,24 @@ contract SSVRegistryNew { _availableBalances[msg.sender] += amount; } - function _createOperatorCollection(uint64[] memory operators) private returns (uint64 groupId) { + function _createCluster(uint64[] memory operators) private returns (uint64 groupId) { for (uint64 index = 0; index < operators.length; ++index) { require(_operators[operators[index]].owner != address(0), "operator not found"); } - _operatorCollections[keccak256(abi.encodePacked(operators))] = OperatorCollection({ operatorIds: operators }); + _clusters[keccak256(abi.encodePacked(operators))] = Cluster({ operatorIds: operators }); } - function _getOrCreateOperatorCollection(uint64[] memory operatorIds) private returns (bytes32) { // , OperatorCollection memory + function _getOrCreateCluster(uint64[] memory operatorIds) private returns (bytes32) { // , Cluster memory for (uint64 i = 0; i < operatorIds.length - 1;) { require(operatorIds[i] <= operatorIds[++i]); } bytes32 key = keccak256(abi.encodePacked(operatorIds)); - OperatorCollection storage operatorCollection = _operatorCollections[key]; - if (operatorCollection.operatorIds.length == 0) { - operatorCollection.operatorIds = operatorIds; + Cluster storage cluster = _clusters[key]; + if (cluster.operatorIds.length == 0) { + cluster.operatorIds = operatorIds; } return key; @@ -479,10 +479,10 @@ contract SSVRegistryNew { return _networkTotalEarnings(dao) - dao.withdrawn; } - function _operatorCollectionCurrentIndex(bytes32 groupId) private view returns (uint64 groupIndex) { - OperatorCollection memory operatorCollection = _operatorCollections[groupId]; - for (uint64 i = 0; i < operatorCollection.operatorIds.length; ++i) { - groupIndex += _operatorCurrentIndex(_operators[operatorCollection.operatorIds[i]]); + function _clusterCurrentIndex(bytes32 groupId) private view returns (uint64 groupIndex) { + Cluster memory cluster = _clusters[groupId]; + for (uint64 i = 0; i < cluster.operatorIds.length; ++i) { + groupIndex += _operatorCurrentIndex(_operators[cluster.operatorIds[i]]); } } From 53a44def815cf6f93cbedd9ef940dc93d963e8e0 Mon Sep 17 00:00:00 2001 From: Lior Rutenberg Date: Thu, 25 Aug 2022 15:08:37 +0300 Subject: [PATCH 037/149] changed group name to pod --- contracts/SSVRegistry.sol | 146 +++++++++++++++++++------------------- tests/vadimToUpdate.js | 2 +- 2 files changed, 74 insertions(+), 74 deletions(-) diff --git a/contracts/SSVRegistry.sol b/contracts/SSVRegistry.sol index 9feb0b68..68f2813a 100644 --- a/contracts/SSVRegistry.sol +++ b/contracts/SSVRegistry.sol @@ -37,7 +37,7 @@ contract SSVRegistryNew { uint64[] operatorIds; } - struct Group { + struct Pod { uint64 balance; uint64 validatorCount; Snapshot usage; @@ -52,19 +52,19 @@ contract SSVRegistryNew { event OperatorAdded(uint64 operatorId, address indexed owner, bytes encryptionPK); event OperatorRemoved(uint64 operatorId); event OperatorFeeUpdated(uint64 operatorId, uint64 fee); - event ValidatorAdded(bytes validatorPK, bytes32 groupId,bytes shares); - event ValidatorTransferedArr(bytes[] validatorPK, bytes32 groupId,bytes[] shares); - event ValidatorUpdated(bytes validatorPK, bytes32 groupId, bytes shares); - event ValidatorRemoved(bytes validatorPK, bytes32 groupId); + event ValidatorAdded(bytes validatorPK, bytes32 podId,bytes shares); + event ValidatorTransferedArr(bytes[] validatorPK, bytes32 podId,bytes[] shares); + event ValidatorUpdated(bytes validatorPK, bytes32 podId, bytes shares); + event ValidatorRemoved(bytes validatorPK, bytes32 podId); // global vars Counters.Counter private lastOperatorId; - Counters.Counter private lastGroupId; + Counters.Counter private lastPodId; // operator vars mapping(uint64 => Operator) private _operators; mapping(bytes32 => Cluster) private _clusters; - mapping(bytes32 => Group) private _groups; + mapping(bytes32 => Pod) private _pods; mapping(address => uint64) _availableBalances; mapping(bytes32 => Validator) _validatorPKs; @@ -120,8 +120,8 @@ contract SSVRegistryNew { function transferValidators( bytes[] calldata validatorPK, - bytes32 fromGroupId, - bytes32 toGroupId, + bytes32 fromPodId, + bytes32 toPodId, bytes[] calldata shares ) external { // _validateValidatorParams @@ -134,7 +134,7 @@ contract SSVRegistryNew { revert ValidatorNotOwned(); } - validator.clusterId = toGroupId; + validator.clusterId = toPodId; _validatorPKs[keccak256(validatorPK[index])] = validator; if (validator.active) { @@ -142,23 +142,23 @@ contract SSVRegistryNew { } // Changing to a single event reducing by 15K gas } - emit ValidatorTransferedArr(validatorPK, toGroupId, shares); + emit ValidatorTransferedArr(validatorPK, toPodId, shares); - uint64[] memory newOperatorIds = _clusters[toGroupId].operatorIds; + uint64[] memory newOperatorIds = _clusters[toPodId].operatorIds; - _updateOperatorsValidatorMove(_clusters[fromGroupId].operatorIds, newOperatorIds, activeValidatorCount); + _updateOperatorsValidatorMove(_clusters[fromPodId].operatorIds, newOperatorIds, activeValidatorCount); - Group memory group = _groups[keccak256(abi.encodePacked(msg.sender, fromGroupId))]; - group.usage.index = _clusterCurrentIndex(fromGroupId); - group.usage.block = uint64(block.number); - group.validatorCount -= activeValidatorCount; + Pod memory pod = _pods[keccak256(abi.encodePacked(msg.sender, fromPodId))]; + pod.usage.index = _clusterCurrentIndex(fromPodId); + pod.usage.block = uint64(block.number); + pod.validatorCount -= activeValidatorCount; - group = _groups[keccak256(abi.encodePacked(msg.sender, toGroupId))]; - group.usage.index = _clusterCurrentIndex(toGroupId); - group.usage.block = uint64(block.number); - group.validatorCount += activeValidatorCount; + pod = _pods[keccak256(abi.encodePacked(msg.sender, toPodId))]; + pod.usage.index = _clusterCurrentIndex(toPodId); + pod.usage.block = uint64(block.number); + pod.validatorCount += activeValidatorCount; - require(!_liquidatable(group.balance, group.validatorCount, newOperatorIds), "account liquidatable"); + require(!_liquidatable(pod.balance, pod.validatorCount, newOperatorIds), "account liquidatable"); } function registerValidator( @@ -175,9 +175,9 @@ contract SSVRegistryNew { // Operator[] memory operators; bytes32 clusterId = _getOrCreateCluster(operatorIds); { - Group memory group; + Pod memory pod; _availableBalances[msg.sender] -= amount; - group = _updateGroupData(clusterId, amount, true); + pod = _updatePodData(clusterId, amount, true); { for (uint64 i = 0; i < operatorIds.length; ++i) { @@ -196,9 +196,9 @@ contract SSVRegistryNew { } // TODO - require(!_liquidatable(group.balance, group.validatorCount, operatorIds), "account liquidatable"); + require(!_liquidatable(pod.balance, pod.validatorCount, operatorIds), "account liquidatable"); - _groups[keccak256(abi.encodePacked(msg.sender, clusterId))] = group; + _pods[keccak256(abi.encodePacked(msg.sender, clusterId))] = pod; } _validatorPKs[keccak256(validatorPK)] = Validator({ owner: msg.sender, clusterId: clusterId, active: true}); @@ -264,10 +264,10 @@ contract SSVRegistryNew { } { - _groups[keccak256(abi.encodePacked(msg.sender, clusterId))] = _updateGroupData(clusterId, 0, false); - // if (group.validatorCount == 0) { - // _availableBalances[msg.sender] += _ownerGroupBalance(group, groupIndex); - // group.balance -= _ownerGroupBalance(group, groupIndex); + _pods[keccak256(abi.encodePacked(msg.sender, clusterId))] = _updatePodData(clusterId, 0, false); + // if (pod.validatorCount == 0) { + // _availableBalances[msg.sender] += _ownerPodBalance(pod, podIndex); + // pod.balance -= _ownerPodBalance(pod, podIndex); // } } @@ -281,11 +281,11 @@ contract SSVRegistryNew { bytes32 newClusterId = _getOrCreateCluster(operatorIds); { - Group memory group; + Pod memory pod; { _availableBalances[msg.sender] -= amount; - _groups[keccak256(abi.encodePacked(msg.sender, newClusterId))] = _updateGroupData(newClusterId, amount, true); + _pods[keccak256(abi.encodePacked(msg.sender, newClusterId))] = _updatePodData(newClusterId, amount, true); _validatorPKs[keccak256(validatorPK)].clusterId = newClusterId; } @@ -295,7 +295,7 @@ contract SSVRegistryNew { _dao = dao; } - require(!_liquidatable(group.balance, group.validatorCount, operatorIds), "account liquidatable"); + require(!_liquidatable(pod.balance, pod.validatorCount, operatorIds), "account liquidatable"); } emit ValidatorUpdated(validatorPK, newClusterId, shares); @@ -312,19 +312,19 @@ contract SSVRegistryNew { bytes32 clusterId = _validatorPKs[keccak256(validatorPK)].clusterId; { - Group memory group = _groups[keccak256(abi.encodePacked(msg.sender, clusterId))]; + Pod memory pod = _pods[keccak256(abi.encodePacked(msg.sender, clusterId))]; Cluster memory cluster = _clusters[clusterId]; uint64 currentBlock = uint64(block.number); - uint64 groupIndex = _clusterCurrentIndex(clusterId); - group.balance = _ownerGroupBalance(group, groupIndex); - group.usage.index = groupIndex; - group.usage.block = currentBlock; - --group.validatorCount; + uint64 podIndex = _clusterCurrentIndex(clusterId); + pod.balance = _ownerPodBalance(pod, podIndex); + pod.usage.index = podIndex; + pod.usage.block = currentBlock; + --pod.validatorCount; - if (group.validatorCount == 0) { - // _availableBalances[msg.sender] += _ownerGroupBalance(group, groupIndex); - // group.balance -= _ownerGroupBalance(group, groupIndex); + if (pod.validatorCount == 0) { + // _availableBalances[msg.sender] += _ownerPodBalance(pod, podIndex); + // pod.balance -= _ownerPodBalance(pod, podIndex); } @@ -342,7 +342,7 @@ contract SSVRegistryNew { _dao = dao; } - _groups[keccak256(abi.encodePacked(msg.sender, clusterId))] = group; + _pods[keccak256(abi.encodePacked(msg.sender, clusterId))] = pod; } emit ValidatorRemoved(validatorPK, clusterId); @@ -369,28 +369,28 @@ contract SSVRegistryNew { } } - function _updateGroupData(bytes32 clusterId, uint64 amount, bool increase) private returns (Group memory) { - Group memory group = _groups[keccak256(abi.encodePacked(msg.sender, clusterId))]; - uint64 groupIndex = _clusterCurrentIndex(clusterId); - group.balance = _ownerGroupBalance(group, groupIndex) + amount; - group.usage.index = groupIndex; - group.usage.block = uint64(block.number); + function _updatePodData(bytes32 clusterId, uint64 amount, bool increase) private returns (Pod memory) { + Pod memory pod = _pods[keccak256(abi.encodePacked(msg.sender, clusterId))]; + uint64 podIndex = _clusterCurrentIndex(clusterId); + pod.balance = _ownerPodBalance(pod, podIndex) + amount; + pod.usage.index = podIndex; + pod.usage.block = uint64(block.number); if (increase) { - ++group.validatorCount; + ++pod.validatorCount; } else { - --group.validatorCount; + --pod.validatorCount; } - if (group.validatorCount == 0) { - // _availableBalances[msg.sender] += _ownerGroupBalance(group, groupIndex); - // group.balance -= _ownerGroupBalance(group, groupIndex); + if (pod.validatorCount == 0) { + // _availableBalances[msg.sender] += _ownerPodBalance(pod, podIndex); + // pod.balance -= _ownerPodBalance(pod, podIndex); } - return group; + return pod; } - function groupBalanceOf(address owner, bytes32 clusterId) external view returns (uint64) { - Group memory group = _groups[keccak256(abi.encodePacked(owner, clusterId))]; - return _ownerGroupBalance(group, _clusterCurrentIndex(clusterId)); + function podBalanceOf(address owner, bytes32 clusterId) external view returns (uint64) { + Pod memory pod = _pods[keccak256(abi.encodePacked(owner, clusterId))]; + return _ownerPodBalance(pod, _clusterCurrentIndex(clusterId)); } function operatorEarningsOf(uint64 operatorId) external view returns (uint64) { @@ -419,7 +419,7 @@ contract SSVRegistryNew { _availableBalances[msg.sender] += amount; } - function _createCluster(uint64[] memory operators) private returns (uint64 groupId) { + function _createCluster(uint64[] memory operators) private returns (uint64 podId) { for (uint64 index = 0; index < operators.length; ++index) { require(_operators[operators[index]].owner != address(0), "operator not found"); } @@ -479,10 +479,10 @@ contract SSVRegistryNew { return _networkTotalEarnings(dao) - dao.withdrawn; } - function _clusterCurrentIndex(bytes32 groupId) private view returns (uint64 groupIndex) { - Cluster memory cluster = _clusters[groupId]; + function _clusterCurrentIndex(bytes32 podId) private view returns (uint64 podIndex) { + Cluster memory cluster = _clusters[podId]; for (uint64 i = 0; i < cluster.operatorIds.length; ++i) { - groupIndex += _operatorCurrentIndex(_operators[cluster.operatorIds[i]]); + podIndex += _operatorCurrentIndex(_operators[cluster.operatorIds[i]]); } } @@ -490,8 +490,8 @@ contract SSVRegistryNew { return operator.earnings.index + (uint64(block.number) - operator.earnings.block) * operator.fee; } - function _ownerGroupBalance(Group memory group, uint64 currentGroupIndex) private view returns (uint64) { - return group.balance - (currentGroupIndex - group.usage.index) * group.validatorCount; + function _ownerPodBalance(Pod memory pod, uint64 currentPodIndex) private view returns (uint64) { + return pod.balance - (currentPodIndex - pod.usage.index) * pod.validatorCount; } function _burnRatePerValidator(Operator[] memory operators) private pure returns (uint64 rate) { @@ -505,16 +505,16 @@ contract SSVRegistryNew { } /* - function liquidate(address owner, bytes32 groupId) external { - OperatorCollection memory operatorCollection = _operatorCollections[groupId]; - Operator[] memory operators = new Operator[](operatorCollection.operatorIds.length); - for (uint64 i = 0; i < operatorCollection.operatorIds.length; ++i) { - operators[i] = _operators[operatorCollection.operatorIds[i]]; + function liquidate(address owner, bytes32 podId) external { + Cluster memory cluster = _clusters[podId]; + Operator[] memory operators = new Operator[](cluster.operatorIds.length); + for (uint64 i = 0; i < cluster.operatorIds.length; ++i) { + operators[i] = _operators[cluster.operatorIds[i]]; } - uint64 groupIndex = _operatorCollectionCurrentIndex(operators); - Group memory group = _groups[owner][groupId]; - uint64 balance = _ownerGroupBalance(group, groupIndex); - require(_liquidatable(balance, group.validatorCount, operators)); + uint64 podIndex = _clusterCurrentIndex(operators); + Pod memory pod = _pods[owner][podId]; + uint64 balance = _ownerPodBalance(pod, podIndex); + require(_liquidatable(balance, pod.validatorCount, operators)); _availableBalances[msg.sender] += balance; uint64 currentBlock = uint64(block.number); { diff --git a/tests/vadimToUpdate.js b/tests/vadimToUpdate.js index e60c3f1d..e12f5ba9 100644 --- a/tests/vadimToUpdate.js +++ b/tests/vadimToUpdate.js @@ -30,7 +30,7 @@ async function log({ action='', operatorIds = [], groupIds = [] }) { for (const id of groupIds) { console.log( `> group #$${id}`, - 'balance', await deployedRegistryContract.groupBalanceOf(owner.address, id), + 'balance', await deployedRegistryContract.podBalanceOf(owner.address, id), ); } } From eeabaf7207ad4280957e41b36469891373cd7faf Mon Sep 17 00:00:00 2001 From: Lior Rutenberg Date: Thu, 25 Aug 2022 16:26:35 +0300 Subject: [PATCH 038/149] init interface with supported events --- contracts/ISSVNetwork.sol | 76 +++++++++++++++++++ contracts/{SSVRegistry.sol => SSVNetwork.sol} | 0 2 files changed, 76 insertions(+) create mode 100644 contracts/ISSVNetwork.sol rename contracts/{SSVRegistry.sol => SSVNetwork.sol} (100%) diff --git a/contracts/ISSVNetwork.sol b/contracts/ISSVNetwork.sol new file mode 100644 index 00000000..8c1dbd8e --- /dev/null +++ b/contracts/ISSVNetwork.sol @@ -0,0 +1,76 @@ + + + +interface ISSVNetwork { + /** + * @dev Emitted when a new operator has been added. + * @param id operator's ID. + * @param owner Operator's ethereum address that can collect fees. + * @param publicKey Operator's public key. Will be used to encrypt secret shares of validators keys. + * @param fee Operator's initial fee. + */ + event OperatorAdded( + uint64 id, + address indexed owner, + bytes publicKey + ); + + /** + * @dev Emitted when operator has been removed. + * @param id operator's ID. + */ + event OperatorRemoved(uint64 id); + + + /** + * @dev Emitted when operator changed fee. + * @param id operator's ID. + * @param fee operator's new fee. + */ + event OperatorFeeSet(uint64 operatorId, uint64 fee); + + + /** + * @dev Emitted when the validator has been added. + * @param publicKey The public key of a validator. + * @param podId The pod id the validator been added to. + * @param shares snappy compressed shares(a set of encrypted and public shares). + */ + event ValidatorAdded( + bytes publicKey, + bytes32 podId, + bytes shares + ); + + /** + * @dev Emitted when validator was transferred between pods. + * @param publicKeys An array of transferred public keys . + * @param podId The validator's new pod id. + * @param shares an array of snappy compressed shares(a set of encrypted and public shares). + */ + event ValidatorTransferred( + bytes publicKey, + bytes32 podId, + bytes shares + ); + + /** + * @dev Emitted when validators were transferred between pods. + * @param publicKeys An array of transferred public keys. + * @param podId The validators new pod id. + * @param shares an array of snappy compressed shares(a set of encrypted and public shares). + */ + event BulkValidatorTransferred( + bytes[] publicKeys, + bytes32 podId, + bytes[] shares + ); + + /** + * @dev Emitted when the validator is removed. + * @param publicKey The public key of a validator. + * @param podId The pod id the validator has been removed from. + */ + event ValidatorRemoved(bytes publicKey, bytes32 podId); + +} \ No newline at end of file diff --git a/contracts/SSVRegistry.sol b/contracts/SSVNetwork.sol similarity index 100% rename from contracts/SSVRegistry.sol rename to contracts/SSVNetwork.sol From 8a35d667b3f477f85b42cb31647d266f540027a0 Mon Sep 17 00:00:00 2001 From: Lior Rutenberg Date: Thu, 25 Aug 2022 17:53:27 +0300 Subject: [PATCH 039/149] interface with supported functions --- contracts/ISSVNetwork.sol | 105 ++++++++++++++- contracts/SSVNetwork.sol | 222 ++++++++++++++++--------------- test/helpers/contract-helpers.ts | 4 +- test/vadimToUpdate.js | 91 ++++++------- 4 files changed, 259 insertions(+), 163 deletions(-) diff --git a/contracts/ISSVNetwork.sol b/contracts/ISSVNetwork.sol index 8c1dbd8e..4abd4535 100644 --- a/contracts/ISSVNetwork.sol +++ b/contracts/ISSVNetwork.sol @@ -1,13 +1,16 @@ - +// File: contracts/ISSVNetwork.sol +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.2; +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; interface ISSVNetwork { + /** * @dev Emitted when a new operator has been added. * @param id operator's ID. * @param owner Operator's ethereum address that can collect fees. * @param publicKey Operator's public key. Will be used to encrypt secret shares of validators keys. - * @param fee Operator's initial fee. */ event OperatorAdded( uint64 id, @@ -21,14 +24,12 @@ interface ISSVNetwork { */ event OperatorRemoved(uint64 id); - /** * @dev Emitted when operator changed fee. * @param id operator's ID. * @param fee operator's new fee. */ - event OperatorFeeSet(uint64 operatorId, uint64 fee); - + event OperatorFeeSet(uint64 id, uint64 fee); /** * @dev Emitted when the validator has been added. @@ -44,9 +45,9 @@ interface ISSVNetwork { /** * @dev Emitted when validator was transferred between pods. - * @param publicKeys An array of transferred public keys . + * @param publicKey The public key of a validator. * @param podId The validator's new pod id. - * @param shares an array of snappy compressed shares(a set of encrypted and public shares). + * @param shares snappy compressed shares(a set of encrypted and public shares). */ event ValidatorTransferred( bytes publicKey, @@ -73,4 +74,94 @@ interface ISSVNetwork { */ event ValidatorRemoved(bytes publicKey, bytes32 podId); + + /** errors */ +// error validatorWithPublicKeyNotExist(); +// error callerNotValidatorOwner(); +// error operatorWithPublicKeyNotExist(); +// error callerNotOperatorOwner(); +// error feeTooLow(); +// error feeExceedsIncreaseLimit(); +// error noPendingFeeChangeRequest(); +// error approvalNotWithinTimeframe(); +// error notEnoughBalance(); +// error burnRatePositive(); +// error accountAlreadyEnabled(); +// error negativeBalance(); + + + /** + * @dev Initializes the contract. + * @param token_ The network token. + */ + function initialize(IERC20 token_) external; + + /** + * @dev Registers a new operator. + * @param publicKey Operator's public key. Used to encrypt secret shares of validators keys. + * @param fee operator's fee. + */ + function registerOperator( + bytes calldata publicKey, + uint64 fee + ) external returns (uint64); + + /** + * @dev Removes an operator. + * @param id Operator's id. + */ + function removeOperator(uint64 id) external; + + /** + * @dev Set operator's fee change request by public key. + * @param id Operator's id. + * @param fee The operator's updated fee. + */ + function updateOperatorFee(uint64 id, uint64 fee) external; + + /** + * @dev Registers a new validator. + * @param publicKey Validator public key. + * @param operatorIds Operator ids. + * @param shares snappy compressed shares(a set of encrypted and public shares). + * @param amount amount of tokens to be deposited for the validator's pod. + */ + function registerValidator( + bytes calldata publicKey, + uint64[] memory operatorIds, + bytes calldata shares, + uint64 amount + ) external; + + /** + * @dev Removes a validator. + * @param publicKey Validator's public key. + */ + function removeValidator(bytes calldata publicKey) external; + + /** + * @dev Transfers a validator. + * @param publicKey Validator public key. + * @param operatorIds new Operator ids(cluster) to transfer the validator to. + * @param shares snappy compressed shares(a set of encrypted and public shares). + * @param amount amount of tokens to be deposited for the validator's pod. + */ + function transferValidator( + bytes calldata publicKey, + uint64[] memory operatorIds, + bytes calldata shares, + uint64 amount + ) external; + + function bulkTransferValidators( + bytes[] calldata validatorPK, + bytes32 fromPodId, + bytes32 toPodId, + bytes[] calldata shares + ) external; + + + + + } \ No newline at end of file diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index 68f2813a..eb4ac99c 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -2,11 +2,15 @@ // SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8.2; +import "./ISSVNetwork.sol"; + import "@openzeppelin/contracts/utils/Counters.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import "hardhat/console.sol"; -contract SSVRegistryNew { +contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { + using Counters for Counters.Counter; struct Snapshot { @@ -49,13 +53,7 @@ contract SSVRegistryNew { bool active; } - event OperatorAdded(uint64 operatorId, address indexed owner, bytes encryptionPK); - event OperatorRemoved(uint64 operatorId); - event OperatorFeeUpdated(uint64 operatorId, uint64 fee); - event ValidatorAdded(bytes validatorPK, bytes32 podId,bytes shares); - event ValidatorTransferedArr(bytes[] validatorPK, bytes32 podId,bytes[] shares); - event ValidatorUpdated(bytes validatorPK, bytes32 podId, bytes shares); - event ValidatorRemoved(bytes validatorPK, bytes32 podId); + // global vars Counters.Counter private lastOperatorId; @@ -80,7 +78,8 @@ contract SSVRegistryNew { DAO private _dao; IERC20 private _token; - constructor() public { + function initialize(IERC20 token_) external initializer override { + _token = token_; } function registerOperator( @@ -115,61 +114,18 @@ contract SSVRegistryNew { _operators[operatorId] = _setFee(operator, fee); - emit OperatorFeeUpdated(operatorId, fee); - } - - function transferValidators( - bytes[] calldata validatorPK, - bytes32 fromPodId, - bytes32 toPodId, - bytes[] calldata shares - ) external { - // _validateValidatorParams - uint64 activeValidatorCount = 0; - - for (uint64 index = 0; index < validatorPK.length; ++index) { - Validator memory validator = _validatorPKs[keccak256(validatorPK[index])]; - - if (validator.owner != msg.sender) { - revert ValidatorNotOwned(); - } - - validator.clusterId = toPodId; - _validatorPKs[keccak256(validatorPK[index])] = validator; - - if (validator.active) { - ++activeValidatorCount; - } - // Changing to a single event reducing by 15K gas - } - emit ValidatorTransferedArr(validatorPK, toPodId, shares); - - uint64[] memory newOperatorIds = _clusters[toPodId].operatorIds; - - _updateOperatorsValidatorMove(_clusters[fromPodId].operatorIds, newOperatorIds, activeValidatorCount); - - Pod memory pod = _pods[keccak256(abi.encodePacked(msg.sender, fromPodId))]; - pod.usage.index = _clusterCurrentIndex(fromPodId); - pod.usage.block = uint64(block.number); - pod.validatorCount -= activeValidatorCount; - - pod = _pods[keccak256(abi.encodePacked(msg.sender, toPodId))]; - pod.usage.index = _clusterCurrentIndex(toPodId); - pod.usage.block = uint64(block.number); - pod.validatorCount += activeValidatorCount; - - require(!_liquidatable(pod.balance, pod.validatorCount, newOperatorIds), "account liquidatable"); + emit OperatorFeeSet(operatorId, fee); } function registerValidator( + bytes calldata publicKey, uint64[] memory operatorIds, - bytes calldata validatorPK, bytes calldata shares, uint64 amount ) external { _validateValidatorParams( operatorIds, - validatorPK + publicKey ); // Operator[] memory operators; @@ -201,73 +157,29 @@ contract SSVRegistryNew { _pods[keccak256(abi.encodePacked(msg.sender, clusterId))] = pod; } - _validatorPKs[keccak256(validatorPK)] = Validator({ owner: msg.sender, clusterId: clusterId, active: true}); - - emit ValidatorAdded(validatorPK, clusterId, shares); - } - - function _updateOperatorsValidatorMove( - uint64[] memory oldOperatorIds, - uint64[] memory newOperatorIds, - uint64 validatorCount - ) private { - uint64 oldIndex; - uint64 newIndex; - - while (oldIndex < oldOperatorIds.length && newIndex < newOperatorIds.length) { - if (oldOperatorIds[oldIndex] < newOperatorIds[newIndex]) { - Operator memory operator = _operators[oldOperatorIds[oldIndex]]; - operator.earnings = _updateOperatorEarnings(operator); - operator.validatorCount -= validatorCount; - _operators[oldOperatorIds[oldIndex]] = operator; - ++oldIndex; - } else if (newOperatorIds[newIndex] < oldOperatorIds[oldIndex]) { - Operator memory operator = _operators[newOperatorIds[newIndex]]; - operator.earnings = _updateOperatorEarnings(operator); - operator.validatorCount += validatorCount; - _operators[newOperatorIds[newIndex]] = operator; - ++newIndex; - } else { - ++oldIndex; - ++newIndex; - } - } - - while (oldIndex < oldOperatorIds.length) { - Operator memory operator = _operators[oldOperatorIds[oldIndex]]; - operator.earnings = _updateOperatorEarnings(operator); - operator.validatorCount -= validatorCount; - _operators[oldOperatorIds[oldIndex]] = operator; - ++oldIndex; - } + _validatorPKs[keccak256(publicKey)] = Validator({ owner: msg.sender, clusterId: clusterId, active: true}); - while (newIndex < newOperatorIds.length) { - Operator memory operator = _operators[newOperatorIds[newIndex]]; - operator.earnings = _updateOperatorEarnings(operator); - operator.validatorCount += validatorCount; - _operators[newOperatorIds[newIndex]] = operator; - ++newIndex; - } + emit ValidatorAdded(publicKey, clusterId, shares); } - function updateValidator( + function transferValidator( + bytes calldata publicKey, uint64[] memory operatorIds, - bytes calldata validatorPK, bytes calldata shares, uint64 amount ) external { uint64 currentBlock = uint64(block.number); - bytes32 clusterId = _validatorPKs[keccak256(validatorPK)].clusterId; + bytes32 clusterId = _validatorPKs[keccak256(publicKey)].clusterId; - if (_validatorPKs[keccak256(validatorPK)].owner != msg.sender) { + if (_validatorPKs[keccak256(publicKey)].owner != msg.sender) { revert ValidatorNotOwned(); } { _pods[keccak256(abi.encodePacked(msg.sender, clusterId))] = _updatePodData(clusterId, 0, false); // if (pod.validatorCount == 0) { - // _availableBalances[msg.sender] += _ownerPodBalance(pod, podIndex); - // pod.balance -= _ownerPodBalance(pod, podIndex); + // _availableBalances[msg.sender] += _ownerPodBalance(pod, podIndex); + // pod.balance -= _ownerPodBalance(pod, podIndex); // } } @@ -286,7 +198,7 @@ contract SSVRegistryNew { _availableBalances[msg.sender] -= amount; _pods[keccak256(abi.encodePacked(msg.sender, newClusterId))] = _updatePodData(newClusterId, amount, true); - _validatorPKs[keccak256(validatorPK)].clusterId = newClusterId; + _validatorPKs[keccak256(publicKey)].clusterId = newClusterId; } { @@ -298,7 +210,7 @@ contract SSVRegistryNew { require(!_liquidatable(pod.balance, pod.validatorCount, operatorIds), "account liquidatable"); } - emit ValidatorUpdated(validatorPK, newClusterId, shares); + emit ValidatorTransferred(publicKey, newClusterId, shares); } } @@ -348,6 +260,98 @@ contract SSVRegistryNew { emit ValidatorRemoved(validatorPK, clusterId); } + function bulkTransferValidators( + bytes[] calldata validatorPK, + bytes32 fromPodId, + bytes32 toPodId, + bytes[] calldata shares + ) external { + // _validateValidatorParams + uint64 activeValidatorCount = 0; + + for (uint64 index = 0; index < validatorPK.length; ++index) { + Validator memory validator = _validatorPKs[keccak256(validatorPK[index])]; + + if (validator.owner != msg.sender) { + revert ValidatorNotOwned(); + } + + validator.clusterId = toPodId; + _validatorPKs[keccak256(validatorPK[index])] = validator; + + if (validator.active) { + ++activeValidatorCount; + } + // Changing to a single event reducing by 15K gas + } + emit BulkValidatorTransferred(validatorPK, toPodId, shares); + + uint64[] memory newOperatorIds = _clusters[toPodId].operatorIds; + + _updateOperatorsValidatorMove(_clusters[fromPodId].operatorIds, newOperatorIds, activeValidatorCount); + + Pod memory pod = _pods[keccak256(abi.encodePacked(msg.sender, fromPodId))]; + pod.usage.index = _clusterCurrentIndex(fromPodId); + pod.usage.block = uint64(block.number); + pod.validatorCount -= activeValidatorCount; + + pod = _pods[keccak256(abi.encodePacked(msg.sender, toPodId))]; + pod.usage.index = _clusterCurrentIndex(toPodId); + pod.usage.block = uint64(block.number); + pod.validatorCount += activeValidatorCount; + + require(!_liquidatable(pod.balance, pod.validatorCount, newOperatorIds), "account liquidatable"); + } + + + // TODO add external functions below to interface + + + function _updateOperatorsValidatorMove( + uint64[] memory oldOperatorIds, + uint64[] memory newOperatorIds, + uint64 validatorCount + ) private { + uint64 oldIndex; + uint64 newIndex; + + while (oldIndex < oldOperatorIds.length && newIndex < newOperatorIds.length) { + if (oldOperatorIds[oldIndex] < newOperatorIds[newIndex]) { + Operator memory operator = _operators[oldOperatorIds[oldIndex]]; + operator.earnings = _updateOperatorEarnings(operator); + operator.validatorCount -= validatorCount; + _operators[oldOperatorIds[oldIndex]] = operator; + ++oldIndex; + } else if (newOperatorIds[newIndex] < oldOperatorIds[oldIndex]) { + Operator memory operator = _operators[newOperatorIds[newIndex]]; + operator.earnings = _updateOperatorEarnings(operator); + operator.validatorCount += validatorCount; + _operators[newOperatorIds[newIndex]] = operator; + ++newIndex; + } else { + ++oldIndex; + ++newIndex; + } + } + + while (oldIndex < oldOperatorIds.length) { + Operator memory operator = _operators[oldOperatorIds[oldIndex]]; + operator.earnings = _updateOperatorEarnings(operator); + operator.validatorCount -= validatorCount; + _operators[oldOperatorIds[oldIndex]] = operator; + ++oldIndex; + } + + while (newIndex < newOperatorIds.length) { + Operator memory operator = _operators[newOperatorIds[newIndex]]; + operator.earnings = _updateOperatorEarnings(operator); + operator.validatorCount += validatorCount; + _operators[newOperatorIds[newIndex]] = operator; + ++newIndex; + } + } + + function _setFee(Operator memory operator, uint64 fee) private returns (Operator memory) { operator.earnings = _updateOperatorEarnings(operator); operator.fee = fee; diff --git a/test/helpers/contract-helpers.ts b/test/helpers/contract-helpers.ts index c115393f..7c3ee073 100644 --- a/test/helpers/contract-helpers.ts +++ b/test/helpers/contract-helpers.ts @@ -9,8 +9,8 @@ export const initializeContract = async (numberOfOperators: number, fee: number) const [owner] = await ethers.getSigners(); // Initialize contract - const registry = await ethers.getContractFactory("SSVRegistryNew") - const deployedRegistryContract = await registry.deploy() + const ssvNetwork = await ethers.getContractFactory("SSVNetwork") + const deployedRegistryContract = await ssvNetwork.deploy() await deployedRegistryContract.deployed(); // Register Operators diff --git a/test/vadimToUpdate.js b/test/vadimToUpdate.js index e12f5ba9..564afee7 100644 --- a/test/vadimToUpdate.js +++ b/test/vadimToUpdate.js @@ -10,7 +10,7 @@ async function mineNBlocks(n) { } const operatorsIndexes = Array.from(Array(5).keys()).map(k => k + 1); -let deployedRegistryContract; +let deployedSSVNetworkContract; async function log({ action='', operatorIds = [], groupIds = [] }) { console.log(`[BLOCK] ${await blockNumber()}`) @@ -21,7 +21,7 @@ async function log({ action='', operatorIds = [], groupIds = [] }) { for (const id of operatorIds) { console.log( `> operator #${id}`, - 'balance', await deployedRegistryContract.operatorEarningsOf(id), + 'balance', await deployedSSVNetworkContract.operatorEarningsOf(id), ); } } @@ -30,7 +30,7 @@ async function log({ action='', operatorIds = [], groupIds = [] }) { for (const id of groupIds) { console.log( `> group #$${id}`, - 'balance', await deployedRegistryContract.podBalanceOf(owner.address, id), + 'balance', await deployedSSVNetworkContract.podBalanceOf(owner.address, id), ); } } @@ -38,17 +38,17 @@ async function log({ action='', operatorIds = [], groupIds = [] }) { describe("Validators", () => { beforeEach(async () => { - const Registry = await ethers.getContractFactory("SSVRegistryNew"); - deployedRegistryContract = await Registry.deploy(); - await deployedRegistryContract.deployed(); + const SSVNetwork = await ethers.getContractFactory("SSVNetwork"); + deployedSSVNetworkContract = await SSVNetwork.deploy(); + await deployedSSVNetworkContract.deployed(); await progressBlocks(99); for (let i = 0; i < 8; i++) { // operatorsIndexes.length var encryptionPK = "0x123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123451"; - await (await deployedRegistryContract.registerOperator(encryptionPK, operator_fee_block)).wait(); + await (await deployedSSVNetworkContract.registerOperator(encryptionPK, operator_fee_block)).wait(); await log({ action: `register operator #${i+1}` }); } - // await deployedRegistryContract.addOperatorToValidator([], operatorsIndexes, []); + // await deployedSSVNetworkContract.addOperatorToValidator([], operatorsIndexes, []); }) it("should register validator", async () => { @@ -57,19 +57,19 @@ describe("Validators", () => { const encryptedShares = Array.from(Array(10).keys()).map(k => `0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765${k}98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765${k}`); // const operatorsIndexes = Array.from(Array(10).keys()).map(k => k + 1); - // await deployedRegistryContract.createGroup([1,2,3,4]); - // await deployedRegistryContract.createGroup([1,2,3,4]); + // await deployedSSVNetworkContract.createGroup([1,2,3,4]); + // await deployedSSVNetworkContract.createGroup([1,2,3,4]); - await deployedRegistryContract.deposit("100000000000"); + await deployedSSVNetworkContract.deposit("100000000000"); await log({ action: 'deposit', operatorIds: [1, 2, 3, 4] }); // validator 1 await progressBlocks(97); - let resultRegister = (await (await deployedRegistryContract.registerValidator( - [1,2,3,4], + let resultRegister = (await (await deployedSSVNetworkContract.registerValidator( validatorPK + "f", + [1,2,3,4], sharePKs[0], '10000' )).wait()).logs[0]; @@ -86,15 +86,15 @@ describe("Validators", () => { groupIds: [outputRegister.groupId] }); - let resultUpdate = (await (await deployedRegistryContract.updateValidator( - [4,5,6,7], + let resultUpdate = (await (await deployedSSVNetworkContract.transferValidator( validatorPK + "f", + [4,5,6,7], sharePKs[2], '10000' )).wait()).logs[0]; - let interfaceUpdate = new ethers.utils.Interface(['event ValidatorUpdated(bytes validatorPK, bytes32 groupId, bytes shares)']); - let outputUpdate = interfaceUpdate.decodeEventLog('ValidatorUpdated', resultUpdate.data, resultUpdate.topics); + let interfaceUpdate = new ethers.utils.Interface(['event ValidatorTransferred(bytes validatorPK, bytes32 groupId, bytes shares)']); + let outputUpdate = interfaceUpdate.decodeEventLog('ValidatorTransferred', resultUpdate.data, resultUpdate.topics); expect(outputRegister.groupId).not.equal(outputUpdate.groupId); expect(outputRegister.validatorPK).to.equal(outputUpdate.validatorPK); @@ -115,14 +115,14 @@ describe("Validators", () => { }); // move back validator 1 to group 1 - resultRegister = (await (await deployedRegistryContract.updateValidator( - [1,2,3,4], + resultRegister = (await (await deployedSSVNetworkContract.transferValidator( validatorPK + "f", + [1,2,3,4], sharePKs[1], '10000' )).wait()).logs[0]; - interfaceRegister = new ethers.utils.Interface(['event ValidatorUpdated(bytes validatorPK, bytes32 groupId)']); // , bytes[] sharesPublicKeys, bytes[] encryptedShares - outputRegister = interfaceUpdate.decodeEventLog('ValidatorUpdated', resultRegister.data, resultRegister.topics); + interfaceRegister = new ethers.utils.Interface(['event ValidatorTransferred(bytes validatorPK, bytes32 groupId)']); // , bytes[] sharesPublicKeys, bytes[] encryptedShares + outputRegister = interfaceUpdate.decodeEventLog('ValidatorTransferred', resultRegister.data, resultRegister.topics); await log({ action: `update validator #1: ${outputRegister.validatorPK} : ${outputRegister.groupId}`, operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], @@ -134,9 +134,9 @@ describe("Validators", () => { groupIds: [outputRegister.groupId, outputUpdate.groupId] }); - const resultRegister2 = (await (await deployedRegistryContract.registerValidator( - [1,2,3,4], + const resultRegister2 = (await (await deployedSSVNetworkContract.registerValidator( validatorPK + "a", + [1,2,3,4], sharePKs[1], "1000" )).wait()).logs[0]; @@ -150,13 +150,14 @@ describe("Validators", () => { }); - const resultRegister3 = (await (await deployedRegistryContract.registerValidator( - [5,6,7,8], + const resultRegister3 = (await (await deployedSSVNetworkContract.registerValidator( validatorPK + "b", + [5,6,7,8], sharePKs[1], "1000000" )).wait()).logs[0]; + const interfaceRegister3 = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId, bytes shares)']); const outputRegister3 = interfaceRegister3.decodeEventLog('ValidatorAdded', resultRegister3.data, resultRegister3.topics); await log({ @@ -177,7 +178,7 @@ describe("Validators", () => { operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], groupIds: [outputRegister.groupId, outputRegister2.groupId] }); - await (await deployedRegistryContract.updateOperatorFee( + await (await deployedSSVNetworkContract.updateOperatorFee( 1, 2 )).wait(); @@ -198,7 +199,7 @@ describe("Validators", () => { }); - await (await deployedRegistryContract.removeValidator(outputRegister2.validatorPK)).wait(); + await (await deployedSSVNetworkContract.removeValidator(outputRegister2.validatorPK)).wait(); await log({ action: 'remove validator #2', operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], @@ -218,9 +219,9 @@ describe("Validators", () => { await progressBlocks(1); let results = [] for (let i = 0; i < 20; ++i) { - let resultRegister = (await (await deployedRegistryContract.registerValidator( - [1,2,3,4], + let resultRegister = (await (await deployedSSVNetworkContract.registerValidator( validatorPK + i % 10, + [1,2,3,4], sharePKs[2], '10000' )).wait()).logs[0]; @@ -233,34 +234,34 @@ describe("Validators", () => { console.log("outputRegister.groupId,outputRegister2.groupId") console.log(outputRegister.groupId,outputRegister3.groupId) - const transferLogs = (await (await deployedRegistryContract.transferValidators( + const transferLogs = (await (await deployedSSVNetworkContract.bulkTransferValidators( results.map(r => r.validatorPK), outputRegister.groupId, outputRegister3.groupId, results.map(r => sharePKs[4]) )).wait()).logs; - return; - await log({ - action: 'transfer', - operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], - groupIds: [outputRegister.groupId, resultRegister3.groupId] - }); + + // await log({ + // action: 'transfer', + // operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], + // groupIds: [outputRegister.groupId, resultRegister3.groupId] + // }); /* // validator 2 - await expect(await deployedRegistryContract.registerValidator( + await expect(await deployedSSVNetworkContract.registerValidator( [1,2,3,4], validatorPK, sharePKs.slice(0, 4), encryptedShares.slice(0, 4), "10000" )) - .to.emit(deployedRegistryContract, 'ValidatorAdded'); + .to.emit(deployedSSVNetworkContract, 'ValidatorAdded'); // .withArgs(validatorPK); - const resultRegister = (await (await deployedRegistryContract.registerValidator( + const resultRegister = (await (await deployedSSVNetworkContract.registerValidator( [1,2,3,4], validatorPK, sharePKs.slice(0, 4), @@ -272,9 +273,9 @@ describe("Validators", () => { expect(outputRegister.validatorPK).to.equal(validatorPK); console.log("register ---->", outputRegister.validatorPK, outputRegister.groupId); - console.log("operatorIdsAfterRegister ---->", await deployedRegistryContract.test_getOperatorsByGroupId(outputRegister.groupId)); + console.log("operatorIdsAfterRegister ---->", await deployedSSVNetworkContract.test_getOperatorsByGroupId(outputRegister.groupId)); - const resultUpdate = (await (await deployedRegistryContract.updateValidator( + const resultUpdate = (await (await deployedSSVNetworkContract.updateValidator( [2,3,4,5], validatorPK, outputRegister.groupId, @@ -286,16 +287,16 @@ describe("Validators", () => { expect(outputRegister.validatorPK).to.equal(outputUpdate.validatorPK); console.log("update ---->", outputUpdate.validatorPK, outputUpdate.groupId); - console.log("operatorIdsAfterUpdate ---->", await deployedRegistryContract.test_getOperatorsByGroupId(outputUpdate.groupId)); + console.log("operatorIdsAfterUpdate ---->", await deployedSSVNetworkContract.test_getOperatorsByGroupId(outputUpdate.groupId)); - await expect(await deployedRegistryContract.removeValidator( + await expect(await deployedSSVNetworkContract.removeValidator( validatorPK, outputUpdate.groupId )) - .to.emit(deployedRegistryContract, 'ValidatorRemoved') + .to.emit(deployedSSVNetworkContract, 'ValidatorRemoved') .withArgs(validatorPK, outputUpdate.groupId); */ - // await deployedRegistryContract.liquidate("0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", "0x392791df626408017a264f53fde61065d5a93a32b60171df9d8a46afdf82992d"); + // await deployedSSVNetworkContract.liquidate("0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", "0x392791df626408017a264f53fde61065d5a93a32b60171df9d8a46afdf82992d"); }); }); From b8b16bd51d89bf7f36c5753dac698507dfee675c Mon Sep 17 00:00:00 2001 From: Adam Zigdon Date: Thu, 25 Aug 2022 18:25:21 +0300 Subject: [PATCH 040/149] add gas usage tracking --- test/helpers/contract-helpers.ts | 8 +++- test/helpers/gas-usage.ts | 49 +++++++++++++++++++++ test/operators/register.ts | 9 ++-- test/validators/gas/1-operator-different.ts | 1 - test/validators/register.ts | 7 +-- 5 files changed, 64 insertions(+), 10 deletions(-) create mode 100644 test/helpers/gas-usage.ts diff --git a/test/helpers/contract-helpers.ts b/test/helpers/contract-helpers.ts index 7c3ee073..03bc4213 100644 --- a/test/helpers/contract-helpers.ts +++ b/test/helpers/contract-helpers.ts @@ -1,6 +1,8 @@ // Imports declare const ethers: any +const { trackGas, getGasStats } = require('./gas-usage'); + // Generate shares const shares = Array.from(Array(10).keys()).map(k => `0xe0096008000000b4010000040000001000000076000000dc000000420d142c307831323334353637383930fe0a00520a000031017afe66008266000032fe66009266000033fe66009266000034016621ac28d60000009c01000062020025c02c307839383736353433323130fe0a00520a000031fe560052560019b0003101dafec60082c6000032fec6007ac6004d6ca666000033ceb401fe8c017e8c014dcca6c6004d7a0035b23200fec6007ec6000034${k}${k}`) @@ -37,12 +39,14 @@ export const registerValidators = async (numberOfValidators: number, amount: str const randomOperator = Math.floor(Math.random() * (operatorAmount - 4)) const validatorPK = `0xa7ae1ea93b860ca0269ccca776b4526977395aa194e5820a00dedbf1cd63e7a898eec9a12f539f733ea4df9c651f${i}` - const registerResult = (await (await contract.registerValidator( + const receipt = await trackGas(contract.registerValidator( [randomOperator, randomOperator + 1, randomOperator + 2, randomOperator + 3], validatorPK, shares[0], amount, - )).wait()).logs[0] + ), 'registerValidator', 400000); + + const registerResult = receipt.logs[0] // Save validator group id emits let interfaceRegister = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId, bytes shares)']); diff --git a/test/helpers/gas-usage.ts b/test/helpers/gas-usage.ts new file mode 100644 index 00000000..9d633fb3 --- /dev/null +++ b/test/helpers/gas-usage.ts @@ -0,0 +1,49 @@ +export class GasStats { + max: number | null = null; + min: number | null = null; + totalGas: number = 0; + txCount: number = 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); + } + + get average(): number { + return this.totalGas / this.txCount; + } +} + + +const gasUsageStats = new Map(); + +const getOrCreate = (group: string) => { + let groupStats = gasUsageStats.get(group); + + if (!groupStats) { + groupStats = new GasStats(); + gasUsageStats.set(group, groupStats); + } + + return groupStats; +} + +export const trackGas = async (tx: Promise, group: string, maxGas: number) => { + const receipt = await (await tx).wait(); + + if (receipt.gasUsed > maxGas) { + throw new Error(`Gas usage too high. Max: ${maxGas}, Actual: ${receipt.gasUsed}`); + } + + const groupStats = getOrCreate(group); + + groupStats.addStat(parseInt(receipt.gasUsed)); + + return receipt; +} + +export const getGasStats = (group: string) => { + return gasUsageStats.get(group) || new GasStats(); +} \ No newline at end of file diff --git a/test/operators/register.ts b/test/operators/register.ts index f1d7f46e..30450aa0 100644 --- a/test/operators/register.ts +++ b/test/operators/register.ts @@ -1,4 +1,5 @@ const { expect } = require("chai"); +const { trackGas } = require("../helpers/gas-usage"); import * as helpers from "../helpers/contract-helpers" let registryContract: any, operatorIDs: any, shares: any, owner: any @@ -25,12 +26,12 @@ describe("Register Operator Tests", () => { const validatorPK = `0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100` // Cost: 364101 - await registryContract.registerValidator( - [1, 2, 3, 4], + await trackGas(registryContract.registerValidator( `${validatorPK}0`, + [1, 2, 3, 4], shares[0], "10000" - ) + ), 'registerValidator', 400000); // // Cost: 185380 // await deployedRegistryContract.registerValidator( @@ -43,8 +44,8 @@ describe("Register Operator Tests", () => { // Cost: 295713 await registryContract.registerValidator( - [1, 2, 5, 6], `${validatorPK}1`, + [1, 2, 5, 6], shares[1], "10000" ) diff --git a/test/validators/gas/1-operator-different.ts b/test/validators/gas/1-operator-different.ts index 64ac80df..af907b45 100644 --- a/test/validators/gas/1-operator-different.ts +++ b/test/validators/gas/1-operator-different.ts @@ -30,5 +30,4 @@ describe("Register Validator Gas Tests 1 Operator Different", () => { "10000" ) }) - }); diff --git a/test/validators/register.ts b/test/validators/register.ts index 040b7a07..6114d262 100644 --- a/test/validators/register.ts +++ b/test/validators/register.ts @@ -1,4 +1,5 @@ const { expect } = require("chai"); +import { trackGas } from "../helpers/gas-usage" import * as helpers from "../helpers/contract-helpers" let registryContract: any, operatorIDs: any, shares: any, owner: any @@ -15,12 +16,12 @@ describe("Register Validator Tests", () => { it("Register validator", async () => { const validatorPK = `0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100` - await registryContract.registerValidator( - [1, 2, 3, 4], + await trackGas(registryContract.registerValidator( `${validatorPK}0`, + [1, 2, 3, 4], shares[0], "10000" - ) + ), 'registerValidator', 500000); }) it("Register validator errors", async () => { From 6a1d5ed6db43e875a9d041f26e64aa5389a5959d Mon Sep 17 00:00:00 2001 From: Vadim Date: Tue, 30 Aug 2022 16:33:15 +0200 Subject: [PATCH 041/149] eslint fixes, runTx, changed validators tests --- .editorconfig | 16 + .eslintrc.js | 27 + contracts/SSVNetwork.sol | 2 - hardhat.config.ts | 2 +- package-lock.json | 2339 ++++++++++++++++--- package.json | 6 + test/account/deposit.ts | 40 +- test/account/withdraw.ts | 38 +- test/dao/network-fee-change.ts | 38 +- test/dao/network-fee-withdraw.ts | 38 +- test/helpers/contract-helpers.ts | 38 +- test/helpers/gas-usage.ts | 11 +- test/helpers/utils.ts | 78 +- test/liquidate/liquidate.ts | 42 +- test/liquidate/liquidation-threshold.ts | 43 +- test/operators/register.ts | 118 +- test/operators/remove.ts | 38 +- test/operators/update.ts | 38 +- test/sanity/balances.ts | 251 +- test/sanity/stress.ts | 105 +- test/validators/gas/1-operator-different.ts | 56 +- test/validators/gas/2-operator-different.ts | 66 +- test/validators/gas/3-operator-different.ts | 66 +- test/validators/gas/4-operator-different.ts | 66 +- test/validators/gas/different-group.ts | 66 +- test/validators/gas/same-group.ts | 66 +- test/validators/register.ts | 98 +- test/validators/remove.ts | 38 +- test/validators/transfer.ts | 70 + test/validators/update.ts | 28 - 30 files changed, 2838 insertions(+), 1090 deletions(-) create mode 100644 .editorconfig create mode 100644 .eslintrc.js create mode 100644 test/validators/transfer.ts delete mode 100644 test/validators/update.ts diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..e638e9b2 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,16 @@ +root = true + +[*.{ts,json,js}] +charset = utf-8 +end_of_line = lf +indent_size = 2 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true + +[*.yml] +indent_size = 2 + +[*.md] +max_line_length = off +trim_trailing_whitespace = false diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 00000000..66e95efb --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,27 @@ +module.exports = { + parser: '@typescript-eslint/parser', + parserOptions: { + project: 'tsconfig.json', + sourceType: 'module', + }, + plugins: ['@typescript-eslint/eslint-plugin'], + extends: [ + 'plugin:@typescript-eslint/recommended', + ], + root: true, + env: { + node: true, + jest: true, + }, + ignorePatterns: ['.eslintrc.js', 'hardhat.config.ts'], + rules: { + '@typescript-eslint/interface-name-prefix': 'off', + '@typescript-eslint/explicit-function-return-type': 'off', + '@typescript-eslint/explicit-module-boundary-types': 'off', + '@typescript-eslint/no-explicit-any': 'off', + 'indent': ['error', 2], + 'semi': [2, 'always'], + 'quotes': [2, 'single', 'avoid-escape'], + '@typescript-eslint/no-empty-function': 0, + }, +}; diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index eb4ac99c..4b26f241 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -98,8 +98,6 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { Operator memory operator = _operators[operatorId]; require(operator.owner == msg.sender, "not owner"); - uint64 currentBlock = uint64(block.number); - operator.earnings = _updateOperatorEarnings(operator); operator.fee = 0; operator.validatorCount = 0; diff --git a/hardhat.config.ts b/hardhat.config.ts index 58ea9a19..64b926de 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -65,4 +65,4 @@ if (process.env.MAINNET_ETH_NODE_URL) { }; } -export default config; \ No newline at end of file +export default config; diff --git a/package-lock.json b/package-lock.json index c9a33077..d3afd37a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,10 +18,12 @@ "@types/cli-table": "^0.3.0", "@types/mocha": "^9.1.0", "@types/node": "^17.0.23", + "@typescript-eslint/eslint-plugin": "^5.36.0", "chai": "^4.3.6", "chai-as-promised": "^7.1.1", "cli-table": "^0.3.11", "dotenv": "^16.0.0", + "eslint": "^8.23.0", "ethereum-public-key-to-address": "0.0.5", "ethereum-waffle": "^3.4.4", "ethers": "^5.6.2", @@ -38,29 +40,38 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", - "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", "dev": true, "dependencies": { - "@babel/highlight": "^7.12.13" + "@babel/highlight": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz", - "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==", - "dev": true + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz", + "integrity": "sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } }, "node_modules/@babel/highlight": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz", - "integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.14.0", + "@babel/helper-validator-identifier": "^7.18.6", "chalk": "^2.0.0", "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/highlight/node_modules/ansi-styles": { @@ -101,13 +112,13 @@ "node_modules/@babel/highlight/node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, "node_modules/@babel/highlight/node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, "engines": { "node": ">=4" @@ -462,6 +473,96 @@ "deprecated": "Please use @ensdomains/ens-contracts", "dev": true }, + "node_modules/@eslint/eslintrc": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.1.tgz", + "integrity": "sha512-OhSY22oQQdw3zgPOOwdoj01l/Dzl1Z+xyUP33tkSN+aqyEhymJCcPHyXt+ylW8FSe0TfRC2VG+ROQOapD0aZSQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.4.0", + "globals": "^13.15.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" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/@eslint/eslintrc/node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/eslintrc/node_modules/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, + "engines": { + "node": ">=4" + } + }, + "node_modules/@eslint/eslintrc/node_modules/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, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@ethereum-waffle/chai": { "version": "3.4.4", "resolved": "https://registry.npmjs.org/@ethereum-waffle/chai/-/chai-3.4.4.tgz", @@ -1335,6 +1436,49 @@ "@ethersproject/strings": "^5.6.0" } }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.4.tgz", + "integrity": "sha512-mXAIHxZT3Vcpg83opl1wGlVZ9xydbfZO3r5YfRSH6Gpp2J/PfdBP0wbDa2sO6/qRbcalpoevVyW6A/fI6LfeMw==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/gitignore-to-minimatch": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz", + "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@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, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "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==", + "dev": true + }, "node_modules/@kwsites/file-exists": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz", @@ -1999,6 +2143,12 @@ "@types/node": "*" } }, + "node_modules/@types/json-schema": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "dev": true + }, "node_modules/@types/level-errors": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/level-errors/-/level-errors-3.0.0.tgz", @@ -2147,6 +2297,309 @@ "@types/underscore": "*" } }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "5.36.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.36.0.tgz", + "integrity": "sha512-X3In41twSDnYRES7hO2xna4ZC02SY05UN9sGW//eL1P5k4CKfvddsdC2hOq0O3+WU1wkCPQkiTY9mzSnXKkA0w==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "5.36.0", + "@typescript-eslint/type-utils": "5.36.0", + "@typescript-eslint/utils": "5.36.0", + "debug": "^4.3.4", + "functional-red-black-tree": "^1.0.1", + "ignore": "^5.2.0", + "regexpp": "^3.2.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/eslint-plugin/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, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/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 + }, + "node_modules/@typescript-eslint/parser": { + "version": "5.36.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.36.0.tgz", + "integrity": "sha512-dlBZj7EGB44XML8KTng4QM0tvjI8swDh8MdpE5NX5iHWgWEfIuqSfSE+GPeCrCdj7m4tQLuevytd57jNDXJ2ZA==", + "dev": true, + "peer": true, + "dependencies": { + "@typescript-eslint/scope-manager": "5.36.0", + "@typescript-eslint/types": "5.36.0", + "@typescript-eslint/typescript-estree": "5.36.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "5.36.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.36.0.tgz", + "integrity": "sha512-PZUC9sz0uCzRiuzbkh6BTec7FqgwXW03isumFVkuPw/Ug/6nbAqPUZaRy4w99WCOUuJTjhn3tMjsM94NtEj64g==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.36.0", + "@typescript-eslint/visitor-keys": "5.36.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "5.36.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.36.0.tgz", + "integrity": "sha512-W/E3yJFqRYsjPljJ2gy0YkoqLJyViWs2DC6xHkXcWyhkIbCDdaVnl7mPLeQphVI+dXtY05EcXFzWLXhq8Mm/lQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "5.36.0", + "@typescript-eslint/utils": "5.36.0", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "5.36.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.36.0.tgz", + "integrity": "sha512-3JJuLL1r3ljRpFdRPeOtgi14Vmpx+2JcR6gryeORmW3gPBY7R1jNYoq4yBN1L//ONZjMlbJ7SCIwugOStucYiQ==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "5.36.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.36.0.tgz", + "integrity": "sha512-EW9wxi76delg/FS9+WV+fkPdwygYzRrzEucdqFVWXMQWPOjFy39mmNNEmxuO2jZHXzSQTXzhxiU1oH60AbIw9A==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.36.0", + "@typescript-eslint/visitor-keys": "5.36.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@typescript-eslint/typescript-estree/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, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@typescript-eslint/typescript-estree/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 + }, + "node_modules/@typescript-eslint/utils": { + "version": "5.36.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.36.0.tgz", + "integrity": "sha512-wAlNhXXYvAAUBbRmoJDywF/j2fhGLBP4gnreFvYvFbtlsmhMJ4qCKVh/Z8OP4SgGR3xbciX2nmG639JX0uw1OQ==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "@typescript-eslint/scope-manager": "5.36.0", + "@typescript-eslint/types": "5.36.0", + "@typescript-eslint/typescript-estree": "5.36.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/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, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "5.36.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.36.0.tgz", + "integrity": "sha512-pdqSJwGKueOrpjYIex0T39xarDt1dn4p7XJ+6FqBWugNQwXlNGC5h62qayAIYZ/RPPtD+ButDWmpXT1eGtiaYg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.36.0", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@ungap/promise-all-settled": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", @@ -2207,9 +2660,9 @@ } }, "node_modules/acorn": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", - "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", + "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -2219,9 +2672,9 @@ } }, "node_modules/acorn-jsx": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", - "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" @@ -3249,7 +3702,7 @@ "node_modules/cli-cursor": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "integrity": "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==", "dev": true, "dependencies": { "restore-cursor": "^2.0.0" @@ -4330,155 +4783,206 @@ } }, "node_modules/eslint": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz", - "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "ajv": "^6.9.1", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", - "debug": "^4.0.1", + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.23.0.tgz", + "integrity": "sha512-pBG/XOn0MsJcKcTRLr27S5HpzQo4kLr+HjLQIyK4EiCsijDl/TB+h5uEuJU6bQ8Edvwz1XWOjpaP2qgnXGpTcA==", + "dev": true, + "dependencies": { + "@eslint/eslintrc": "^1.3.1", + "@humanwhocodes/config-array": "^0.10.4", + "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", + "@humanwhocodes/module-importer": "^1.0.1", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", "doctrine": "^3.0.0", - "eslint-scope": "^4.0.3", - "eslint-utils": "^1.3.1", - "eslint-visitor-keys": "^1.0.0", - "espree": "^5.0.1", - "esquery": "^1.0.1", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.4.0", + "esquery": "^1.4.0", "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", "functional-red-black-tree": "^1.0.1", - "glob": "^7.1.2", - "globals": "^11.7.0", - "ignore": "^4.0.6", + "glob-parent": "^6.0.1", + "globals": "^13.15.0", + "globby": "^11.1.0", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", - "inquirer": "^6.2.2", - "js-yaml": "^3.13.0", + "is-glob": "^4.0.0", + "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.11", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "path-is-inside": "^1.0.2", - "progress": "^2.0.0", - "regexpp": "^2.0.1", - "semver": "^5.5.1", - "strip-ansi": "^4.0.0", - "strip-json-comments": "^2.0.1", - "table": "^5.2.3", + "optionator": "^0.9.1", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" }, "bin": { "eslint": "bin/eslint.js" }, "engines": { - "node": "^6.14.0 || ^8.10.0 || >=9.10.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", "dev": true, "dependencies": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" }, "engines": { - "node": ">=4.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/eslint-scope/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, "engines": { "node": ">=4.0" } }, "node_modules/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==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", "dev": true, "dependencies": { - "eslint-visitor-keys": "^1.1.0" + "eslint-visitor-keys": "^2.0.0" }, "engines": { - "node": ">=6" + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "engines": { + "node": ">=10" } }, "node_modules/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==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", "dev": true, "engines": { - "node": ">=4" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/eslint/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==", + "node_modules/eslint/node_modules/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, - "dependencies": { - "color-convert": "^1.9.0" - }, "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/eslint/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/eslint/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/eslint/node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" }, "engines": { - "node": ">=4" + "node": ">= 8" } }, - "node_modules/eslint/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/eslint/node_modules/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, - "dependencies": { - "color-name": "1.1.3" + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true + "node_modules/eslint/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, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "node_modules/eslint/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, "engines": { - "node": ">=4" + "node": ">=10.13.0" } }, - "node_modules/eslint/node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "node_modules/eslint/node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, "engines": { - "node": ">= 4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/eslint/node_modules/import-fresh": { @@ -4497,6 +5001,132 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/eslint/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/eslint/node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/eslint/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint/node_modules/optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "dependencies": { + "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" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/eslint/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/eslint/node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -4506,39 +5136,102 @@ "node": ">=4" } }, - "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==", + "node_modules/eslint/node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, - "bin": { - "semver": "bin/semver" + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/eslint/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/eslint/node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/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, "dependencies": { - "has-flag": "^3.0.0" + "ansi-regex": "^5.0.1" }, "engines": { - "node": ">=4" + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/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, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/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/eslint/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, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" } }, "node_modules/espree": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz", - "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", + "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", "dev": true, "dependencies": { - "acorn": "^6.0.7", - "acorn-jsx": "^5.0.0", - "eslint-visitor-keys": "^1.0.0" + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.3.0" }, "engines": { - "node": ">=6.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/esprima": { @@ -4588,9 +5281,9 @@ } }, "node_modules/esrecurse/node_modules/estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, "engines": { "node": ">=4.0" @@ -5663,20 +6356,19 @@ "dev": true }, "node_modules/fast-glob": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz", - "integrity": "sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==", + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", + "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.0", + "glob-parent": "^5.1.2", "merge2": "^1.3.0", - "micromatch": "^4.0.2", - "picomatch": "^2.2.1" + "micromatch": "^4.0.4" }, "engines": { - "node": ">=8" + "node": ">=8.6.0" } }, "node_modules/fast-json-stable-stringify": { @@ -5703,7 +6395,7 @@ "node_modules/figures": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "integrity": "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==", "dev": true, "dependencies": { "escape-string-regexp": "^1.0.5" @@ -5713,15 +6405,15 @@ } }, "node_modules/file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "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, "dependencies": { - "flat-cache": "^2.0.1" + "flat-cache": "^3.0.4" }, "engines": { - "node": ">=4" + "node": "^10.12.0 || >=12.0.0" } }, "node_modules/file-uri-to-path": { @@ -5874,35 +6566,37 @@ } }, "node_modules/flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", "dev": true, "dependencies": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" + "flatted": "^3.1.0", + "rimraf": "^3.0.2" }, "engines": { - "node": ">=4" + "node": "^10.12.0 || >=12.0.0" } }, "node_modules/flat-cache/node_modules/rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, "dependencies": { "glob": "^7.1.3" }, "bin": { "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/flatted": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", - "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", + "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": { @@ -15512,12 +16206,30 @@ } }, "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "version": "13.17.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", + "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, "engines": { - "node": ">=4" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globals/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, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/globby": { @@ -15576,6 +16288,12 @@ "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", "dev": true }, + "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==", + "dev": true + }, "node_modules/growl": { "version": "1.10.5", "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", @@ -16160,9 +16878,9 @@ ] }, "node_modules/ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", "dev": true, "engines": { "node": ">= 4" @@ -16266,6 +16984,15 @@ "node": ">=4" } }, + "node_modules/inquirer/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==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/inquirer/node_modules/ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -16304,13 +17031,13 @@ "node_modules/inquirer/node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, "node_modules/inquirer/node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, "engines": { "node": ">=4" @@ -16328,15 +17055,6 @@ "node": ">=6" } }, - "node_modules/inquirer/node_modules/strip-ansi/node_modules/ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/inquirer/node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -16579,9 +17297,9 @@ } }, "node_modules/is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, "dependencies": { "is-extglob": "^2.1.1" @@ -17177,6 +17895,12 @@ "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=", "dev": true }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, "node_modules/lodash.toarray": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.toarray/-/lodash.toarray-4.4.0.tgz", @@ -17968,7 +18692,7 @@ "node_modules/mute-stream": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "integrity": "sha512-r65nCZhrbXXb6dXOACihYApHw2Q6pV0M3V0PSxd74N0+D8nzAdEAITq2oAjA1jVnKI+tGvEBUpqiMh0+rW6zDQ==", "dev": true }, "node_modules/nan": { @@ -18292,7 +19016,7 @@ "node_modules/onetime": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "integrity": "sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==", "dev": true, "dependencies": { "mimic-fn": "^1.0.0" @@ -18626,7 +19350,7 @@ "node_modules/path-is-inside": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", "dev": true }, "node_modules/path-key": { @@ -19180,12 +19904,15 @@ } }, "node_modules/regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "dev": true, "engines": { - "node": ">=6.5.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" } }, "node_modules/req-cwd": { @@ -19335,7 +20062,7 @@ "node_modules/restore-cursor": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "integrity": "sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==", "dev": true, "dependencies": { "onetime": "^2.0.0", @@ -19886,7 +20613,7 @@ "node_modules/slice-ansi/node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, "node_modules/solc": { @@ -19974,6 +20701,18 @@ "prettier": "^1.14.3" } }, + "node_modules/solhint/node_modules/acorn": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", + "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/solhint/node_modules/ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -20021,6 +20760,163 @@ "integrity": "sha512-6CYPa+JP2ftfRU2qkDK+UTVeQYosOg/2GbcjIcKPHfinyOLPVGXu/ovN86RP49Re5ndJK1N0kuiidFFuepc4ZQ==", "dev": true }, + "node_modules/solhint/node_modules/eslint": { + "version": "5.16.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz", + "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "ajv": "^6.9.1", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "eslint-scope": "^4.0.3", + "eslint-utils": "^1.3.1", + "eslint-visitor-keys": "^1.0.0", + "espree": "^5.0.1", + "esquery": "^1.0.1", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob": "^7.1.2", + "globals": "^11.7.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "inquirer": "^6.2.2", + "js-yaml": "^3.13.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.11", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.2", + "progress": "^2.0.0", + "regexpp": "^2.0.1", + "semver": "^5.5.1", + "strip-ansi": "^4.0.0", + "strip-json-comments": "^2.0.1", + "table": "^5.2.3", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^6.14.0 || ^8.10.0 || >=9.10.0" + } + }, + "node_modules/solhint/node_modules/eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/solhint/node_modules/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, + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/solhint/node_modules/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, + "engines": { + "node": ">=4" + } + }, + "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==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/solhint/node_modules/espree": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz", + "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==", + "dev": true, + "dependencies": { + "acorn": "^6.0.7", + "acorn-jsx": "^5.0.0", + "eslint-visitor-keys": "^1.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/solhint/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/solhint/node_modules/file-entry-cache": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "dev": true, + "dependencies": { + "flat-cache": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/solhint/node_modules/flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "dev": true, + "dependencies": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/solhint/node_modules/flatted": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", + "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", + "dev": true + }, + "node_modules/solhint/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/solhint/node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -20039,6 +20935,22 @@ "node": ">= 4" } }, + "node_modules/solhint/node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/solhint/node_modules/prettier": { "version": "1.19.1", "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", @@ -20052,6 +20964,36 @@ "node": ">=4" } }, + "node_modules/solhint/node_modules/regexpp": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "dev": true, + "engines": { + "node": ">=6.5.0" + } + }, + "node_modules/solhint/node_modules/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, + "engines": { + "node": ">=4" + } + }, + "node_modules/solhint/node_modules/rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, "node_modules/solhint/node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -20635,9 +21577,9 @@ } }, "node_modules/table/node_modules/ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", "dev": true, "engines": { "node": ">=6" @@ -20756,7 +21698,7 @@ "node_modules/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", "dev": true }, "node_modules/timed-out": { @@ -20996,18 +21938,6 @@ } } }, - "node_modules/ts-node/node_modules/acorn": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", - "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/ts-node/node_modules/diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", @@ -21029,6 +21959,21 @@ "integrity": "sha1-4igPXoF/i/QnVlf9D5rr1E9aJ4Y=", "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", @@ -22298,27 +23243,27 @@ }, "dependencies": { "@babel/code-frame": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", - "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", "dev": true, "requires": { - "@babel/highlight": "^7.12.13" + "@babel/highlight": "^7.18.6" } }, "@babel/helper-validator-identifier": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz", - "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz", + "integrity": "sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==", "dev": true }, "@babel/highlight": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz", - "integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.14.0", + "@babel/helper-validator-identifier": "^7.18.6", "chalk": "^2.0.0", "js-tokens": "^4.0.0" }, @@ -22355,13 +23300,13 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true }, "supports-color": { @@ -22652,6 +23597,71 @@ "integrity": "sha512-bvaTH34PMCbv6anRa9I/0zjLJgY4EuznbEMgbV77JBCQ9KNC46rzi0avuxpOfu+xDjPEtSFGqVEOr5GlUSGudA==", "dev": true }, + "@eslint/eslintrc": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.1.tgz", + "integrity": "sha512-OhSY22oQQdw3zgPOOwdoj01l/Dzl1Z+xyUP33tkSN+aqyEhymJCcPHyXt+ylW8FSe0TfRC2VG+ROQOapD0aZSQ==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.4.0", + "globals": "^13.15.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": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "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 + }, + "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 + } + } + }, "@ethereum-waffle/chai": { "version": "3.4.4", "resolved": "https://registry.npmjs.org/@ethereum-waffle/chai/-/chai-3.4.4.tgz", @@ -23214,6 +24224,35 @@ "@ethersproject/strings": "^5.6.0" } }, + "@humanwhocodes/config-array": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.4.tgz", + "integrity": "sha512-mXAIHxZT3Vcpg83opl1wGlVZ9xydbfZO3r5YfRSH6Gpp2J/PfdBP0wbDa2sO6/qRbcalpoevVyW6A/fI6LfeMw==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + } + }, + "@humanwhocodes/gitignore-to-minimatch": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz", + "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==", + "dev": true + }, + "@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 + }, "@kwsites/file-exists": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz", @@ -23824,6 +24863,12 @@ "@types/node": "*" } }, + "@types/json-schema": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "dev": true + }, "@types/level-errors": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/level-errors/-/level-errors-3.0.0.tgz", @@ -23971,6 +25016,193 @@ "@types/underscore": "*" } }, + "@typescript-eslint/eslint-plugin": { + "version": "5.36.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.36.0.tgz", + "integrity": "sha512-X3In41twSDnYRES7hO2xna4ZC02SY05UN9sGW//eL1P5k4CKfvddsdC2hOq0O3+WU1wkCPQkiTY9mzSnXKkA0w==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "5.36.0", + "@typescript-eslint/type-utils": "5.36.0", + "@typescript-eslint/utils": "5.36.0", + "debug": "^4.3.4", + "functional-red-black-tree": "^1.0.1", + "ignore": "^5.2.0", + "regexpp": "^3.2.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.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "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 + } + } + }, + "@typescript-eslint/parser": { + "version": "5.36.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.36.0.tgz", + "integrity": "sha512-dlBZj7EGB44XML8KTng4QM0tvjI8swDh8MdpE5NX5iHWgWEfIuqSfSE+GPeCrCdj7m4tQLuevytd57jNDXJ2ZA==", + "dev": true, + "peer": true, + "requires": { + "@typescript-eslint/scope-manager": "5.36.0", + "@typescript-eslint/types": "5.36.0", + "@typescript-eslint/typescript-estree": "5.36.0", + "debug": "^4.3.4" + } + }, + "@typescript-eslint/scope-manager": { + "version": "5.36.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.36.0.tgz", + "integrity": "sha512-PZUC9sz0uCzRiuzbkh6BTec7FqgwXW03isumFVkuPw/Ug/6nbAqPUZaRy4w99WCOUuJTjhn3tMjsM94NtEj64g==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.36.0", + "@typescript-eslint/visitor-keys": "5.36.0" + } + }, + "@typescript-eslint/type-utils": { + "version": "5.36.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.36.0.tgz", + "integrity": "sha512-W/E3yJFqRYsjPljJ2gy0YkoqLJyViWs2DC6xHkXcWyhkIbCDdaVnl7mPLeQphVI+dXtY05EcXFzWLXhq8Mm/lQ==", + "dev": true, + "requires": { + "@typescript-eslint/typescript-estree": "5.36.0", + "@typescript-eslint/utils": "5.36.0", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/types": { + "version": "5.36.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.36.0.tgz", + "integrity": "sha512-3JJuLL1r3ljRpFdRPeOtgi14Vmpx+2JcR6gryeORmW3gPBY7R1jNYoq4yBN1L//ONZjMlbJ7SCIwugOStucYiQ==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "5.36.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.36.0.tgz", + "integrity": "sha512-EW9wxi76delg/FS9+WV+fkPdwygYzRrzEucdqFVWXMQWPOjFy39mmNNEmxuO2jZHXzSQTXzhxiU1oH60AbIw9A==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.36.0", + "@typescript-eslint/visitor-keys": "5.36.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "dependencies": { + "globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + } + }, + "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.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "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 + } + } + }, + "@typescript-eslint/utils": { + "version": "5.36.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.36.0.tgz", + "integrity": "sha512-wAlNhXXYvAAUBbRmoJDywF/j2fhGLBP4gnreFvYvFbtlsmhMJ4qCKVh/Z8OP4SgGR3xbciX2nmG639JX0uw1OQ==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.9", + "@typescript-eslint/scope-manager": "5.36.0", + "@typescript-eslint/types": "5.36.0", + "@typescript-eslint/typescript-estree": "5.36.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + }, + "dependencies": { + "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" + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + } + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.36.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.36.0.tgz", + "integrity": "sha512-pdqSJwGKueOrpjYIex0T39xarDt1dn4p7XJ+6FqBWugNQwXlNGC5h62qayAIYZ/RPPtD+ButDWmpXT1eGtiaYg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.36.0", + "eslint-visitor-keys": "^3.3.0" + } + }, "@ungap/promise-all-settled": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", @@ -24022,15 +25254,15 @@ } }, "acorn": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", - "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", + "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", "dev": true }, "acorn-jsx": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", - "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, "requires": {} }, @@ -24871,7 +26103,7 @@ "cli-cursor": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "integrity": "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==", "dev": true, "requires": { "restore-cursor": "^2.0.0" @@ -25765,95 +26997,113 @@ } }, "eslint": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz", - "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "ajv": "^6.9.1", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", - "debug": "^4.0.1", + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.23.0.tgz", + "integrity": "sha512-pBG/XOn0MsJcKcTRLr27S5HpzQo4kLr+HjLQIyK4EiCsijDl/TB+h5uEuJU6bQ8Edvwz1XWOjpaP2qgnXGpTcA==", + "dev": true, + "requires": { + "@eslint/eslintrc": "^1.3.1", + "@humanwhocodes/config-array": "^0.10.4", + "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", + "@humanwhocodes/module-importer": "^1.0.1", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", "doctrine": "^3.0.0", - "eslint-scope": "^4.0.3", - "eslint-utils": "^1.3.1", - "eslint-visitor-keys": "^1.0.0", - "espree": "^5.0.1", - "esquery": "^1.0.1", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.4.0", + "esquery": "^1.4.0", "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", "functional-red-black-tree": "^1.0.1", - "glob": "^7.1.2", - "globals": "^11.7.0", - "ignore": "^4.0.6", + "glob-parent": "^6.0.1", + "globals": "^13.15.0", + "globby": "^11.1.0", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", - "inquirer": "^6.2.2", - "js-yaml": "^3.13.0", + "is-glob": "^4.0.0", + "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.11", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "path-is-inside": "^1.0.2", - "progress": "^2.0.0", - "regexpp": "^2.0.1", - "semver": "^5.5.1", - "strip-ansi": "^4.0.0", - "strip-json-comments": "^2.0.1", - "table": "^5.2.3", + "optionator": "^0.9.1", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", "text-table": "^0.2.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==", + "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 + }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "requires": { - "color-convert": "^1.9.0" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" } }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "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 + }, + "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, "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "locate-path": "^6.0.0", + "path-exists": "^4.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==", + "glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, "requires": { - "color-name": "1.1.3" + "is-glob": "^4.0.3" } }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true + "globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + } }, "import-fresh": { "version": "3.3.0", @@ -25865,71 +27115,205 @@ "resolve-from": "^4.0.0" } }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "requires": { + "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" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "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 }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "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==", + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "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": { - "has-flag": "^3.0.0" + "ansi-regex": "^5.0.1" + } + }, + "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 + }, + "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" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" } } } }, "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", "dev": true, "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" }, "dependencies": { "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true } } }, "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==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", "dev": true, "requires": { - "eslint-visitor-keys": "^1.1.0" + "eslint-visitor-keys": "^2.0.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true + } } }, "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==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", "dev": true }, "espree": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz", - "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", + "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", "dev": true, "requires": { - "acorn": "^6.0.7", - "acorn-jsx": "^5.0.0", - "eslint-visitor-keys": "^1.0.0" + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.3.0" } }, "esprima": { @@ -25965,9 +27349,9 @@ }, "dependencies": { "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true } } @@ -26877,17 +28261,16 @@ "dev": true }, "fast-glob": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz", - "integrity": "sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==", + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", + "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.0", + "glob-parent": "^5.1.2", "merge2": "^1.3.0", - "micromatch": "^4.0.2", - "picomatch": "^2.2.1" + "micromatch": "^4.0.4" } }, "fast-json-stable-stringify": { @@ -26914,19 +28297,19 @@ "figures": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "integrity": "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==", "dev": true, "requires": { "escape-string-regexp": "^1.0.5" } }, "file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "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, "requires": { - "flat-cache": "^2.0.1" + "flat-cache": "^3.0.4" } }, "file-uri-to-path": { @@ -27050,20 +28433,19 @@ "dev": true }, "flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", "dev": true, "requires": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" + "flatted": "^3.1.0", + "rimraf": "^3.0.2" }, "dependencies": { "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, "requires": { "glob": "^7.1.3" @@ -27072,9 +28454,9 @@ } }, "flatted": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", - "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "dev": true }, "follow-redirects": { @@ -34455,10 +35837,21 @@ } }, "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true + "version": "13.17.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", + "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + }, + "dependencies": { + "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 + } + } }, "globby": { "version": "10.0.2", @@ -34509,6 +35902,12 @@ "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", "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 + }, "growl": { "version": "1.10.5", "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", @@ -34965,9 +36364,9 @@ "dev": true }, "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", "dev": true }, "immediate": { @@ -35053,6 +36452,12 @@ "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", "dev": 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==", + "dev": true + }, "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -35085,13 +36490,13 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true }, "strip-ansi": { @@ -35101,14 +36506,6 @@ "dev": true, "requires": { "ansi-regex": "^4.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - } } }, "supports-color": { @@ -35263,9 +36660,9 @@ "dev": true }, "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, "requires": { "is-extglob": "^2.1.1" @@ -35727,6 +37124,12 @@ "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=", "dev": true }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, "lodash.toarray": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.toarray/-/lodash.toarray-4.4.0.tgz", @@ -36341,7 +37744,7 @@ "mute-stream": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "integrity": "sha512-r65nCZhrbXXb6dXOACihYApHw2Q6pV0M3V0PSxd74N0+D8nzAdEAITq2oAjA1jVnKI+tGvEBUpqiMh0+rW6zDQ==", "dev": true }, "nan": { @@ -36594,7 +37997,7 @@ "onetime": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "integrity": "sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==", "dev": true, "requires": { "mimic-fn": "^1.0.0" @@ -36851,7 +38254,7 @@ "path-is-inside": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", "dev": true }, "path-key": { @@ -37265,9 +38668,9 @@ } }, "regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "dev": true }, "req-cwd": { @@ -37382,7 +38785,7 @@ "restore-cursor": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "integrity": "sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==", "dev": true, "requires": { "onetime": "^2.0.0", @@ -37803,7 +39206,7 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true } } @@ -37881,6 +39284,12 @@ "semver": "^6.3.0" }, "dependencies": { + "acorn": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", + "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", + "dev": true + }, "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -37922,6 +39331,132 @@ "integrity": "sha512-6CYPa+JP2ftfRU2qkDK+UTVeQYosOg/2GbcjIcKPHfinyOLPVGXu/ovN86RP49Re5ndJK1N0kuiidFFuepc4ZQ==", "dev": true }, + "eslint": { + "version": "5.16.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz", + "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "ajv": "^6.9.1", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "eslint-scope": "^4.0.3", + "eslint-utils": "^1.3.1", + "eslint-visitor-keys": "^1.0.0", + "espree": "^5.0.1", + "esquery": "^1.0.1", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob": "^7.1.2", + "globals": "^11.7.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "inquirer": "^6.2.2", + "js-yaml": "^3.13.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.11", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.2", + "progress": "^2.0.0", + "regexpp": "^2.0.1", + "semver": "^5.5.1", + "strip-ansi": "^4.0.0", + "strip-json-comments": "^2.0.1", + "table": "^5.2.3", + "text-table": "^0.2.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "dev": true, + "requires": { + "esrecurse": "^4.1.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" + } + }, + "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 + }, + "espree": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz", + "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==", + "dev": true, + "requires": { + "acorn": "^6.0.7", + "acorn-jsx": "^5.0.0", + "eslint-visitor-keys": "^1.0.0" + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "file-entry-cache": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "dev": true, + "requires": { + "flat-cache": "^2.0.1" + } + }, + "flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "dev": true, + "requires": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + } + }, + "flatted": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", + "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", + "dev": true + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -37934,6 +39469,16 @@ "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, "prettier": { "version": "1.19.1", "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", @@ -37941,6 +39486,27 @@ "dev": true, "optional": true }, + "regexpp": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "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 + }, + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -38421,9 +39987,9 @@ }, "dependencies": { "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", "dev": true }, "string-width": { @@ -38526,7 +40092,7 @@ "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", "dev": true }, "timed-out": { @@ -38706,12 +40272,6 @@ "yn": "3.1.1" }, "dependencies": { - "acorn": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", - "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", - "dev": true - }, "diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", @@ -38732,6 +40292,15 @@ "integrity": "sha1-4igPXoF/i/QnVlf9D5rr1E9aJ4Y=", "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, + "requires": { + "tslib": "^1.8.1" + } + }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", diff --git a/package.json b/package.json index 99eb4a3f..71ab663c 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,9 @@ { "name": "ssv-network", + "scripts": { + "lint": "eslint . --ext .ts", + "lint:fix": "eslint --fix . --ext .ts" + }, "devDependencies": { "@nomiclabs/hardhat-ethers": "^2.0.5", "@nomiclabs/hardhat-etherscan": "^3.0.3", @@ -13,10 +17,12 @@ "@types/cli-table": "^0.3.0", "@types/mocha": "^9.1.0", "@types/node": "^17.0.23", + "@typescript-eslint/eslint-plugin": "^5.36.0", "chai": "^4.3.6", "chai-as-promised": "^7.1.1", "cli-table": "^0.3.11", "dotenv": "^16.0.0", + "eslint": "^8.23.0", "ethereum-public-key-to-address": "0.0.5", "ethereum-waffle": "^3.4.4", "ethers": "^5.6.2", diff --git a/test/account/deposit.ts b/test/account/deposit.ts index 1174f98b..6554c4ef 100644 --- a/test/account/deposit.ts +++ b/test/account/deposit.ts @@ -1,28 +1,30 @@ -const { expect } = require("chai"); +import * as helpers from '../helpers/contract-helpers'; -import * as helpers from "../helpers/contract-helpers" -let registryContract: any, operatorIDs: any, shares: any, owner: any -const numberOfOperators = 4 -const operatorFee = 4 +import { expect } from 'chai'; -describe("Deposit Tests", () => { - beforeEach(async () => { - const contractData = await helpers.initializeContract(numberOfOperators, operatorFee) - registryContract = contractData.contract - operatorIDs = contractData.operatorIDs - shares = contractData.shares - }) - - it("Deposit", async () => { +const numberOfOperators = 4; +const operatorFee = 4; - }) +let registryContract: any, operatorIDs: any, shares: any, owner: any; - it("Deposit errors", async () => { +describe('Deposit Tests', () => { + beforeEach(async () => { + const contractData = await helpers.initializeContract(numberOfOperators, operatorFee); + registryContract = contractData.contract; + operatorIDs = contractData.operatorIDs; + shares = contractData.shares; + }); - }) + it('Deposit', async () => { - it("Deposit gas limits", async () => { + }); - }) + it('Deposit errors', async () => { + + }); + + it('Deposit gas limits', async () => { + + }); }); diff --git a/test/account/withdraw.ts b/test/account/withdraw.ts index 04140e46..f6dd9d87 100644 --- a/test/account/withdraw.ts +++ b/test/account/withdraw.ts @@ -1,28 +1,30 @@ -const { expect } = require("chai"); +import * as helpers from '../helpers/contract-helpers'; -import * as helpers from "../helpers/contract-helpers" -let registryContract: any, operatorIDs: any, shares: any, owner: any -const numberOfOperators = 4 -const operatorFee = 4 +import { expect } from 'chai'; -describe("Withdraw Tests", () => { - beforeEach(async () => { - const contractData = await helpers.initializeContract(numberOfOperators, operatorFee) - registryContract = contractData.contract - operatorIDs = contractData.operatorIDs - shares = contractData.shares - }) +const numberOfOperators = 4; +const operatorFee = 4; - it("Withdraw", async () => { +let registryContract: any, operatorIDs: any, shares: any, owner: any; - }) +describe('Withdraw Tests', () => { + beforeEach(async () => { + const contractData = await helpers.initializeContract(numberOfOperators, operatorFee); + registryContract = contractData.contract; + operatorIDs = contractData.operatorIDs; + shares = contractData.shares; + }); - it("Withdraw errors", async () => { + it('Withdraw', async () => { - }) + }); - it("Withdraw gas limits", async () => { + it('Withdraw errors', async () => { - }) + }); + + it('Withdraw gas limits', async () => { + + }); }); diff --git a/test/dao/network-fee-change.ts b/test/dao/network-fee-change.ts index bd9d8dba..85cdd03e 100644 --- a/test/dao/network-fee-change.ts +++ b/test/dao/network-fee-change.ts @@ -1,28 +1,30 @@ -const { expect } = require("chai"); +import * as helpers from '../helpers/contract-helpers'; -import * as helpers from "../helpers/contract-helpers" -let registryContract: any, operatorIDs: any, shares: any, owner: any -const numberOfOperators = 4 -const operatorFee = 4 +import { expect } from 'chai'; -describe("DAO Network Fee Change Tests", () => { - beforeEach(async () => { - const contractData = await helpers.initializeContract(numberOfOperators, operatorFee) - registryContract = contractData.contract - operatorIDs = contractData.operatorIDs - shares = contractData.shares - }) +const numberOfOperators = 4; +const operatorFee = 4; - it("Get network fee", async () => { +let registryContract: any, operatorIDs: any, shares: any, owner: any; - }) +describe('DAO Network Fee Change Tests', () => { + beforeEach(async () => { + const contractData = await helpers.initializeContract(numberOfOperators, operatorFee); + registryContract = contractData.contract; + operatorIDs = contractData.operatorIDs; + shares = contractData.shares; + }); - it("Change network fee", async () => { + it('Get network fee', async () => { - }) + }); - it("Change network fee errors", async () => { + it('Change network fee', async () => { - }) + }); + + it('Change network fee errors', async () => { + + }); }); diff --git a/test/dao/network-fee-withdraw.ts b/test/dao/network-fee-withdraw.ts index 53ef288a..8ea57fd0 100644 --- a/test/dao/network-fee-withdraw.ts +++ b/test/dao/network-fee-withdraw.ts @@ -1,28 +1,30 @@ -const { expect } = require("chai"); +import * as helpers from '../helpers/contract-helpers'; -import * as helpers from "../helpers/contract-helpers" -let registryContract: any, operatorIDs: any, shares: any, owner: any -const numberOfOperators = 4 -const operatorFee = 4 +import { expect } from 'chai'; -describe("DAO Network Fee Withdraw Tests", () => { - beforeEach(async () => { - const contractData = await helpers.initializeContract(numberOfOperators, operatorFee) - registryContract = contractData.contract - operatorIDs = contractData.operatorIDs - shares = contractData.shares - }) +const numberOfOperators = 4; +const operatorFee = 4; - it("Get withdrawable network fee amount", async () => { +let registryContract: any, operatorIDs: any, shares: any, owner: any; - }) +describe('DAO Network Fee Withdraw Tests', () => { + beforeEach(async () => { + const contractData = await helpers.initializeContract(numberOfOperators, operatorFee); + registryContract = contractData.contract; + operatorIDs = contractData.operatorIDs; + shares = contractData.shares; + }); - it("Withdraw network fee", async () => { + it('Get withdrawable network fee amount', async () => { - }) + }); - it("Withdraw network fee errors", async () => { + it('Withdraw network fee', async () => { - }) + }); + + it('Withdraw network fee errors', async () => { + + }); }); diff --git a/test/helpers/contract-helpers.ts b/test/helpers/contract-helpers.ts index 03bc4213..85b67ee6 100644 --- a/test/helpers/contract-helpers.ts +++ b/test/helpers/contract-helpers.ts @@ -1,43 +1,43 @@ // Imports -declare const ethers: any +declare const ethers: any; -const { trackGas, getGasStats } = require('./gas-usage'); +import { trackGas, getGasStats } from './gas-usage'; // Generate shares -const shares = Array.from(Array(10).keys()).map(k => `0xe0096008000000b4010000040000001000000076000000dc000000420d142c307831323334353637383930fe0a00520a000031017afe66008266000032fe66009266000033fe66009266000034016621ac28d60000009c01000062020025c02c307839383736353433323130fe0a00520a000031fe560052560019b0003101dafec60082c6000032fec6007ac6004d6ca666000033ceb401fe8c017e8c014dcca6c6004d7a0035b23200fec6007ec6000034${k}${k}`) +const shares = Array.from(Array(10).keys()).map(k => `0xe0096008000000b4010000040000001000000076000000dc000000420d142c307831323334353637383930fe0a00520a000031017afe66008266000032fe66009266000033fe66009266000034016621ac28d60000009c01000062020025c02c307839383736353433323130fe0a00520a000031fe560052560019b0003101dafec60082c6000032fec6007ac6004d6ca666000033ceb401fe8c017e8c014dcca6c6004d7a0035b23200fec6007ec6000034${k}${k}`); export const initializeContract = async (numberOfOperators: number, fee: number) => { // Define accounts const [owner] = await ethers.getSigners(); // Initialize contract - const ssvNetwork = await ethers.getContractFactory("SSVNetwork") - const deployedRegistryContract = await ssvNetwork.deploy() + const ssvNetwork = await ethers.getContractFactory('SSVNetwork'); + const deployedRegistryContract = await ssvNetwork.deploy(); await deployedRegistryContract.deployed(); // Register Operators for (let i = 0; i < numberOfOperators; i++) { - const encodedABI = "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002644c5330744c5331435255644a54694253553045675546564354456c4449457446575330744c533074436b314a53554a4a616b464f516d64726357687261556335647a424351564646526b464254304e425554684254556c4a516b4e6e53304e42555556424e5756554e557777563068365a54647954575a506232787456484d4b64577449513245344b336474625577324f54464a5131527052454531556b4a31546b787153565132576b4530597a4d78635652495933464256486c3565566b774c7a6b3352336c4b5a32646f596e6c465232526f5a516f76616c6836615756544f584a325279744a56474631516a684d566c686b656b78475956517857455a5765466c6e4e327832546c42344f5552504c315a6f526b686b5757786e54334932643052745633466a52476f33436c68575557464f57454674526e67334e6a56514e546c584e585a7a564752585657464852577858536d3933536b5a4b646e6332556c5249536b5a315456686a537a5a5661574a3063555a4d536d4a774f57356b6455674b516a6c4c537a4e57636d59725a6d744a4f5752425a327478524446484f456c785130744b4d566c33626a557965477878625452434e69744f4f475a555a45314d53314a75635770465a6d527a563164774d46567a4d51704c54573976535863796333426f6158417a5546704e596e4a61615530774e6a4a325a556f3055336f76596a424f62576450546e685464304a4a546e4e7863473534516a68465556517853544e6a4e6b6c714e586868436d35525355524255554643436930744c5330745255354549464a545153425156554a4d53554d675330565a4c5330744c53304b00000000000000000000000000000000000000000000000000000000"; + const encodedABI = '0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002644c5330744c5331435255644a54694253553045675546564354456c4449457446575330744c533074436b314a53554a4a616b464f516d64726357687261556335647a424351564646526b464254304e425554684254556c4a516b4e6e53304e42555556424e5756554e557777563068365a54647954575a506232787456484d4b64577449513245344b336474625577324f54464a5131527052454531556b4a31546b787153565132576b4530597a4d78635652495933464256486c3565566b774c7a6b3352336c4b5a32646f596e6c465232526f5a516f76616c6836615756544f584a325279744a56474631516a684d566c686b656b78475956517857455a5765466c6e4e327832546c42344f5552504c315a6f526b686b5757786e54334932643052745633466a52476f33436c68575557464f57454674526e67334e6a56514e546c584e585a7a564752585657464852577858536d3933536b5a4b646e6332556c5249536b5a315456686a537a5a5661574a3063555a4d536d4a774f57356b6455674b516a6c4c537a4e57636d59725a6d744a4f5752425a327478524446484f456c785130744b4d566c33626a557965477878625452434e69744f4f475a555a45314d53314a75635770465a6d527a563164774d46567a4d51704c54573976535863796333426f6158417a5546704e596e4a61615530774e6a4a325a556f3055336f76596a424f62576450546e685464304a4a546e4e7863473534516a68465556517853544e6a4e6b6c714e586868436d35525355524255554643436930744c5330745255354549464a545153425156554a4d53554d675330565a4c5330744c53304b00000000000000000000000000000000000000000000000000000000'; await deployedRegistryContract.registerOperator(encodedABI, fee); } // Generate Operator IDs - const operatorIDs = Array.from(Array(numberOfOperators).keys()).map(k => k + 1) + const operatorIDs = Array.from(Array(numberOfOperators).keys()).map(k => k + 1); // Deposit to the contract - await deployedRegistryContract.deposit("9000000000000000000") + await deployedRegistryContract.deposit('9000000000000000000'); - return { contract: deployedRegistryContract, operatorIDs: operatorIDs, shares: shares, owner: owner } -} + return { contract: deployedRegistryContract, operatorIDs: operatorIDs, shares: shares, owner: owner }; +}; export const registerValidators = async (numberOfValidators: number, amount: string, operatorAmount: number, contract: any) => { - let validatorData: any = [] - const validatorsToRegister = 1000 + numberOfValidators + const validatorData: any = []; + const validatorsToRegister = 1000 + numberOfValidators; // Register validators to contract for (let i = 1000; i < validatorsToRegister; i++) { - const randomOperator = Math.floor(Math.random() * (operatorAmount - 4)) - const validatorPK = `0xa7ae1ea93b860ca0269ccca776b4526977395aa194e5820a00dedbf1cd63e7a898eec9a12f539f733ea4df9c651f${i}` + const randomOperator = Math.floor(Math.random() * (operatorAmount - 4)); + const validatorPK = `0xa7ae1ea93b860ca0269ccca776b4526977395aa194e5820a00dedbf1cd63e7a898eec9a12f539f733ea4df9c651f${i}`; const receipt = await trackGas(contract.registerValidator( [randomOperator, randomOperator + 1, randomOperator + 2, randomOperator + 3], @@ -46,16 +46,16 @@ export const registerValidators = async (numberOfValidators: number, amount: str amount, ), 'registerValidator', 400000); - const registerResult = receipt.logs[0] + const registerResult = receipt.logs[0]; // Save validator group id emits - let interfaceRegister = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId, bytes shares)']); + const interfaceRegister = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId, bytes shares)']); const outputRegister = interfaceRegister.decodeEventLog('ValidatorAdded', registerResult.data, registerResult.topics); // Save the validator emit - validatorData.push({ publicKey: validatorPK, groupId: outputRegister.groupId }) + validatorData.push({ publicKey: validatorPK, groupId: outputRegister.groupId }); } - return validatorData + return validatorData; -} \ No newline at end of file +}; diff --git a/test/helpers/gas-usage.ts b/test/helpers/gas-usage.ts index 9d633fb3..7d72f277 100644 --- a/test/helpers/gas-usage.ts +++ b/test/helpers/gas-usage.ts @@ -1,8 +1,8 @@ export class GasStats { max: number | null = null; min: number | null = null; - totalGas: number = 0; - txCount: number = 0; + totalGas = 0; + txCount = 0; addStat(gas: number) { this.totalGas += gas; @@ -28,7 +28,7 @@ const getOrCreate = (group: string) => { } return groupStats; -} +}; export const trackGas = async (tx: Promise, group: string, maxGas: number) => { const receipt = await (await tx).wait(); @@ -36,14 +36,15 @@ export const trackGas = async (tx: Promise, group: string, maxGas: number) if (receipt.gasUsed > maxGas) { throw new Error(`Gas usage too high. Max: ${maxGas}, Actual: ${receipt.gasUsed}`); } + console.log('\t', +receipt.gasUsed); const groupStats = getOrCreate(group); groupStats.addStat(parseInt(receipt.gasUsed)); return receipt; -} +}; export const getGasStats = (group: string) => { return gasUsageStats.get(group) || new GasStats(); -} \ No newline at end of file +}; diff --git a/test/helpers/utils.ts b/test/helpers/utils.ts index f0d29165..e31f1cfe 100644 --- a/test/helpers/utils.ts +++ b/test/helpers/utils.ts @@ -1,60 +1,58 @@ -declare var network: any; -declare var ethers: any; - -//@ts-ignore -export const strToHex = str => `0x${Buffer.from(str, 'utf8').toString('hex')}`; -//@ts-ignore -export const asciiToHex = str => { - var arr1 = []; - for (var n = 0, l = str.length; n < l; n ++) { - var hex = Number(str.charCodeAt(n)).toString(16); +declare let network: any; +declare let ethers: any; + +export const strToHex = (str: any) => `0x${Buffer.from(str, 'utf8').toString('hex')}`; + +export const asciiToHex = (str: any) => { + const arr1 = []; + for (let n = 0, l = str.length; n < l; n ++) { + const hex = Number(str.charCodeAt(n)).toString(16); arr1.push(hex); } return arr1.join(''); -} -//@ts-ignore +}; + export const blockNumber = async function() { return await ethers.provider.getBlockNumber(); -} -//@ts-ignore -export const progress = async function(time, blocks, func = null) { +}; + +export const progress = async function(time: any, blocks: any, func: any = null) { let snapshot; if (func) { - snapshot = await network.provider.send("evm_snapshot"); + snapshot = await network.provider.send('evm_snapshot'); } if (time) { - await network.provider.send("evm_increaseTime", [time]); + await network.provider.send('evm_increaseTime', [time]); if (!blocks) { - await network.provider.send("evm_mine", []); + await network.provider.send('evm_mine', []); } } for (let index = 0; index < blocks; ++index) { - await network.provider.send("evm_mine", []); + await network.provider.send('evm_mine', []); } if (func) { - //@ts-ignore await func(); - await network.provider.send("evm_revert", [snapshot]); + await network.provider.send('evm_revert', [snapshot]); } -} -//@ts-ignore -export const progressTime = async function(time, func = null) { +}; + +export const progressTime = async function(time: any, func: any = null) { return progress(time, 1, func); -} -//@ts-ignore -export const progressBlocks = async function(blocks, func = null) { +}; + +export const progressBlocks = async function(blocks: any, func = null) { return progress(0, blocks, func); -} -//@ts-ignore -export const snapshot = async function(func) { +}; + +export const snapshot = async function(func: any) { return progress(0, 0, func); -} +}; -export const mineOneBlock = async () => network.provider.send("evm_mine", []); +export const mineOneBlock = async () => network.provider.send('evm_mine', []); export const mineChunk = async (amount: number) => Promise.all( @@ -69,4 +67,18 @@ export const mine = async (amount: number) => { await mineChunk(MAX_PARALLEL_CALLS); } return mineChunk(amount % MAX_PARALLEL_CALLS); -}; \ No newline at end of file +}; + +export const runTx = async (tx: Promise, eventName?: any, eventInterface?: any) => { + const receipt = await (await tx).wait(); + let data; + + if (eventName && eventInterface) { + const result = receipt.logs[0]; + const schema = new ethers.utils.Interface([`event ${eventName}(${eventInterface})`]); + data = schema.decodeEventLog(eventName, result.data, result.topics); + } + console.log('\t', +receipt.gasUsed); + + return { gasUsed: +receipt.gasUsed, data }; +} diff --git a/test/liquidate/liquidate.ts b/test/liquidate/liquidate.ts index a6778fa2..13ed585f 100644 --- a/test/liquidate/liquidate.ts +++ b/test/liquidate/liquidate.ts @@ -1,32 +1,34 @@ -const { expect } = require("chai"); +import * as helpers from '../helpers/contract-helpers'; -import * as helpers from "../helpers/contract-helpers" -let registryContract: any, operatorIDs: any, shares: any, owner: any -const numberOfOperators = 4 -const operatorFee = 4 +import { expect } from 'chai'; -describe("Liquidate Tests", () => { - beforeEach(async () => { - const contractData = await helpers.initializeContract(numberOfOperators, operatorFee) - registryContract = contractData.contract - operatorIDs = contractData.operatorIDs - shares = contractData.shares - }) +const numberOfOperators = 4; +const operatorFee = 4; - it("Liquidatable", async () => { +let registryContract: any, operatorIDs: any, shares: any, owner: any; - }) +describe('Liquidate Tests', () => { + beforeEach(async () => { + const contractData = await helpers.initializeContract(numberOfOperators, operatorFee); + registryContract = contractData.contract; + operatorIDs = contractData.operatorIDs; + shares = contractData.shares; + }); - it("Liquidate", async () => { + it('Liquidatable', async () => { - }) + }); - it("Liquidate errors", async () => { + it('Liquidate', async () => { - }) + }); - it("Liquidate gas limits", async () => { + it('Liquidate errors', async () => { - }) + }); + + it('Liquidate gas limits', async () => { + + }); }); diff --git a/test/liquidate/liquidation-threshold.ts b/test/liquidate/liquidation-threshold.ts index 63c46436..e4098801 100644 --- a/test/liquidate/liquidation-threshold.ts +++ b/test/liquidate/liquidation-threshold.ts @@ -1,32 +1,35 @@ -const { expect } = require("chai"); +import * as helpers from '../helpers/contract-helpers'; -import * as helpers from "../helpers/contract-helpers" -let registryContract: any, operatorIDs: any, shares: any, owner: any -const numberOfOperators = 4 -const operatorFee = 4 +import { expect } from 'chai'; -describe("Liquidation Threshold Tests", () => { - beforeEach(async () => { - const contractData = await helpers.initializeContract(numberOfOperators, operatorFee) - registryContract = contractData.contract - operatorIDs = contractData.operatorIDs - shares = contractData.shares - }) +const numberOfOperators = 4; +const operatorFee = 4; - it("Get liquidation threshold", async () => { +let registryContract: any, operatorIDs: any, shares: any, owner: any; - }) - it("Change liquidation threshold", async () => { +describe('Liquidation Threshold Tests', () => { + beforeEach(async () => { + const contractData = await helpers.initializeContract(numberOfOperators, operatorFee); + registryContract = contractData.contract; + operatorIDs = contractData.operatorIDs; + shares = contractData.shares; + }); - }) + it('Get liquidation threshold', async () => { - it("Change liquidation threshold errors", async () => { + }); - }) + it('Change liquidation threshold', async () => { - it("Liquidation threshold gas limits", async () => { + }); - }) + it('Change liquidation threshold errors', async () => { + + }); + + it('Liquidation threshold gas limits', async () => { + + }); }); diff --git a/test/operators/register.ts b/test/operators/register.ts index 30450aa0..e4594d10 100644 --- a/test/operators/register.ts +++ b/test/operators/register.ts @@ -1,72 +1,74 @@ -const { expect } = require("chai"); -const { trackGas } = require("../helpers/gas-usage"); +import * as helpers from '../helpers/contract-helpers'; -import * as helpers from "../helpers/contract-helpers" -let registryContract: any, operatorIDs: any, shares: any, owner: any -const numberOfOperators = 4 -const operatorFee = 4 +import { expect } from 'chai'; +import { trackGas } from '../helpers/gas-usage'; -describe("Register Operator Tests", () => { - beforeEach(async () => { - const contractData = await helpers.initializeContract(numberOfOperators, operatorFee) - registryContract = contractData.contract - operatorIDs = contractData.operatorIDs - shares = contractData.shares - }) +const numberOfOperators = 4; +const operatorFee = 4; - it("Register operator", async () => { +let registryContract: any, operatorIDs: any, shares: any, owner: any; - }) +describe('Register Operator Tests', () => { + beforeEach(async () => { + const contractData = await helpers.initializeContract(numberOfOperators, operatorFee); + registryContract = contractData.contract; + operatorIDs = contractData.operatorIDs; + shares = contractData.shares; + }); - it("Register operator errors", async () => { + it('Register operator', async () => { - }) + }); - it("Register operator gas limits", async () => { - const validatorPK = `0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100` + it('Register operator errors', async () => { - // Cost: 364101 - await trackGas(registryContract.registerValidator( - `${validatorPK}0`, - [1, 2, 3, 4], - shares[0], - "10000" - ), 'registerValidator', 400000); + }); - // // Cost: 185380 - // await deployedRegistryContract.registerValidator( - // [1, 2, 3, 4], - // `${validatorPK}1`, - // sharePKs.slice(0, 4), - // encryptedShares.slice(0, 4), - // "10000" - // ) + it('Register operator gas limits', async () => { + const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; - // Cost: 295713 - await registryContract.registerValidator( - `${validatorPK}1`, - [1, 2, 5, 6], - shares[1], - "10000" - ) + // Cost: 364101 + await trackGas(registryContract.registerValidator( + `${validatorPK}0`, + [1, 2, 3, 4], + shares[0], + '10000' + ), 'registerValidator', 400000); - // // Cost: 312813 - // await deployedRegistryContract.registerValidator( - // [1, 5, 6, 7], - // `${validatorPK}2`, - // sharePKs.slice(0, 4), - // encryptedShares.slice(0, 4), - // "10000" - // ) + // // Cost: 185380 + // await deployedRegistryContract.registerValidator( + // [1, 2, 3, 4], + // `${validatorPK}1`, + // sharePKs.slice(0, 4), + // encryptedShares.slice(0, 4), + // "10000" + // ) - // // Cost: 329901 - // await deployedRegistryContract.registerValidator( - // [5, 6, 7, 8], - // `${validatorPK}0`, - // sharePKs.slice(0, 4), - // encryptedShares.slice(0, 4), - // "10000" - // ) - }) + // Cost: 295713 + await registryContract.registerValidator( + `${validatorPK}1`, + [1, 2, 5, 6], + shares[1], + '10000' + ); + + // // Cost: 312813 + // await deployedRegistryContract.registerValidator( + // [1, 5, 6, 7], + // `${validatorPK}2`, + // sharePKs.slice(0, 4), + // encryptedShares.slice(0, 4), + // "10000" + // ) + + // // Cost: 329901 + // await deployedRegistryContract.registerValidator( + // [5, 6, 7, 8], + // `${validatorPK}0`, + // sharePKs.slice(0, 4), + // encryptedShares.slice(0, 4), + // "10000" + // ) + }); }); diff --git a/test/operators/remove.ts b/test/operators/remove.ts index 09b21f34..60a561fd 100644 --- a/test/operators/remove.ts +++ b/test/operators/remove.ts @@ -1,28 +1,30 @@ -const { expect } = require("chai"); +import * as helpers from '../helpers/contract-helpers'; -import * as helpers from "../helpers/contract-helpers" -let registryContract: any, operatorIDs: any, shares: any, owner: any -const numberOfOperators = 4 -const operatorFee = 4 +import { expect } from 'chai'; -describe("Remove Operator Tests", () => { - beforeEach(async () => { - const contractData = await helpers.initializeContract(numberOfOperators, operatorFee) - registryContract = contractData.contract - operatorIDs = contractData.operatorIDs - shares = contractData.shares - }) +const numberOfOperators = 4; +const operatorFee = 4; - it("Remove operator", async () => { +let registryContract: any, operatorIDs: any, shares: any, owner: any; - }) +describe('Remove Operator Tests', () => { + beforeEach(async () => { + const contractData = await helpers.initializeContract(numberOfOperators, operatorFee); + registryContract = contractData.contract; + operatorIDs = contractData.operatorIDs; + shares = contractData.shares; + }); - it("Remove operator errors", async () => { + it('Remove operator', async () => { - }) + }); - it("Remove operator gas limits", async () => { + it('Remove operator errors', async () => { - }) + }); + + it('Remove operator gas limits', async () => { + + }); }); diff --git a/test/operators/update.ts b/test/operators/update.ts index ef4e3f4b..d0c82444 100644 --- a/test/operators/update.ts +++ b/test/operators/update.ts @@ -1,28 +1,30 @@ -const { expect } = require("chai"); +import * as helpers from '../helpers/contract-helpers'; -import * as helpers from "../helpers/contract-helpers" -let registryContract: any, operatorIDs: any, shares: any, owner: any -const numberOfOperators = 4 -const operatorFee = 4 +import { expect } from 'chai'; -describe("Update Operator Tests", () => { - beforeEach(async () => { - const contractData = await helpers.initializeContract(numberOfOperators, operatorFee) - registryContract = contractData.contract - operatorIDs = contractData.operatorIDs - shares = contractData.shares - }) +const numberOfOperators = 4; +const operatorFee = 4; - it("Update operator", async () => { +let registryContract: any, operatorIDs: any, shares: any, owner: any; - }) +describe('Update Operator Tests', () => { + beforeEach(async () => { + const contractData = await helpers.initializeContract(numberOfOperators, operatorFee); + registryContract = contractData.contract; + operatorIDs = contractData.operatorIDs; + shares = contractData.shares; + }); - it("Update operator errors", async () => { + it('Update operator', async () => { - }) + }); - it("Update operator gas limits", async () => { + it('Update operator errors', async () => { - }) + }); + + it('Update operator gas limits', async () => { + + }); }); diff --git a/test/sanity/balances.ts b/test/sanity/balances.ts index 895e89ff..2ae1fb91 100644 --- a/test/sanity/balances.ts +++ b/test/sanity/balances.ts @@ -1,126 +1,129 @@ -const { expect } = require("chai"); -declare const ethers: any - -import * as helpers from "../helpers/contract-helpers" -import * as utils from "../helpers/utils" -let registryContract: any, operatorIDs: any, shares: any, owner: any -const numberOfOperators = 6 -const operatorFee = 1 - -describe("Balance Tests", () => { - beforeEach(async () => { - const contractData = await helpers.initializeContract(numberOfOperators, operatorFee) - registryContract = contractData.contract - operatorIDs = contractData.operatorIDs - shares = contractData.shares - owner = contractData.owner - }) - - it("Check balances", async () => { - // // Register 1000 validators - // const validatorPK = `0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100` - - // expect(await registryContract.operatorEarningsOf(1)).to.equal('0') - - // // Register a validator - // const validator1 = (await (await registryContract.registerValidator( - // [1, 2, 3, 4], - // `${validatorPK}0`, - // shares[0], - // "10000" - // )).wait()).logs[0] - // let interfaceRegister = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId, bytes shares)']); - // const outputRegister = interfaceRegister.decodeEventLog('ValidatorAdded', validator1.data, validator1.topics); - - // // Progress 50 blocks and check operator balances and group balance - // await utils.progressBlocks(50) - // expect(await registryContract.operatorEarningsOf(1)).to.equal('50') - // expect(await registryContract.operatorEarningsOf(2)).to.equal('50') - // expect(await registryContract.operatorEarningsOf(3)).to.equal('50') - // expect(await registryContract.operatorEarningsOf(4)).to.equal('50') - // expect(await registryContract.groupBalanceOf(owner.address, outputRegister.groupId)).to.equal(10000 - 150) - - // // Update one of the operator fees - // await registryContract.updateOperatorFee(1, 10) - - // // Progress 50 blocks and check operator balances and group balance - // await utils.progressBlocks(50) - // expect(await registryContract.operatorEarningsOf(1)).to.equal('551') - // expect(await registryContract.operatorEarningsOf(2)).to.equal('101') - // expect(await registryContract.operatorEarningsOf(3)).to.equal('101') - // expect(await registryContract.operatorEarningsOf(4)).to.equal('101') - // expect(await registryContract.groupBalanceOf(owner.address, outputRegister.groupId)).to.equal(10000 - 904) - - // // Update 3 operator fees - // await registryContract.updateOperatorFee(2, 20) - // await registryContract.updateOperatorFee(3, 20) - // await registryContract.updateOperatorFee(4, 20) - - // // Progress 50 blocks and check operator balances and group balance - // await utils.progressBlocks(50) - // expect(await registryContract.operatorEarningsOf(1)).to.equal('1081') - // expect(await registryContract.operatorEarningsOf(2)).to.equal('1142') - // expect(await registryContract.operatorEarningsOf(3)).to.equal('1123') - // expect(await registryContract.operatorEarningsOf(4)).to.equal('1104') - // expect(await registryContract.groupBalanceOf(owner.address, outputRegister.groupId)).to.equal(10000 - 4500) - - // // Add another validator - // await registryContract.registerValidator( - // [1, 2, 3, 5], - // `${validatorPK}1`, - // shares[1], - // "10000" - // ) - - // // Progress 50 blocks and check operator balances and group balance - // await utils.progressBlocks(50) - // expect(await registryContract.operatorEarningsOf(1)).to.equal('2091') - // expect(await registryContract.operatorEarningsOf(2)).to.equal('3162') - // expect(await registryContract.operatorEarningsOf(3)).to.equal('3143') - // expect(await registryContract.operatorEarningsOf(4)).to.equal('2124') - // expect(await registryContract.operatorEarningsOf(5)).to.equal('5000') - // expect(await registryContract.groupBalanceOf(owner.address, outputRegister.groupId)).to.equal(10000 - 4500) - - // // Remove an operator - // await registryContract.removeOperator(1) - - // // Progress 50 blocks and check operator balances and group balance - // await utils.progressBlocks(50) - // expect(await registryContract.operatorEarningsOf(1)).to.equal('2091') - // expect(await registryContract.operatorEarningsOf(2)).to.equal('3162') - // expect(await registryContract.operatorEarningsOf(3)).to.equal('3143') - // expect(await registryContract.operatorEarningsOf(4)).to.equal('2124') - // expect(await registryContract.operatorEarningsOf(5)).to.equal('5000') - // expect(await registryContract.groupBalanceOf(owner.address, outputRegister.groupId)).to.equal(10000 - 4500) - - // // Update a validator - // await registryContract.updateValidator( - // [1, 2, 3, 5], - // `${validatorPK}0`, - // shares[1], - // "10" - // ) - - // // Progress 50 blocks and check operator balances and group balance - // await utils.progressBlocks(50) - // expect(await registryContract.operatorEarningsOf(1)).to.equal('2091') - // expect(await registryContract.operatorEarningsOf(2)).to.equal('3162') - // expect(await registryContract.operatorEarningsOf(3)).to.equal('3143') - // expect(await registryContract.operatorEarningsOf(4)).to.equal('2124') - // expect(await registryContract.operatorEarningsOf(5)).to.equal('5000') - // expect(await registryContract.groupBalanceOf(owner.address, outputRegister.groupId)).to.equal(10000 - 4500) - - // // Remove a validator - // await registryContract.removeValidator(`${validatorPK}0`, outputRegister.groupId) - - // // Progress 50 blocks and check operator balances and group balance - // await utils.progressBlocks(50) - // expect(await registryContract.operatorEarningsOf(1)).to.equal('2091') - // expect(await registryContract.operatorEarningsOf(2)).to.equal('3162') - // expect(await registryContract.operatorEarningsOf(3)).to.equal('3143') - // expect(await registryContract.operatorEarningsOf(4)).to.equal('2124') - // expect(await registryContract.operatorEarningsOf(5)).to.equal('5000') - // expect(await registryContract.groupBalanceOf(owner.address, outputRegister.groupId)).to.equal(10000 - 4500) - }) +declare const ethers: any; + +import * as helpers from '../helpers/contract-helpers'; +import * as utils from '../helpers/utils'; + +import { expect } from 'chai'; + +const numberOfOperators = 6; +const operatorFee = 1; + +let registryContract: any, operatorIDs: any, shares: any, owner: any; + +describe('Balance Tests', () => { + beforeEach(async () => { + const contractData = await helpers.initializeContract(numberOfOperators, operatorFee); + registryContract = contractData.contract; + operatorIDs = contractData.operatorIDs; + shares = contractData.shares; + owner = contractData.owner; + }); + + it('Check balances', async () => { + // // Register 1000 validators + // const validatorPK = `0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100` + + // expect(await registryContract.operatorEarningsOf(1)).to.equal('0') + + // // Register a validator + // const validator1 = (await (await registryContract.registerValidator( + // [1, 2, 3, 4], + // `${validatorPK}0`, + // shares[0], + // "10000" + // )).wait()).logs[0] + // let interfaceRegister = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId, bytes shares)']); + // const outputRegister = interfaceRegister.decodeEventLog('ValidatorAdded', validator1.data, validator1.topics); + + // // Progress 50 blocks and check operator balances and group balance + // await utils.progressBlocks(50) + // expect(await registryContract.operatorEarningsOf(1)).to.equal('50') + // expect(await registryContract.operatorEarningsOf(2)).to.equal('50') + // expect(await registryContract.operatorEarningsOf(3)).to.equal('50') + // expect(await registryContract.operatorEarningsOf(4)).to.equal('50') + // expect(await registryContract.groupBalanceOf(owner.address, outputRegister.groupId)).to.equal(10000 - 150) + + // // Update one of the operator fees + // await registryContract.updateOperatorFee(1, 10) + + // // Progress 50 blocks and check operator balances and group balance + // await utils.progressBlocks(50) + // expect(await registryContract.operatorEarningsOf(1)).to.equal('551') + // expect(await registryContract.operatorEarningsOf(2)).to.equal('101') + // expect(await registryContract.operatorEarningsOf(3)).to.equal('101') + // expect(await registryContract.operatorEarningsOf(4)).to.equal('101') + // expect(await registryContract.groupBalanceOf(owner.address, outputRegister.groupId)).to.equal(10000 - 904) + + // // Update 3 operator fees + // await registryContract.updateOperatorFee(2, 20) + // await registryContract.updateOperatorFee(3, 20) + // await registryContract.updateOperatorFee(4, 20) + + // // Progress 50 blocks and check operator balances and group balance + // await utils.progressBlocks(50) + // expect(await registryContract.operatorEarningsOf(1)).to.equal('1081') + // expect(await registryContract.operatorEarningsOf(2)).to.equal('1142') + // expect(await registryContract.operatorEarningsOf(3)).to.equal('1123') + // expect(await registryContract.operatorEarningsOf(4)).to.equal('1104') + // expect(await registryContract.groupBalanceOf(owner.address, outputRegister.groupId)).to.equal(10000 - 4500) + + // // Add another validator + // await registryContract.registerValidator( + // [1, 2, 3, 5], + // `${validatorPK}1`, + // shares[1], + // "10000" + // ) + + // // Progress 50 blocks and check operator balances and group balance + // await utils.progressBlocks(50) + // expect(await registryContract.operatorEarningsOf(1)).to.equal('2091') + // expect(await registryContract.operatorEarningsOf(2)).to.equal('3162') + // expect(await registryContract.operatorEarningsOf(3)).to.equal('3143') + // expect(await registryContract.operatorEarningsOf(4)).to.equal('2124') + // expect(await registryContract.operatorEarningsOf(5)).to.equal('5000') + // expect(await registryContract.groupBalanceOf(owner.address, outputRegister.groupId)).to.equal(10000 - 4500) + + // // Remove an operator + // await registryContract.removeOperator(1) + + // // Progress 50 blocks and check operator balances and group balance + // await utils.progressBlocks(50) + // expect(await registryContract.operatorEarningsOf(1)).to.equal('2091') + // expect(await registryContract.operatorEarningsOf(2)).to.equal('3162') + // expect(await registryContract.operatorEarningsOf(3)).to.equal('3143') + // expect(await registryContract.operatorEarningsOf(4)).to.equal('2124') + // expect(await registryContract.operatorEarningsOf(5)).to.equal('5000') + // expect(await registryContract.groupBalanceOf(owner.address, outputRegister.groupId)).to.equal(10000 - 4500) + + // // Update a validator + // await registryContract.updateValidator( + // [1, 2, 3, 5], + // `${validatorPK}0`, + // shares[1], + // "10" + // ) + + // // Progress 50 blocks and check operator balances and group balance + // await utils.progressBlocks(50) + // expect(await registryContract.operatorEarningsOf(1)).to.equal('2091') + // expect(await registryContract.operatorEarningsOf(2)).to.equal('3162') + // expect(await registryContract.operatorEarningsOf(3)).to.equal('3143') + // expect(await registryContract.operatorEarningsOf(4)).to.equal('2124') + // expect(await registryContract.operatorEarningsOf(5)).to.equal('5000') + // expect(await registryContract.groupBalanceOf(owner.address, outputRegister.groupId)).to.equal(10000 - 4500) + + // // Remove a validator + // await registryContract.removeValidator(`${validatorPK}0`, outputRegister.groupId) + + // // Progress 50 blocks and check operator balances and group balance + // await utils.progressBlocks(50) + // expect(await registryContract.operatorEarningsOf(1)).to.equal('2091') + // expect(await registryContract.operatorEarningsOf(2)).to.equal('3162') + // expect(await registryContract.operatorEarningsOf(3)).to.equal('3143') + // expect(await registryContract.operatorEarningsOf(4)).to.equal('2124') + // expect(await registryContract.operatorEarningsOf(5)).to.equal('5000') + // expect(await registryContract.groupBalanceOf(owner.address, outputRegister.groupId)).to.equal(10000 - 4500) + }); }); diff --git a/test/sanity/stress.ts b/test/sanity/stress.ts index d7ff8879..75c70df1 100644 --- a/test/sanity/stress.ts +++ b/test/sanity/stress.ts @@ -1,51 +1,54 @@ -const { expect } = require("chai"); -declare const ethers: any - -import * as helpers from "../helpers/contract-helpers" -let registryContract: any, operatorIDs: any, shares: any -const numberOfOperators = 1000 -const operatorFee = 1 -let validatorData: any = [] - -describe("Stress Tests", () => { - beforeEach(async () => { - const contractData = await helpers.initializeContract(numberOfOperators, operatorFee) - registryContract = contractData.contract - operatorIDs = contractData.operatorIDs - shares = contractData.shares - - // Register 1000 validators - validatorData = await helpers.registerValidators(1000, '10000', numberOfOperators, registryContract) - }) - - it("Update 1000 operators", async () => { - for (let i = 0; i < operatorIDs.length; i++) { - await registryContract.updateOperatorFee(operatorIDs[i], 10) - } - }) - - it("Update 1000 validators", async () => { - for (let i = 1000; i < (validatorData.length + 1000); i++) { - const randomOperator = Math.floor(Math.random() * (numberOfOperators - 4)) - await registryContract.updateValidator( - [randomOperator, randomOperator + 1, randomOperator + 2, randomOperator + 3], - validatorData[i-1000].publicKey, - shares[1], - "10001" - ) - } - }) - - it("Remove 1000 operators", async () => { - for (let i = 0; i < operatorIDs.length; i++) { - await registryContract.removeOperator(operatorIDs[i]) - } - }) - - it("Remove 1000 validators", async () => { - for (let i = 0; i < validatorData.length; i++) { - await registryContract.removeValidator(validatorData[i].publicKey) - } - }) - -}); \ No newline at end of file +declare const ethers: any; + +import * as helpers from '../helpers/contract-helpers'; + +import { expect } from 'chai'; + +const numberOfOperators = 1000; +const operatorFee = 1; + +let registryContract: any, operatorIDs: any, shares: any; +let validatorData: any = []; + +describe('Stress Tests', () => { + beforeEach(async () => { + const contractData = await helpers.initializeContract(numberOfOperators, operatorFee); + registryContract = contractData.contract; + operatorIDs = contractData.operatorIDs; + shares = contractData.shares; + + // Register 1000 validators + validatorData = await helpers.registerValidators(1000, '10000', numberOfOperators, registryContract); + }); + + it('Update 1000 operators', async () => { + for (let i = 0; i < operatorIDs.length; i++) { + await registryContract.updateOperatorFee(operatorIDs[i], 10); + } + }); + + it('Update 1000 validators', async () => { + for (let i = 1000; i < (validatorData.length + 1000); i++) { + const randomOperator = Math.floor(Math.random() * (numberOfOperators - 4)); + await registryContract.updateValidator( + [randomOperator, randomOperator + 1, randomOperator + 2, randomOperator + 3], + validatorData[i-1000].publicKey, + shares[1], + '10001' + ); + } + }); + + it('Remove 1000 operators', async () => { + for (let i = 0; i < operatorIDs.length; i++) { + await registryContract.removeOperator(operatorIDs[i]); + } + }); + + it('Remove 1000 validators', async () => { + for (let i = 0; i < validatorData.length; i++) { + await registryContract.removeValidator(validatorData[i].publicKey); + } + }); + +}); diff --git a/test/validators/gas/1-operator-different.ts b/test/validators/gas/1-operator-different.ts index af907b45..b5fbe03e 100644 --- a/test/validators/gas/1-operator-different.ts +++ b/test/validators/gas/1-operator-different.ts @@ -1,33 +1,35 @@ -const { expect } = require("chai"); +import * as helpers from '../../helpers/contract-helpers'; -import * as helpers from "../../helpers/contract-helpers" -let registryContract: any, operatorIDs: any, shares: any, owner: any -const numberOfOperators = 4 -const operatorFee = 4 +import { expect } from 'chai'; -describe("Register Validator Gas Tests 1 Operator Different", () => { - beforeEach(async () => { - const contractData = await helpers.initializeContract(numberOfOperators, operatorFee) - registryContract = contractData.contract - operatorIDs = contractData.operatorIDs - shares = contractData.shares - }) +const numberOfOperators = 4; +const operatorFee = 4; - it("1 Operator Different", async () => { - const validatorPK = `0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100` +let registryContract: any, operatorIDs: any, shares: any, owner: any; - await registryContract.registerValidator( - [1, 2, 3, 4], - `${validatorPK}0`, - shares[0], - "10000" - ) +describe('Register Validator Gas Tests 1 Operator Different', () => { + beforeEach(async () => { + const contractData = await helpers.initializeContract(numberOfOperators, operatorFee); + registryContract = contractData.contract; + operatorIDs = contractData.operatorIDs; + shares = contractData.shares; + }); - await registryContract.registerValidator( - [1, 2, 3, 5], - `${validatorPK}1`, - shares[1], - "10000" - ) - }) + it('1 Operator Different', async () => { + const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; + + await registryContract.registerValidator( + [1, 2, 3, 4], + `${validatorPK}0`, + shares[0], + '10000' + ); + + await registryContract.registerValidator( + [1, 2, 3, 5], + `${validatorPK}1`, + shares[1], + '10000' + ); + }); }); diff --git a/test/validators/gas/2-operator-different.ts b/test/validators/gas/2-operator-different.ts index 8719fc1b..bb705c9c 100644 --- a/test/validators/gas/2-operator-different.ts +++ b/test/validators/gas/2-operator-different.ts @@ -1,34 +1,36 @@ -const { expect } = require("chai"); - -import * as helpers from "../../helpers/contract-helpers" -let registryContract: any, operatorIDs: any, shares: any, owner: any -const numberOfOperators = 4 -const operatorFee = 4 - -describe("Register Validator Gas Tests 2 Operator Different", () => { - beforeEach(async () => { - const contractData = await helpers.initializeContract(numberOfOperators, operatorFee) - registryContract = contractData.contract - operatorIDs = contractData.operatorIDs - shares = contractData.shares - }) - - it("2 Operator Different", async () => { - const validatorPK = `0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100` - - await registryContract.registerValidator( - [1, 2, 3, 4], - `${validatorPK}0`, - shares[0], - "10000" - ) - - await registryContract.registerValidator( - [1, 2, 5, 6], - `${validatorPK}1`, - shares[1], - "10000" - ) - }) +import * as helpers from '../../helpers/contract-helpers'; + +import { expect } from 'chai'; + +const numberOfOperators = 4; +const operatorFee = 4; + +let registryContract: any, operatorIDs: any, shares: any, owner: any; + +describe('Register Validator Gas Tests 2 Operator Different', () => { + beforeEach(async () => { + const contractData = await helpers.initializeContract(numberOfOperators, operatorFee); + registryContract = contractData.contract; + operatorIDs = contractData.operatorIDs; + shares = contractData.shares; + }); + + it('2 Operator Different', async () => { + const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; + + await registryContract.registerValidator( + [1, 2, 3, 4], + `${validatorPK}0`, + shares[0], + '10000' + ); + + await registryContract.registerValidator( + [1, 2, 5, 6], + `${validatorPK}1`, + shares[1], + '10000' + ); + }); }); diff --git a/test/validators/gas/3-operator-different.ts b/test/validators/gas/3-operator-different.ts index a2e30c48..802b4cb8 100644 --- a/test/validators/gas/3-operator-different.ts +++ b/test/validators/gas/3-operator-different.ts @@ -1,34 +1,36 @@ -const { expect } = require("chai"); - -import * as helpers from "../../helpers/contract-helpers" -let registryContract: any, operatorIDs: any, shares: any, owner: any -const numberOfOperators = 4 -const operatorFee = 4 - -describe("Register Validator Gas Tests 3 Operator Different", () => { - beforeEach(async () => { - const contractData = await helpers.initializeContract(numberOfOperators, operatorFee) - registryContract = contractData.contract - operatorIDs = contractData.operatorIDs - shares = contractData.shares - }) - - it("3 Operator Different", async () => { - const validatorPK = `0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100` - - await registryContract.registerValidator( - [1, 2, 3, 4], - `${validatorPK}0`, - shares[0], - "10000" - ) - - await registryContract.registerValidator( - [1, 5, 6, 7], - `${validatorPK}1`, - shares[1], - "10000" - ) - }) +import * as helpers from '../../helpers/contract-helpers'; + +import { expect } from 'chai'; + +const numberOfOperators = 4; +const operatorFee = 4; + +let registryContract: any, operatorIDs: any, shares: any, owner: any; + +describe('Register Validator Gas Tests 3 Operator Different', () => { + beforeEach(async () => { + const contractData = await helpers.initializeContract(numberOfOperators, operatorFee); + registryContract = contractData.contract; + operatorIDs = contractData.operatorIDs; + shares = contractData.shares; + }); + + it('3 Operator Different', async () => { + const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; + + await registryContract.registerValidator( + [1, 2, 3, 4], + `${validatorPK}0`, + shares[0], + '10000' + ); + + await registryContract.registerValidator( + [1, 5, 6, 7], + `${validatorPK}1`, + shares[1], + '10000' + ); + }); }); diff --git a/test/validators/gas/4-operator-different.ts b/test/validators/gas/4-operator-different.ts index a779d42e..3c308416 100644 --- a/test/validators/gas/4-operator-different.ts +++ b/test/validators/gas/4-operator-different.ts @@ -1,34 +1,36 @@ -const { expect } = require("chai"); - -import * as helpers from "../../helpers/contract-helpers" -let registryContract: any, operatorIDs: any, shares: any, owner: any -const numberOfOperators = 4 -const operatorFee = 4 - -describe("Register Validator Gas Tests 3 Operator Different", () => { - beforeEach(async () => { - const contractData = await helpers.initializeContract(numberOfOperators, operatorFee) - registryContract = contractData.contract - operatorIDs = contractData.operatorIDs - shares = contractData.shares - }) - - it("3 Operator Different", async () => { - const validatorPK = `0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100` - - await registryContract.registerValidator( - [1, 2, 3, 4], - `${validatorPK}0`, - shares[0], - "10000" - ) - - await registryContract.registerValidator( - [5, 6, 7, 8], - `${validatorPK}1`, - shares[1], - "10000" - ) - }) +import * as helpers from '../../helpers/contract-helpers'; + +import { expect } from 'chai'; + +const numberOfOperators = 4; +const operatorFee = 4; + +let registryContract: any, operatorIDs: any, shares: any, owner: any; + +describe('Register Validator Gas Tests 3 Operator Different', () => { + beforeEach(async () => { + const contractData = await helpers.initializeContract(numberOfOperators, operatorFee); + registryContract = contractData.contract; + operatorIDs = contractData.operatorIDs; + shares = contractData.shares; + }); + + it('3 Operator Different', async () => { + const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; + + await registryContract.registerValidator( + [1, 2, 3, 4], + `${validatorPK}0`, + shares[0], + '10000' + ); + + await registryContract.registerValidator( + [5, 6, 7, 8], + `${validatorPK}1`, + shares[1], + '10000' + ); + }); }); diff --git a/test/validators/gas/different-group.ts b/test/validators/gas/different-group.ts index 2919d7c5..6480d8a2 100644 --- a/test/validators/gas/different-group.ts +++ b/test/validators/gas/different-group.ts @@ -1,34 +1,36 @@ -const { expect } = require("chai"); - -import * as helpers from "../../helpers/contract-helpers" -let registryContract: any, operatorIDs: any, shares: any, owner: any -const numberOfOperators = 4 -const operatorFee = 4 - -describe("Register Validator Gas Tests Different Group", () => { - beforeEach(async () => { - const contractData = await helpers.initializeContract(numberOfOperators, operatorFee) - registryContract = contractData.contract - operatorIDs = contractData.operatorIDs - shares = contractData.shares - }) - - it("Different group", async () => { - const validatorPK = `0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100` - - await registryContract.registerValidator( - [1, 2, 3, 4], - `${validatorPK}0`, - shares[0], - "10000" - ) - - await registryContract.registerValidator( - [5, 6, 7, 8], - `${validatorPK}1`, - shares[1], - "10000" - ) - }) +import * as helpers from '../../helpers/contract-helpers'; + +import { expect } from 'chai'; + +const numberOfOperators = 4; +const operatorFee = 4; + +let registryContract: any, operatorIDs: any, shares: any, owner: any; + +describe('Register Validator Gas Tests Different Group', () => { + beforeEach(async () => { + const contractData = await helpers.initializeContract(numberOfOperators, operatorFee); + registryContract = contractData.contract; + operatorIDs = contractData.operatorIDs; + shares = contractData.shares; + }); + + it('Different group', async () => { + const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; + + await registryContract.registerValidator( + [1, 2, 3, 4], + `${validatorPK}0`, + shares[0], + '10000' + ); + + await registryContract.registerValidator( + [5, 6, 7, 8], + `${validatorPK}1`, + shares[1], + '10000' + ); + }); }); diff --git a/test/validators/gas/same-group.ts b/test/validators/gas/same-group.ts index 44f1166d..9df3c17c 100644 --- a/test/validators/gas/same-group.ts +++ b/test/validators/gas/same-group.ts @@ -1,34 +1,36 @@ -const { expect } = require("chai"); - -import * as helpers from "../../helpers/contract-helpers" -let registryContract: any, operatorIDs: any, shares: any, owner: any -const numberOfOperators = 4 -const operatorFee = 4 - -describe("Register Validator Gas Tests Same Group", () => { - beforeEach(async () => { - const contractData = await helpers.initializeContract(numberOfOperators, operatorFee) - registryContract = contractData.contract - operatorIDs = contractData.operatorIDs - shares = contractData.shares - }) - - it("Same group", async () => { - const validatorPK = `0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100` - - await registryContract.registerValidator( - [1, 2, 3, 4], - `${validatorPK}0`, - shares[0], - "10000" - ) - - await registryContract.registerValidator( - [1, 2, 3, 4], - `${validatorPK}1`, - shares[1], - "10000" - ) - }) +import * as helpers from '../../helpers/contract-helpers'; + +import { expect } from 'chai'; + +const numberOfOperators = 4; +const operatorFee = 4; + +let registryContract: any, operatorIDs: any, shares: any, owner: any; + +describe('Register Validator Gas Tests Same Group', () => { + beforeEach(async () => { + const contractData = await helpers.initializeContract(numberOfOperators, operatorFee); + registryContract = contractData.contract; + operatorIDs = contractData.operatorIDs; + shares = contractData.shares; + }); + + it('Same group', async () => { + const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; + + await registryContract.registerValidator( + [1, 2, 3, 4], + `${validatorPK}0`, + shares[0], + '10000' + ); + + await registryContract.registerValidator( + [1, 2, 3, 4], + `${validatorPK}1`, + shares[1], + '10000' + ); + }); }); diff --git a/test/validators/register.ts b/test/validators/register.ts index 6114d262..18ca8e2a 100644 --- a/test/validators/register.ts +++ b/test/validators/register.ts @@ -1,30 +1,68 @@ -const { expect } = require("chai"); -import { trackGas } from "../helpers/gas-usage" - -import * as helpers from "../helpers/contract-helpers" -let registryContract: any, operatorIDs: any, shares: any, owner: any -const numberOfOperators = 4 -const operatorFee = 4 - -describe("Register Validator Tests", () => { - beforeEach(async () => { - const contractData = await helpers.initializeContract(numberOfOperators, operatorFee) - registryContract = contractData.contract - operatorIDs = contractData.operatorIDs - shares = contractData.shares - }) - - it("Register validator", async () => { - const validatorPK = `0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100` - await trackGas(registryContract.registerValidator( - `${validatorPK}0`, - [1, 2, 3, 4], - shares[0], - "10000" - ), 'registerValidator', 500000); - }) - - it("Register validator errors", async () => { - - }) -}); \ No newline at end of file +import * as helpers from '../helpers/contract-helpers'; + +import { expect } from 'chai'; +import { runTx } from '../helpers/utils'; + +const numberOfOperators = 8; +const operatorFee = 4; + +let registryContract: any, operatorIDs: any, shares: any, owner: any; + +describe('Register Validator Tests', () => { + beforeEach(async () => { + const contractData = await helpers.initializeContract(numberOfOperators, operatorFee); + registryContract = contractData.contract; + operatorIDs = contractData.operatorIDs; + shares = contractData.shares; + }); + + it('Register validator in empty pod', async () => { + const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; + const { gasUsed } = await runTx(registryContract.registerValidator( + `${validatorPK}0`, + operatorIDs.slice(0, 4), + shares[0], + '10000' + )); + expect(gasUsed).lessThan(400000); + }); + + it('Register two validators in same pod', async () => { + const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; + const firstValidator = await runTx(registryContract.registerValidator( + `${validatorPK}0`, + operatorIDs.slice(0, 4), + shares[0], + '10000' + )); + expect(firstValidator.gasUsed).lessThan(400000); + + const secondValidator = await runTx(registryContract.registerValidator( + `${validatorPK}1`, + operatorIDs.slice(0, 4), + shares[0], + '10000' + )); + expect(secondValidator.gasUsed).lessThan(220000); + + }); + + it('Register two validators in different pods', async () => { + const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; + const firstValidator = await runTx(registryContract.registerValidator( + `${validatorPK}0`, + operatorIDs.slice(0, 4), + shares[0], + '10000' + )); + expect(firstValidator.gasUsed).lessThan(400000); + + const secondValidator = await runTx(registryContract.registerValidator( + `${validatorPK}1`, + operatorIDs.slice(4, 8), + shares[0], + '10000' + )); + expect(secondValidator.gasUsed).lessThan(400000); + }); +}); diff --git a/test/validators/remove.ts b/test/validators/remove.ts index ccffbdc3..68ed30d4 100644 --- a/test/validators/remove.ts +++ b/test/validators/remove.ts @@ -1,28 +1,30 @@ -const { expect } = require("chai"); +import * as helpers from '../helpers/contract-helpers'; -import * as helpers from "../helpers/contract-helpers" -let registryContract: any, operatorIDs: any, shares: any, owner: any -const numberOfOperators = 4 -const operatorFee = 4 +import { expect } from 'chai'; -describe("Remove Validator Tests", () => { - beforeEach(async () => { - const contractData = await helpers.initializeContract(numberOfOperators, operatorFee) - registryContract = contractData.contract - operatorIDs = contractData.operatorIDs - shares = contractData.shares - }) +const numberOfOperators = 4; +const operatorFee = 4; - it("Remove validator", async () => { +let registryContract: any, operatorIDs: any, shares: any, owner: any; - }) +describe('Remove Validator Tests', () => { + beforeEach(async () => { + const contractData = await helpers.initializeContract(numberOfOperators, operatorFee); + registryContract = contractData.contract; + operatorIDs = contractData.operatorIDs; + shares = contractData.shares; + }); - it("Remove validator errors", async () => { + it('Remove validator', async () => { - }) + }); - it("Remove Validator gas limits", async () => { + it('Remove validator errors', async () => { - }) + }); + + it('Remove Validator gas limits', async () => { + + }); }); diff --git a/test/validators/transfer.ts b/test/validators/transfer.ts new file mode 100644 index 00000000..940e3ff1 --- /dev/null +++ b/test/validators/transfer.ts @@ -0,0 +1,70 @@ +import * as helpers from '../helpers/contract-helpers'; + +import { expect } from 'chai'; +import { runTx } from '../helpers/utils'; + +const numberOfOperators = 8; +const operatorFee = 4; + +let registryContract: any, operatorIDs: any, shares: any, owner: any; + +describe('Transfer Validator Tests', () => { + beforeEach(async () => { + const contractData = await helpers.initializeContract(numberOfOperators, operatorFee); + registryContract = contractData.contract; + operatorIDs = contractData.operatorIDs; + shares = contractData.shares; + }); + + it('Transfer validator into new pod', async () => { + const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; + const validatorBeforeTransfer = await runTx(registryContract.registerValidator( + `${validatorPK}0`, + operatorIDs.slice(0, 4), + shares[0], + '10000' + ), 'ValidatorAdded', 'bytes validatorPK, bytes32 podId, bytes shares'); + + const transferedValidator = await runTx(registryContract.transferValidator( + `${validatorPK}0`, + operatorIDs.slice(4, 8), + shares[0], + '10000' + ), 'ValidatorTransferred', 'bytes publicKey, bytes32 podId, bytes shares'); + expect(transferedValidator.gasUsed).lessThan(410000); + + expect(validatorBeforeTransfer.data.podId).not.equals(transferedValidator.data.podId); + }); + + it('Transfer validator to existed pod', async () => { + const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; + const validatorOne = await runTx(registryContract.registerValidator( + `${validatorPK}0`, + operatorIDs.slice(0, 4), + shares[0], + '10000' + ), 'ValidatorAdded', 'bytes validatorPK, bytes32 podId, bytes shares'); + + const validatorTwo = await runTx(registryContract.registerValidator( + `${validatorPK}1`, + operatorIDs.slice(4, 8), + shares[0], + '10000' + ), 'ValidatorAdded', 'bytes validatorPK, bytes32 podId, bytes shares'); + + const transferedValidator = await runTx(registryContract.transferValidator( + `${validatorPK}0`, + operatorIDs.slice(4, 8), + shares[0], + '10000' + ), 'ValidatorTransferred', 'bytes publicKey, bytes32 podId, bytes shares'); + expect(transferedValidator.gasUsed).lessThan(270000); + + expect(validatorTwo.data.podId).equals(transferedValidator.data.podId); + }); + + it('Transfer Validator gas limits', async () => { + + }); + +}); diff --git a/test/validators/update.ts b/test/validators/update.ts deleted file mode 100644 index 72c22082..00000000 --- a/test/validators/update.ts +++ /dev/null @@ -1,28 +0,0 @@ -const { expect } = require("chai"); - -import * as helpers from "../helpers/contract-helpers" -let registryContract: any, operatorIDs: any, shares: any, owner: any -const numberOfOperators = 4 -const operatorFee = 4 - -describe("Update Validator Tests", () => { - beforeEach(async () => { - const contractData = await helpers.initializeContract(numberOfOperators, operatorFee) - registryContract = contractData.contract - operatorIDs = contractData.operatorIDs - shares = contractData.shares - }) - - it("Update validator", async () => { - - }) - - it("Update validator errors", async () => { - - }) - - it("Update Validator gas limits", async () => { - - }) - -}); From 5947e1349b78d2e064d22143d839363999115394 Mon Sep 17 00:00:00 2001 From: Vadim Date: Wed, 31 Aug 2022 14:15:27 +0200 Subject: [PATCH 042/149] runTx -> trackGas + fix tests --- test/helpers/contract-helpers.ts | 12 +++------- test/helpers/gas-usage.ts | 18 ++++++-------- test/helpers/utils.ts | 14 ----------- test/sanity/stress.ts | 2 +- test/validators/gas/1-operator-different.ts | 4 ++-- test/validators/gas/2-operator-different.ts | 4 ++-- test/validators/gas/3-operator-different.ts | 4 ++-- test/validators/gas/4-operator-different.ts | 4 ++-- test/validators/gas/different-group.ts | 4 ++-- test/validators/gas/same-group.ts | 4 ++-- test/validators/register.ts | 12 +++++----- test/validators/transfer.ts | 26 ++++++++++----------- 12 files changed, 42 insertions(+), 66 deletions(-) diff --git a/test/helpers/contract-helpers.ts b/test/helpers/contract-helpers.ts index 85b67ee6..8ef5ea69 100644 --- a/test/helpers/contract-helpers.ts +++ b/test/helpers/contract-helpers.ts @@ -40,20 +40,14 @@ export const registerValidators = async (numberOfValidators: number, amount: str const validatorPK = `0xa7ae1ea93b860ca0269ccca776b4526977395aa194e5820a00dedbf1cd63e7a898eec9a12f539f733ea4df9c651f${i}`; const receipt = await trackGas(contract.registerValidator( - [randomOperator, randomOperator + 1, randomOperator + 2, randomOperator + 3], validatorPK, + [randomOperator, randomOperator + 1, randomOperator + 2, randomOperator + 3], shares[0], amount, - ), 'registerValidator', 400000); - - const registerResult = receipt.logs[0]; - - // Save validator group id emits - const interfaceRegister = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId, bytes shares)']); - const outputRegister = interfaceRegister.decodeEventLog('ValidatorAdded', registerResult.data, registerResult.topics); + ), ['registerValidator']); // Save the validator emit - validatorData.push({ publicKey: validatorPK, groupId: outputRegister.groupId }); + validatorData.push({ publicKey: validatorPK, groupId: receipt.events.ValidatorAdded.args.podId }); } return validatorData; diff --git a/test/helpers/gas-usage.ts b/test/helpers/gas-usage.ts index 7d72f277..95ba5556 100644 --- a/test/helpers/gas-usage.ts +++ b/test/helpers/gas-usage.ts @@ -30,21 +30,17 @@ const getOrCreate = (group: string) => { return groupStats; }; -export const trackGas = async (tx: Promise, group: string, maxGas: number) => { +export const trackGas = async (tx: Promise, groups?: Array): Promise => { const receipt = await (await tx).wait(); - if (receipt.gasUsed > maxGas) { - throw new Error(`Gas usage too high. Max: ${maxGas}, Actual: ${receipt.gasUsed}`); - } - console.log('\t', +receipt.gasUsed); - - const groupStats = getOrCreate(group); - - groupStats.addStat(parseInt(receipt.gasUsed)); - - return receipt; + groups && groups.forEach(group => { + const groupStats = getOrCreate(group); + groupStats.addStat(parseInt(receipt.gasUsed)); + }); + return { gasUsed: +receipt.gasUsed, events: receipt.events.reduce((aggr: any, item: any) => { aggr[item.event] = item; return aggr; }, {}) }; }; export const getGasStats = (group: string) => { return gasUsageStats.get(group) || new GasStats(); }; + diff --git a/test/helpers/utils.ts b/test/helpers/utils.ts index e31f1cfe..f1bf131d 100644 --- a/test/helpers/utils.ts +++ b/test/helpers/utils.ts @@ -68,17 +68,3 @@ export const mine = async (amount: number) => { } return mineChunk(amount % MAX_PARALLEL_CALLS); }; - -export const runTx = async (tx: Promise, eventName?: any, eventInterface?: any) => { - const receipt = await (await tx).wait(); - let data; - - if (eventName && eventInterface) { - const result = receipt.logs[0]; - const schema = new ethers.utils.Interface([`event ${eventName}(${eventInterface})`]); - data = schema.decodeEventLog(eventName, result.data, result.topics); - } - console.log('\t', +receipt.gasUsed); - - return { gasUsed: +receipt.gasUsed, data }; -} diff --git a/test/sanity/stress.ts b/test/sanity/stress.ts index 75c70df1..6b32691b 100644 --- a/test/sanity/stress.ts +++ b/test/sanity/stress.ts @@ -31,8 +31,8 @@ describe('Stress Tests', () => { for (let i = 1000; i < (validatorData.length + 1000); i++) { const randomOperator = Math.floor(Math.random() * (numberOfOperators - 4)); await registryContract.updateValidator( - [randomOperator, randomOperator + 1, randomOperator + 2, randomOperator + 3], validatorData[i-1000].publicKey, + [randomOperator, randomOperator + 1, randomOperator + 2, randomOperator + 3], shares[1], '10001' ); diff --git a/test/validators/gas/1-operator-different.ts b/test/validators/gas/1-operator-different.ts index b5fbe03e..62464030 100644 --- a/test/validators/gas/1-operator-different.ts +++ b/test/validators/gas/1-operator-different.ts @@ -19,15 +19,15 @@ describe('Register Validator Gas Tests 1 Operator Different', () => { const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; await registryContract.registerValidator( - [1, 2, 3, 4], `${validatorPK}0`, + [1, 2, 3, 4], shares[0], '10000' ); await registryContract.registerValidator( - [1, 2, 3, 5], `${validatorPK}1`, + [1, 2, 3, 5], shares[1], '10000' ); diff --git a/test/validators/gas/2-operator-different.ts b/test/validators/gas/2-operator-different.ts index bb705c9c..f5f9f6e4 100644 --- a/test/validators/gas/2-operator-different.ts +++ b/test/validators/gas/2-operator-different.ts @@ -19,15 +19,15 @@ describe('Register Validator Gas Tests 2 Operator Different', () => { const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; await registryContract.registerValidator( - [1, 2, 3, 4], `${validatorPK}0`, + [1, 2, 3, 4], shares[0], '10000' ); await registryContract.registerValidator( - [1, 2, 5, 6], `${validatorPK}1`, + [1, 2, 5, 6], shares[1], '10000' ); diff --git a/test/validators/gas/3-operator-different.ts b/test/validators/gas/3-operator-different.ts index 802b4cb8..171ff5cd 100644 --- a/test/validators/gas/3-operator-different.ts +++ b/test/validators/gas/3-operator-different.ts @@ -19,15 +19,15 @@ describe('Register Validator Gas Tests 3 Operator Different', () => { const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; await registryContract.registerValidator( - [1, 2, 3, 4], `${validatorPK}0`, + [1, 2, 3, 4], shares[0], '10000' ); await registryContract.registerValidator( - [1, 5, 6, 7], `${validatorPK}1`, + [1, 5, 6, 7], shares[1], '10000' ); diff --git a/test/validators/gas/4-operator-different.ts b/test/validators/gas/4-operator-different.ts index 3c308416..03d94db6 100644 --- a/test/validators/gas/4-operator-different.ts +++ b/test/validators/gas/4-operator-different.ts @@ -19,15 +19,15 @@ describe('Register Validator Gas Tests 3 Operator Different', () => { const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; await registryContract.registerValidator( - [1, 2, 3, 4], `${validatorPK}0`, + [1, 2, 3, 4], shares[0], '10000' ); await registryContract.registerValidator( - [5, 6, 7, 8], `${validatorPK}1`, + [5, 6, 7, 8], shares[1], '10000' ); diff --git a/test/validators/gas/different-group.ts b/test/validators/gas/different-group.ts index 6480d8a2..c7f2f346 100644 --- a/test/validators/gas/different-group.ts +++ b/test/validators/gas/different-group.ts @@ -19,15 +19,15 @@ describe('Register Validator Gas Tests Different Group', () => { const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; await registryContract.registerValidator( - [1, 2, 3, 4], `${validatorPK}0`, + [1, 2, 3, 4], shares[0], '10000' ); await registryContract.registerValidator( - [5, 6, 7, 8], `${validatorPK}1`, + [5, 6, 7, 8], shares[1], '10000' ); diff --git a/test/validators/gas/same-group.ts b/test/validators/gas/same-group.ts index 9df3c17c..2122accc 100644 --- a/test/validators/gas/same-group.ts +++ b/test/validators/gas/same-group.ts @@ -19,15 +19,15 @@ describe('Register Validator Gas Tests Same Group', () => { const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; await registryContract.registerValidator( - [1, 2, 3, 4], `${validatorPK}0`, + [1, 2, 3, 4], shares[0], '10000' ); await registryContract.registerValidator( - [1, 2, 3, 4], `${validatorPK}1`, + [1, 2, 3, 4], shares[1], '10000' ); diff --git a/test/validators/register.ts b/test/validators/register.ts index 18ca8e2a..017ad249 100644 --- a/test/validators/register.ts +++ b/test/validators/register.ts @@ -1,7 +1,7 @@ import * as helpers from '../helpers/contract-helpers'; import { expect } from 'chai'; -import { runTx } from '../helpers/utils'; +import { trackGas } from '../helpers/gas-usage'; const numberOfOperators = 8; const operatorFee = 4; @@ -18,7 +18,7 @@ describe('Register Validator Tests', () => { it('Register validator in empty pod', async () => { const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; - const { gasUsed } = await runTx(registryContract.registerValidator( + const { gasUsed } = await trackGas(registryContract.registerValidator( `${validatorPK}0`, operatorIDs.slice(0, 4), shares[0], @@ -29,7 +29,7 @@ describe('Register Validator Tests', () => { it('Register two validators in same pod', async () => { const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; - const firstValidator = await runTx(registryContract.registerValidator( + const firstValidator = await trackGas(registryContract.registerValidator( `${validatorPK}0`, operatorIDs.slice(0, 4), shares[0], @@ -37,7 +37,7 @@ describe('Register Validator Tests', () => { )); expect(firstValidator.gasUsed).lessThan(400000); - const secondValidator = await runTx(registryContract.registerValidator( + const secondValidator = await trackGas(registryContract.registerValidator( `${validatorPK}1`, operatorIDs.slice(0, 4), shares[0], @@ -49,7 +49,7 @@ describe('Register Validator Tests', () => { it('Register two validators in different pods', async () => { const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; - const firstValidator = await runTx(registryContract.registerValidator( + const firstValidator = await trackGas(registryContract.registerValidator( `${validatorPK}0`, operatorIDs.slice(0, 4), shares[0], @@ -57,7 +57,7 @@ describe('Register Validator Tests', () => { )); expect(firstValidator.gasUsed).lessThan(400000); - const secondValidator = await runTx(registryContract.registerValidator( + const secondValidator = await trackGas(registryContract.registerValidator( `${validatorPK}1`, operatorIDs.slice(4, 8), shares[0], diff --git a/test/validators/transfer.ts b/test/validators/transfer.ts index 940e3ff1..9d1712e1 100644 --- a/test/validators/transfer.ts +++ b/test/validators/transfer.ts @@ -1,7 +1,7 @@ import * as helpers from '../helpers/contract-helpers'; import { expect } from 'chai'; -import { runTx } from '../helpers/utils'; +import { trackGas } from '../helpers/gas-usage'; const numberOfOperators = 8; const operatorFee = 4; @@ -18,49 +18,49 @@ describe('Transfer Validator Tests', () => { it('Transfer validator into new pod', async () => { const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; - const validatorBeforeTransfer = await runTx(registryContract.registerValidator( + const validatorBeforeTransfer = await trackGas(registryContract.registerValidator( `${validatorPK}0`, operatorIDs.slice(0, 4), shares[0], '10000' - ), 'ValidatorAdded', 'bytes validatorPK, bytes32 podId, bytes shares'); + )); - const transferedValidator = await runTx(registryContract.transferValidator( + const transferedValidator = await trackGas(registryContract.transferValidator( `${validatorPK}0`, operatorIDs.slice(4, 8), shares[0], '10000' - ), 'ValidatorTransferred', 'bytes publicKey, bytes32 podId, bytes shares'); + )); expect(transferedValidator.gasUsed).lessThan(410000); - expect(validatorBeforeTransfer.data.podId).not.equals(transferedValidator.data.podId); + expect(validatorBeforeTransfer.events.ValidatorAdded.args.podId).not.equals(transferedValidator.events.ValidatorTransferred.args.podId); }); it('Transfer validator to existed pod', async () => { const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; - const validatorOne = await runTx(registryContract.registerValidator( + const validatorOne = await trackGas(registryContract.registerValidator( `${validatorPK}0`, operatorIDs.slice(0, 4), shares[0], '10000' - ), 'ValidatorAdded', 'bytes validatorPK, bytes32 podId, bytes shares'); + )); - const validatorTwo = await runTx(registryContract.registerValidator( + const validatorTwo = await trackGas(registryContract.registerValidator( `${validatorPK}1`, operatorIDs.slice(4, 8), shares[0], '10000' - ), 'ValidatorAdded', 'bytes validatorPK, bytes32 podId, bytes shares'); + )); - const transferedValidator = await runTx(registryContract.transferValidator( + const transferedValidator = await trackGas(registryContract.transferValidator( `${validatorPK}0`, operatorIDs.slice(4, 8), shares[0], '10000' - ), 'ValidatorTransferred', 'bytes publicKey, bytes32 podId, bytes shares'); + )); expect(transferedValidator.gasUsed).lessThan(270000); - expect(validatorTwo.data.podId).equals(transferedValidator.data.podId); + expect(validatorTwo.events.ValidatorAdded.args.podId).equals(transferedValidator.events.ValidatorTransferred.args.podId); }); it('Transfer Validator gas limits', async () => { From cd1bd4bd8f83fb19aa335be8aa7838ef7c4876d0 Mon Sep 17 00:00:00 2001 From: Vadim Date: Wed, 31 Aug 2022 14:28:48 +0200 Subject: [PATCH 043/149] fix tests, extend validators tests --- test/helpers/contract-helpers.ts | 5 ++++- test/validators/register.ts | 26 ++++++++++++++++++++++++-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/test/helpers/contract-helpers.ts b/test/helpers/contract-helpers.ts index 8ef5ea69..f9510872 100644 --- a/test/helpers/contract-helpers.ts +++ b/test/helpers/contract-helpers.ts @@ -25,7 +25,10 @@ export const initializeContract = async (numberOfOperators: number, fee: number) const operatorIDs = Array.from(Array(numberOfOperators).keys()).map(k => k + 1); // Deposit to the contract - await deployedRegistryContract.deposit('9000000000000000000'); + const [addr1, addr2, addr3] = await ethers.getSigners(); + await deployedRegistryContract.connect(addr1).deposit('9000000000000000000'); + await deployedRegistryContract.connect(addr2).deposit('9000000000000000000'); + await deployedRegistryContract.connect(addr3).deposit('9000000000000000000'); return { contract: deployedRegistryContract, operatorIDs: operatorIDs, shares: shares, owner: owner }; }; diff --git a/test/validators/register.ts b/test/validators/register.ts index 017ad249..9cf05ed6 100644 --- a/test/validators/register.ts +++ b/test/validators/register.ts @@ -1,3 +1,5 @@ +declare const ethers: any; + import * as helpers from '../helpers/contract-helpers'; import { expect } from 'chai'; @@ -6,10 +8,12 @@ import { trackGas } from '../helpers/gas-usage'; const numberOfOperators = 8; const operatorFee = 4; -let registryContract: any, operatorIDs: any, shares: any, owner: any; +let registryContract: any, operatorIDs: any, shares: any, addr1: any, addr2: any; describe('Register Validator Tests', () => { beforeEach(async () => { + [addr1, addr2] = await ethers.getSigners(); + const contractData = await helpers.initializeContract(numberOfOperators, operatorFee); registryContract = contractData.contract; operatorIDs = contractData.operatorIDs; @@ -27,7 +31,7 @@ describe('Register Validator Tests', () => { expect(gasUsed).lessThan(400000); }); - it('Register two validators in same pod', async () => { + it('Register two validators with one owner in same pod', async () => { const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; const firstValidator = await trackGas(registryContract.registerValidator( `${validatorPK}0`, @@ -47,6 +51,24 @@ describe('Register Validator Tests', () => { }); + it('Register two validators with different owners in same pod', async () => { + const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; + const firstValidator = await trackGas(registryContract.connect(addr1).registerValidator( + `${validatorPK}0`, + operatorIDs.slice(0, 4), + shares[0], + '10000' + )); + expect(firstValidator.gasUsed).lessThan(400000); + const secondValidator = await trackGas(registryContract.connect(addr2).registerValidator( + `${validatorPK}1`, + operatorIDs.slice(0, 4), + shares[0], + '10000' + )); + expect(secondValidator.gasUsed).lessThan(250000); + }); + it('Register two validators in different pods', async () => { const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; const firstValidator = await trackGas(registryContract.registerValidator( From 5655ca828699edd1b9f26383cf44b19e47f0ca65 Mon Sep 17 00:00:00 2001 From: Vadim Date: Wed, 31 Aug 2022 14:54:00 +0200 Subject: [PATCH 044/149] improvements and remove validator --- test/helpers/gas-usage.ts | 9 ++++++++- test/validators/register.ts | 23 +++++++++++++++++++++-- test/validators/remove.ts | 33 +++++++++++++++++++++++++-------- test/validators/transfer.ts | 26 +++++++++++++++++++++----- 4 files changed, 75 insertions(+), 16 deletions(-) diff --git a/test/helpers/gas-usage.ts b/test/helpers/gas-usage.ts index 95ba5556..248e7b49 100644 --- a/test/helpers/gas-usage.ts +++ b/test/helpers/gas-usage.ts @@ -37,7 +37,14 @@ export const trackGas = async (tx: Promise, groups?: Array): Promis const groupStats = getOrCreate(group); groupStats.addStat(parseInt(receipt.gasUsed)); }); - return { gasUsed: +receipt.gasUsed, events: receipt.events.reduce((aggr: any, item: any) => { aggr[item.event] = item; return aggr; }, {}) }; + return { + receipt, + gasUsed: +receipt.gasUsed, + eventsByName: receipt.events.reduce((aggr: any, item: any) => { + aggr[item.event] = aggr[item.event] || []; + aggr[item.event].push(item); + return aggr; + }, {}) }; }; export const getGasStats = (group: string) => { diff --git a/test/validators/register.ts b/test/validators/register.ts index 9cf05ed6..9fc39ab4 100644 --- a/test/validators/register.ts +++ b/test/validators/register.ts @@ -31,7 +31,7 @@ describe('Register Validator Tests', () => { expect(gasUsed).lessThan(400000); }); - it('Register two validators with one owner in same pod', async () => { + it('Register two validators same owner in same pod', async () => { const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; const firstValidator = await trackGas(registryContract.registerValidator( `${validatorPK}0`, @@ -69,7 +69,7 @@ describe('Register Validator Tests', () => { expect(secondValidator.gasUsed).lessThan(250000); }); - it('Register two validators in different pods', async () => { + it('Register two validators same owner in different pods', async () => { const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; const firstValidator = await trackGas(registryContract.registerValidator( `${validatorPK}0`, @@ -87,4 +87,23 @@ describe('Register Validator Tests', () => { )); expect(secondValidator.gasUsed).lessThan(400000); }); + + it('Register two validators different owners in different pods', async () => { + const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; + const firstValidator = await trackGas(registryContract.connect(addr1).registerValidator( + `${validatorPK}0`, + operatorIDs.slice(0, 4), + shares[0], + '10000' + )); + expect(firstValidator.gasUsed).lessThan(400000); + + const secondValidator = await trackGas(registryContract.connect(addr2).registerValidator( + `${validatorPK}1`, + operatorIDs.slice(4, 8), + shares[0], + '10000' + )); + expect(secondValidator.gasUsed).lessThan(400000); + }); }); diff --git a/test/validators/remove.ts b/test/validators/remove.ts index 68ed30d4..bc224d82 100644 --- a/test/validators/remove.ts +++ b/test/validators/remove.ts @@ -1,14 +1,19 @@ +declare const ethers: any; + import * as helpers from '../helpers/contract-helpers'; import { expect } from 'chai'; +import { trackGas } from '../helpers/gas-usage'; const numberOfOperators = 4; const operatorFee = 4; -let registryContract: any, operatorIDs: any, shares: any, owner: any; +let registryContract: any, operatorIDs: any, shares: any, addr1: any, addr2: any; describe('Remove Validator Tests', () => { beforeEach(async () => { + [addr1, addr2] = await ethers.getSigners(); + const contractData = await helpers.initializeContract(numberOfOperators, operatorFee); registryContract = contractData.contract; operatorIDs = contractData.operatorIDs; @@ -16,15 +21,27 @@ describe('Remove Validator Tests', () => { }); it('Remove validator', async () => { - + const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; + await trackGas(registryContract.registerValidator( + `${validatorPK}0`, + operatorIDs.slice(0, 4), + shares[0], + '10000' + )); + + const { gasUsed } = await trackGas(registryContract.removeValidator(`${validatorPK}0`)); + expect(gasUsed).lessThan(150000); }); - it('Remove validator errors', async () => { + it('Fails to transfer validator with no owner', async () => { + const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; + await trackGas(registryContract.registerValidator( + `${validatorPK}0`, + operatorIDs.slice(0, 4), + shares[0], + '10000' + )); + await expect(trackGas(registryContract.connect(addr2).removeValidator(`${validatorPK}0`))).to.be.revertedWith('ValidatorNotOwned'); }); - - it('Remove Validator gas limits', async () => { - - }); - }); diff --git a/test/validators/transfer.ts b/test/validators/transfer.ts index 9d1712e1..fb596fcd 100644 --- a/test/validators/transfer.ts +++ b/test/validators/transfer.ts @@ -1,3 +1,5 @@ +declare const ethers: any; + import * as helpers from '../helpers/contract-helpers'; import { expect } from 'chai'; @@ -6,10 +8,12 @@ import { trackGas } from '../helpers/gas-usage'; const numberOfOperators = 8; const operatorFee = 4; -let registryContract: any, operatorIDs: any, shares: any, owner: any; +let registryContract: any, operatorIDs: any, shares: any, addr1: any, addr2: any; describe('Transfer Validator Tests', () => { beforeEach(async () => { + [addr1, addr2] = await ethers.getSigners(); + const contractData = await helpers.initializeContract(numberOfOperators, operatorFee); registryContract = contractData.contract; operatorIDs = contractData.operatorIDs; @@ -33,7 +37,7 @@ describe('Transfer Validator Tests', () => { )); expect(transferedValidator.gasUsed).lessThan(410000); - expect(validatorBeforeTransfer.events.ValidatorAdded.args.podId).not.equals(transferedValidator.events.ValidatorTransferred.args.podId); + expect(validatorBeforeTransfer.eventsByName.ValidatorAdded[0].args.podId).not.equals(transferedValidator.eventsByName.ValidatorTransferred[0].args.podId); }); it('Transfer validator to existed pod', async () => { @@ -60,11 +64,23 @@ describe('Transfer Validator Tests', () => { )); expect(transferedValidator.gasUsed).lessThan(270000); - expect(validatorTwo.events.ValidatorAdded.args.podId).equals(transferedValidator.events.ValidatorTransferred.args.podId); + expect(validatorTwo.eventsByName.ValidatorAdded[0].args.podId).equals(transferedValidator.eventsByName.ValidatorTransferred[0].args.podId); }); - it('Transfer Validator gas limits', async () => { + it('Fails to transfer validator with no owner', async () => { + const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; + await trackGas(registryContract.registerValidator( + `${validatorPK}0`, + operatorIDs.slice(0, 4), + shares[0], + '10000' + )); + await expect(trackGas(registryContract.connect(addr2).transferValidator( + `${validatorPK}0`, + operatorIDs.slice(4, 8), + shares[0], + '10000' + ))).to.be.revertedWith('ValidatorNotOwned'); }); - }); From 7fa7206a0352d7466cadaf72faf459971f0e44fa Mon Sep 17 00:00:00 2001 From: Vadim Date: Wed, 31 Aug 2022 15:10:50 +0200 Subject: [PATCH 045/149] fix tests --- test/helpers/contract-helpers.ts | 2 +- test/operators/register.ts | 2 +- test/sanity/stress.ts | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/helpers/contract-helpers.ts b/test/helpers/contract-helpers.ts index f9510872..8255422f 100644 --- a/test/helpers/contract-helpers.ts +++ b/test/helpers/contract-helpers.ts @@ -50,7 +50,7 @@ export const registerValidators = async (numberOfValidators: number, amount: str ), ['registerValidator']); // Save the validator emit - validatorData.push({ publicKey: validatorPK, groupId: receipt.events.ValidatorAdded.args.podId }); + validatorData.push({ publicKey: validatorPK, groupId: receipt.eventsByName.ValidatorAdded[0].args.podId }); } return validatorData; diff --git a/test/operators/register.ts b/test/operators/register.ts index e4594d10..f8cda5e8 100644 --- a/test/operators/register.ts +++ b/test/operators/register.ts @@ -33,7 +33,7 @@ describe('Register Operator Tests', () => { [1, 2, 3, 4], shares[0], '10000' - ), 'registerValidator', 400000); + ), ['registerValidator']); // // Cost: 185380 // await deployedRegistryContract.registerValidator( diff --git a/test/sanity/stress.ts b/test/sanity/stress.ts index 6b32691b..25881252 100644 --- a/test/sanity/stress.ts +++ b/test/sanity/stress.ts @@ -27,10 +27,10 @@ describe('Stress Tests', () => { } }); - it('Update 1000 validators', async () => { + it('Transfer 1000 validators', async () => { for (let i = 1000; i < (validatorData.length + 1000); i++) { const randomOperator = Math.floor(Math.random() * (numberOfOperators - 4)); - await registryContract.updateValidator( + await registryContract.transferValidator( validatorData[i-1000].publicKey, [randomOperator, randomOperator + 1, randomOperator + 2, randomOperator + 3], shares[1], From 1e73ff41dad2e2e2e48e68e78f5380fb391bb193 Mon Sep 17 00:00:00 2001 From: Vadim Date: Wed, 31 Aug 2022 15:15:21 +0200 Subject: [PATCH 046/149] misspel fix --- test/validators/register.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/validators/register.ts b/test/validators/register.ts index 9fc39ab4..f60425a7 100644 --- a/test/validators/register.ts +++ b/test/validators/register.ts @@ -51,7 +51,7 @@ describe('Register Validator Tests', () => { }); - it('Register two validators with different owners in same pod', async () => { + it('Register two validators with different owners with same cluster', async () => { const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; const firstValidator = await trackGas(registryContract.connect(addr1).registerValidator( `${validatorPK}0`, @@ -69,7 +69,7 @@ describe('Register Validator Tests', () => { expect(secondValidator.gasUsed).lessThan(250000); }); - it('Register two validators same owner in different pods', async () => { + it('Register two validators same owner in different clusters', async () => { const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; const firstValidator = await trackGas(registryContract.registerValidator( `${validatorPK}0`, @@ -88,7 +88,7 @@ describe('Register Validator Tests', () => { expect(secondValidator.gasUsed).lessThan(400000); }); - it('Register two validators different owners in different pods', async () => { + it('Register two validators different owners in different clusters', async () => { const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; const firstValidator = await trackGas(registryContract.connect(addr1).registerValidator( `${validatorPK}0`, From 24f68c646dfb2de3519f1b195c56191fb525d582 Mon Sep 17 00:00:00 2001 From: Adam Zigdon Date: Wed, 31 Aug 2022 17:22:20 +0300 Subject: [PATCH 047/149] adding GasGroup enum --- test/helpers/contract-helpers.ts | 4 +-- test/helpers/gas-usage.ts | 46 +++++++++++++++++++++----------- test/operators/register.ts | 4 +-- test/validators/transfer.ts | 4 +-- 4 files changed, 36 insertions(+), 22 deletions(-) diff --git a/test/helpers/contract-helpers.ts b/test/helpers/contract-helpers.ts index f9510872..8b425a1d 100644 --- a/test/helpers/contract-helpers.ts +++ b/test/helpers/contract-helpers.ts @@ -1,7 +1,7 @@ // Imports declare const ethers: any; -import { trackGas, getGasStats } from './gas-usage'; +import { trackGas, getGasStats, GasGroup } from './gas-usage'; // Generate shares const shares = Array.from(Array(10).keys()).map(k => `0xe0096008000000b4010000040000001000000076000000dc000000420d142c307831323334353637383930fe0a00520a000031017afe66008266000032fe66009266000033fe66009266000034016621ac28d60000009c01000062020025c02c307839383736353433323130fe0a00520a000031fe560052560019b0003101dafec60082c6000032fec6007ac6004d6ca666000033ceb401fe8c017e8c014dcca6c6004d7a0035b23200fec6007ec6000034${k}${k}`); @@ -47,7 +47,7 @@ export const registerValidators = async (numberOfValidators: number, amount: str [randomOperator, randomOperator + 1, randomOperator + 2, randomOperator + 3], shares[0], amount, - ), ['registerValidator']); + ), [ GasGroup.registerValidator ]); // Save the validator emit validatorData.push({ publicKey: validatorPK, groupId: receipt.events.ValidatorAdded.args.podId }); diff --git a/test/helpers/gas-usage.ts b/test/helpers/gas-usage.ts index 248e7b49..778c3cd2 100644 --- a/test/helpers/gas-usage.ts +++ b/test/helpers/gas-usage.ts @@ -1,9 +1,25 @@ -export class GasStats { +export enum GasGroup { + registerValidator, + registerValidatorExistingGroup +} + +// const MAX_GAS_PER_GROUP = { +// registerValidator: 400000, +// registerValidatorExistingGroup: 250000 +// } + +const MAX_GAS_PER_GROUP = { + [GasGroup.registerValidator]: 400000, + [GasGroup.registerValidatorExistingGroup]: 250000 +} + +class GasStats { max: number | null = null; min: number | null = null; totalGas = 0; txCount = 0; + addStat(gas: number) { this.totalGas += gas; ++this.txCount; @@ -19,27 +35,25 @@ export class GasStats { const gasUsageStats = new Map(); -const getOrCreate = (group: string) => { - let groupStats = gasUsageStats.get(group); - - if (!groupStats) { - groupStats = new GasStats(); - gasUsageStats.set(group, groupStats); - } - - return groupStats; -}; +for (const group in MAX_GAS_PER_GROUP) { + gasUsageStats.set(group, new GasStats()); +} -export const trackGas = async (tx: Promise, groups?: Array): Promise => { +export const trackGas = async (tx: Promise, groups?: Array): Promise => { const receipt = await (await tx).wait(); groups && groups.forEach(group => { - const groupStats = getOrCreate(group); - groupStats.addStat(parseInt(receipt.gasUsed)); + const gasUsed = parseInt(receipt.gasUsed); + const maxGas = MAX_GAS_PER_GROUP[group as keyof typeof MAX_GAS_PER_GROUP]; + + if (gasUsed > maxGas) { + throw new Error(`Gas usage too high. Max: ${maxGas}, Actual: ${gasUsed}`); + } + + gasUsageStats.get(group.toString()).addStat(gasUsed); }); return { - receipt, - gasUsed: +receipt.gasUsed, + ...receipt, eventsByName: receipt.events.reduce((aggr: any, item: any) => { aggr[item.event] = aggr[item.event] || []; aggr[item.event].push(item); diff --git a/test/operators/register.ts b/test/operators/register.ts index e4594d10..42506a38 100644 --- a/test/operators/register.ts +++ b/test/operators/register.ts @@ -1,7 +1,7 @@ import * as helpers from '../helpers/contract-helpers'; import { expect } from 'chai'; -import { trackGas } from '../helpers/gas-usage'; +import { trackGas, GasGroup } from '../helpers/gas-usage'; const numberOfOperators = 4; const operatorFee = 4; @@ -33,7 +33,7 @@ describe('Register Operator Tests', () => { [1, 2, 3, 4], shares[0], '10000' - ), 'registerValidator', 400000); + ), [ GasGroup.registerValidator ]); // // Cost: 185380 // await deployedRegistryContract.registerValidator( diff --git a/test/validators/transfer.ts b/test/validators/transfer.ts index fb596fcd..81291a42 100644 --- a/test/validators/transfer.ts +++ b/test/validators/transfer.ts @@ -3,7 +3,7 @@ declare const ethers: any; import * as helpers from '../helpers/contract-helpers'; import { expect } from 'chai'; -import { trackGas } from '../helpers/gas-usage'; +import { trackGas, GasGroup } from '../helpers/gas-usage'; const numberOfOperators = 8; const operatorFee = 4; @@ -27,7 +27,7 @@ describe('Transfer Validator Tests', () => { operatorIDs.slice(0, 4), shares[0], '10000' - )); + ), [ GasGroup.registerValidator ]); const transferedValidator = await trackGas(registryContract.transferValidator( `${validatorPK}0`, From 8acb6404658de773cbeee709ae969052efcf896f Mon Sep 17 00:00:00 2001 From: Vadim Date: Thu, 1 Sep 2022 11:24:09 +0200 Subject: [PATCH 048/149] fix trackgas output --- test/helpers/gas-usage.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/test/helpers/gas-usage.ts b/test/helpers/gas-usage.ts index 778c3cd2..cc897b76 100644 --- a/test/helpers/gas-usage.ts +++ b/test/helpers/gas-usage.ts @@ -54,6 +54,7 @@ export const trackGas = async (tx: Promise, groups?: Array): Prom }); return { ...receipt, + gasUsed: +receipt.gasUsed, eventsByName: receipt.events.reduce((aggr: any, item: any) => { aggr[item.event] = aggr[item.event] || []; aggr[item.event].push(item); From 03fc0d829cb48bacdbba1643548d7fe45853dcb4 Mon Sep 17 00:00:00 2001 From: Lior Rutenberg Date: Thu, 1 Sep 2022 14:27:30 +0300 Subject: [PATCH 049/149] rename eraningins to snapshot + gas improvment --- contracts/ISSVNetwork.sol | 5 +++ contracts/SSVNetwork.sol | 64 ++++++++++++++++++--------------------- test/vadimToUpdate.js | 2 +- 3 files changed, 35 insertions(+), 36 deletions(-) diff --git a/contracts/ISSVNetwork.sol b/contracts/ISSVNetwork.sol index 4abd4535..078795cd 100644 --- a/contracts/ISSVNetwork.sol +++ b/contracts/ISSVNetwork.sol @@ -75,6 +75,11 @@ interface ISSVNetwork { event ValidatorRemoved(bytes publicKey, bytes32 podId); + /** errors */ + error InvalidPublicKeyLength(); + error OessDataStructureInvalid(); + error ValidatorNotOwned(); + /** errors */ // error validatorWithPublicKeyNotExist(); // error callerNotValidatorOwner(); diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index eb4ac99c..c13d1cc1 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -27,7 +27,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { uint64 fee; uint64 validatorCount; - Snapshot earnings; + Snapshot snapshot; } struct DAO { @@ -70,10 +70,6 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { uint64 constant LIQUIDATION_MIN_BLOCKS = 50; // uint64 constant NETWORK_FEE_PER_BLOCK = 1; - /** errors */ - error InvalidPublicKeyLength(); - error OessDataStructureInvalid(); - error ValidatorNotOwned(); DAO private _dao; IERC20 private _token; @@ -90,7 +86,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { lastOperatorId.increment(); operatorId = uint64(lastOperatorId.current()); - _operators[operatorId] = Operator({ owner: msg.sender, earnings: Snapshot({ block: uint64(block.number), index: 0, balance: 0}), validatorCount: 0, fee: fee}); + _operators[operatorId] = Operator({ owner: msg.sender, snapshot: Snapshot({ block: uint64(block.number), index: 0, balance: 0}), validatorCount: 0, fee: fee}); emit OperatorAdded(operatorId, msg.sender, encryptionPK); } @@ -100,7 +96,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { uint64 currentBlock = uint64(block.number); - operator.earnings = _updateOperatorEarnings(operator); + operator.snapshot = _getSnapshot(operator, currentBlock); operator.fee = 0; operator.validatorCount = 0; _operators[operatorId] = operator; @@ -138,7 +134,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { { for (uint64 i = 0; i < operatorIds.length; ++i) { Operator memory operator = _operators[operatorIds[i]]; - operator.earnings = _updateOperatorEarnings(operator); + operator.snapshot = _getSnapshot(operator, uint64(block.number)); ++operator.validatorCount; _operators[operatorIds[i]] = operator; } @@ -151,7 +147,6 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _dao = dao; } - // TODO require(!_liquidatable(pod.balance, pod.validatorCount, operatorIds), "account liquidatable"); _pods[keccak256(abi.encodePacked(msg.sender, clusterId))] = pod; @@ -242,7 +237,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { for (uint64 i = 0; i < cluster.operatorIds.length; ++i) { uint64 id = cluster.operatorIds[i]; - _operators[id].earnings = _updateOperatorEarnings(_operators[id]); + _operators[id].snapshot = _getSnapshot(_operators[id], uint64(block.number)); --_operators[id].validatorCount; } @@ -307,6 +302,18 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { // TODO add external functions below to interface + // @dev internal operators functions + + function _getSnapshot(Operator memory operator, uint64 currentBlock) private view returns (Snapshot memory) { + uint64 blockDiffFee = (currentBlock - operator.snapshot.block)* operator.fee; + + operator.snapshot.index += blockDiffFee; + operator.snapshot.balance += blockDiffFee * operator.validatorCount; + operator.snapshot.block = currentBlock; + + return operator.snapshot; + } + function _updateOperatorsValidatorMove( uint64[] memory oldOperatorIds, uint64[] memory newOperatorIds, @@ -314,17 +321,18 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { ) private { uint64 oldIndex; uint64 newIndex; + uint64 currentBlock = uint64(block.number); while (oldIndex < oldOperatorIds.length && newIndex < newOperatorIds.length) { if (oldOperatorIds[oldIndex] < newOperatorIds[newIndex]) { Operator memory operator = _operators[oldOperatorIds[oldIndex]]; - operator.earnings = _updateOperatorEarnings(operator); + operator.snapshot = _getSnapshot(operator, currentBlock); operator.validatorCount -= validatorCount; _operators[oldOperatorIds[oldIndex]] = operator; ++oldIndex; } else if (newOperatorIds[newIndex] < oldOperatorIds[oldIndex]) { Operator memory operator = _operators[newOperatorIds[newIndex]]; - operator.earnings = _updateOperatorEarnings(operator); + operator.snapshot = _getSnapshot(operator, currentBlock); operator.validatorCount += validatorCount; _operators[newOperatorIds[newIndex]] = operator; ++newIndex; @@ -336,7 +344,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { while (oldIndex < oldOperatorIds.length) { Operator memory operator = _operators[oldOperatorIds[oldIndex]]; - operator.earnings = _updateOperatorEarnings(operator); + operator.snapshot = _getSnapshot(operator, currentBlock); operator.validatorCount -= validatorCount; _operators[oldOperatorIds[oldIndex]] = operator; ++oldIndex; @@ -344,7 +352,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { while (newIndex < newOperatorIds.length) { Operator memory operator = _operators[newOperatorIds[newIndex]]; - operator.earnings = _updateOperatorEarnings(operator); + operator.snapshot = _getSnapshot(operator, currentBlock); operator.validatorCount += validatorCount; _operators[newOperatorIds[newIndex]] = operator; ++newIndex; @@ -353,7 +361,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { function _setFee(Operator memory operator, uint64 fee) private returns (Operator memory) { - operator.earnings = _updateOperatorEarnings(operator); + operator.snapshot = _getSnapshot(operator, uint64(block.number)); operator.fee = fee; return operator; @@ -363,7 +371,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { uint64 currentBlock = uint64(block.number); for (uint64 i = 0; i < operatorIds.length; ++i) { Operator memory operator = _operators[operatorIds[i]]; - operator.earnings = _updateOperatorEarnings(operator); + operator.snapshot = _getSnapshot(operator, uint64(block.number)); if (increase) { ++operator.validatorCount; } else { @@ -397,8 +405,8 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { return _ownerPodBalance(pod, _clusterCurrentIndex(clusterId)); } - function operatorEarningsOf(uint64 operatorId) external view returns (uint64) { - return _operatorCurrentEarnings(_operators[operatorId]); + function operatorSnapshot(uint64 operatorId) external view returns (Snapshot memory) { + return _getSnapshot(_operators[operatorId], uint64(block.number)); } /** @@ -446,13 +454,6 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { return key; } - function _updateOperatorEarnings(Operator memory operator) private returns (Snapshot memory) { - operator.earnings.index = _operatorCurrentIndex(operator); - operator.earnings.balance = _operatorCurrentEarnings(operator); - operator.earnings.block = uint64(block.number); - - return operator.earnings; - } function _updateDAOEarnings(DAO memory dao) private returns (DAO memory) { dao.earnings.balance = _networkTotalEarnings(dao); @@ -461,12 +462,6 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { return dao; } - // TODO - // no connection with owner address - function _operatorCurrentEarnings(Operator memory operator) private view returns (uint64) { - return operator.earnings.balance + (uint64(block.number) - operator.earnings.block) * operator.validatorCount * operator.fee; - } - function _extractOperators(uint64[] memory operatorIds) private view returns (Operator[] memory) { Operator[] memory operators = new Operator[](operatorIds.length); for (uint64 i = 0; i < operatorIds.length; ++i) { @@ -485,14 +480,13 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { function _clusterCurrentIndex(bytes32 podId) private view returns (uint64 podIndex) { Cluster memory cluster = _clusters[podId]; + uint64 currentBlock = uint64(block.number); for (uint64 i = 0; i < cluster.operatorIds.length; ++i) { - podIndex += _operatorCurrentIndex(_operators[cluster.operatorIds[i]]); + Snapshot memory s = _operators[cluster.operatorIds[i]].snapshot; + podIndex += s.index + (currentBlock - s.block) * _operators[cluster.operatorIds[i]].fee; } } - function _operatorCurrentIndex(Operator memory operator) private view returns (uint64) { - return operator.earnings.index + (uint64(block.number) - operator.earnings.block) * operator.fee; - } function _ownerPodBalance(Pod memory pod, uint64 currentPodIndex) private view returns (uint64) { return pod.balance - (currentPodIndex - pod.usage.index) * pod.validatorCount; diff --git a/test/vadimToUpdate.js b/test/vadimToUpdate.js index 564afee7..8eec612a 100644 --- a/test/vadimToUpdate.js +++ b/test/vadimToUpdate.js @@ -21,7 +21,7 @@ async function log({ action='', operatorIds = [], groupIds = [] }) { for (const id of operatorIds) { console.log( `> operator #${id}`, - 'balance', await deployedSSVNetworkContract.operatorEarningsOf(id), + 'balance', (await deployedSSVNetworkContract.operatorSnapshot(id)).balance, ); } } From 067e558e7ac2e5a467af27836d0ee9cf1a0184db Mon Sep 17 00:00:00 2001 From: Lior Rutenberg Date: Thu, 1 Sep 2022 14:42:58 +0300 Subject: [PATCH 050/149] operatorSnapshot to interface --- contracts/ISSVNetwork.sol | 10 ++++++++++ contracts/SSVNetwork.sol | 10 +++++++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/contracts/ISSVNetwork.sol b/contracts/ISSVNetwork.sol index 078795cd..bb1060d9 100644 --- a/contracts/ISSVNetwork.sol +++ b/contracts/ISSVNetwork.sol @@ -124,6 +124,16 @@ interface ISSVNetwork { */ function updateOperatorFee(uint64 id, uint64 fee) external; + /** + * @dev Gets the operators current snapshot. + * @param id Operator's id. + * @return currentBlock the block that the snapshot is updated to + * @return index the index of the operator + * @return balance the current balance of the operator + */ + function operatorSnapshot(uint64 id) external view returns (uint64 currentBlock, uint64 index, uint64 balance); + + /** * @dev Registers a new validator. * @param publicKey Validator public key. diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index c13d1cc1..574bbe3f 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -301,6 +301,12 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { // TODO add external functions below to interface + // @dev external operators functions + + function operatorSnapshot(uint64 id) external view returns (uint64 currentBlock, uint64 index, uint64 balance) { + Snapshot memory s = _getSnapshot(_operators[id], uint64(block.number)); + return (s.block, s.index, s.balance); + } // @dev internal operators functions @@ -405,9 +411,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { return _ownerPodBalance(pod, _clusterCurrentIndex(clusterId)); } - function operatorSnapshot(uint64 operatorId) external view returns (Snapshot memory) { - return _getSnapshot(_operators[operatorId], uint64(block.number)); - } + /** * @dev Validates the params for a validator. From f04e4fc934378d24b047c813f4576ebdd2b925b8 Mon Sep 17 00:00:00 2001 From: Lior Rutenberg Date: Thu, 1 Sep 2022 15:22:21 +0300 Subject: [PATCH 051/149] wip errors --- contracts/ISSVNetwork.sol | 12 +++++++++--- contracts/SSVNetwork.sol | 8 ++++---- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/contracts/ISSVNetwork.sol b/contracts/ISSVNetwork.sol index bb1060d9..dfc09794 100644 --- a/contracts/ISSVNetwork.sol +++ b/contracts/ISSVNetwork.sol @@ -76,6 +76,12 @@ interface ISSVNetwork { /** errors */ + error FeeTooLow(); + error CallerNotOwner(); + + + + error InvalidPublicKeyLength(); error OessDataStructureInvalid(); error ValidatorNotOwned(); @@ -127,9 +133,9 @@ interface ISSVNetwork { /** * @dev Gets the operators current snapshot. * @param id Operator's id. - * @return currentBlock the block that the snapshot is updated to - * @return index the index of the operator - * @return balance the current balance of the operator + * @return currentBlock the block that the snapshot is updated to. + * @return index the index of the operator. + * @return balance the current balance of the operator. */ function operatorSnapshot(uint64 id) external view returns (uint64 currentBlock, uint64 index, uint64 balance); diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index 574bbe3f..141ee189 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -81,8 +81,8 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { function registerOperator( bytes calldata encryptionPK, uint64 fee - ) external returns (uint64 operatorId) { - require(fee > 0); + ) external returns (uint64 id) { + if (fee <= 0) revert FeeTooLow(); lastOperatorId.increment(); operatorId = uint64(lastOperatorId.current()); @@ -92,7 +92,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { function removeOperator(uint64 operatorId) external { Operator memory operator = _operators[operatorId]; - require(operator.owner == msg.sender, "not owner"); + if (operator.owner != msg.sender) revert CallerNotOwner(); uint64 currentBlock = uint64(block.number); @@ -106,7 +106,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { function updateOperatorFee(uint64 operatorId, uint64 fee) external { Operator memory operator = _operators[operatorId]; - require(operator.owner == msg.sender, "not owner"); + if (operator.owner != msg.sender) revert CallerNotOwner(); _operators[operatorId] = _setFee(operator, fee); From af0317ea2156cc55d7423b096abed3b15e349af6 Mon Sep 17 00:00:00 2001 From: Adam Zigdon Date: Thu, 1 Sep 2022 16:55:15 +0300 Subject: [PATCH 052/149] refactor helpers --- contracts/SSVNetwork.sol | 6 +- test/account/deposit.ts | 8 +- test/account/withdraw.ts | 8 +- test/dao/network-fee-change.ts | 8 +- test/dao/network-fee-withdraw.ts | 8 +- test/helpers/contract-helpers.ts | 121 +++++++++++++++------- test/helpers/gas-usage.ts | 23 ++--- test/liquidate/liquidate.ts | 8 +- test/liquidate/liquidation-threshold.ts | 8 +- test/operators/register.ts | 51 +--------- test/operators/remove.ts | 8 +- test/operators/update.ts | 8 +- test/sanity/balances.ts | 42 ++++---- test/validators/register.ts | 128 +++++++++--------------- 14 files changed, 193 insertions(+), 242 deletions(-) diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index 141ee189..11b1e597 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -85,9 +85,9 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { if (fee <= 0) revert FeeTooLow(); lastOperatorId.increment(); - operatorId = uint64(lastOperatorId.current()); - _operators[operatorId] = Operator({ owner: msg.sender, snapshot: Snapshot({ block: uint64(block.number), index: 0, balance: 0}), validatorCount: 0, fee: fee}); - emit OperatorAdded(operatorId, msg.sender, encryptionPK); + id = uint64(lastOperatorId.current()); + _operators[id] = Operator({ owner: msg.sender, snapshot: Snapshot({ block: uint64(block.number), index: 0, balance: 0}), validatorCount: 0, fee: fee}); + emit OperatorAdded(id, msg.sender, encryptionPK); } function removeOperator(uint64 operatorId) external { diff --git a/test/account/deposit.ts b/test/account/deposit.ts index 6554c4ef..c88c01dc 100644 --- a/test/account/deposit.ts +++ b/test/account/deposit.ts @@ -5,14 +5,12 @@ import { expect } from 'chai'; const numberOfOperators = 4; const operatorFee = 4; -let registryContract: any, operatorIDs: any, shares: any, owner: any; +let ssvNetworkContract: any, operatorIDs: any, shares: any, owner: any; describe('Deposit Tests', () => { beforeEach(async () => { - const contractData = await helpers.initializeContract(numberOfOperators, operatorFee); - registryContract = contractData.contract; - operatorIDs = contractData.operatorIDs; - shares = contractData.shares; + const contractData = await helpers.initializeContract(); + ssvNetworkContract = contractData.contract; }); it('Deposit', async () => { diff --git a/test/account/withdraw.ts b/test/account/withdraw.ts index f6dd9d87..afa962dd 100644 --- a/test/account/withdraw.ts +++ b/test/account/withdraw.ts @@ -5,14 +5,12 @@ import { expect } from 'chai'; const numberOfOperators = 4; const operatorFee = 4; -let registryContract: any, operatorIDs: any, shares: any, owner: any; +let ssvNetworkContract: any, operatorIDs: any, shares: any, owner: any; describe('Withdraw Tests', () => { beforeEach(async () => { - const contractData = await helpers.initializeContract(numberOfOperators, operatorFee); - registryContract = contractData.contract; - operatorIDs = contractData.operatorIDs; - shares = contractData.shares; + const contractData = await helpers.initializeContract(); + ssvNetworkContract = contractData.contract; }); it('Withdraw', async () => { diff --git a/test/dao/network-fee-change.ts b/test/dao/network-fee-change.ts index 85cdd03e..68e4b0b3 100644 --- a/test/dao/network-fee-change.ts +++ b/test/dao/network-fee-change.ts @@ -5,14 +5,12 @@ import { expect } from 'chai'; const numberOfOperators = 4; const operatorFee = 4; -let registryContract: any, operatorIDs: any, shares: any, owner: any; +let ssvNetworkContract: any, operatorIDs: any, shares: any, owner: any; describe('DAO Network Fee Change Tests', () => { beforeEach(async () => { - const contractData = await helpers.initializeContract(numberOfOperators, operatorFee); - registryContract = contractData.contract; - operatorIDs = contractData.operatorIDs; - shares = contractData.shares; + const contractData = await helpers.initializeContract(); + ssvNetworkContract = contractData.contract; }); it('Get network fee', async () => { diff --git a/test/dao/network-fee-withdraw.ts b/test/dao/network-fee-withdraw.ts index 8ea57fd0..63d09864 100644 --- a/test/dao/network-fee-withdraw.ts +++ b/test/dao/network-fee-withdraw.ts @@ -5,14 +5,12 @@ import { expect } from 'chai'; const numberOfOperators = 4; const operatorFee = 4; -let registryContract: any, operatorIDs: any, shares: any, owner: any; +let ssvNetworkContract: any, operatorIDs: any, shares: any, owner: any; describe('DAO Network Fee Withdraw Tests', () => { beforeEach(async () => { - const contractData = await helpers.initializeContract(numberOfOperators, operatorFee); - registryContract = contractData.contract; - operatorIDs = contractData.operatorIDs; - shares = contractData.shares; + const contractData = await helpers.initializeContract(); + ssvNetworkContract = contractData.contract; }); it('Get withdrawable network fee amount', async () => { diff --git a/test/helpers/contract-helpers.ts b/test/helpers/contract-helpers.ts index 2610e8f7..271ccf31 100644 --- a/test/helpers/contract-helpers.ts +++ b/test/helpers/contract-helpers.ts @@ -3,56 +3,103 @@ declare const ethers: any; import { trackGas, getGasStats, GasGroup } from './gas-usage'; -// Generate shares -const shares = Array.from(Array(10).keys()).map(k => `0xe0096008000000b4010000040000001000000076000000dc000000420d142c307831323334353637383930fe0a00520a000031017afe66008266000032fe66009266000033fe66009266000034016621ac28d60000009c01000062020025c02c307839383736353433323130fe0a00520a000031fe560052560019b0003101dafec60082c6000032fec6007ac6004d6ca666000033ceb401fe8c017e8c014dcca6c6004d7a0035b23200fec6007ec6000034${k}${k}`); +export let DB: any; -export const initializeContract = async (numberOfOperators: number, fee: number) => { +export const DataGenerator = { + publicKey: (index: number) => `0x${index.toString(16).padStart(96,'1')}`, + shares: (index: number) => `0x${index.toString(16).padStart(360,'1')}`, + pod: { + new: (size: number = 4) => { + const usedOperatorIds: any = {}; + for (const podId in DB.pods) { + for (const operatorId of DB.pods[podId].operatorIds) { + usedOperatorIds[operatorId] = true; + } + } + + const result = []; + for (const operator of DB.operators) { + if (operator && !usedOperatorIds[operator.id]) { + result.push(operator.id); + usedOperatorIds[operator.id] = true; + + if (result.length == size) { + break; + } + } + } + if (result.length < size) { + throw new Error("No new pods. Try to register more operators."); + } + + return result; + }, + byId: (id: any) => DB.pods[id].operatorIds + } +} + +export const initializeContract = async () => { + DB = { + owners: [], + validators: [], + operators: [], + pods: [], + ssvNetwork: {} + } // Define accounts - const [owner] = await ethers.getSigners(); + DB.owners = await ethers.getSigners(); // Initialize contract const ssvNetwork = await ethers.getContractFactory('SSVNetwork'); - const deployedRegistryContract = await ssvNetwork.deploy(); - await deployedRegistryContract.deployed(); + DB.ssvNetwork.contract = await ssvNetwork.deploy(); + await DB.ssvNetwork.contract.deployed(); + DB.ssvNetwork.owner = DB.owners[0]; - // Register Operators - for (let i = 0; i < numberOfOperators; i++) { - const encodedABI = '0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002644c5330744c5331435255644a54694253553045675546564354456c4449457446575330744c533074436b314a53554a4a616b464f516d64726357687261556335647a424351564646526b464254304e425554684254556c4a516b4e6e53304e42555556424e5756554e557777563068365a54647954575a506232787456484d4b64577449513245344b336474625577324f54464a5131527052454531556b4a31546b787153565132576b4530597a4d78635652495933464256486c3565566b774c7a6b3352336c4b5a32646f596e6c465232526f5a516f76616c6836615756544f584a325279744a56474631516a684d566c686b656b78475956517857455a5765466c6e4e327832546c42344f5552504c315a6f526b686b5757786e54334932643052745633466a52476f33436c68575557464f57454674526e67334e6a56514e546c584e585a7a564752585657464852577858536d3933536b5a4b646e6332556c5249536b5a315456686a537a5a5661574a3063555a4d536d4a774f57356b6455674b516a6c4c537a4e57636d59725a6d744a4f5752425a327478524446484f456c785130744b4d566c33626a557965477878625452434e69744f4f475a555a45314d53314a75635770465a6d527a563164774d46567a4d51704c54573976535863796333426f6158417a5546704e596e4a61615530774e6a4a325a556f3055336f76596a424f62576450546e685464304a4a546e4e7863473534516a68465556517853544e6a4e6b6c714e586868436d35525355524255554643436930744c5330745255354549464a545153425156554a4d53554d675330565a4c5330744c53304b00000000000000000000000000000000000000000000000000000000'; - await deployedRegistryContract.registerOperator(encodedABI, fee); - } + return { contract: DB.ssvNetwork.contract, owner: DB.ssvNetwork.owner }; +}; - // Generate Operator IDs - const operatorIDs = Array.from(Array(numberOfOperators).keys()).map(k => k + 1); +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.id] = { + id: event.args.id, ownerId: ownerId, publicKey: DataGenerator.publicKey(i) + } + } +} - // Deposit to the contract - const [addr1, addr2, addr3] = await ethers.getSigners(); - await deployedRegistryContract.connect(addr1).deposit('9000000000000000000'); - await deployedRegistryContract.connect(addr2).deposit('9000000000000000000'); - await deployedRegistryContract.connect(addr3).deposit('9000000000000000000'); +export const deposit = async (ownerIds: number[], amounts: string[]) => { + for (let i = 0; i < ownerIds.length; ++i) { + await DB.ssvNetwork.contract.connect(DB.owners[ownerIds[i]]).deposit(amounts[i]); + } +} - return { contract: deployedRegistryContract, operatorIDs: operatorIDs, shares: shares, owner: owner }; -}; -export const registerValidators = async (numberOfValidators: number, amount: string, operatorAmount: number, contract: any) => { - const validatorData: any = []; - const validatorsToRegister = 1000 + numberOfValidators; +export const registerValidators = async (ownerId: number, numberOfValidators: number, amount: string, pod: number[], gasGroups: GasGroup[] = [ GasGroup.REGISTER_VALIDATOR ]) => { + const validators: any = []; + let podId: any; // Register validators to contract - for (let i = 1000; i < validatorsToRegister; i++) { - const randomOperator = Math.floor(Math.random() * (operatorAmount - 4)); - const validatorPK = `0xa7ae1ea93b860ca0269ccca776b4526977395aa194e5820a00dedbf1cd63e7a898eec9a12f539f733ea4df9c651f${i}`; - - const receipt = await trackGas(contract.registerValidator( - validatorPK, - [randomOperator, randomOperator + 1, randomOperator + 2, randomOperator + 3], - shares[0], + for (let i = 0; i < numberOfValidators; i++) { + const publicKey = DataGenerator.publicKey(DB.validators.length); + const shares = DataGenerator.shares(DB.validators.length); + + const { eventsByName } = await trackGas(DB.ssvNetwork.contract.connect(DB.owners[ownerId]).registerValidator( + publicKey, + pod, + shares, amount, - ), [ GasGroup.registerValidator ]); + ), gasGroups); - // Save the validator emit - validatorData.push({ publicKey: validatorPK, groupId: receipt.eventsByName.ValidatorAdded[0].args.podId }); + const event = eventsByName.ValidatorAdded[0]; + podId = event.podId; + DB.pods[podId] = ({ id: event.podId, operatorIds: pod }); + DB.validators.push({ publicKey, podId: event.podId, shares }); + validators.push({ publicKey, shares }); } - return validatorData; - -}; + return { validators, podId }; +}; \ No newline at end of file diff --git a/test/helpers/gas-usage.ts b/test/helpers/gas-usage.ts index cc897b76..f80dfae4 100644 --- a/test/helpers/gas-usage.ts +++ b/test/helpers/gas-usage.ts @@ -1,16 +1,13 @@ export enum GasGroup { - registerValidator, - registerValidatorExistingGroup + REGISTER_OPERATOR, + REGISTER_VALIDATOR, + REGISTER_VALIDATOR_NEW_STATE } -// const MAX_GAS_PER_GROUP = { -// registerValidator: 400000, -// registerValidatorExistingGroup: 250000 -// } - -const MAX_GAS_PER_GROUP = { - [GasGroup.registerValidator]: 400000, - [GasGroup.registerValidatorExistingGroup]: 250000 +const MAX_GAS_PER_GROUP: any = { + [GasGroup.REGISTER_OPERATOR]: 100000, + [GasGroup.REGISTER_VALIDATOR]: 250000, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE]: 400000 } class GasStats { @@ -42,12 +39,12 @@ for (const group in MAX_GAS_PER_GROUP) { export const trackGas = async (tx: Promise, groups?: Array): Promise => { const receipt = await (await tx).wait(); - groups && groups.forEach(group => { + groups && [...new Set(groups)].forEach(group => { const gasUsed = parseInt(receipt.gasUsed); - const maxGas = MAX_GAS_PER_GROUP[group as keyof typeof MAX_GAS_PER_GROUP]; + const maxGas = MAX_GAS_PER_GROUP[group]; if (gasUsed > maxGas) { - throw new Error(`Gas usage too high. Max: ${maxGas}, Actual: ${gasUsed}`); + throw new Error(`Gas usage too high. Violated group: ${GasGroup[group]}. Max usage: ${maxGas}, Actual usage: ${gasUsed}.`); } gasUsageStats.get(group.toString()).addStat(gasUsed); diff --git a/test/liquidate/liquidate.ts b/test/liquidate/liquidate.ts index 13ed585f..4d49f333 100644 --- a/test/liquidate/liquidate.ts +++ b/test/liquidate/liquidate.ts @@ -5,14 +5,12 @@ import { expect } from 'chai'; const numberOfOperators = 4; const operatorFee = 4; -let registryContract: any, operatorIDs: any, shares: any, owner: any; +let ssvNetworkContract: any, operatorIDs: any, shares: any, owner: any; describe('Liquidate Tests', () => { beforeEach(async () => { - const contractData = await helpers.initializeContract(numberOfOperators, operatorFee); - registryContract = contractData.contract; - operatorIDs = contractData.operatorIDs; - shares = contractData.shares; + const contractData = await helpers.initializeContract(); + ssvNetworkContract = contractData.contract; }); it('Liquidatable', async () => { diff --git a/test/liquidate/liquidation-threshold.ts b/test/liquidate/liquidation-threshold.ts index e4098801..78c65536 100644 --- a/test/liquidate/liquidation-threshold.ts +++ b/test/liquidate/liquidation-threshold.ts @@ -5,15 +5,13 @@ import { expect } from 'chai'; const numberOfOperators = 4; const operatorFee = 4; -let registryContract: any, operatorIDs: any, shares: any, owner: any; +let ssvNetworkContract: any, operatorIDs: any, shares: any, owner: any; describe('Liquidation Threshold Tests', () => { beforeEach(async () => { - const contractData = await helpers.initializeContract(numberOfOperators, operatorFee); - registryContract = contractData.contract; - operatorIDs = contractData.operatorIDs; - shares = contractData.shares; + const contractData = await helpers.initializeContract(); + ssvNetworkContract = contractData.contract; }); it('Get liquidation threshold', async () => { diff --git a/test/operators/register.ts b/test/operators/register.ts index 42506a38..86cabf3d 100644 --- a/test/operators/register.ts +++ b/test/operators/register.ts @@ -6,14 +6,12 @@ import { trackGas, GasGroup } from '../helpers/gas-usage'; const numberOfOperators = 4; const operatorFee = 4; -let registryContract: any, operatorIDs: any, shares: any, owner: any; +let ssvNetworkContract: any, operatorIDs: any, shares: any, owner: any; describe('Register Operator Tests', () => { beforeEach(async () => { - const contractData = await helpers.initializeContract(numberOfOperators, operatorFee); - registryContract = contractData.contract; - operatorIDs = contractData.operatorIDs; - shares = contractData.shares; + const contractData = await helpers.initializeContract(); + ssvNetworkContract = contractData.contract; }); it('Register operator', async () => { @@ -25,50 +23,7 @@ describe('Register Operator Tests', () => { }); it('Register operator gas limits', async () => { - const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; - // Cost: 364101 - await trackGas(registryContract.registerValidator( - `${validatorPK}0`, - [1, 2, 3, 4], - shares[0], - '10000' - ), [ GasGroup.registerValidator ]); - - // // Cost: 185380 - // await deployedRegistryContract.registerValidator( - // [1, 2, 3, 4], - // `${validatorPK}1`, - // sharePKs.slice(0, 4), - // encryptedShares.slice(0, 4), - // "10000" - // ) - - // Cost: 295713 - await registryContract.registerValidator( - `${validatorPK}1`, - [1, 2, 5, 6], - shares[1], - '10000' - ); - - // // Cost: 312813 - // await deployedRegistryContract.registerValidator( - // [1, 5, 6, 7], - // `${validatorPK}2`, - // sharePKs.slice(0, 4), - // encryptedShares.slice(0, 4), - // "10000" - // ) - - // // Cost: 329901 - // await deployedRegistryContract.registerValidator( - // [5, 6, 7, 8], - // `${validatorPK}0`, - // sharePKs.slice(0, 4), - // encryptedShares.slice(0, 4), - // "10000" - // ) }); }); diff --git a/test/operators/remove.ts b/test/operators/remove.ts index 60a561fd..3ae1fb9b 100644 --- a/test/operators/remove.ts +++ b/test/operators/remove.ts @@ -5,14 +5,12 @@ import { expect } from 'chai'; const numberOfOperators = 4; const operatorFee = 4; -let registryContract: any, operatorIDs: any, shares: any, owner: any; +let ssvNetworkContract: any, operatorIDs: any, shares: any, owner: any; describe('Remove Operator Tests', () => { beforeEach(async () => { - const contractData = await helpers.initializeContract(numberOfOperators, operatorFee); - registryContract = contractData.contract; - operatorIDs = contractData.operatorIDs; - shares = contractData.shares; + const contractData = await helpers.initializeContract(); + ssvNetworkContract = contractData.contract; }); it('Remove operator', async () => { diff --git a/test/operators/update.ts b/test/operators/update.ts index d0c82444..29bc186c 100644 --- a/test/operators/update.ts +++ b/test/operators/update.ts @@ -5,14 +5,12 @@ import { expect } from 'chai'; const numberOfOperators = 4; const operatorFee = 4; -let registryContract: any, operatorIDs: any, shares: any, owner: any; +let ssvNetworkContract: any, operatorIDs: any, shares: any, owner: any; describe('Update Operator Tests', () => { beforeEach(async () => { - const contractData = await helpers.initializeContract(numberOfOperators, operatorFee); - registryContract = contractData.contract; - operatorIDs = contractData.operatorIDs; - shares = contractData.shares; + const contractData = await helpers.initializeContract(); + ssvNetworkContract = contractData.contract; }); it('Update operator', async () => { diff --git a/test/sanity/balances.ts b/test/sanity/balances.ts index 2ae1fb91..e831c8ff 100644 --- a/test/sanity/balances.ts +++ b/test/sanity/balances.ts @@ -2,6 +2,7 @@ declare const ethers: any; import * as helpers from '../helpers/contract-helpers'; import * as utils from '../helpers/utils'; +import { trackGas, GasGroup } from '../helpers/gas-usage'; import { expect } from 'chai'; @@ -20,27 +21,26 @@ describe('Balance Tests', () => { }); it('Check balances', async () => { - // // Register 1000 validators - // const validatorPK = `0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100` - - // expect(await registryContract.operatorEarningsOf(1)).to.equal('0') - - // // Register a validator - // const validator1 = (await (await registryContract.registerValidator( - // [1, 2, 3, 4], - // `${validatorPK}0`, - // shares[0], - // "10000" - // )).wait()).logs[0] - // let interfaceRegister = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId, bytes shares)']); - // const outputRegister = interfaceRegister.decodeEventLog('ValidatorAdded', validator1.data, validator1.topics); - - // // Progress 50 blocks and check operator balances and group balance - // await utils.progressBlocks(50) - // expect(await registryContract.operatorEarningsOf(1)).to.equal('50') - // expect(await registryContract.operatorEarningsOf(2)).to.equal('50') - // expect(await registryContract.operatorEarningsOf(3)).to.equal('50') - // expect(await registryContract.operatorEarningsOf(4)).to.equal('50') + const validatorPK = `0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100` + + expect(await registryContract.operatorEarningsOf(1)).to.equal('0'); + + // Register a validator + const validator1 = await trackGas(registryContract.registerValidator( + `${validatorPK}0`, + [1, 2, 3, 4], + shares[0], + "10000" + ), [ GasGroup.registerValidator ]); + + const outputRegister = validator1.eventsByName.ValidatorAdded[0]; + + // Progress 50 blocks and check operator balances and group balance + await utils.progressBlocks(50) + expect(await registryContract.operatorEarningsOf(1)).to.equal('50') + expect(await registryContract.operatorEarningsOf(2)).to.equal('50') + expect(await registryContract.operatorEarningsOf(3)).to.equal('50') + expect(await registryContract.operatorEarningsOf(4)).to.equal('50') // expect(await registryContract.groupBalanceOf(owner.address, outputRegister.groupId)).to.equal(10000 - 150) // // Update one of the operator fees diff --git a/test/validators/register.ts b/test/validators/register.ts index f60425a7..e7223575 100644 --- a/test/validators/register.ts +++ b/test/validators/register.ts @@ -3,7 +3,7 @@ declare const ethers: any; import * as helpers from '../helpers/contract-helpers'; import { expect } from 'chai'; -import { trackGas } from '../helpers/gas-usage'; +import { trackGas, GasGroup } from '../helpers/gas-usage'; const numberOfOperators = 8; const operatorFee = 4; @@ -12,98 +12,66 @@ let registryContract: any, operatorIDs: any, shares: any, addr1: any, addr2: any describe('Register Validator Tests', () => { beforeEach(async () => { - [addr1, addr2] = await ethers.getSigners(); - - const contractData = await helpers.initializeContract(numberOfOperators, operatorFee); + const contractData = await helpers.initializeContract(); registryContract = contractData.contract; - operatorIDs = contractData.operatorIDs; - shares = contractData.shares; + await helpers.registerOperators(0, 1, '10'); + await helpers.registerOperators(1, 1, '10'); + await helpers.registerOperators(2, 1, '10'); + await helpers.registerOperators(3, 1, '10'); + + await helpers.deposit([4], ['100000']); + await helpers.deposit([5], ['100000']); }); it('Register validator in empty pod', async () => { - const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; - const { gasUsed } = await trackGas(registryContract.registerValidator( - `${validatorPK}0`, - operatorIDs.slice(0, 4), - shares[0], - '10000' - )); - expect(gasUsed).lessThan(400000); + await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); }); it('Register two validators same owner in same pod', async () => { - const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; - const firstValidator = await trackGas(registryContract.registerValidator( - `${validatorPK}0`, - operatorIDs.slice(0, 4), - shares[0], - '10000' - )); - expect(firstValidator.gasUsed).lessThan(400000); - - const secondValidator = await trackGas(registryContract.registerValidator( - `${validatorPK}1`, - operatorIDs.slice(0, 4), - shares[0], - '10000' - )); - expect(secondValidator.gasUsed).lessThan(220000); - + const result = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.byId(result.podId)); }); it('Register two validators with different owners with same cluster', async () => { - const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; - const firstValidator = await trackGas(registryContract.connect(addr1).registerValidator( - `${validatorPK}0`, - operatorIDs.slice(0, 4), - shares[0], - '10000' - )); - expect(firstValidator.gasUsed).lessThan(400000); - const secondValidator = await trackGas(registryContract.connect(addr2).registerValidator( - `${validatorPK}1`, - operatorIDs.slice(0, 4), - shares[0], - '10000' - )); - expect(secondValidator.gasUsed).lessThan(250000); + const result = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + await helpers.registerValidators(5, 1, '10000', helpers.DataGenerator.pod.byId(result.podId)); }); - it('Register two validators same owner in different clusters', async () => { - const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; - const firstValidator = await trackGas(registryContract.registerValidator( - `${validatorPK}0`, - operatorIDs.slice(0, 4), - shares[0], - '10000' - )); - expect(firstValidator.gasUsed).lessThan(400000); + // it('Register two validators same owner in different clusters', async () => { + // const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; + // const firstValidator = await trackGas(registryContract.registerValidator( + // `${validatorPK}0`, + // operatorIDs.slice(0, 4), + // shares[0], + // '10000' + // )); + // expect(firstValidator.gasUsed).lessThan(400000); - const secondValidator = await trackGas(registryContract.registerValidator( - `${validatorPK}1`, - operatorIDs.slice(4, 8), - shares[0], - '10000' - )); - expect(secondValidator.gasUsed).lessThan(400000); - }); + // const secondValidator = await trackGas(registryContract.registerValidator( + // `${validatorPK}1`, + // operatorIDs.slice(4, 8), + // shares[0], + // '10000' + // )); + // expect(secondValidator.gasUsed).lessThan(400000); + // }); - it('Register two validators different owners in different clusters', async () => { - const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; - const firstValidator = await trackGas(registryContract.connect(addr1).registerValidator( - `${validatorPK}0`, - operatorIDs.slice(0, 4), - shares[0], - '10000' - )); - expect(firstValidator.gasUsed).lessThan(400000); + // it('Register two validators different owners in different clusters', async () => { + // const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; + // const firstValidator = await trackGas(registryContract.connect(addr1).registerValidator( + // `${validatorPK}0`, + // operatorIDs.slice(0, 4), + // shares[0], + // '10000' + // )); + // expect(firstValidator.gasUsed).lessThan(400000); - const secondValidator = await trackGas(registryContract.connect(addr2).registerValidator( - `${validatorPK}1`, - operatorIDs.slice(4, 8), - shares[0], - '10000' - )); - expect(secondValidator.gasUsed).lessThan(400000); - }); + // const secondValidator = await trackGas(registryContract.connect(addr2).registerValidator( + // `${validatorPK}1`, + // operatorIDs.slice(4, 8), + // shares[0], + // '10000' + // )); + // expect(secondValidator.gasUsed).lessThan(400000); + // }); }); From 0a81d8b74f8b14c6012c491510ddf11218bc4eef Mon Sep 17 00:00:00 2001 From: Adam Zigdon Date: Thu, 1 Sep 2022 17:59:08 +0300 Subject: [PATCH 053/149] comment out some files --- test/sanity/balances.ts | 60 ++++++++-------- test/sanity/stress.ts | 78 ++++++++++----------- test/validators/gas/1-operator-different.ts | 35 --------- test/validators/gas/2-operator-different.ts | 36 ---------- test/validators/gas/3-operator-different.ts | 36 ---------- test/validators/gas/4-operator-different.ts | 36 ---------- test/validators/gas/different-group.ts | 36 ---------- test/validators/gas/same-group.ts | 36 ---------- 8 files changed, 69 insertions(+), 284 deletions(-) delete mode 100644 test/validators/gas/1-operator-different.ts delete mode 100644 test/validators/gas/2-operator-different.ts delete mode 100644 test/validators/gas/3-operator-different.ts delete mode 100644 test/validators/gas/4-operator-different.ts delete mode 100644 test/validators/gas/different-group.ts delete mode 100644 test/validators/gas/same-group.ts diff --git a/test/sanity/balances.ts b/test/sanity/balances.ts index e831c8ff..26465f15 100644 --- a/test/sanity/balances.ts +++ b/test/sanity/balances.ts @@ -12,35 +12,35 @@ const operatorFee = 1; let registryContract: any, operatorIDs: any, shares: any, owner: any; describe('Balance Tests', () => { - beforeEach(async () => { - const contractData = await helpers.initializeContract(numberOfOperators, operatorFee); - registryContract = contractData.contract; - operatorIDs = contractData.operatorIDs; - shares = contractData.shares; - owner = contractData.owner; - }); - - it('Check balances', async () => { - const validatorPK = `0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100` - - expect(await registryContract.operatorEarningsOf(1)).to.equal('0'); - - // Register a validator - const validator1 = await trackGas(registryContract.registerValidator( - `${validatorPK}0`, - [1, 2, 3, 4], - shares[0], - "10000" - ), [ GasGroup.registerValidator ]); - - const outputRegister = validator1.eventsByName.ValidatorAdded[0]; - - // Progress 50 blocks and check operator balances and group balance - await utils.progressBlocks(50) - expect(await registryContract.operatorEarningsOf(1)).to.equal('50') - expect(await registryContract.operatorEarningsOf(2)).to.equal('50') - expect(await registryContract.operatorEarningsOf(3)).to.equal('50') - expect(await registryContract.operatorEarningsOf(4)).to.equal('50') + // beforeEach(async () => { + // const contractData = await helpers.initializeContract(numberOfOperators, operatorFee); + // registryContract = contractData.contract; + // operatorIDs = contractData.operatorIDs; + // shares = contractData.shares; + // owner = contractData.owner; + // }); + + // it('Check balances', async () => { + // const validatorPK = `0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100` + + // expect(await registryContract.operatorEarningsOf(1)).to.equal('0'); + + // // Register a validator + // const validator1 = await trackGas(registryContract.registerValidator( + // `${validatorPK}0`, + // [1, 2, 3, 4], + // shares[0], + // "10000" + // ), [ GasGroup.registerValidator ]); + + // const outputRegister = validator1.eventsByName.ValidatorAdded[0]; + + // // Progress 50 blocks and check operator balances and group balance + // await utils.progressBlocks(50) + // expect(await registryContract.operatorEarningsOf(1)).to.equal('50') + // expect(await registryContract.operatorEarningsOf(2)).to.equal('50') + // expect(await registryContract.operatorEarningsOf(3)).to.equal('50') + // expect(await registryContract.operatorEarningsOf(4)).to.equal('50') // expect(await registryContract.groupBalanceOf(owner.address, outputRegister.groupId)).to.equal(10000 - 150) // // Update one of the operator fees @@ -124,6 +124,6 @@ describe('Balance Tests', () => { // expect(await registryContract.operatorEarningsOf(4)).to.equal('2124') // expect(await registryContract.operatorEarningsOf(5)).to.equal('5000') // expect(await registryContract.groupBalanceOf(owner.address, outputRegister.groupId)).to.equal(10000 - 4500) - }); + // }); }); diff --git a/test/sanity/stress.ts b/test/sanity/stress.ts index 25881252..e11543cc 100644 --- a/test/sanity/stress.ts +++ b/test/sanity/stress.ts @@ -11,44 +11,44 @@ let registryContract: any, operatorIDs: any, shares: any; let validatorData: any = []; describe('Stress Tests', () => { - beforeEach(async () => { - const contractData = await helpers.initializeContract(numberOfOperators, operatorFee); - registryContract = contractData.contract; - operatorIDs = contractData.operatorIDs; - shares = contractData.shares; - - // Register 1000 validators - validatorData = await helpers.registerValidators(1000, '10000', numberOfOperators, registryContract); - }); - - it('Update 1000 operators', async () => { - for (let i = 0; i < operatorIDs.length; i++) { - await registryContract.updateOperatorFee(operatorIDs[i], 10); - } - }); - - it('Transfer 1000 validators', async () => { - for (let i = 1000; i < (validatorData.length + 1000); i++) { - const randomOperator = Math.floor(Math.random() * (numberOfOperators - 4)); - await registryContract.transferValidator( - validatorData[i-1000].publicKey, - [randomOperator, randomOperator + 1, randomOperator + 2, randomOperator + 3], - shares[1], - '10001' - ); - } - }); - - it('Remove 1000 operators', async () => { - for (let i = 0; i < operatorIDs.length; i++) { - await registryContract.removeOperator(operatorIDs[i]); - } - }); - - it('Remove 1000 validators', async () => { - for (let i = 0; i < validatorData.length; i++) { - await registryContract.removeValidator(validatorData[i].publicKey); - } - }); + // beforeEach(async () => { + // const contractData = await helpers.initializeContract(numberOfOperators, operatorFee); + // registryContract = contractData.contract; + // operatorIDs = contractData.operatorIDs; + // shares = contractData.shares; + + // // Register 1000 validators + // validatorData = await helpers.registerValidators(1000, '10000', numberOfOperators, registryContract); + // }); + + // it('Update 1000 operators', async () => { + // for (let i = 0; i < operatorIDs.length; i++) { + // await registryContract.updateOperatorFee(operatorIDs[i], 10); + // } + // }); + + // it('Transfer 1000 validators', async () => { + // for (let i = 1000; i < (validatorData.length + 1000); i++) { + // const randomOperator = Math.floor(Math.random() * (numberOfOperators - 4)); + // await registryContract.transferValidator( + // validatorData[i-1000].publicKey, + // [randomOperator, randomOperator + 1, randomOperator + 2, randomOperator + 3], + // shares[1], + // '10001' + // ); + // } + // }); + + // it('Remove 1000 operators', async () => { + // for (let i = 0; i < operatorIDs.length; i++) { + // await registryContract.removeOperator(operatorIDs[i]); + // } + // }); + + // it('Remove 1000 validators', async () => { + // for (let i = 0; i < validatorData.length; i++) { + // await registryContract.removeValidator(validatorData[i].publicKey); + // } + // }); }); diff --git a/test/validators/gas/1-operator-different.ts b/test/validators/gas/1-operator-different.ts deleted file mode 100644 index 62464030..00000000 --- a/test/validators/gas/1-operator-different.ts +++ /dev/null @@ -1,35 +0,0 @@ -import * as helpers from '../../helpers/contract-helpers'; - -import { expect } from 'chai'; - -const numberOfOperators = 4; -const operatorFee = 4; - -let registryContract: any, operatorIDs: any, shares: any, owner: any; - -describe('Register Validator Gas Tests 1 Operator Different', () => { - beforeEach(async () => { - const contractData = await helpers.initializeContract(numberOfOperators, operatorFee); - registryContract = contractData.contract; - operatorIDs = contractData.operatorIDs; - shares = contractData.shares; - }); - - it('1 Operator Different', async () => { - const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; - - await registryContract.registerValidator( - `${validatorPK}0`, - [1, 2, 3, 4], - shares[0], - '10000' - ); - - await registryContract.registerValidator( - `${validatorPK}1`, - [1, 2, 3, 5], - shares[1], - '10000' - ); - }); -}); diff --git a/test/validators/gas/2-operator-different.ts b/test/validators/gas/2-operator-different.ts deleted file mode 100644 index f5f9f6e4..00000000 --- a/test/validators/gas/2-operator-different.ts +++ /dev/null @@ -1,36 +0,0 @@ -import * as helpers from '../../helpers/contract-helpers'; - -import { expect } from 'chai'; - -const numberOfOperators = 4; -const operatorFee = 4; - -let registryContract: any, operatorIDs: any, shares: any, owner: any; - -describe('Register Validator Gas Tests 2 Operator Different', () => { - beforeEach(async () => { - const contractData = await helpers.initializeContract(numberOfOperators, operatorFee); - registryContract = contractData.contract; - operatorIDs = contractData.operatorIDs; - shares = contractData.shares; - }); - - it('2 Operator Different', async () => { - const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; - - await registryContract.registerValidator( - `${validatorPK}0`, - [1, 2, 3, 4], - shares[0], - '10000' - ); - - await registryContract.registerValidator( - `${validatorPK}1`, - [1, 2, 5, 6], - shares[1], - '10000' - ); - }); - -}); diff --git a/test/validators/gas/3-operator-different.ts b/test/validators/gas/3-operator-different.ts deleted file mode 100644 index 171ff5cd..00000000 --- a/test/validators/gas/3-operator-different.ts +++ /dev/null @@ -1,36 +0,0 @@ -import * as helpers from '../../helpers/contract-helpers'; - -import { expect } from 'chai'; - -const numberOfOperators = 4; -const operatorFee = 4; - -let registryContract: any, operatorIDs: any, shares: any, owner: any; - -describe('Register Validator Gas Tests 3 Operator Different', () => { - beforeEach(async () => { - const contractData = await helpers.initializeContract(numberOfOperators, operatorFee); - registryContract = contractData.contract; - operatorIDs = contractData.operatorIDs; - shares = contractData.shares; - }); - - it('3 Operator Different', async () => { - const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; - - await registryContract.registerValidator( - `${validatorPK}0`, - [1, 2, 3, 4], - shares[0], - '10000' - ); - - await registryContract.registerValidator( - `${validatorPK}1`, - [1, 5, 6, 7], - shares[1], - '10000' - ); - }); - -}); diff --git a/test/validators/gas/4-operator-different.ts b/test/validators/gas/4-operator-different.ts deleted file mode 100644 index 03d94db6..00000000 --- a/test/validators/gas/4-operator-different.ts +++ /dev/null @@ -1,36 +0,0 @@ -import * as helpers from '../../helpers/contract-helpers'; - -import { expect } from 'chai'; - -const numberOfOperators = 4; -const operatorFee = 4; - -let registryContract: any, operatorIDs: any, shares: any, owner: any; - -describe('Register Validator Gas Tests 3 Operator Different', () => { - beforeEach(async () => { - const contractData = await helpers.initializeContract(numberOfOperators, operatorFee); - registryContract = contractData.contract; - operatorIDs = contractData.operatorIDs; - shares = contractData.shares; - }); - - it('3 Operator Different', async () => { - const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; - - await registryContract.registerValidator( - `${validatorPK}0`, - [1, 2, 3, 4], - shares[0], - '10000' - ); - - await registryContract.registerValidator( - `${validatorPK}1`, - [5, 6, 7, 8], - shares[1], - '10000' - ); - }); - -}); diff --git a/test/validators/gas/different-group.ts b/test/validators/gas/different-group.ts deleted file mode 100644 index c7f2f346..00000000 --- a/test/validators/gas/different-group.ts +++ /dev/null @@ -1,36 +0,0 @@ -import * as helpers from '../../helpers/contract-helpers'; - -import { expect } from 'chai'; - -const numberOfOperators = 4; -const operatorFee = 4; - -let registryContract: any, operatorIDs: any, shares: any, owner: any; - -describe('Register Validator Gas Tests Different Group', () => { - beforeEach(async () => { - const contractData = await helpers.initializeContract(numberOfOperators, operatorFee); - registryContract = contractData.contract; - operatorIDs = contractData.operatorIDs; - shares = contractData.shares; - }); - - it('Different group', async () => { - const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; - - await registryContract.registerValidator( - `${validatorPK}0`, - [1, 2, 3, 4], - shares[0], - '10000' - ); - - await registryContract.registerValidator( - `${validatorPK}1`, - [5, 6, 7, 8], - shares[1], - '10000' - ); - }); - -}); diff --git a/test/validators/gas/same-group.ts b/test/validators/gas/same-group.ts deleted file mode 100644 index 2122accc..00000000 --- a/test/validators/gas/same-group.ts +++ /dev/null @@ -1,36 +0,0 @@ -import * as helpers from '../../helpers/contract-helpers'; - -import { expect } from 'chai'; - -const numberOfOperators = 4; -const operatorFee = 4; - -let registryContract: any, operatorIDs: any, shares: any, owner: any; - -describe('Register Validator Gas Tests Same Group', () => { - beforeEach(async () => { - const contractData = await helpers.initializeContract(numberOfOperators, operatorFee); - registryContract = contractData.contract; - operatorIDs = contractData.operatorIDs; - shares = contractData.shares; - }); - - it('Same group', async () => { - const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; - - await registryContract.registerValidator( - `${validatorPK}0`, - [1, 2, 3, 4], - shares[0], - '10000' - ); - - await registryContract.registerValidator( - `${validatorPK}1`, - [1, 2, 3, 4], - shares[1], - '10000' - ); - }); - -}); From 2619cb0634fd611290b8d0022dea8059fba19edf Mon Sep 17 00:00:00 2001 From: Adam Zigdon Date: Thu, 1 Sep 2022 18:22:25 +0300 Subject: [PATCH 054/149] change to chai --- test/helpers/gas-usage.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/helpers/gas-usage.ts b/test/helpers/gas-usage.ts index f80dfae4..299489f1 100644 --- a/test/helpers/gas-usage.ts +++ b/test/helpers/gas-usage.ts @@ -1,3 +1,5 @@ +import { expect } from 'chai'; + export enum GasGroup { REGISTER_OPERATOR, REGISTER_VALIDATOR, @@ -43,9 +45,7 @@ export const trackGas = async (tx: Promise, groups?: Array): Prom const gasUsed = parseInt(receipt.gasUsed); const maxGas = MAX_GAS_PER_GROUP[group]; - if (gasUsed > maxGas) { - throw new Error(`Gas usage too high. Violated group: ${GasGroup[group]}. Max usage: ${maxGas}, Actual usage: ${gasUsed}.`); - } + expect(gasUsed).to.be.lessThanOrEqual(maxGas); gasUsageStats.get(group.toString()).addStat(gasUsed); }); From a04ad3e895669e08083ed3cb42475fe12a01fc15 Mon Sep 17 00:00:00 2001 From: Vadim Date: Sun, 4 Sep 2022 09:03:11 +0200 Subject: [PATCH 055/149] finilise validator tests with changed infrastructure --- test/helpers/contract-helpers.ts | 13 +- test/helpers/gas-usage.ts | 18 +- test/vadimToUpdate.js.old | 302 +++++++++++++++++++++++++++++++ test/validators/register.ts | 56 +----- test/validators/remove.ts | 43 ++--- test/validators/transfer.ts | 98 +++++----- 6 files changed, 389 insertions(+), 141 deletions(-) create mode 100644 test/vadimToUpdate.js.old diff --git a/test/helpers/contract-helpers.ts b/test/helpers/contract-helpers.ts index 271ccf31..507a4e40 100644 --- a/test/helpers/contract-helpers.ts +++ b/test/helpers/contract-helpers.ts @@ -78,7 +78,7 @@ export const deposit = async (ownerIds: number[], amounts: string[]) => { } -export const registerValidators = async (ownerId: number, numberOfValidators: number, amount: string, pod: number[], gasGroups: GasGroup[] = [ GasGroup.REGISTER_VALIDATOR ]) => { +export const registerValidators = async (ownerId: number, numberOfValidators: number, amount: string, operatorIds: number[], gasGroups?: GasGroup[]) => { const validators: any = []; let podId: any; @@ -89,17 +89,16 @@ export const registerValidators = async (ownerId: number, numberOfValidators: nu const { eventsByName } = await trackGas(DB.ssvNetwork.contract.connect(DB.owners[ownerId]).registerValidator( publicKey, - pod, + operatorIds, shares, amount, ), gasGroups); - const event = eventsByName.ValidatorAdded[0]; - podId = event.podId; - DB.pods[podId] = ({ id: event.podId, operatorIds: pod }); - DB.validators.push({ publicKey, podId: event.podId, shares }); + podId = eventsByName.ValidatorAdded[0].args.podId; + DB.pods[podId] = ({ id: podId, operatorIds }); + DB.validators.push({ publicKey, podId, shares }); validators.push({ publicKey, shares }); } return { validators, podId }; -}; \ No newline at end of file +}; diff --git a/test/helpers/gas-usage.ts b/test/helpers/gas-usage.ts index 299489f1..24b4e58e 100644 --- a/test/helpers/gas-usage.ts +++ b/test/helpers/gas-usage.ts @@ -2,14 +2,24 @@ import { expect } from 'chai'; export enum GasGroup { REGISTER_OPERATOR, - REGISTER_VALIDATOR, - REGISTER_VALIDATOR_NEW_STATE + REGISTER_VALIDATOR_EXISTED_POD, + REGISTER_VALIDATOR_EXISTED_CLUSTER, + REGISTER_VALIDATOR_NEW_STATE, + REMOVE_VALIDATOR, + TRANSFER_VALIDATOR_NEW_POD, + TRANSFER_VALIDATOR_EXISTED_POD, + TRANSFER_VALIDATOR_EXISTED_CLUSTER, } const MAX_GAS_PER_GROUP: any = { [GasGroup.REGISTER_OPERATOR]: 100000, - [GasGroup.REGISTER_VALIDATOR]: 250000, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE]: 400000 + [GasGroup.REGISTER_VALIDATOR_EXISTED_POD]: 220000, + [GasGroup.REGISTER_VALIDATOR_EXISTED_CLUSTER]: 250000, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE]: 400000, + [GasGroup.REMOVE_VALIDATOR]: 120000, + [GasGroup.TRANSFER_VALIDATOR_NEW_POD]: 400000, + [GasGroup.TRANSFER_VALIDATOR_EXISTED_POD]: 260000, + [GasGroup.TRANSFER_VALIDATOR_EXISTED_CLUSTER]: 290000, } class GasStats { diff --git a/test/vadimToUpdate.js.old b/test/vadimToUpdate.js.old new file mode 100644 index 00000000..564afee7 --- /dev/null +++ b/test/vadimToUpdate.js.old @@ -0,0 +1,302 @@ +const { expect } = require("chai"); +const { progressBlocks, blockNumber } = require('./helpers/utils'); +const operator_fee_block = 1; + + +async function mineNBlocks(n) { + for (let index = 0; index < n; index++) { + await ethers.provider.send('evm_mine'); + } +} + +const operatorsIndexes = Array.from(Array(5).keys()).map(k => k + 1); +let deployedSSVNetworkContract; + +async function log({ action='', operatorIds = [], groupIds = [] }) { + console.log(`[BLOCK] ${await blockNumber()}`) + if (action) { + console.log(`> ${action}`); + } + if (operatorIds.length) { + for (const id of operatorIds) { + console.log( + `> operator #${id}`, + 'balance', await deployedSSVNetworkContract.operatorEarningsOf(id), + ); + } + } + if (groupIds.length) { + const [owner] = await ethers.getSigners(); + for (const id of groupIds) { + console.log( + `> group #$${id}`, + 'balance', await deployedSSVNetworkContract.podBalanceOf(owner.address, id), + ); + } + } +} + +describe("Validators", () => { + beforeEach(async () => { + const SSVNetwork = await ethers.getContractFactory("SSVNetwork"); + deployedSSVNetworkContract = await SSVNetwork.deploy(); + await deployedSSVNetworkContract.deployed(); + + await progressBlocks(99); + for (let i = 0; i < 8; i++) { // operatorsIndexes.length + var encryptionPK = "0x123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123451"; + await (await deployedSSVNetworkContract.registerOperator(encryptionPK, operator_fee_block)).wait(); + await log({ action: `register operator #${i+1}` }); + } + // await deployedSSVNetworkContract.addOperatorToValidator([], operatorsIndexes, []); + }) + + it("should register validator", async () => { + const validatorPK = "0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765"; + const sharePKs = Array.from(Array(10).keys()).map(k => `0xe0096008000000b4010000040000001000000076000000dc000000420d142c307831323334353637383930fe0a00520a000031017afe66008266000032fe66009266000033fe66009266000034016621ac28d60000009c01000062020025c02c307839383736353433323130fe0a00520a000031fe560052560019b0003101dafec60082c6000032fec6007ac6004d6ca666000033ceb401fe8c017e8c014dcca6c6004d7a0035b23200fec6007ec6000034${k}${k}`); + const encryptedShares = Array.from(Array(10).keys()).map(k => `0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765${k}98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765${k}`); + // const operatorsIndexes = Array.from(Array(10).keys()).map(k => k + 1); + + // await deployedSSVNetworkContract.createGroup([1,2,3,4]); + // await deployedSSVNetworkContract.createGroup([1,2,3,4]); + + await deployedSSVNetworkContract.deposit("100000000000"); + await log({ + action: 'deposit', + operatorIds: [1, 2, 3, 4] + }); + // validator 1 + await progressBlocks(97); + let resultRegister = (await (await deployedSSVNetworkContract.registerValidator( + validatorPK + "f", + [1,2,3,4], + sharePKs[0], + '10000' + )).wait()).logs[0]; + + let interfaceRegister = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId, bytes shares)']); + let outputRegister = interfaceRegister.decodeEventLog('ValidatorAdded', resultRegister.data, resultRegister.topics); + await log({ + action: `register validator #1: ${outputRegister.validatorPK} : ${outputRegister.groupId}`, + operatorIds: [1, 2, 3, 4] + }); + await progressBlocks(1); + await log({ + operatorIds: [1, 2, 3, 4], + groupIds: [outputRegister.groupId] + }); + + let resultUpdate = (await (await deployedSSVNetworkContract.transferValidator( + validatorPK + "f", + [4,5,6,7], + sharePKs[2], + '10000' + )).wait()).logs[0]; + + let interfaceUpdate = new ethers.utils.Interface(['event ValidatorTransferred(bytes validatorPK, bytes32 groupId, bytes shares)']); + let outputUpdate = interfaceUpdate.decodeEventLog('ValidatorTransferred', resultUpdate.data, resultUpdate.topics); + expect(outputRegister.groupId).not.equal(outputUpdate.groupId); + expect(outputRegister.validatorPK).to.equal(outputUpdate.validatorPK); + + await log({ + action: `update validator #1: ${outputUpdate.validatorPK} : ${outputUpdate.groupId}`, + operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], + groupIds: [outputRegister.groupId, outputUpdate.groupId] + }); + await progressBlocks(1); + await log({ + operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], + groupIds: [outputRegister.groupId, outputUpdate.groupId] + }); + await progressBlocks(1); + await log({ + operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], + groupIds: [outputRegister.groupId, outputUpdate.groupId] + }); + + // move back validator 1 to group 1 + resultRegister = (await (await deployedSSVNetworkContract.transferValidator( + validatorPK + "f", + [1,2,3,4], + sharePKs[1], + '10000' + )).wait()).logs[0]; + interfaceRegister = new ethers.utils.Interface(['event ValidatorTransferred(bytes validatorPK, bytes32 groupId)']); // , bytes[] sharesPublicKeys, bytes[] encryptedShares + outputRegister = interfaceUpdate.decodeEventLog('ValidatorTransferred', resultRegister.data, resultRegister.topics); + await log({ + action: `update validator #1: ${outputRegister.validatorPK} : ${outputRegister.groupId}`, + operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], + groupIds: [outputRegister.groupId, outputUpdate.groupId] + }); + await progressBlocks(1); + await log({ + operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], + groupIds: [outputRegister.groupId, outputUpdate.groupId] + }); + + const resultRegister2 = (await (await deployedSSVNetworkContract.registerValidator( + validatorPK + "a", + [1,2,3,4], + sharePKs[1], + "1000" + )).wait()).logs[0]; + + const interfaceRegister2 = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId, bytes shares)']); + const outputRegister2 = interfaceRegister2.decodeEventLog('ValidatorAdded', resultRegister2.data, resultRegister2.topics); + await log({ + action: `register validator #2: ${outputRegister2.validatorPK} : ${outputRegister2.groupId}`, + operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], + groupIds: [outputRegister.groupId, outputRegister2.groupId] + }); + + + const resultRegister3 = (await (await deployedSSVNetworkContract.registerValidator( + validatorPK + "b", + [5,6,7,8], + sharePKs[1], + "1000000" + )).wait()).logs[0]; + + + const interfaceRegister3 = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId, bytes shares)']); + const outputRegister3 = interfaceRegister3.decodeEventLog('ValidatorAdded', resultRegister3.data, resultRegister3.topics); + await log({ + action: `register validator #3: ${resultRegister3.validatorPK} : ${resultRegister3.groupId}`, + operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], + groupIds: [outputRegister.groupId, outputRegister2.groupId] + }); + + + + await progressBlocks(1); + await log({ + operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], + groupIds: [outputRegister.groupId, outputRegister2.groupId] + }); + await progressBlocks(1); + await log({ + operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], + groupIds: [outputRegister.groupId, outputRegister2.groupId] + }); + await (await deployedSSVNetworkContract.updateOperatorFee( + 1, + 2 + )).wait(); + await log({ + action: 'operator #1 fee updated 2', + operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], + groupIds: [outputRegister.groupId, outputRegister2.groupId] + }); + await progressBlocks(1); + await log({ + operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], + groupIds: [outputRegister.groupId, outputRegister2.groupId] + }); + await progressBlocks(1); + await log({ + operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], + groupIds: [outputRegister.groupId, outputRegister2.groupId] + }); + + + await (await deployedSSVNetworkContract.removeValidator(outputRegister2.validatorPK)).wait(); + await log({ + action: 'remove validator #2', + operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], + groupIds: [outputRegister.groupId, outputRegister2.groupId] + }); + + await progressBlocks(1); + await log({ + operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], + groupIds: [outputRegister.groupId, outputRegister2.groupId] + }); + await progressBlocks(1); + await log({ + operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], + groupIds: [outputRegister.groupId, outputRegister2.groupId] + }); + await progressBlocks(1); + let results = [] + for (let i = 0; i < 20; ++i) { + let resultRegister = (await (await deployedSSVNetworkContract.registerValidator( + validatorPK + i % 10, + [1,2,3,4], + sharePKs[2], + '10000' + )).wait()).logs[0]; + + const interfaceRegister = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId, bytes shares)']); + const outputRegister = interfaceRegister.decodeEventLog('ValidatorAdded', resultRegister.data, resultRegister.topics); + + results.push(outputRegister); + } + console.log("outputRegister.groupId,outputRegister2.groupId") + console.log(outputRegister.groupId,outputRegister3.groupId) + + const transferLogs = (await (await deployedSSVNetworkContract.bulkTransferValidators( + results.map(r => r.validatorPK), + outputRegister.groupId, + outputRegister3.groupId, + results.map(r => sharePKs[4]) + + )).wait()).logs; + + // await log({ + // action: 'transfer', + // operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], + // groupIds: [outputRegister.groupId, resultRegister3.groupId] + // }); + + /* + // validator 2 + await expect(await deployedSSVNetworkContract.registerValidator( + [1,2,3,4], + validatorPK, + sharePKs.slice(0, 4), + encryptedShares.slice(0, 4), + "10000" + )) + .to.emit(deployedSSVNetworkContract, 'ValidatorAdded'); + // .withArgs(validatorPK); + + + const resultRegister = (await (await deployedSSVNetworkContract.registerValidator( + [1,2,3,4], + validatorPK, + sharePKs.slice(0, 4), + encryptedShares.slice(0, 4), + '10000' + )).wait()).logs[0]; + const interfaceRegister = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId)']); + const outputRegister = interfaceRegister.decodeEventLog('ValidatorAdded', resultRegister.data, resultRegister.topics); + expect(outputRegister.validatorPK).to.equal(validatorPK); + + console.log("register ---->", outputRegister.validatorPK, outputRegister.groupId); + console.log("operatorIdsAfterRegister ---->", await deployedSSVNetworkContract.test_getOperatorsByGroupId(outputRegister.groupId)); + + const resultUpdate = (await (await deployedSSVNetworkContract.updateValidator( + [2,3,4,5], + validatorPK, + outputRegister.groupId, + '10000' + )).wait()).logs[0];; + const interfaceUpdate = new ethers.utils.Interface(['event ValidatorUpdated(bytes validatorPK, bytes32 groupId)']); + const outputUpdate = interfaceUpdate.decodeEventLog('ValidatorUpdated', resultUpdate.data, resultUpdate.topics); + expect(outputRegister.groupId).not.equal(outputUpdate.groupId); + expect(outputRegister.validatorPK).to.equal(outputUpdate.validatorPK); + + console.log("update ---->", outputUpdate.validatorPK, outputUpdate.groupId); + console.log("operatorIdsAfterUpdate ---->", await deployedSSVNetworkContract.test_getOperatorsByGroupId(outputUpdate.groupId)); + + await expect(await deployedSSVNetworkContract.removeValidator( + validatorPK, + outputUpdate.groupId + )) + .to.emit(deployedSSVNetworkContract, 'ValidatorRemoved') + .withArgs(validatorPK, outputUpdate.groupId); + + */ + // await deployedSSVNetworkContract.liquidate("0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", "0x392791df626408017a264f53fde61065d5a93a32b60171df9d8a46afdf82992d"); + }); +}); diff --git a/test/validators/register.ts b/test/validators/register.ts index e7223575..32e5d09c 100644 --- a/test/validators/register.ts +++ b/test/validators/register.ts @@ -2,13 +2,13 @@ declare const ethers: any; import * as helpers from '../helpers/contract-helpers'; -import { expect } from 'chai'; -import { trackGas, GasGroup } from '../helpers/gas-usage'; +// import { expect } from 'chai'; +import { GasGroup } from '../helpers/gas-usage'; const numberOfOperators = 8; const operatorFee = 4; -let registryContract: any, operatorIDs: any, shares: any, addr1: any, addr2: any; +let registryContract: any; describe('Register Validator Tests', () => { beforeEach(async () => { @@ -27,51 +27,13 @@ describe('Register Validator Tests', () => { await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); }); - it('Register two validators same owner in same pod', async () => { - const result = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); - await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.byId(result.podId)); + it('Register two validators in existed pod', async () => { + const result = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); + await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.byId(result.podId), [GasGroup.REGISTER_VALIDATOR_EXISTED_POD]); }); - it('Register two validators with different owners with same cluster', async () => { - const result = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); - await helpers.registerValidators(5, 1, '10000', helpers.DataGenerator.pod.byId(result.podId)); + it('Register two validators in existed cluster', async () => { + const result = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); + await helpers.registerValidators(5, 1, '10000', helpers.DataGenerator.pod.byId(result.podId), [GasGroup.REGISTER_VALIDATOR_EXISTED_CLUSTER]); }); - - // it('Register two validators same owner in different clusters', async () => { - // const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; - // const firstValidator = await trackGas(registryContract.registerValidator( - // `${validatorPK}0`, - // operatorIDs.slice(0, 4), - // shares[0], - // '10000' - // )); - // expect(firstValidator.gasUsed).lessThan(400000); - - // const secondValidator = await trackGas(registryContract.registerValidator( - // `${validatorPK}1`, - // operatorIDs.slice(4, 8), - // shares[0], - // '10000' - // )); - // expect(secondValidator.gasUsed).lessThan(400000); - // }); - - // it('Register two validators different owners in different clusters', async () => { - // const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; - // const firstValidator = await trackGas(registryContract.connect(addr1).registerValidator( - // `${validatorPK}0`, - // operatorIDs.slice(0, 4), - // shares[0], - // '10000' - // )); - // expect(firstValidator.gasUsed).lessThan(400000); - - // const secondValidator = await trackGas(registryContract.connect(addr2).registerValidator( - // `${validatorPK}1`, - // operatorIDs.slice(4, 8), - // shares[0], - // '10000' - // )); - // expect(secondValidator.gasUsed).lessThan(400000); - // }); }); diff --git a/test/validators/remove.ts b/test/validators/remove.ts index bc224d82..d368a454 100644 --- a/test/validators/remove.ts +++ b/test/validators/remove.ts @@ -3,45 +3,30 @@ declare const ethers: any; import * as helpers from '../helpers/contract-helpers'; import { expect } from 'chai'; -import { trackGas } from '../helpers/gas-usage'; +import { trackGas, GasGroup } from '../helpers/gas-usage'; -const numberOfOperators = 4; -const operatorFee = 4; -let registryContract: any, operatorIDs: any, shares: any, addr1: any, addr2: any; +let registryContract: any; describe('Remove Validator Tests', () => { beforeEach(async () => { - [addr1, addr2] = await ethers.getSigners(); - - const contractData = await helpers.initializeContract(numberOfOperators, operatorFee); + const contractData = await helpers.initializeContract(); registryContract = contractData.contract; - operatorIDs = contractData.operatorIDs; - shares = contractData.shares; + await helpers.registerOperators(0, 1, '10'); + await helpers.registerOperators(1, 1, '10'); + await helpers.registerOperators(2, 1, '10'); + await helpers.registerOperators(3, 1, '10'); + + await helpers.deposit([4], ['100000']); }); it('Remove validator', async () => { - const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; - await trackGas(registryContract.registerValidator( - `${validatorPK}0`, - operatorIDs.slice(0, 4), - shares[0], - '10000' - )); - - const { gasUsed } = await trackGas(registryContract.removeValidator(`${validatorPK}0`)); - expect(gasUsed).lessThan(150000); + const { validators } = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); + await trackGas(registryContract.connect(helpers.DB.owners[4]).removeValidator(validators[0].publicKey), [GasGroup.REMOVE_VALIDATOR]); }); - it('Fails to transfer validator with no owner', async () => { - const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; - await trackGas(registryContract.registerValidator( - `${validatorPK}0`, - operatorIDs.slice(0, 4), - shares[0], - '10000' - )); - - await expect(trackGas(registryContract.connect(addr2).removeValidator(`${validatorPK}0`))).to.be.revertedWith('ValidatorNotOwned'); + it('Fails to remove validator with no owner', async () => { + const { validators } = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); + await expect(trackGas(registryContract.connect(helpers.DB.owners[3]).removeValidator(validators[0].publicKey))).to.be.revertedWith('ValidatorNotOwned'); }); }); diff --git a/test/validators/transfer.ts b/test/validators/transfer.ts index 81291a42..a52b47f2 100644 --- a/test/validators/transfer.ts +++ b/test/validators/transfer.ts @@ -5,81 +5,71 @@ import * as helpers from '../helpers/contract-helpers'; import { expect } from 'chai'; import { trackGas, GasGroup } from '../helpers/gas-usage'; -const numberOfOperators = 8; -const operatorFee = 4; - -let registryContract: any, operatorIDs: any, shares: any, addr1: any, addr2: any; +let registryContract: any; describe('Transfer Validator Tests', () => { beforeEach(async () => { - [addr1, addr2] = await ethers.getSigners(); - - const contractData = await helpers.initializeContract(numberOfOperators, operatorFee); + const contractData = await helpers.initializeContract(); registryContract = contractData.contract; - operatorIDs = contractData.operatorIDs; - shares = contractData.shares; + await helpers.registerOperators(0, 1, '10'); + await helpers.registerOperators(1, 1, '10'); + await helpers.registerOperators(2, 1, '10'); + await helpers.registerOperators(3, 1, '10'); + await helpers.registerOperators(4, 1, '10'); + await helpers.registerOperators(5, 1, '10'); + await helpers.registerOperators(6, 1, '10'); + await helpers.registerOperators(7, 1, '10'); + + await helpers.deposit([4], ['100000']); + await helpers.deposit([5], ['100000']); }); it('Transfer validator into new pod', async () => { - const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; - const validatorBeforeTransfer = await trackGas(registryContract.registerValidator( - `${validatorPK}0`, - operatorIDs.slice(0, 4), - shares[0], - '10000' - ), [ GasGroup.registerValidator ]); + const { validators, podId } = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); - const transferedValidator = await trackGas(registryContract.transferValidator( - `${validatorPK}0`, - operatorIDs.slice(4, 8), - shares[0], + const transferedValidator = await trackGas(registryContract.connect(helpers.DB.owners[4]).transferValidator( + validators[0].publicKey, + helpers.DataGenerator.pod.new(), + helpers.DataGenerator.shares(helpers.DB.validators.length), '10000' - )); - expect(transferedValidator.gasUsed).lessThan(410000); + ), [GasGroup.TRANSFER_VALIDATOR_NEW_POD]); - expect(validatorBeforeTransfer.eventsByName.ValidatorAdded[0].args.podId).not.equals(transferedValidator.eventsByName.ValidatorTransferred[0].args.podId); + expect(podId).not.equals(transferedValidator.eventsByName.ValidatorTransferred[0].args.podId); }); it('Transfer validator to existed pod', async () => { - const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; - const validatorOne = await trackGas(registryContract.registerValidator( - `${validatorPK}0`, - operatorIDs.slice(0, 4), - shares[0], + const validator1 = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); + const { podId } = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); + const transfredValidator1 = await trackGas(registryContract.connect(helpers.DB.owners[4]).transferValidator( + validator1.validators[0].publicKey, + helpers.DataGenerator.pod.byId(podId), + helpers.DataGenerator.shares(helpers.DB.validators.length), '10000' - )); + ), [GasGroup.TRANSFER_VALIDATOR_EXISTED_POD]); - const validatorTwo = await trackGas(registryContract.registerValidator( - `${validatorPK}1`, - operatorIDs.slice(4, 8), - shares[0], - '10000' - )); + expect(podId).equals(transfredValidator1.eventsByName.ValidatorTransferred[0].args.podId); + }); - const transferedValidator = await trackGas(registryContract.transferValidator( - `${validatorPK}0`, - operatorIDs.slice(4, 8), - shares[0], + it('Transfer validator to existed cluster', async () => { + const validator1 = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); + const { podId } = await helpers.registerValidators(5, 1, '10000', helpers.DataGenerator.pod.new()); + const transfredValidator1 = await trackGas(registryContract.connect(helpers.DB.owners[4]).transferValidator( + validator1.validators[0].publicKey, + helpers.DataGenerator.pod.byId(podId), + helpers.DataGenerator.shares(helpers.DB.validators.length), '10000' - )); - expect(transferedValidator.gasUsed).lessThan(270000); + ), [GasGroup.TRANSFER_VALIDATOR_EXISTED_CLUSTER]); - expect(validatorTwo.eventsByName.ValidatorAdded[0].args.podId).equals(transferedValidator.eventsByName.ValidatorTransferred[0].args.podId); + expect(podId).equals(transfredValidator1.eventsByName.ValidatorTransferred[0].args.podId); }); it('Fails to transfer validator with no owner', async () => { - const validatorPK = '0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100'; - await trackGas(registryContract.registerValidator( - `${validatorPK}0`, - operatorIDs.slice(0, 4), - shares[0], - '10000' - )); - - await expect(trackGas(registryContract.connect(addr2).transferValidator( - `${validatorPK}0`, - operatorIDs.slice(4, 8), - shares[0], + const validator1 = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); + const { podId } = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); + await expect(trackGas(registryContract.connect(helpers.DB.owners[5]).transferValidator( + validator1.validators[0].publicKey, + helpers.DataGenerator.pod.byId(podId), + helpers.DataGenerator.shares(helpers.DB.validators.length), '10000' ))).to.be.revertedWith('ValidatorNotOwned'); }); From 898481344daf944f8f4268627dfb4f6579991e57 Mon Sep 17 00:00:00 2001 From: Vadim Date: Sun, 4 Sep 2022 09:04:04 +0200 Subject: [PATCH 056/149] fix lint issues --- test/helpers/contract-helpers.ts | 14 +-- test/helpers/gas-usage.ts | 2 +- test/sanity/balances.ts | 166 +++++++++++++++---------------- test/sanity/stress.ts | 2 +- 4 files changed, 92 insertions(+), 92 deletions(-) diff --git a/test/helpers/contract-helpers.ts b/test/helpers/contract-helpers.ts index 507a4e40..079aed2f 100644 --- a/test/helpers/contract-helpers.ts +++ b/test/helpers/contract-helpers.ts @@ -9,7 +9,7 @@ export const DataGenerator = { publicKey: (index: number) => `0x${index.toString(16).padStart(96,'1')}`, shares: (index: number) => `0x${index.toString(16).padStart(360,'1')}`, pod: { - new: (size: number = 4) => { + new: (size = 4) => { const usedOperatorIds: any = {}; for (const podId in DB.pods) { for (const operatorId of DB.pods[podId].operatorIds) { @@ -29,14 +29,14 @@ export const DataGenerator = { } } if (result.length < size) { - throw new Error("No new pods. Try to register more operators."); + throw new Error('No new pods. Try to register more operators.'); } return result; }, byId: (id: any) => DB.pods[id].operatorIds } -} +}; export const initializeContract = async () => { DB = { @@ -45,7 +45,7 @@ export const initializeContract = async () => { operators: [], pods: [], ssvNetwork: {} - } + }; // Define accounts DB.owners = await ethers.getSigners(); @@ -67,15 +67,15 @@ export const registerOperators = async (ownerId: number, numberOfOperators: numb const event = eventsByName.OperatorAdded[0]; DB.operators[event.args.id] = { id: event.args.id, ownerId: ownerId, publicKey: DataGenerator.publicKey(i) - } + }; } -} +}; export const deposit = async (ownerIds: number[], amounts: string[]) => { for (let i = 0; i < ownerIds.length; ++i) { await DB.ssvNetwork.contract.connect(DB.owners[ownerIds[i]]).deposit(amounts[i]); } -} +}; export const registerValidators = async (ownerId: number, numberOfValidators: number, amount: string, operatorIds: number[], gasGroups?: GasGroup[]) => { diff --git a/test/helpers/gas-usage.ts b/test/helpers/gas-usage.ts index 24b4e58e..bbd56d4d 100644 --- a/test/helpers/gas-usage.ts +++ b/test/helpers/gas-usage.ts @@ -20,7 +20,7 @@ const MAX_GAS_PER_GROUP: any = { [GasGroup.TRANSFER_VALIDATOR_NEW_POD]: 400000, [GasGroup.TRANSFER_VALIDATOR_EXISTED_POD]: 260000, [GasGroup.TRANSFER_VALIDATOR_EXISTED_CLUSTER]: 290000, -} +}; class GasStats { max: number | null = null; diff --git a/test/sanity/balances.ts b/test/sanity/balances.ts index 26465f15..3a3e54a2 100644 --- a/test/sanity/balances.ts +++ b/test/sanity/balances.ts @@ -41,89 +41,89 @@ describe('Balance Tests', () => { // expect(await registryContract.operatorEarningsOf(2)).to.equal('50') // expect(await registryContract.operatorEarningsOf(3)).to.equal('50') // expect(await registryContract.operatorEarningsOf(4)).to.equal('50') - // expect(await registryContract.groupBalanceOf(owner.address, outputRegister.groupId)).to.equal(10000 - 150) - - // // Update one of the operator fees - // await registryContract.updateOperatorFee(1, 10) - - // // Progress 50 blocks and check operator balances and group balance - // await utils.progressBlocks(50) - // expect(await registryContract.operatorEarningsOf(1)).to.equal('551') - // expect(await registryContract.operatorEarningsOf(2)).to.equal('101') - // expect(await registryContract.operatorEarningsOf(3)).to.equal('101') - // expect(await registryContract.operatorEarningsOf(4)).to.equal('101') - // expect(await registryContract.groupBalanceOf(owner.address, outputRegister.groupId)).to.equal(10000 - 904) - - // // Update 3 operator fees - // await registryContract.updateOperatorFee(2, 20) - // await registryContract.updateOperatorFee(3, 20) - // await registryContract.updateOperatorFee(4, 20) - - // // Progress 50 blocks and check operator balances and group balance - // await utils.progressBlocks(50) - // expect(await registryContract.operatorEarningsOf(1)).to.equal('1081') - // expect(await registryContract.operatorEarningsOf(2)).to.equal('1142') - // expect(await registryContract.operatorEarningsOf(3)).to.equal('1123') - // expect(await registryContract.operatorEarningsOf(4)).to.equal('1104') - // expect(await registryContract.groupBalanceOf(owner.address, outputRegister.groupId)).to.equal(10000 - 4500) - - // // Add another validator - // await registryContract.registerValidator( - // [1, 2, 3, 5], - // `${validatorPK}1`, - // shares[1], - // "10000" - // ) - - // // Progress 50 blocks and check operator balances and group balance - // await utils.progressBlocks(50) - // expect(await registryContract.operatorEarningsOf(1)).to.equal('2091') - // expect(await registryContract.operatorEarningsOf(2)).to.equal('3162') - // expect(await registryContract.operatorEarningsOf(3)).to.equal('3143') - // expect(await registryContract.operatorEarningsOf(4)).to.equal('2124') - // expect(await registryContract.operatorEarningsOf(5)).to.equal('5000') - // expect(await registryContract.groupBalanceOf(owner.address, outputRegister.groupId)).to.equal(10000 - 4500) - - // // Remove an operator - // await registryContract.removeOperator(1) - - // // Progress 50 blocks and check operator balances and group balance - // await utils.progressBlocks(50) - // expect(await registryContract.operatorEarningsOf(1)).to.equal('2091') - // expect(await registryContract.operatorEarningsOf(2)).to.equal('3162') - // expect(await registryContract.operatorEarningsOf(3)).to.equal('3143') - // expect(await registryContract.operatorEarningsOf(4)).to.equal('2124') - // expect(await registryContract.operatorEarningsOf(5)).to.equal('5000') - // expect(await registryContract.groupBalanceOf(owner.address, outputRegister.groupId)).to.equal(10000 - 4500) - - // // Update a validator - // await registryContract.updateValidator( - // [1, 2, 3, 5], - // `${validatorPK}0`, - // shares[1], - // "10" - // ) - - // // Progress 50 blocks and check operator balances and group balance - // await utils.progressBlocks(50) - // expect(await registryContract.operatorEarningsOf(1)).to.equal('2091') - // expect(await registryContract.operatorEarningsOf(2)).to.equal('3162') - // expect(await registryContract.operatorEarningsOf(3)).to.equal('3143') - // expect(await registryContract.operatorEarningsOf(4)).to.equal('2124') - // expect(await registryContract.operatorEarningsOf(5)).to.equal('5000') - // expect(await registryContract.groupBalanceOf(owner.address, outputRegister.groupId)).to.equal(10000 - 4500) - - // // Remove a validator - // await registryContract.removeValidator(`${validatorPK}0`, outputRegister.groupId) - - // // Progress 50 blocks and check operator balances and group balance - // await utils.progressBlocks(50) - // expect(await registryContract.operatorEarningsOf(1)).to.equal('2091') - // expect(await registryContract.operatorEarningsOf(2)).to.equal('3162') - // expect(await registryContract.operatorEarningsOf(3)).to.equal('3143') - // expect(await registryContract.operatorEarningsOf(4)).to.equal('2124') - // expect(await registryContract.operatorEarningsOf(5)).to.equal('5000') - // expect(await registryContract.groupBalanceOf(owner.address, outputRegister.groupId)).to.equal(10000 - 4500) + // expect(await registryContract.groupBalanceOf(owner.address, outputRegister.groupId)).to.equal(10000 - 150) + + // // Update one of the operator fees + // await registryContract.updateOperatorFee(1, 10) + + // // Progress 50 blocks and check operator balances and group balance + // await utils.progressBlocks(50) + // expect(await registryContract.operatorEarningsOf(1)).to.equal('551') + // expect(await registryContract.operatorEarningsOf(2)).to.equal('101') + // expect(await registryContract.operatorEarningsOf(3)).to.equal('101') + // expect(await registryContract.operatorEarningsOf(4)).to.equal('101') + // expect(await registryContract.groupBalanceOf(owner.address, outputRegister.groupId)).to.equal(10000 - 904) + + // // Update 3 operator fees + // await registryContract.updateOperatorFee(2, 20) + // await registryContract.updateOperatorFee(3, 20) + // await registryContract.updateOperatorFee(4, 20) + + // // Progress 50 blocks and check operator balances and group balance + // await utils.progressBlocks(50) + // expect(await registryContract.operatorEarningsOf(1)).to.equal('1081') + // expect(await registryContract.operatorEarningsOf(2)).to.equal('1142') + // expect(await registryContract.operatorEarningsOf(3)).to.equal('1123') + // expect(await registryContract.operatorEarningsOf(4)).to.equal('1104') + // expect(await registryContract.groupBalanceOf(owner.address, outputRegister.groupId)).to.equal(10000 - 4500) + + // // Add another validator + // await registryContract.registerValidator( + // [1, 2, 3, 5], + // `${validatorPK}1`, + // shares[1], + // "10000" + // ) + + // // Progress 50 blocks and check operator balances and group balance + // await utils.progressBlocks(50) + // expect(await registryContract.operatorEarningsOf(1)).to.equal('2091') + // expect(await registryContract.operatorEarningsOf(2)).to.equal('3162') + // expect(await registryContract.operatorEarningsOf(3)).to.equal('3143') + // expect(await registryContract.operatorEarningsOf(4)).to.equal('2124') + // expect(await registryContract.operatorEarningsOf(5)).to.equal('5000') + // expect(await registryContract.groupBalanceOf(owner.address, outputRegister.groupId)).to.equal(10000 - 4500) + + // // Remove an operator + // await registryContract.removeOperator(1) + + // // Progress 50 blocks and check operator balances and group balance + // await utils.progressBlocks(50) + // expect(await registryContract.operatorEarningsOf(1)).to.equal('2091') + // expect(await registryContract.operatorEarningsOf(2)).to.equal('3162') + // expect(await registryContract.operatorEarningsOf(3)).to.equal('3143') + // expect(await registryContract.operatorEarningsOf(4)).to.equal('2124') + // expect(await registryContract.operatorEarningsOf(5)).to.equal('5000') + // expect(await registryContract.groupBalanceOf(owner.address, outputRegister.groupId)).to.equal(10000 - 4500) + + // // Update a validator + // await registryContract.updateValidator( + // [1, 2, 3, 5], + // `${validatorPK}0`, + // shares[1], + // "10" + // ) + + // // Progress 50 blocks and check operator balances and group balance + // await utils.progressBlocks(50) + // expect(await registryContract.operatorEarningsOf(1)).to.equal('2091') + // expect(await registryContract.operatorEarningsOf(2)).to.equal('3162') + // expect(await registryContract.operatorEarningsOf(3)).to.equal('3143') + // expect(await registryContract.operatorEarningsOf(4)).to.equal('2124') + // expect(await registryContract.operatorEarningsOf(5)).to.equal('5000') + // expect(await registryContract.groupBalanceOf(owner.address, outputRegister.groupId)).to.equal(10000 - 4500) + + // // Remove a validator + // await registryContract.removeValidator(`${validatorPK}0`, outputRegister.groupId) + + // // Progress 50 blocks and check operator balances and group balance + // await utils.progressBlocks(50) + // expect(await registryContract.operatorEarningsOf(1)).to.equal('2091') + // expect(await registryContract.operatorEarningsOf(2)).to.equal('3162') + // expect(await registryContract.operatorEarningsOf(3)).to.equal('3143') + // expect(await registryContract.operatorEarningsOf(4)).to.equal('2124') + // expect(await registryContract.operatorEarningsOf(5)).to.equal('5000') + // expect(await registryContract.groupBalanceOf(owner.address, outputRegister.groupId)).to.equal(10000 - 4500) // }); }); diff --git a/test/sanity/stress.ts b/test/sanity/stress.ts index e11543cc..1ff2f5f2 100644 --- a/test/sanity/stress.ts +++ b/test/sanity/stress.ts @@ -8,7 +8,7 @@ const numberOfOperators = 1000; const operatorFee = 1; let registryContract: any, operatorIDs: any, shares: any; -let validatorData: any = []; +const validatorData: any = []; describe('Stress Tests', () => { // beforeEach(async () => { From a6074c644355662a8b54800894301a675737b78b Mon Sep 17 00:00:00 2001 From: Vadim Date: Tue, 6 Sep 2022 09:00:01 +0200 Subject: [PATCH 057/149] extend register validator test --- test/validators/register.ts | 21 +++++++++++++-------- test/validators/remove.ts | 9 ++++----- test/validators/transfer.ts | 13 ++++++------- 3 files changed, 23 insertions(+), 20 deletions(-) diff --git a/test/validators/register.ts b/test/validators/register.ts index 32e5d09c..44085065 100644 --- a/test/validators/register.ts +++ b/test/validators/register.ts @@ -2,18 +2,14 @@ declare const ethers: any; import * as helpers from '../helpers/contract-helpers'; -// import { expect } from 'chai'; -import { GasGroup } from '../helpers/gas-usage'; +import { expect } from 'chai'; +import { trackGas, GasGroup } from '../helpers/gas-usage'; -const numberOfOperators = 8; -const operatorFee = 4; - -let registryContract: any; +let ssvNetworkContract: any; describe('Register Validator Tests', () => { beforeEach(async () => { - const contractData = await helpers.initializeContract(); - registryContract = contractData.contract; + ssvNetworkContract = (await helpers.initializeContract()).contract; await helpers.registerOperators(0, 1, '10'); await helpers.registerOperators(1, 1, '10'); await helpers.registerOperators(2, 1, '10'); @@ -36,4 +32,13 @@ describe('Register Validator Tests', () => { const result = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); await helpers.registerValidators(5, 1, '10000', helpers.DataGenerator.pod.byId(result.podId), [GasGroup.REGISTER_VALIDATOR_EXISTED_CLUSTER]); }); + + it('Fails to register with invalid operator list size', async () => { + await expect(trackGas(ssvNetworkContract.registerValidator( + helpers.DataGenerator.publicKey(helpers.DB.validators.length), + [1, 2], + helpers.DataGenerator.shares(helpers.DB.validators.length), + '10000' + ))).to.be.revertedWith('OessDataStructureInvalid'); + }); }); diff --git a/test/validators/remove.ts b/test/validators/remove.ts index d368a454..b407fc90 100644 --- a/test/validators/remove.ts +++ b/test/validators/remove.ts @@ -6,12 +6,11 @@ import { expect } from 'chai'; import { trackGas, GasGroup } from '../helpers/gas-usage'; -let registryContract: any; +let ssvNetworkContract: any; describe('Remove Validator Tests', () => { beforeEach(async () => { - const contractData = await helpers.initializeContract(); - registryContract = contractData.contract; + ssvNetworkContract = (await helpers.initializeContract()).contract; await helpers.registerOperators(0, 1, '10'); await helpers.registerOperators(1, 1, '10'); await helpers.registerOperators(2, 1, '10'); @@ -22,11 +21,11 @@ describe('Remove Validator Tests', () => { it('Remove validator', async () => { const { validators } = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); - await trackGas(registryContract.connect(helpers.DB.owners[4]).removeValidator(validators[0].publicKey), [GasGroup.REMOVE_VALIDATOR]); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator(validators[0].publicKey), [GasGroup.REMOVE_VALIDATOR]); }); it('Fails to remove validator with no owner', async () => { const { validators } = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); - await expect(trackGas(registryContract.connect(helpers.DB.owners[3]).removeValidator(validators[0].publicKey))).to.be.revertedWith('ValidatorNotOwned'); + await expect(trackGas(ssvNetworkContract.connect(helpers.DB.owners[3]).removeValidator(validators[0].publicKey))).to.be.revertedWith('ValidatorNotOwned'); }); }); diff --git a/test/validators/transfer.ts b/test/validators/transfer.ts index a52b47f2..d2fdd36e 100644 --- a/test/validators/transfer.ts +++ b/test/validators/transfer.ts @@ -5,12 +5,11 @@ import * as helpers from '../helpers/contract-helpers'; import { expect } from 'chai'; import { trackGas, GasGroup } from '../helpers/gas-usage'; -let registryContract: any; +let ssvNetworkContract: any; describe('Transfer Validator Tests', () => { beforeEach(async () => { - const contractData = await helpers.initializeContract(); - registryContract = contractData.contract; + ssvNetworkContract = (await helpers.initializeContract()).contract; await helpers.registerOperators(0, 1, '10'); await helpers.registerOperators(1, 1, '10'); await helpers.registerOperators(2, 1, '10'); @@ -27,7 +26,7 @@ describe('Transfer Validator Tests', () => { it('Transfer validator into new pod', async () => { const { validators, podId } = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); - const transferedValidator = await trackGas(registryContract.connect(helpers.DB.owners[4]).transferValidator( + const transferedValidator = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( validators[0].publicKey, helpers.DataGenerator.pod.new(), helpers.DataGenerator.shares(helpers.DB.validators.length), @@ -40,7 +39,7 @@ describe('Transfer Validator Tests', () => { it('Transfer validator to existed pod', async () => { const validator1 = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); const { podId } = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); - const transfredValidator1 = await trackGas(registryContract.connect(helpers.DB.owners[4]).transferValidator( + const transfredValidator1 = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( validator1.validators[0].publicKey, helpers.DataGenerator.pod.byId(podId), helpers.DataGenerator.shares(helpers.DB.validators.length), @@ -53,7 +52,7 @@ describe('Transfer Validator Tests', () => { it('Transfer validator to existed cluster', async () => { const validator1 = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); const { podId } = await helpers.registerValidators(5, 1, '10000', helpers.DataGenerator.pod.new()); - const transfredValidator1 = await trackGas(registryContract.connect(helpers.DB.owners[4]).transferValidator( + const transfredValidator1 = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( validator1.validators[0].publicKey, helpers.DataGenerator.pod.byId(podId), helpers.DataGenerator.shares(helpers.DB.validators.length), @@ -66,7 +65,7 @@ describe('Transfer Validator Tests', () => { it('Fails to transfer validator with no owner', async () => { const validator1 = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); const { podId } = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); - await expect(trackGas(registryContract.connect(helpers.DB.owners[5]).transferValidator( + await expect(trackGas(ssvNetworkContract.connect(helpers.DB.owners[5]).transferValidator( validator1.validators[0].publicKey, helpers.DataGenerator.pod.byId(podId), helpers.DataGenerator.shares(helpers.DB.validators.length), From 03e21ed52de57f9077642cb4c6f285375d427112 Mon Sep 17 00:00:00 2001 From: Vadim Date: Tue, 6 Sep 2022 09:28:28 +0200 Subject: [PATCH 058/149] extend tests by new cases --- test/validators/register.ts | 37 +++++++++++++++++++++++-------------- test/validators/remove.ts | 12 ++++++++++-- test/validators/transfer.ts | 21 ++++++++++++++++----- 3 files changed, 49 insertions(+), 21 deletions(-) diff --git a/test/validators/register.ts b/test/validators/register.ts index 44085065..1eba0b71 100644 --- a/test/validators/register.ts +++ b/test/validators/register.ts @@ -15,30 +15,39 @@ describe('Register Validator Tests', () => { await helpers.registerOperators(2, 1, '10'); await helpers.registerOperators(3, 1, '10'); - await helpers.deposit([4], ['100000']); - await helpers.deposit([5], ['100000']); + await helpers.deposit([0], ['100000']); + await helpers.deposit([1], ['100000']); }); - it('Register validator in empty pod', async () => { - await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + it('Register validator emits ValidatorAdded event', async () => { + await expect(ssvNetworkContract.registerValidator( + helpers.DataGenerator.publicKey(0), + helpers.DataGenerator.pod.new(), + helpers.DataGenerator.shares(0), + '10000' + )).to.emit(ssvNetworkContract, 'ValidatorAdded'); + }); + + it('Register one validator in empty pod with gas track', async () => { + await helpers.registerValidators(0, 1, '10000', helpers.DataGenerator.pod.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); }); - it('Register two validators in existed pod', async () => { - const result = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); - await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.byId(result.podId), [GasGroup.REGISTER_VALIDATOR_EXISTED_POD]); + it('Register two validators in existed pod with gas track', async () => { + const result = await helpers.registerValidators(0, 1, '10000', helpers.DataGenerator.pod.new()); + await helpers.registerValidators(0, 1, '10000', helpers.DataGenerator.pod.byId(result.podId), [GasGroup.REGISTER_VALIDATOR_EXISTED_POD]); }); - it('Register two validators in existed cluster', async () => { - const result = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); - await helpers.registerValidators(5, 1, '10000', helpers.DataGenerator.pod.byId(result.podId), [GasGroup.REGISTER_VALIDATOR_EXISTED_CLUSTER]); + it('Register two validators in existed cluster with gas track', async () => { + const result = await helpers.registerValidators(0, 1, '10000', helpers.DataGenerator.pod.new()); + await helpers.registerValidators(1, 1, '10000', helpers.DataGenerator.pod.byId(result.podId), [GasGroup.REGISTER_VALIDATOR_EXISTED_CLUSTER]); }); it('Fails to register with invalid operator list size', async () => { - await expect(trackGas(ssvNetworkContract.registerValidator( - helpers.DataGenerator.publicKey(helpers.DB.validators.length), + await expect(ssvNetworkContract.registerValidator( + helpers.DataGenerator.publicKey(0), [1, 2], - helpers.DataGenerator.shares(helpers.DB.validators.length), + helpers.DataGenerator.shares(0), '10000' - ))).to.be.revertedWith('OessDataStructureInvalid'); + )).to.be.revertedWith('OessDataStructureInvalid'); }); }); diff --git a/test/validators/remove.ts b/test/validators/remove.ts index b407fc90..ae5faed9 100644 --- a/test/validators/remove.ts +++ b/test/validators/remove.ts @@ -19,13 +19,21 @@ describe('Remove Validator Tests', () => { await helpers.deposit([4], ['100000']); }); - it('Remove validator', async () => { + it('Remove validator emits ValidatorRemoved event', async () => { + const { validators } = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); + + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator( + validators[0].publicKey, + )).to.emit(ssvNetworkContract, 'ValidatorRemoved'); + }); + + it('Remove validator track gas', async () => { const { validators } = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator(validators[0].publicKey), [GasGroup.REMOVE_VALIDATOR]); }); it('Fails to remove validator with no owner', async () => { const { validators } = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); - await expect(trackGas(ssvNetworkContract.connect(helpers.DB.owners[3]).removeValidator(validators[0].publicKey))).to.be.revertedWith('ValidatorNotOwned'); + await expect(ssvNetworkContract.connect(helpers.DB.owners[3]).removeValidator(validators[0].publicKey)).to.be.revertedWith('ValidatorNotOwned'); }); }); diff --git a/test/validators/transfer.ts b/test/validators/transfer.ts index d2fdd36e..3c8c3eb4 100644 --- a/test/validators/transfer.ts +++ b/test/validators/transfer.ts @@ -23,7 +23,18 @@ describe('Transfer Validator Tests', () => { await helpers.deposit([5], ['100000']); }); - it('Transfer validator into new pod', async () => { + it('Transfer validator emits ValidatorTransferred event', async () => { + const { validators } = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); + + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( + validators[0].publicKey, + helpers.DataGenerator.pod.new(), + helpers.DataGenerator.shares(helpers.DB.validators.length), + '10000' + )).to.emit(ssvNetworkContract, 'ValidatorTransferred'); + }); + + it('Transfer validator into new pod track gas', async () => { const { validators, podId } = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); const transferedValidator = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( @@ -36,7 +47,7 @@ describe('Transfer Validator Tests', () => { expect(podId).not.equals(transferedValidator.eventsByName.ValidatorTransferred[0].args.podId); }); - it('Transfer validator to existed pod', async () => { + it('Transfer validator to existed pod track gas', async () => { const validator1 = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); const { podId } = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); const transfredValidator1 = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( @@ -49,7 +60,7 @@ describe('Transfer Validator Tests', () => { expect(podId).equals(transfredValidator1.eventsByName.ValidatorTransferred[0].args.podId); }); - it('Transfer validator to existed cluster', async () => { + it('Transfer validator to existed cluster track gas', async () => { const validator1 = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); const { podId } = await helpers.registerValidators(5, 1, '10000', helpers.DataGenerator.pod.new()); const transfredValidator1 = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( @@ -65,11 +76,11 @@ describe('Transfer Validator Tests', () => { it('Fails to transfer validator with no owner', async () => { const validator1 = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); const { podId } = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); - await expect(trackGas(ssvNetworkContract.connect(helpers.DB.owners[5]).transferValidator( + await expect(ssvNetworkContract.connect(helpers.DB.owners[5]).transferValidator( validator1.validators[0].publicKey, helpers.DataGenerator.pod.byId(podId), helpers.DataGenerator.shares(helpers.DB.validators.length), '10000' - ))).to.be.revertedWith('ValidatorNotOwned'); + )).to.be.revertedWith('ValidatorNotOwned'); }); }); From 46cfa626709db4d9100d6d7d56c37b3cf59cbac6 Mon Sep 17 00:00:00 2001 From: Wadym Date: Mon, 12 Sep 2022 09:52:56 +0200 Subject: [PATCH 059/149] Tests operator register--IO1-1740 (#92) * eslint fixes, runTx, changed validators tests * runTx -> trackGas + fix tests * fix tests, extend validators tests * improvements and remove validator * adding GasGroup enum * fix trackgas output * refactor helpers * comment out some files * change to chai * finilise validator tests with changed infrastructure * fix lint issues * extend register validator test * register operator tests * extend tests by new cases Co-authored-by: Vadim Co-authored-by: Vadim Co-authored-by: Adam Zigdon Co-authored-by: Vadim Co-authored-by: Vadim Co-authored-by: Vadim --- test/operators/register.ts | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/test/operators/register.ts b/test/operators/register.ts index 86cabf3d..18d12fe9 100644 --- a/test/operators/register.ts +++ b/test/operators/register.ts @@ -3,27 +3,33 @@ import * as helpers from '../helpers/contract-helpers'; import { expect } from 'chai'; import { trackGas, GasGroup } from '../helpers/gas-usage'; -const numberOfOperators = 4; -const operatorFee = 4; - -let ssvNetworkContract: any, operatorIDs: any, shares: any, owner: any; +let ssvNetworkContract: any; describe('Register Operator Tests', () => { beforeEach(async () => { - const contractData = await helpers.initializeContract(); - ssvNetworkContract = contractData.contract; + ssvNetworkContract = (await helpers.initializeContract()).contract; }); it('Register operator', async () => { - + const publicKey = helpers.DataGenerator.publicKey(0); + await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).registerOperator( + publicKey, + '10' + )).to.emit(ssvNetworkContract, 'OperatorAdded').withArgs(1, helpers.DB.owners[1].address, publicKey); }); - it('Register operator errors', async () => { - + it('Fails to register with low fee', async () => { + await expect(ssvNetworkContract.registerOperator( + helpers.DataGenerator.publicKey(0), + '0' + )).to.be.revertedWith('FeeTooLow'); }); it('Register operator gas limits', async () => { - + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerOperator( + helpers.DataGenerator.publicKey(0), + '10' + ), [GasGroup.REGISTER_OPERATOR]); }); }); From 698bad80abccaea2c50ff152525d41b315ceedfa Mon Sep 17 00:00:00 2001 From: Wadym Date: Mon, 12 Sep 2022 09:53:30 +0200 Subject: [PATCH 060/149] Tests operator remove--IO1-1741 (#93) * eslint fixes, runTx, changed validators tests * runTx -> trackGas + fix tests * fix tests, extend validators tests * adding GasGroup enum * fix trackgas output * refactor helpers * comment out some files * change to chai * finilise validator tests with changed infrastructure * fix lint issues * extend register validator test * register operator tests * extend tests by new cases * remove operator tests --- test/helpers/gas-usage.ts | 2 ++ test/operators/remove.ts | 24 +++++++++++++----------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/test/helpers/gas-usage.ts b/test/helpers/gas-usage.ts index bbd56d4d..09f5a73b 100644 --- a/test/helpers/gas-usage.ts +++ b/test/helpers/gas-usage.ts @@ -2,6 +2,7 @@ import { expect } from 'chai'; export enum GasGroup { REGISTER_OPERATOR, + REMOVE_OPERATOR, REGISTER_VALIDATOR_EXISTED_POD, REGISTER_VALIDATOR_EXISTED_CLUSTER, REGISTER_VALIDATOR_NEW_STATE, @@ -13,6 +14,7 @@ export enum GasGroup { const MAX_GAS_PER_GROUP: any = { [GasGroup.REGISTER_OPERATOR]: 100000, + [GasGroup.REMOVE_OPERATOR]: 40000, [GasGroup.REGISTER_VALIDATOR_EXISTED_POD]: 220000, [GasGroup.REGISTER_VALIDATOR_EXISTED_CLUSTER]: 250000, [GasGroup.REGISTER_VALIDATOR_NEW_STATE]: 400000, diff --git a/test/operators/remove.ts b/test/operators/remove.ts index 3ae1fb9b..b956d533 100644 --- a/test/operators/remove.ts +++ b/test/operators/remove.ts @@ -1,28 +1,30 @@ import * as helpers from '../helpers/contract-helpers'; import { expect } from 'chai'; +import { trackGas, GasGroup } from '../helpers/gas-usage'; -const numberOfOperators = 4; -const operatorFee = 4; - -let ssvNetworkContract: any, operatorIDs: any, shares: any, owner: any; +let ssvNetworkContract: any; describe('Remove Operator Tests', () => { beforeEach(async () => { - const contractData = await helpers.initializeContract(); - ssvNetworkContract = contractData.contract; + ssvNetworkContract = (await helpers.initializeContract()).contract; }); - it('Remove operator', async () => { - + it('Remove operator emits OperatorRemoved event', async () => { + await helpers.registerOperators(0, 1, '10'); + await expect(ssvNetworkContract.connect(helpers.DB.owners[0]).removeOperator(1)) + .to.emit(ssvNetworkContract, 'OperatorRemoved').withArgs(1); }); - it('Remove operator errors', async () => { - + it('Fails to remove operator with no owner', async () => { + await helpers.registerOperators(0, 1, '10'); + await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).removeOperator(1)) + .to.be.revertedWith('CallerNotOwner'); }); it('Remove operator gas limits', async () => { - + await helpers.registerOperators(0, 1, '10'); + await trackGas(ssvNetworkContract.removeOperator(1), [GasGroup.REMOVE_OPERATOR]); }); }); From 9ea025beee84516506f5d6498deb07ad8335fe5c Mon Sep 17 00:00:00 2001 From: Lior Rutenberg Date: Mon, 12 Sep 2022 12:00:20 +0300 Subject: [PATCH 061/149] enable optimzier and update gas limits --- hardhat.config.ts | 2 -- test/helpers/gas-usage.ts | 4 ++-- test/vadimToUpdate.js | 6 +++--- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/hardhat.config.ts b/hardhat.config.ts index 64b926de..cedb7866 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -20,12 +20,10 @@ const config: HardhatUserConfig = { { version: '0.8.13', settings: { - /* optimizer: { enabled: true, runs: 10000 } - */ } } ], diff --git a/test/helpers/gas-usage.ts b/test/helpers/gas-usage.ts index bbd56d4d..188ce2b7 100644 --- a/test/helpers/gas-usage.ts +++ b/test/helpers/gas-usage.ts @@ -13,8 +13,8 @@ export enum GasGroup { const MAX_GAS_PER_GROUP: any = { [GasGroup.REGISTER_OPERATOR]: 100000, - [GasGroup.REGISTER_VALIDATOR_EXISTED_POD]: 220000, - [GasGroup.REGISTER_VALIDATOR_EXISTED_CLUSTER]: 250000, + [GasGroup.REGISTER_VALIDATOR_EXISTED_POD]: 190000, + [GasGroup.REGISTER_VALIDATOR_EXISTED_CLUSTER]: 230000, [GasGroup.REGISTER_VALIDATOR_NEW_STATE]: 400000, [GasGroup.REMOVE_VALIDATOR]: 120000, [GasGroup.TRANSFER_VALIDATOR_NEW_POD]: 400000, diff --git a/test/vadimToUpdate.js b/test/vadimToUpdate.js index 8eec612a..769ae622 100644 --- a/test/vadimToUpdate.js +++ b/test/vadimToUpdate.js @@ -97,7 +97,7 @@ describe("Validators", () => { let outputUpdate = interfaceUpdate.decodeEventLog('ValidatorTransferred', resultUpdate.data, resultUpdate.topics); expect(outputRegister.groupId).not.equal(outputUpdate.groupId); expect(outputRegister.validatorPK).to.equal(outputUpdate.validatorPK); - + await log({ action: `update validator #1: ${outputUpdate.validatorPK} : ${outputUpdate.groupId}`, operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], @@ -218,7 +218,7 @@ describe("Validators", () => { }); await progressBlocks(1); let results = [] - for (let i = 0; i < 20; ++i) { + for (let i = 0; i < 10; ++i) { let resultRegister = (await (await deployedSSVNetworkContract.registerValidator( validatorPK + i % 10, [1,2,3,4], @@ -274,7 +274,7 @@ describe("Validators", () => { console.log("register ---->", outputRegister.validatorPK, outputRegister.groupId); console.log("operatorIdsAfterRegister ---->", await deployedSSVNetworkContract.test_getOperatorsByGroupId(outputRegister.groupId)); - + const resultUpdate = (await (await deployedSSVNetworkContract.updateValidator( [2,3,4,5], validatorPK, From c37fa618c54ce131f94a9b7758f1043ca9336e0e Mon Sep 17 00:00:00 2001 From: AndrewBlox Date: Mon, 12 Sep 2022 19:34:22 +0300 Subject: [PATCH 062/149] adding validator testing --- test/validators/register.ts | 184 +++++++++++++++++++++++++++--------- test/validators/remove.ts | 90 +++++++++++------- test/validators/transfer.ts | 129 ++++++++++++++++++------- 3 files changed, 293 insertions(+), 110 deletions(-) diff --git a/test/validators/register.ts b/test/validators/register.ts index 1eba0b71..3471efa2 100644 --- a/test/validators/register.ts +++ b/test/validators/register.ts @@ -1,53 +1,145 @@ -declare const ethers: any; - import * as helpers from '../helpers/contract-helpers'; import { expect } from 'chai'; -import { trackGas, GasGroup } from '../helpers/gas-usage'; +import { GasGroup } from '../helpers/gas-usage'; -let ssvNetworkContract: any; +let ssvNetworkContract: any, podResult: any; describe('Register Validator Tests', () => { - beforeEach(async () => { - ssvNetworkContract = (await helpers.initializeContract()).contract; - await helpers.registerOperators(0, 1, '10'); - await helpers.registerOperators(1, 1, '10'); - await helpers.registerOperators(2, 1, '10'); - await helpers.registerOperators(3, 1, '10'); - - await helpers.deposit([0], ['100000']); - await helpers.deposit([1], ['100000']); - }); - - it('Register validator emits ValidatorAdded event', async () => { - await expect(ssvNetworkContract.registerValidator( - helpers.DataGenerator.publicKey(0), - helpers.DataGenerator.pod.new(), - helpers.DataGenerator.shares(0), - '10000' - )).to.emit(ssvNetworkContract, 'ValidatorAdded'); - }); - - it('Register one validator in empty pod with gas track', async () => { - await helpers.registerValidators(0, 1, '10000', helpers.DataGenerator.pod.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); - }); - - it('Register two validators in existed pod with gas track', async () => { - const result = await helpers.registerValidators(0, 1, '10000', helpers.DataGenerator.pod.new()); - await helpers.registerValidators(0, 1, '10000', helpers.DataGenerator.pod.byId(result.podId), [GasGroup.REGISTER_VALIDATOR_EXISTED_POD]); - }); - - it('Register two validators in existed cluster with gas track', async () => { - const result = await helpers.registerValidators(0, 1, '10000', helpers.DataGenerator.pod.new()); - await helpers.registerValidators(1, 1, '10000', helpers.DataGenerator.pod.byId(result.podId), [GasGroup.REGISTER_VALIDATOR_EXISTED_CLUSTER]); - }); - - it('Fails to register with invalid operator list size', async () => { - await expect(ssvNetworkContract.registerValidator( - helpers.DataGenerator.publicKey(0), - [1, 2], - helpers.DataGenerator.shares(0), - '10000' - )).to.be.revertedWith('OessDataStructureInvalid'); - }); + beforeEach(async () => { + // Initialize contract + ssvNetworkContract = (await helpers.initializeContract()).contract; + + // Register operators + await helpers.registerOperators(0, 1, '10'); + await helpers.registerOperators(1, 1, '10'); + await helpers.registerOperators(2, 1, '10'); + await helpers.registerOperators(3, 8, '10'); + + // Deposit into accounts + await helpers.deposit([0], ['100000']); + await helpers.deposit([1], ['100000']); + + // Register a validator + podResult = await helpers.registerValidators(0, 1, '10000', helpers.DataGenerator.pod.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + }); + + it('Register validator emits ValidatorAdded event', async () => { + await expect(ssvNetworkContract.registerValidator( + helpers.DataGenerator.publicKey(0), + helpers.DataGenerator.pod.new(), + helpers.DataGenerator.shares(0), + '10000' + )).to.emit(ssvNetworkContract, 'ValidatorAdded'); + }); + + it('Register one validator into an empty pod', async () => { + await helpers.registerValidators(0, 1, '10000', helpers.DataGenerator.pod.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + }); + + it('Register two validators into an existing pod', async () => { + await helpers.registerValidators(0, 1, '10000', helpers.DataGenerator.pod.byId(podResult.podId), [GasGroup.REGISTER_VALIDATOR_EXISTED_POD]); + }); + + it('Register two validators into an existing cluster', async () => { + await helpers.registerValidators(1, 1, '10000', helpers.DataGenerator.pod.byId(podResult.podId), [GasGroup.REGISTER_VALIDATOR_EXISTED_CLUSTER]); + }); + + it('Invalid operator amount', async () => { + // 2 Operators + await expect(ssvNetworkContract.registerValidator( + helpers.DataGenerator.publicKey(0), + [1, 2], + helpers.DataGenerator.shares(0), + '10000' + )).to.be.revertedWith('OessDataStructureInvalid'); + + // 6 Operators + await expect(ssvNetworkContract.registerValidator( + helpers.DataGenerator.publicKey(0), + [1, 2, 3, 4, 5, 6], + helpers.DataGenerator.shares(0), + '10000' + )).to.be.revertedWith('OessDataStructureInvalid'); + }); + + it('Invalid public key length', async () => { + await expect(ssvNetworkContract.registerValidator( + helpers.DataGenerator.shares(0), + [1, 2, 3, 4], + helpers.DataGenerator.shares(0), + '10000' + )).to.be.revertedWith('InvalidPublicKeyLength'); + }); + + it('Not enough amount', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( + helpers.DataGenerator.publicKey(0), + [1, 2, 3, 4], + helpers.DataGenerator.shares(0), + '1' + )).to.be.revertedWith('account liquidatable'); + }); + + // GAS AMOUNT IS ABOVE EXPECTED + it('Register with 7 operators', async () => { + await helpers.registerValidators(0, 1, '10000', helpers.DataGenerator.pod.new(7), [GasGroup.REGISTER_VALIDATOR_EXISTED_POD]); + }); + + // THIS NEEDS VALIDITY + it('Non existent operator', async () => { + await expect(ssvNetworkContract.registerValidator( + helpers.DataGenerator.publicKey(0), + [1, 2, 3, 25], + helpers.DataGenerator.shares(0), + '4000' + )).to.be.revertedWith('OperatorDoesntExist'); + }); + + // THIS NEEDS VALIDITY + it('Register with existing validator', async () => { + // Register a validator + await ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( + helpers.DataGenerator.publicKey(0), + helpers.DataGenerator.pod.new(), + helpers.DataGenerator.shares(0), + '4000' + ) + + // Register the same validator again + await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( + helpers.DataGenerator.publicKey(0), + [1, 2, 3, 25], + helpers.DataGenerator.shares(0), + '4000' + )).to.be.revertedWith('ValidatorExistsAlready'); + }); + + // THIS NEEDS SOME PROPER ERROR MESSAGE + it('Not enough deposited', async () => { + await expect(ssvNetworkContract.registerValidator( + helpers.DataGenerator.publicKey(0), + [1, 2, 3, 4], + helpers.DataGenerator.shares(0), + '100001' + )).to.be.revertedWith('NotEnoughDeposited'); + }); + + // MAYBE WE WILL ADD SOME VALIDITY HERE? + // it('Invalid share', async () => { + // await expect(ssvNetworkContract.registerValidator( + // helpers.DataGenerator.publicKey(0), + // [1, 2, 3, 4], + // helpers.DataGenerator.publicKey(0), + // '10000' + // )).to.be.revertedWith('InvalidShareLength'); + // }); }); + + + + + + + + diff --git a/test/validators/remove.ts b/test/validators/remove.ts index ae5faed9..96a24f45 100644 --- a/test/validators/remove.ts +++ b/test/validators/remove.ts @@ -1,39 +1,65 @@ -declare const ethers: any; - import * as helpers from '../helpers/contract-helpers'; import { expect } from 'chai'; import { trackGas, GasGroup } from '../helpers/gas-usage'; - -let ssvNetworkContract: any; +let ssvNetworkContract: any, podResult: any; describe('Remove Validator Tests', () => { - beforeEach(async () => { - ssvNetworkContract = (await helpers.initializeContract()).contract; - await helpers.registerOperators(0, 1, '10'); - await helpers.registerOperators(1, 1, '10'); - await helpers.registerOperators(2, 1, '10'); - await helpers.registerOperators(3, 1, '10'); - - await helpers.deposit([4], ['100000']); - }); - - it('Remove validator emits ValidatorRemoved event', async () => { - const { validators } = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); - - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator( - validators[0].publicKey, - )).to.emit(ssvNetworkContract, 'ValidatorRemoved'); - }); - - it('Remove validator track gas', async () => { - const { validators } = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator(validators[0].publicKey), [GasGroup.REMOVE_VALIDATOR]); - }); - - it('Fails to remove validator with no owner', async () => { - const { validators } = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); - await expect(ssvNetworkContract.connect(helpers.DB.owners[3]).removeValidator(validators[0].publicKey)).to.be.revertedWith('ValidatorNotOwned'); - }); -}); + beforeEach(async () => { + // Initialize contract + ssvNetworkContract = (await helpers.initializeContract()).contract; + + // Register operators + await helpers.registerOperators(0, 1, '10'); + await helpers.registerOperators(1, 1, '10'); + await helpers.registerOperators(2, 1, '10'); + await helpers.registerOperators(3, 1, '10'); + + // Deposit into accounts + await helpers.deposit([4], ['100000']); + + podResult = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + }); + + it('Remove validator emits ValidatorRemoved event', async () => { + // Remove validator + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator( + podResult.validators[0].publicKey, + )).to.emit(ssvNetworkContract, 'ValidatorRemoved'); + }); + + it('Remove validator', async () => { + // Remove validator + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator(podResult.validators[0].publicKey), [GasGroup.REMOVE_VALIDATOR]); + }); + + it('Fail to remove validator with an invalid owner', async () => { + // Remove validator + await expect(ssvNetworkContract.connect(helpers.DB.owners[3]).removeValidator(podResult.validators[0].publicKey)).to.be.revertedWith('ValidatorNotOwned'); + }); + + // THIS SHOULD PASS + it('Try to remove validator twice', async () => { + // Remove validator + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator(podResult.validators[0].publicKey), [GasGroup.REMOVE_VALIDATOR]); + + // Remove validator again + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator(podResult.validators[0].publicKey)).to.be.revertedWith('ValidatorNotOwned'); + }); + + // UPDATE ONCE LIQUIDATE FUNCTION IS IMPLEMENTED + // it('Remove validator from a liquidated pod', async () => { + // // Register validator + // const { validators } = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); + + // // Liquidate pod + // // Progress blocks to liquidatable state + // // Liquidate pod + + // // Remove validator + // await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator( + // validators[0].publicKey, + // )).to.emit(ssvNetworkContract, 'ValidatorRemoved'); + // }); +}); \ No newline at end of file diff --git a/test/validators/transfer.ts b/test/validators/transfer.ts index 3c8c3eb4..01b5351b 100644 --- a/test/validators/transfer.ts +++ b/test/validators/transfer.ts @@ -1,15 +1,16 @@ -declare const ethers: any; - import * as helpers from '../helpers/contract-helpers'; import { expect } from 'chai'; import { trackGas, GasGroup } from '../helpers/gas-usage'; -let ssvNetworkContract: any; +let ssvNetworkContract: any, podResult1: any, podResult2: any; describe('Transfer Validator Tests', () => { beforeEach(async () => { + // Initialize contract ssvNetworkContract = (await helpers.initializeContract()).contract; + + // Register operators await helpers.registerOperators(0, 1, '10'); await helpers.registerOperators(1, 1, '10'); await helpers.registerOperators(2, 1, '10'); @@ -17,70 +18,134 @@ describe('Transfer Validator Tests', () => { await helpers.registerOperators(4, 1, '10'); await helpers.registerOperators(5, 1, '10'); await helpers.registerOperators(6, 1, '10'); - await helpers.registerOperators(7, 1, '10'); + await helpers.registerOperators(7, 5, '10'); + // Deposit into accounts await helpers.deposit([4], ['100000']); await helpers.deposit([5], ['100000']); + + // Register validators + podResult1 = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + podResult2 = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); }); it('Transfer validator emits ValidatorTransferred event', async () => { - const { validators } = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( - validators[0].publicKey, + podResult1.validators[0].publicKey, helpers.DataGenerator.pod.new(), helpers.DataGenerator.shares(helpers.DB.validators.length), '10000' )).to.emit(ssvNetworkContract, 'ValidatorTransferred'); }); - it('Transfer validator into new pod track gas', async () => { - const { validators, podId } = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); - + it('Transfer validator into a new pod', async () => { const transferedValidator = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( - validators[0].publicKey, + podResult1.validators[0].publicKey, helpers.DataGenerator.pod.new(), helpers.DataGenerator.shares(helpers.DB.validators.length), '10000' ), [GasGroup.TRANSFER_VALIDATOR_NEW_POD]); - expect(podId).not.equals(transferedValidator.eventsByName.ValidatorTransferred[0].args.podId); + expect(podResult1.podId).not.equals(transferedValidator.eventsByName.ValidatorTransferred[0].args.podId); }); - it('Transfer validator to existed pod track gas', async () => { - const validator1 = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); - const { podId } = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); + it('Transfer validator to an existing pod', async () => { const transfredValidator1 = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( - validator1.validators[0].publicKey, - helpers.DataGenerator.pod.byId(podId), + podResult1.validators[0].publicKey, + helpers.DataGenerator.pod.byId(podResult2.podId), helpers.DataGenerator.shares(helpers.DB.validators.length), '10000' ), [GasGroup.TRANSFER_VALIDATOR_EXISTED_POD]); - - expect(podId).equals(transfredValidator1.eventsByName.ValidatorTransferred[0].args.podId); + expect(podResult2.podId).equals(transfredValidator1.eventsByName.ValidatorTransferred[0].args.podId); }); - it('Transfer validator to existed cluster track gas', async () => { - const validator1 = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); - const { podId } = await helpers.registerValidators(5, 1, '10000', helpers.DataGenerator.pod.new()); + it('Transfer validator to an existing cluster with gas tracking', async () => { const transfredValidator1 = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( - validator1.validators[0].publicKey, - helpers.DataGenerator.pod.byId(podId), + podResult1.validators[0].publicKey, + helpers.DataGenerator.pod.byId(podResult2.podId), helpers.DataGenerator.shares(helpers.DB.validators.length), '10000' ), [GasGroup.TRANSFER_VALIDATOR_EXISTED_CLUSTER]); - - expect(podId).equals(transfredValidator1.eventsByName.ValidatorTransferred[0].args.podId); + expect(podResult2.podId).equals(transfredValidator1.eventsByName.ValidatorTransferred[0].args.podId); }); - it('Fails to transfer validator with no owner', async () => { - const validator1 = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); - const { podId } = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); + it('Transfer validator with an invalid owner', async () => { + // Transfer validator with an invalid owner await expect(ssvNetworkContract.connect(helpers.DB.owners[5]).transferValidator( - validator1.validators[0].publicKey, - helpers.DataGenerator.pod.byId(podId), + podResult1.validators[0].publicKey, + helpers.DataGenerator.pod.byId(podResult2.podId), helpers.DataGenerator.shares(helpers.DB.validators.length), '10000' )).to.be.revertedWith('ValidatorNotOwned'); + + // Transfer validator with an invalid public key + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( + helpers.DataGenerator.shares(0), + helpers.DataGenerator.pod.byId(podResult2.podId), + helpers.DataGenerator.shares(helpers.DB.validators.length), + '10000' + )).to.be.revertedWith('ValidatorNotOwned'); + }); + + it('Transfer validator to a pod with 7 operators', async () => { + // Register validator with 7 operators + const { podId } = await helpers.registerValidators(4, 1, '10000', [1, 2, 3, 4, 5, 6, 7]); + + // Transfer validator to an existing pod + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( + podResult1.validators[0].publicKey, + helpers.DataGenerator.pod.byId(podId), + helpers.DataGenerator.shares(helpers.DB.validators.length), + '10000' + )).to.emit(ssvNetworkContract, 'ValidatorTransferred'); + }); + + // THIS NEEDS SOME PROPER ERROR MESSAGE + it('Transfer validator with not enough amount', async () => { + // Register validator + const { podId } = await helpers.registerValidators(4, 1, '10000', [1, 2, 3, 9]); + + // Increase operator fee + await ssvNetworkContract.connect(helpers.DB.owners[7]).updateOperatorFee(9, '100000') + + // Transfer to pod with not enough amount + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( + podResult1.validators[0].publicKey, + helpers.DataGenerator.pod.byId(podId), + helpers.DataGenerator.shares(helpers.DB.validators.length), + '1' + )).to.be.revertedWith('account liquidatable'); }); -}); + + // THIS NEEDS SOME PROPER ERROR MESSAGE + it('Transfer validator with an invalid pod', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( + podResult1.validators[0].publicKey, + podResult2.validators[0].publicKey, + helpers.DataGenerator.shares(helpers.DB.validators.length), + '10000' + )).to.be.revertedWith('InvalidPod'); + }); + + // THIS NEEDS SOME PROPER ERROR MESSAGE + it('Transfer validator with not enough balance', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( + podResult1.validators[0].publicKey, + helpers.DataGenerator.pod.byId(podResult2.podId), + helpers.DataGenerator.shares(helpers.DB.validators.length), + '100001' + )).to.be.revertedWith('NotEnoughBalance'); + }); + + // MAYBE WE WILL ADD SOME VALIDITY HERE? + // it('Transfer validator with an invalid share', async () => { + // await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); + // const { podId } = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); + // await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( + // helpers.DataGenerator.publicKey(0), + // helpers.DataGenerator.pod.byId(podId), + // helpers.DataGenerator.shares(helpers.DB.validators.length), + // '10000' + // )).to.be.revertedWith('InvalidShares'); + // }); +}); \ No newline at end of file From 4237af6b6774d1b03390b59741a9e7ebe532e7da Mon Sep 17 00:00:00 2001 From: AndrewBlox Date: Tue, 13 Sep 2022 13:12:28 +0300 Subject: [PATCH 063/149] update validator tests --- contracts/ISSVNetwork.sol | 4 +++- contracts/SSVNetwork.sol | 6 ++++++ contracts/mocks/SSVTokenMock.sol | 22 ++++++++++++++++++++++ test/validators/register.ts | 23 +++++++---------------- 4 files changed, 38 insertions(+), 17 deletions(-) create mode 100644 contracts/mocks/SSVTokenMock.sol diff --git a/contracts/ISSVNetwork.sol b/contracts/ISSVNetwork.sol index dfc09794..69b56862 100644 --- a/contracts/ISSVNetwork.sol +++ b/contracts/ISSVNetwork.sol @@ -78,7 +78,9 @@ interface ISSVNetwork { /** errors */ error FeeTooLow(); error CallerNotOwner(); - + error OperatorDoesntExist(); + error NotEnoughDeposited(); + error ValidatorAlreadyExists(); diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index 11b1e597..6f632481 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -134,6 +134,9 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { { for (uint64 i = 0; i < operatorIds.length; ++i) { Operator memory operator = _operators[operatorIds[i]]; + if (!(operator.snapshot.block > 0)) { + revert OperatorDoesntExist(); + } operator.snapshot = _getSnapshot(operator, uint64(block.number)); ++operator.validatorCount; _operators[operatorIds[i]] = operator; @@ -152,6 +155,9 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _pods[keccak256(abi.encodePacked(msg.sender, clusterId))] = pod; } + if (_validatorPKs[keccak256(publicKey)].clusterId > 0) { + revert ValidatorAlreadyExists(); + } _validatorPKs[keccak256(publicKey)] = Validator({ owner: msg.sender, clusterId: clusterId, active: true}); emit ValidatorAdded(publicKey, clusterId, shares); diff --git a/contracts/mocks/SSVTokenMock.sol b/contracts/mocks/SSVTokenMock.sol new file mode 100644 index 00000000..c9044eed --- /dev/null +++ b/contracts/mocks/SSVTokenMock.sol @@ -0,0 +1,22 @@ +//SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.13; +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 + */ + function mint(address to, uint256 amount) external onlyOwner { + _mint(to, amount); + } +} \ No newline at end of file diff --git a/test/validators/register.ts b/test/validators/register.ts index 3471efa2..26c77a98 100644 --- a/test/validators/register.ts +++ b/test/validators/register.ts @@ -26,7 +26,7 @@ describe('Register Validator Tests', () => { it('Register validator emits ValidatorAdded event', async () => { await expect(ssvNetworkContract.registerValidator( - helpers.DataGenerator.publicKey(0), + helpers.DataGenerator.publicKey(1), helpers.DataGenerator.pod.new(), helpers.DataGenerator.shares(0), '10000' @@ -86,7 +86,7 @@ describe('Register Validator Tests', () => { await helpers.registerValidators(0, 1, '10000', helpers.DataGenerator.pod.new(7), [GasGroup.REGISTER_VALIDATOR_EXISTED_POD]); }); - // THIS NEEDS VALIDITY + // THIS NEEDS VALIDITY (I ADDED IN SOLIDITY CODE) it('Non existent operator', async () => { await expect(ssvNetworkContract.registerValidator( helpers.DataGenerator.publicKey(0), @@ -96,32 +96,23 @@ describe('Register Validator Tests', () => { )).to.be.revertedWith('OperatorDoesntExist'); }); - // THIS NEEDS VALIDITY + // THIS NEEDS VALIDITY (I ADDED IN SOLIDITY CODE) it('Register with existing validator', async () => { - // Register a validator - await ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(0), - helpers.DataGenerator.pod.new(), - helpers.DataGenerator.shares(0), - '4000' - ) - - // Register the same validator again await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( helpers.DataGenerator.publicKey(0), - [1, 2, 3, 25], + [1, 2, 3, 4], helpers.DataGenerator.shares(0), '4000' - )).to.be.revertedWith('ValidatorExistsAlready'); + )).to.be.revertedWith('ValidatorAlreadyExists'); }); - // THIS NEEDS SOME PROPER ERROR MESSAGE + // THIS NEEDS SOME PROPER ERROR MESSAGE (COULDNT GET ERROR MESSAGE TO WORK HERE WHEN I ADDED LOGIC IN SOLIDITY) it('Not enough deposited', async () => { await expect(ssvNetworkContract.registerValidator( helpers.DataGenerator.publicKey(0), [1, 2, 3, 4], helpers.DataGenerator.shares(0), - '100001' + '100005' )).to.be.revertedWith('NotEnoughDeposited'); }); From 6a1e50cdd6020a1a4e50fe8cd45f597b3c4c8e84 Mon Sep 17 00:00:00 2001 From: AndrewBlox Date: Tue, 13 Sep 2022 14:29:38 +0300 Subject: [PATCH 064/149] Update solidity code --- contracts/SSVNetwork.sol | 43 +++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index 6f632481..e5ae324a 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -126,10 +126,12 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { // Operator[] memory operators; bytes32 clusterId = _getOrCreateCluster(operatorIds); + bytes32 decodedValidator = keccak256(publicKey); + bytes32 decodedPod = keccak256(abi.encodePacked(msg.sender, clusterId)); { Pod memory pod; _availableBalances[msg.sender] -= amount; - pod = _updatePodData(clusterId, amount, true); + pod = _updatePodData(clusterId, amount, decodedPod, true); { for (uint64 i = 0; i < operatorIds.length; ++i) { @@ -152,13 +154,13 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { require(!_liquidatable(pod.balance, pod.validatorCount, operatorIds), "account liquidatable"); - _pods[keccak256(abi.encodePacked(msg.sender, clusterId))] = pod; + _pods[decodedPod] = pod; } - if (_validatorPKs[keccak256(publicKey)].clusterId > 0) { + if (_validatorPKs[decodedValidator].clusterId > 0) { revert ValidatorAlreadyExists(); } - _validatorPKs[keccak256(publicKey)] = Validator({ owner: msg.sender, clusterId: clusterId, active: true}); + _validatorPKs[decodedValidator] = Validator({ owner: msg.sender, clusterId: clusterId, active: true}); emit ValidatorAdded(publicKey, clusterId, shares); } @@ -169,15 +171,16 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { bytes calldata shares, uint64 amount ) external { - uint64 currentBlock = uint64(block.number); - bytes32 clusterId = _validatorPKs[keccak256(publicKey)].clusterId; + bytes32 decodedValidator = keccak256(publicKey); + bytes32 clusterId = _validatorPKs[decodedValidator].clusterId; + bytes32 decodedPod = keccak256(abi.encodePacked(msg.sender, clusterId)); - if (_validatorPKs[keccak256(publicKey)].owner != msg.sender) { + if (_validatorPKs[decodedValidator].owner != msg.sender) { revert ValidatorNotOwned(); } { - _pods[keccak256(abi.encodePacked(msg.sender, clusterId))] = _updatePodData(clusterId, 0, false); + _pods[decodedPod] = _updatePodData(clusterId, 0, decodedPod, false); // if (pod.validatorCount == 0) { // _availableBalances[msg.sender] += _ownerPodBalance(pod, podIndex); // pod.balance -= _ownerPodBalance(pod, podIndex); @@ -197,9 +200,10 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { Pod memory pod; { _availableBalances[msg.sender] -= amount; + bytes32 decodedPodNew = keccak256(abi.encodePacked(msg.sender, newClusterId)); - _pods[keccak256(abi.encodePacked(msg.sender, newClusterId))] = _updatePodData(newClusterId, amount, true); - _validatorPKs[keccak256(publicKey)].clusterId = newClusterId; + _pods[decodedPodNew] = _updatePodData(newClusterId, amount, decodedPodNew, true); + _validatorPKs[decodedValidator].clusterId = newClusterId; } { @@ -218,14 +222,16 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { function removeValidator( bytes calldata validatorPK ) external { - if (_validatorPKs[keccak256(validatorPK)].owner != msg.sender) { + bytes32 decodedValidator = keccak256(validatorPK); + if (_validatorPKs[decodedValidator].owner != msg.sender) { revert ValidatorNotOwned(); } - bytes32 clusterId = _validatorPKs[keccak256(validatorPK)].clusterId; + bytes32 clusterId = _validatorPKs[decodedValidator].clusterId; + bytes32 decodedPod = keccak256(abi.encodePacked(msg.sender, clusterId)); { - Pod memory pod = _pods[keccak256(abi.encodePacked(msg.sender, clusterId))]; + Pod memory pod = _pods[decodedPod]; Cluster memory cluster = _clusters[clusterId]; uint64 currentBlock = uint64(block.number); @@ -255,7 +261,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _dao = dao; } - _pods[keccak256(abi.encodePacked(msg.sender, clusterId))] = pod; + _pods[decodedPod] = pod; } emit ValidatorRemoved(validatorPK, clusterId); @@ -271,14 +277,15 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { uint64 activeValidatorCount = 0; for (uint64 index = 0; index < validatorPK.length; ++index) { - Validator memory validator = _validatorPKs[keccak256(validatorPK[index])]; + bytes32 decodedValidator = keccak256(validatorPK[index]); + Validator memory validator = _validatorPKs[decodedValidator]; if (validator.owner != msg.sender) { revert ValidatorNotOwned(); } validator.clusterId = toPodId; - _validatorPKs[keccak256(validatorPK[index])] = validator; + _validatorPKs[decodedValidator] = validator; if (validator.active) { ++activeValidatorCount; @@ -393,8 +400,8 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } } - function _updatePodData(bytes32 clusterId, uint64 amount, bool increase) private returns (Pod memory) { - Pod memory pod = _pods[keccak256(abi.encodePacked(msg.sender, clusterId))]; + function _updatePodData(bytes32 clusterId, uint64 amount, bytes32 decodedPod, bool increase) private returns (Pod memory) { + Pod memory pod = _pods[decodedPod]; uint64 podIndex = _clusterCurrentIndex(clusterId); pod.balance = _ownerPodBalance(pod, podIndex) + amount; pod.usage.index = podIndex; From a1969429b2bea919a8292d8159c98ae725e85980 Mon Sep 17 00:00:00 2001 From: AndrewBlox Date: Tue, 13 Sep 2022 16:02:40 +0300 Subject: [PATCH 065/149] add bulk transfer tests --- test/validators/register.ts | 5 +- test/validators/remove.ts | 5 +- test/validators/transfer-bulk.ts | 137 +++++++++++++++++++++++++++++++ test/validators/transfer.ts | 11 +-- 4 files changed, 141 insertions(+), 17 deletions(-) create mode 100644 test/validators/transfer-bulk.ts diff --git a/test/validators/register.ts b/test/validators/register.ts index 26c77a98..a0a280e8 100644 --- a/test/validators/register.ts +++ b/test/validators/register.ts @@ -11,10 +11,7 @@ describe('Register Validator Tests', () => { ssvNetworkContract = (await helpers.initializeContract()).contract; // Register operators - await helpers.registerOperators(0, 1, '10'); - await helpers.registerOperators(1, 1, '10'); - await helpers.registerOperators(2, 1, '10'); - await helpers.registerOperators(3, 8, '10'); + await helpers.registerOperators(0, 11, '10'); // Deposit into accounts await helpers.deposit([0], ['100000']); diff --git a/test/validators/remove.ts b/test/validators/remove.ts index 96a24f45..c3f29454 100644 --- a/test/validators/remove.ts +++ b/test/validators/remove.ts @@ -11,10 +11,7 @@ describe('Remove Validator Tests', () => { ssvNetworkContract = (await helpers.initializeContract()).contract; // Register operators - await helpers.registerOperators(0, 1, '10'); - await helpers.registerOperators(1, 1, '10'); - await helpers.registerOperators(2, 1, '10'); - await helpers.registerOperators(3, 1, '10'); + await helpers.registerOperators(0, 4, '10'); // Deposit into accounts await helpers.deposit([4], ['100000']); diff --git a/test/validators/transfer-bulk.ts b/test/validators/transfer-bulk.ts new file mode 100644 index 00000000..4eb5737d --- /dev/null +++ b/test/validators/transfer-bulk.ts @@ -0,0 +1,137 @@ +import * as helpers from '../helpers/contract-helpers'; + +import { expect } from 'chai'; +import { trackGas, GasGroup } from '../helpers/gas-usage'; + +let ssvNetworkContract: any, podResult1: any, podResult2: any, podResult3: any; + +describe('Bulk Transfer Validator Tests', () => { + beforeEach(async () => { + // Initialize contract + ssvNetworkContract = (await helpers.initializeContract()).contract; + + // Register operators + await helpers.registerOperators(0, 12, '10'); + + // Deposit into accounts + await helpers.deposit([4], ['1000000']); + await helpers.deposit([5], ['100000']); + + // Register validators + podResult1 = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + podResult2 = await helpers.registerValidators(4, 9, '10000', helpers.DataGenerator.pod.byId(podResult1.podId), [GasGroup.REGISTER_VALIDATOR_EXISTED_POD]); + podResult3 = await helpers.registerValidators(4, 1, '90000', helpers.DataGenerator.pod.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + }); + + it('Bulk transfer 10 validators emits BulkValidatorTransferred event', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( + [podResult1.validators[0].publicKey, ...podResult2.validators.map((validator: any) => validator.publicKey)], + podResult1.podId, + podResult3.podId, + Array(podResult2.validators.length).fill(helpers.DataGenerator.shares(0)) + )).to.emit(ssvNetworkContract, 'BulkValidatorTransferred'); + }); + + it('Bulk transfer validator with an invalid owner', async () => { + // Transfer validator with an invalid owner + await expect(ssvNetworkContract.connect(helpers.DB.owners[5]).bulkTransferValidators( + [podResult1.validators[0].publicKey, ...podResult2.validators.map((validator: any) => validator.publicKey)], + podResult1.podId, + podResult3.podId, + Array(podResult2.validators.length).fill(helpers.DataGenerator.shares(0)) + )).to.be.revertedWith('ValidatorNotOwned'); + + // Transfer validator with an unowned validator + const account5Pod = await helpers.registerValidators(5, 1, '10000', helpers.DataGenerator.pod.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( + [podResult1.validators[0].publicKey, account5Pod.validators[0].publicKey, ...podResult2.validators.map((validator: any) => validator.publicKey)], + podResult1.podId, + podResult3.podId, + Array(podResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)) + )).to.be.revertedWith('ValidatorNotOwned'); + + // Transfer with an invalid public key + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( + [podResult1.validators[0].publicKey, helpers.DataGenerator.shares(0), ...podResult2.validators.map((validator: any) => validator.publicKey)], + podResult1.podId, + podResult3.podId, + Array(podResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)) + )).to.be.revertedWith('ValidatorNotOwned'); + }); + + // NEED TO MAKE NEW GAS GROUP FOR BULK TRANSFER + it('Bulk transfer 10 validators', async () => { + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( + [podResult1.validators[0].publicKey, ...podResult2.validators.map((validator: any) => validator.publicKey)], + podResult1.podId, + podResult3.podId, + Array(podResult2.validators.length).fill(helpers.DataGenerator.shares(0)) + ), [GasGroup.TRANSFER_VALIDATOR_EXISTED_POD]); + }); + + // NEED TO MAKE NEW GAS GROUP FOR BULK TRANSFER + it('Bulk transfer 10 validators to a pod with 7 operators', async () => { + // Register validator with 7 operators + const { podId } = await helpers.registerValidators(4, 1, '90000', [1, 2, 3, 4, 5, 6, 7]); + + // Transfer validator to an existing pod + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( + [podResult1.validators[0].publicKey, ...podResult2.validators.map((validator: any) => validator.publicKey)], + podResult1.podId, + podId, + Array(podResult2.validators.length).fill(helpers.DataGenerator.shares(0)) + ), [GasGroup.TRANSFER_VALIDATOR_EXISTED_POD]); + }); + + // SHOULD GIVE ERROR OF MAYBE INVALID TO POD INSTEAD OF ACCOUNT LIQUIDATABLE + it('Bulk transfer 10 validators to a non owned pod', async () => { + // Register validator with 7 operators + const { podId } = await helpers.registerValidators(5, 1, '90000', helpers.DataGenerator.pod.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( + [podResult1.validators[0].publicKey, ...podResult2.validators.map((validator: any) => validator.publicKey)], + podResult1.podId, + podId, + Array(podResult2.validators.length).fill(helpers.DataGenerator.shares(0)) + )).to.be.revertedWith('InvalidPod'); + }); + + // SHOULD GIVE ERROR OF MAYBE INVALID FROM POD + it('Bulk transfer 10 validators to an invalid pod', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( + [podResult1.validators[0].publicKey, ...podResult2.validators.map((validator: any) => validator.publicKey)], + podResult1.podId.slice(0, -1) + 'a', + podResult1.podId, + Array(podResult2.validators.length).fill(helpers.DataGenerator.shares(0)) + )).to.be.revertedWith('InvalidPod'); + }); + + // SHOULD GIVE ERROR OF MAYBE VALIDATOR SHARE MISMATCH + it('Validator and share length mismatch', async () => { + // 10 validators and 11 shares + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( + [podResult1.validators[0].publicKey, ...podResult2.validators.map((validator: any) => validator.publicKey)], + podResult1.podId, + podResult3.podId, + Array(podResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)) + )).to.be.revertedWith('ValidatorShareMismatch'); + + // 9 validators and 10 shares + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( + podResult2.validators.map((validator: any) => validator.publicKey), + podResult1.podId, + podResult3.podId, + Array(podResult2.validators.length).fill(helpers.DataGenerator.shares(0)) + )).to.be.revertedWith('ValidatorShareMismatch'); + }); + + // // NEED TO IMPLEMENT AN AMOUNT + // it('Transfer validator with not enough amount', async () => { + + // }); + + // // NEED TO IMPLEMENT AN AMOUNT + // it('Transfer validator with not enough balance', async () => { + + // }); +}); \ No newline at end of file diff --git a/test/validators/transfer.ts b/test/validators/transfer.ts index 01b5351b..f3d517ef 100644 --- a/test/validators/transfer.ts +++ b/test/validators/transfer.ts @@ -11,14 +11,7 @@ describe('Transfer Validator Tests', () => { ssvNetworkContract = (await helpers.initializeContract()).contract; // Register operators - await helpers.registerOperators(0, 1, '10'); - await helpers.registerOperators(1, 1, '10'); - await helpers.registerOperators(2, 1, '10'); - await helpers.registerOperators(3, 1, '10'); - await helpers.registerOperators(4, 1, '10'); - await helpers.registerOperators(5, 1, '10'); - await helpers.registerOperators(6, 1, '10'); - await helpers.registerOperators(7, 5, '10'); + await helpers.registerOperators(0, 12, '10'); // Deposit into accounts await helpers.deposit([4], ['100000']); @@ -59,7 +52,7 @@ describe('Transfer Validator Tests', () => { expect(podResult2.podId).equals(transfredValidator1.eventsByName.ValidatorTransferred[0].args.podId); }); - it('Transfer validator to an existing cluster with gas tracking', async () => { + it('Transfer validator to an existing cluster', async () => { const transfredValidator1 = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( podResult1.validators[0].publicKey, helpers.DataGenerator.pod.byId(podResult2.podId), From 5aa17200f7ba92a9158e9d6d46864f096565e19a Mon Sep 17 00:00:00 2001 From: AndrewBlox Date: Wed, 14 Sep 2022 12:48:13 +0300 Subject: [PATCH 066/149] update remove testing --- test/validators/remove.ts | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/test/validators/remove.ts b/test/validators/remove.ts index c3f29454..6a0dc771 100644 --- a/test/validators/remove.ts +++ b/test/validators/remove.ts @@ -16,28 +16,26 @@ describe('Remove Validator Tests', () => { // Deposit into accounts await helpers.deposit([4], ['100000']); + // Register a validator podResult = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); }); it('Remove validator emits ValidatorRemoved event', async () => { - // Remove validator await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator( podResult.validators[0].publicKey, )).to.emit(ssvNetworkContract, 'ValidatorRemoved'); }); it('Remove validator', async () => { - // Remove validator await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator(podResult.validators[0].publicKey), [GasGroup.REMOVE_VALIDATOR]); }); - it('Fail to remove validator with an invalid owner', async () => { - // Remove validator + it('Remove validator with an invalid owner', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[3]).removeValidator(podResult.validators[0].publicKey)).to.be.revertedWith('ValidatorNotOwned'); }); // THIS SHOULD PASS - it('Try to remove validator twice', async () => { + it('Remove validator twice', async () => { // Remove validator await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator(podResult.validators[0].publicKey), [GasGroup.REMOVE_VALIDATOR]); @@ -45,6 +43,23 @@ describe('Remove Validator Tests', () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator(podResult.validators[0].publicKey)).to.be.revertedWith('ValidatorNotOwned'); }); + // THIS SHOULD PASS + it('Register / remove validator twice', async () => { + // Remove validator + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator(podResult.validators[0].publicKey), [GasGroup.REMOVE_VALIDATOR]); + + // Re-register validator + await ssvNetworkContract.connect(helpers.DB.owners[4]).registerValidator( + helpers.DataGenerator.publicKey(0), + [1, 2, 3, 4], + helpers.DataGenerator.shares(0), + '1000' + ); + + // Remove the validator again + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator(helpers.DataGenerator.publicKey(0)), [GasGroup.REMOVE_VALIDATOR]); + }); + // UPDATE ONCE LIQUIDATE FUNCTION IS IMPLEMENTED // it('Remove validator from a liquidated pod', async () => { // // Register validator From 1748cf57fa7fc5de9f9066497311b309e319014b Mon Sep 17 00:00:00 2001 From: Adam Zigdon Date: Wed, 14 Sep 2022 14:06:38 +0300 Subject: [PATCH 067/149] some changes --- contracts/ISSVNetwork.sol | 7 +- contracts/SSVNetwork.sol | 107 ++++++++++++++++--------------- test/validators/register.ts | 4 +- test/validators/transfer-bulk.ts | 4 +- 4 files changed, 62 insertions(+), 60 deletions(-) diff --git a/contracts/ISSVNetwork.sol b/contracts/ISSVNetwork.sol index 69b56862..4c6905dc 100644 --- a/contracts/ISSVNetwork.sol +++ b/contracts/ISSVNetwork.sol @@ -79,14 +79,13 @@ interface ISSVNetwork { error FeeTooLow(); error CallerNotOwner(); error OperatorDoesntExist(); - error NotEnoughDeposited(); + error NotEnoughBalance(); error ValidatorAlreadyExists(); - - - + error AccountLiquidatable(); error InvalidPublicKeyLength(); error OessDataStructureInvalid(); error ValidatorNotOwned(); + error InvalidCluster(); /** errors */ // error validatorWithPublicKeyNotExist(); diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index e5ae324a..f9ffc9f4 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -53,8 +53,6 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { bool active; } - - // global vars Counters.Counter private lastOperatorId; Counters.Counter private lastPodId; @@ -126,12 +124,17 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { // Operator[] memory operators; bytes32 clusterId = _getOrCreateCluster(operatorIds); - bytes32 decodedValidator = keccak256(publicKey); - bytes32 decodedPod = keccak256(abi.encodePacked(msg.sender, clusterId)); + bytes32 hashedValidator = keccak256(publicKey); + bytes32 hashedPod = keccak256(abi.encodePacked(msg.sender, clusterId)); { Pod memory pod; + + if (_availableBalances[msg.sender] < amount) { + revert NotEnoughBalance(); + } + _availableBalances[msg.sender] -= amount; - pod = _updatePodData(clusterId, amount, decodedPod, true); + pod = _updatePodData(clusterId, amount, hashedPod, true); { for (uint64 i = 0; i < operatorIds.length; ++i) { @@ -152,15 +155,17 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _dao = dao; } - require(!_liquidatable(pod.balance, pod.validatorCount, operatorIds), "account liquidatable"); + if (_liquidatable(pod.balance, pod.validatorCount, operatorIds)) { + revert AccountLiquidatable(); + } - _pods[decodedPod] = pod; + _pods[hashedPod] = pod; } - if (_validatorPKs[decodedValidator].clusterId > 0) { + if (_validatorPKs[hashedValidator].clusterId > 0) { revert ValidatorAlreadyExists(); } - _validatorPKs[decodedValidator] = Validator({ owner: msg.sender, clusterId: clusterId, active: true}); + _validatorPKs[hashedValidator] = Validator({ owner: msg.sender, clusterId: clusterId, active: true}); emit ValidatorAdded(publicKey, clusterId, shares); } @@ -171,16 +176,16 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { bytes calldata shares, uint64 amount ) external { - bytes32 decodedValidator = keccak256(publicKey); - bytes32 clusterId = _validatorPKs[decodedValidator].clusterId; - bytes32 decodedPod = keccak256(abi.encodePacked(msg.sender, clusterId)); + bytes32 hashedValidator = keccak256(publicKey); + bytes32 clusterId = _validatorPKs[hashedValidator].clusterId; + bytes32 hashedPod = keccak256(abi.encodePacked(msg.sender, clusterId)); - if (_validatorPKs[decodedValidator].owner != msg.sender) { + if (_validatorPKs[hashedValidator].owner != msg.sender) { revert ValidatorNotOwned(); } { - _pods[decodedPod] = _updatePodData(clusterId, 0, decodedPod, false); + _pods[hashedPod] = _updatePodData(clusterId, 0, hashedPod, false); // if (pod.validatorCount == 0) { // _availableBalances[msg.sender] += _ownerPodBalance(pod, podIndex); // pod.balance -= _ownerPodBalance(pod, podIndex); @@ -200,10 +205,10 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { Pod memory pod; { _availableBalances[msg.sender] -= amount; - bytes32 decodedPodNew = keccak256(abi.encodePacked(msg.sender, newClusterId)); + bytes32 hashedPodNew = keccak256(abi.encodePacked(msg.sender, newClusterId)); - _pods[decodedPodNew] = _updatePodData(newClusterId, amount, decodedPodNew, true); - _validatorPKs[decodedValidator].clusterId = newClusterId; + _pods[hashedPodNew] = _updatePodData(newClusterId, amount, hashedPodNew, true); + _validatorPKs[hashedValidator].clusterId = newClusterId; } { @@ -222,16 +227,16 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { function removeValidator( bytes calldata validatorPK ) external { - bytes32 decodedValidator = keccak256(validatorPK); - if (_validatorPKs[decodedValidator].owner != msg.sender) { + bytes32 hashedValidator = keccak256(validatorPK); + if (_validatorPKs[hashedValidator].owner != msg.sender) { revert ValidatorNotOwned(); } - bytes32 clusterId = _validatorPKs[decodedValidator].clusterId; - bytes32 decodedPod = keccak256(abi.encodePacked(msg.sender, clusterId)); + bytes32 clusterId = _validatorPKs[hashedValidator].clusterId; + bytes32 hashedPod = keccak256(abi.encodePacked(msg.sender, clusterId)); { - Pod memory pod = _pods[decodedPod]; + Pod memory pod = _pods[hashedPod]; Cluster memory cluster = _clusters[clusterId]; uint64 currentBlock = uint64(block.number); @@ -261,50 +266,57 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _dao = dao; } - _pods[decodedPod] = pod; + _pods[hashedPod] = pod; } + delete _validatorPKs[hashedValidator]; + emit ValidatorRemoved(validatorPK, clusterId); } function bulkTransferValidators( bytes[] calldata validatorPK, - bytes32 fromPodId, - bytes32 toPodId, + bytes32 fromClusterId, + bytes32 toClusterId, bytes[] calldata shares ) external { // _validateValidatorParams uint64 activeValidatorCount = 0; for (uint64 index = 0; index < validatorPK.length; ++index) { - bytes32 decodedValidator = keccak256(validatorPK[index]); - Validator memory validator = _validatorPKs[decodedValidator]; + bytes32 hashedValidator = keccak256(validatorPK[index]); + Validator memory validator = _validatorPKs[hashedValidator]; if (validator.owner != msg.sender) { revert ValidatorNotOwned(); } - validator.clusterId = toPodId; - _validatorPKs[decodedValidator] = validator; + validator.clusterId = toClusterId; + _validatorPKs[hashedValidator] = validator; if (validator.active) { ++activeValidatorCount; } // Changing to a single event reducing by 15K gas } - emit BulkValidatorTransferred(validatorPK, toPodId, shares); + emit BulkValidatorTransferred(validatorPK, toClusterId, shares); - uint64[] memory newOperatorIds = _clusters[toPodId].operatorIds; + uint64[] memory oldOperatorIds = _clusters[fromClusterId].operatorIds; + uint64[] memory newOperatorIds = _clusters[toClusterId].operatorIds; - _updateOperatorsValidatorMove(_clusters[fromPodId].operatorIds, newOperatorIds, activeValidatorCount); + if (oldOperatorIds.length == 0 || newOperatorIds.length == 0) { + revert InvalidCluster(); + } + + _updateOperatorsValidatorMove(oldOperatorIds, newOperatorIds, activeValidatorCount); - Pod memory pod = _pods[keccak256(abi.encodePacked(msg.sender, fromPodId))]; - pod.usage.index = _clusterCurrentIndex(fromPodId); + Pod memory pod = _pods[keccak256(abi.encodePacked(msg.sender, fromClusterId))]; + pod.usage.index = _clusterCurrentIndex(fromClusterId); pod.usage.block = uint64(block.number); pod.validatorCount -= activeValidatorCount; - pod = _pods[keccak256(abi.encodePacked(msg.sender, toPodId))]; - pod.usage.index = _clusterCurrentIndex(toPodId); + pod = _pods[keccak256(abi.encodePacked(msg.sender, toClusterId))]; + pod.usage.index = _clusterCurrentIndex(toClusterId); pod.usage.block = uint64(block.number); pod.validatorCount += activeValidatorCount; @@ -323,8 +335,8 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { // @dev internal operators functions - function _getSnapshot(Operator memory operator, uint64 currentBlock) private view returns (Snapshot memory) { - uint64 blockDiffFee = (currentBlock - operator.snapshot.block)* operator.fee; + function _getSnapshot(Operator memory operator, uint64 currentBlock) private pure returns (Snapshot memory) { + uint64 blockDiffFee = (currentBlock - operator.snapshot.block) * operator.fee; operator.snapshot.index += blockDiffFee; operator.snapshot.balance += blockDiffFee * operator.validatorCount; @@ -379,7 +391,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } - function _setFee(Operator memory operator, uint64 fee) private returns (Operator memory) { + function _setFee(Operator memory operator, uint64 fee) private view returns (Operator memory) { operator.snapshot = _getSnapshot(operator, uint64(block.number)); operator.fee = fee; @@ -387,7 +399,6 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } function _updateOperatorsData(uint64[] memory operatorIds, bool increase) private { - uint64 currentBlock = uint64(block.number); for (uint64 i = 0; i < operatorIds.length; ++i) { Operator memory operator = _operators[operatorIds[i]]; operator.snapshot = _getSnapshot(operator, uint64(block.number)); @@ -400,8 +411,8 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } } - function _updatePodData(bytes32 clusterId, uint64 amount, bytes32 decodedPod, bool increase) private returns (Pod memory) { - Pod memory pod = _pods[decodedPod]; + function _updatePodData(bytes32 clusterId, uint64 amount, bytes32 hashedPod, bool increase) private view returns (Pod memory) { + Pod memory pod = _pods[hashedPod]; uint64 podIndex = _clusterCurrentIndex(clusterId); pod.balance = _ownerPodBalance(pod, podIndex) + amount; pod.usage.index = podIndex; @@ -448,14 +459,6 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _availableBalances[msg.sender] += amount; } - function _createCluster(uint64[] memory operators) private returns (uint64 podId) { - for (uint64 index = 0; index < operators.length; ++index) { - require(_operators[operators[index]].owner != address(0), "operator not found"); - } - - _clusters[keccak256(abi.encodePacked(operators))] = Cluster({ operatorIds: operators }); - } - function _getOrCreateCluster(uint64[] memory operatorIds) private returns (bytes32) { // , Cluster memory for (uint64 i = 0; i < operatorIds.length - 1;) { require(operatorIds[i] <= operatorIds[++i]); @@ -472,7 +475,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } - function _updateDAOEarnings(DAO memory dao) private returns (DAO memory) { + function _updateDAOEarnings(DAO memory dao) private view returns (DAO memory) { dao.earnings.balance = _networkTotalEarnings(dao); dao.earnings.block = uint64(block.number); @@ -505,7 +508,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } - function _ownerPodBalance(Pod memory pod, uint64 currentPodIndex) private view returns (uint64) { + function _ownerPodBalance(Pod memory pod, uint64 currentPodIndex) private pure returns (uint64) { return pod.balance - (currentPodIndex - pod.usage.index) * pod.validatorCount; } diff --git a/test/validators/register.ts b/test/validators/register.ts index a0a280e8..0f77b88d 100644 --- a/test/validators/register.ts +++ b/test/validators/register.ts @@ -104,13 +104,13 @@ describe('Register Validator Tests', () => { }); // THIS NEEDS SOME PROPER ERROR MESSAGE (COULDNT GET ERROR MESSAGE TO WORK HERE WHEN I ADDED LOGIC IN SOLIDITY) - it('Not enough deposited', async () => { + it('Not enough balance', async () => { await expect(ssvNetworkContract.registerValidator( helpers.DataGenerator.publicKey(0), [1, 2, 3, 4], helpers.DataGenerator.shares(0), '100005' - )).to.be.revertedWith('NotEnoughDeposited'); + )).to.be.revertedWith('NotEnoughBalance'); }); // MAYBE WE WILL ADD SOME VALIDITY HERE? diff --git a/test/validators/transfer-bulk.ts b/test/validators/transfer-bulk.ts index 4eb5737d..7a824768 100644 --- a/test/validators/transfer-bulk.ts +++ b/test/validators/transfer-bulk.ts @@ -93,7 +93,7 @@ describe('Bulk Transfer Validator Tests', () => { podResult1.podId, podId, Array(podResult2.validators.length).fill(helpers.DataGenerator.shares(0)) - )).to.be.revertedWith('InvalidPod'); + )).to.be.revertedWith('InvalidCluster'); }); // SHOULD GIVE ERROR OF MAYBE INVALID FROM POD @@ -103,7 +103,7 @@ describe('Bulk Transfer Validator Tests', () => { podResult1.podId.slice(0, -1) + 'a', podResult1.podId, Array(podResult2.validators.length).fill(helpers.DataGenerator.shares(0)) - )).to.be.revertedWith('InvalidPod'); + )).to.be.revertedWith('InvalidCluster'); }); // SHOULD GIVE ERROR OF MAYBE VALIDATOR SHARE MISMATCH From b2bdc9532b599073a2018532777f6e808812a877 Mon Sep 17 00:00:00 2001 From: AndrewBlox Date: Wed, 14 Sep 2022 15:01:04 +0300 Subject: [PATCH 068/149] update terminology --- contracts/ISSVNetwork.sol | 2 +- contracts/SSVNetwork.sol | 4 +- test/helpers/contract-helpers.ts | 22 +++---- test/helpers/gas-usage.ts | 20 +++--- test/validators/register.ts | 31 ++++----- test/validators/remove.ts | 26 ++++---- test/validators/transfer-bulk.ts | 110 +++++++++++++++---------------- test/validators/transfer.ts | 81 ++++++++++++----------- 8 files changed, 146 insertions(+), 150 deletions(-) diff --git a/contracts/ISSVNetwork.sol b/contracts/ISSVNetwork.sol index 4c6905dc..c7210195 100644 --- a/contracts/ISSVNetwork.sol +++ b/contracts/ISSVNetwork.sol @@ -78,7 +78,7 @@ interface ISSVNetwork { /** errors */ error FeeTooLow(); error CallerNotOwner(); - error OperatorDoesntExist(); + error OperatorDoesNotExist(); error NotEnoughBalance(); error ValidatorAlreadyExists(); error AccountLiquidatable(); diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index f9ffc9f4..286ad9aa 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -139,8 +139,8 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { { for (uint64 i = 0; i < operatorIds.length; ++i) { Operator memory operator = _operators[operatorIds[i]]; - if (!(operator.snapshot.block > 0)) { - revert OperatorDoesntExist(); + if (operator.owner == address(0)) { + revert OperatorDoesNotExist(); } operator.snapshot = _getSnapshot(operator, uint64(block.number)); ++operator.validatorCount; diff --git a/test/helpers/contract-helpers.ts b/test/helpers/contract-helpers.ts index 079aed2f..ba7850e6 100644 --- a/test/helpers/contract-helpers.ts +++ b/test/helpers/contract-helpers.ts @@ -8,11 +8,11 @@ export let DB: any; export const DataGenerator = { publicKey: (index: number) => `0x${index.toString(16).padStart(96,'1')}`, shares: (index: number) => `0x${index.toString(16).padStart(360,'1')}`, - pod: { + cluster: { new: (size = 4) => { const usedOperatorIds: any = {}; - for (const podId in DB.pods) { - for (const operatorId of DB.pods[podId].operatorIds) { + for (const clusterId in DB.clusters) { + for (const operatorId of DB.clusters[clusterId].operatorIds) { usedOperatorIds[operatorId] = true; } } @@ -29,12 +29,12 @@ export const DataGenerator = { } } if (result.length < size) { - throw new Error('No new pods. Try to register more operators.'); + throw new Error('No new clusters. Try to register more operators.'); } return result; }, - byId: (id: any) => DB.pods[id].operatorIds + byId: (id: any) => DB.clusters[id].operatorIds } }; @@ -43,7 +43,7 @@ export const initializeContract = async () => { owners: [], validators: [], operators: [], - pods: [], + clusters: [], ssvNetwork: {} }; // Define accounts @@ -80,7 +80,7 @@ export const deposit = async (ownerIds: number[], amounts: string[]) => { export const registerValidators = async (ownerId: number, numberOfValidators: number, amount: string, operatorIds: number[], gasGroups?: GasGroup[]) => { const validators: any = []; - let podId: any; + let clusterId: any; // Register validators to contract for (let i = 0; i < numberOfValidators; i++) { @@ -94,11 +94,11 @@ export const registerValidators = async (ownerId: number, numberOfValidators: nu amount, ), gasGroups); - podId = eventsByName.ValidatorAdded[0].args.podId; - DB.pods[podId] = ({ id: podId, operatorIds }); - DB.validators.push({ publicKey, podId, shares }); + clusterId = eventsByName.ValidatorAdded[0].args.clusterId; + DB.clusters[clusterId] = ({ id: clusterId, operatorIds }); + DB.validators.push({ publicKey, clusterId, shares }); validators.push({ publicKey, shares }); } - return { validators, podId }; + return { validators, clusterId }; }; diff --git a/test/helpers/gas-usage.ts b/test/helpers/gas-usage.ts index 0d019e3b..592da29d 100644 --- a/test/helpers/gas-usage.ts +++ b/test/helpers/gas-usage.ts @@ -3,25 +3,25 @@ import { expect } from 'chai'; export enum GasGroup { REGISTER_OPERATOR, REMOVE_OPERATOR, - REGISTER_VALIDATOR_EXISTED_POD, - REGISTER_VALIDATOR_EXISTED_CLUSTER, + REGISTER_VALIDATOR_EXISTING_POD, + REGISTER_VALIDATOR_EXISTING_CLUSTER, REGISTER_VALIDATOR_NEW_STATE, REMOVE_VALIDATOR, - TRANSFER_VALIDATOR_NEW_POD, - TRANSFER_VALIDATOR_EXISTED_POD, - TRANSFER_VALIDATOR_EXISTED_CLUSTER, + TRANSFER_VALIDATOR_NEW_CLUSTER, + TRANSFER_VALIDATOR, + TRANSFER_VALIDATOR_NON_EXISTING_POD, } const MAX_GAS_PER_GROUP: any = { [GasGroup.REGISTER_OPERATOR]: 100000, [GasGroup.REMOVE_OPERATOR]: 40000, - [GasGroup.REGISTER_VALIDATOR_EXISTED_POD]: 190000, - [GasGroup.REGISTER_VALIDATOR_EXISTED_CLUSTER]: 230000, + [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]: 190000, + [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]: 230000, [GasGroup.REGISTER_VALIDATOR_NEW_STATE]: 400000, [GasGroup.REMOVE_VALIDATOR]: 120000, - [GasGroup.TRANSFER_VALIDATOR_NEW_POD]: 400000, - [GasGroup.TRANSFER_VALIDATOR_EXISTED_POD]: 260000, - [GasGroup.TRANSFER_VALIDATOR_EXISTED_CLUSTER]: 290000, + [GasGroup.TRANSFER_VALIDATOR_NEW_CLUSTER]: 400000, + [GasGroup.TRANSFER_VALIDATOR]: 260000, + [GasGroup.TRANSFER_VALIDATOR_NON_EXISTING_POD]: 290000, }; class GasStats { diff --git a/test/validators/register.ts b/test/validators/register.ts index 0f77b88d..85308494 100644 --- a/test/validators/register.ts +++ b/test/validators/register.ts @@ -3,7 +3,7 @@ import * as helpers from '../helpers/contract-helpers'; import { expect } from 'chai'; import { GasGroup } from '../helpers/gas-usage'; -let ssvNetworkContract: any, podResult: any; +let ssvNetworkContract: any, clusterResult: any; describe('Register Validator Tests', () => { beforeEach(async () => { @@ -18,28 +18,28 @@ describe('Register Validator Tests', () => { await helpers.deposit([1], ['100000']); // Register a validator - podResult = await helpers.registerValidators(0, 1, '10000', helpers.DataGenerator.pod.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + clusterResult = await helpers.registerValidators(0, 1, '10000', helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); }); it('Register validator emits ValidatorAdded event', async () => { await expect(ssvNetworkContract.registerValidator( helpers.DataGenerator.publicKey(1), - helpers.DataGenerator.pod.new(), + helpers.DataGenerator.cluster.new(), helpers.DataGenerator.shares(0), '10000' )).to.emit(ssvNetworkContract, 'ValidatorAdded'); }); - it('Register one validator into an empty pod', async () => { - await helpers.registerValidators(0, 1, '10000', helpers.DataGenerator.pod.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + it('Register one validator into an empty cluster', async () => { + await helpers.registerValidators(0, 1, '10000', helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); }); - it('Register two validators into an existing pod', async () => { - await helpers.registerValidators(0, 1, '10000', helpers.DataGenerator.pod.byId(podResult.podId), [GasGroup.REGISTER_VALIDATOR_EXISTED_POD]); + it('Register two validators into an existing cluster', async () => { + await helpers.registerValidators(0, 1, '10000', helpers.DataGenerator.cluster.byId(clusterResult.clusterId), [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]); }); it('Register two validators into an existing cluster', async () => { - await helpers.registerValidators(1, 1, '10000', helpers.DataGenerator.pod.byId(podResult.podId), [GasGroup.REGISTER_VALIDATOR_EXISTED_CLUSTER]); + await helpers.registerValidators(1, 1, '10000', helpers.DataGenerator.cluster.byId(clusterResult.clusterId), [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]); }); it('Invalid operator amount', async () => { @@ -75,15 +75,9 @@ describe('Register Validator Tests', () => { [1, 2, 3, 4], helpers.DataGenerator.shares(0), '1' - )).to.be.revertedWith('account liquidatable'); - }); - - // GAS AMOUNT IS ABOVE EXPECTED - it('Register with 7 operators', async () => { - await helpers.registerValidators(0, 1, '10000', helpers.DataGenerator.pod.new(7), [GasGroup.REGISTER_VALIDATOR_EXISTED_POD]); + )).to.be.revertedWith('AccountLiquidatable'); }); - // THIS NEEDS VALIDITY (I ADDED IN SOLIDITY CODE) it('Non existent operator', async () => { await expect(ssvNetworkContract.registerValidator( helpers.DataGenerator.publicKey(0), @@ -93,7 +87,6 @@ describe('Register Validator Tests', () => { )).to.be.revertedWith('OperatorDoesntExist'); }); - // THIS NEEDS VALIDITY (I ADDED IN SOLIDITY CODE) it('Register with existing validator', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( helpers.DataGenerator.publicKey(0), @@ -103,7 +96,6 @@ describe('Register Validator Tests', () => { )).to.be.revertedWith('ValidatorAlreadyExists'); }); - // THIS NEEDS SOME PROPER ERROR MESSAGE (COULDNT GET ERROR MESSAGE TO WORK HERE WHEN I ADDED LOGIC IN SOLIDITY) it('Not enough balance', async () => { await expect(ssvNetworkContract.registerValidator( helpers.DataGenerator.publicKey(0), @@ -113,6 +105,11 @@ describe('Register Validator Tests', () => { )).to.be.revertedWith('NotEnoughBalance'); }); + // GAS AMOUNT IS ABOVE EXPECTED + it('Register with 7 operators', async () => { + await helpers.registerValidators(0, 1, '10000', helpers.DataGenerator.cluster.new(7), [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]); + }); + // MAYBE WE WILL ADD SOME VALIDITY HERE? // it('Invalid share', async () => { // await expect(ssvNetworkContract.registerValidator( diff --git a/test/validators/remove.ts b/test/validators/remove.ts index 6a0dc771..3c8df8a9 100644 --- a/test/validators/remove.ts +++ b/test/validators/remove.ts @@ -3,7 +3,7 @@ import * as helpers from '../helpers/contract-helpers'; import { expect } from 'chai'; import { trackGas, GasGroup } from '../helpers/gas-usage'; -let ssvNetworkContract: any, podResult: any; +let ssvNetworkContract: any, clusterResult: any; describe('Remove Validator Tests', () => { beforeEach(async () => { @@ -17,36 +17,34 @@ describe('Remove Validator Tests', () => { await helpers.deposit([4], ['100000']); // Register a validator - podResult = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + clusterResult = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); }); it('Remove validator emits ValidatorRemoved event', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator( - podResult.validators[0].publicKey, + clusterResult.validators[0].publicKey, )).to.emit(ssvNetworkContract, 'ValidatorRemoved'); }); it('Remove validator', async () => { - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator(podResult.validators[0].publicKey), [GasGroup.REMOVE_VALIDATOR]); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator(clusterResult.validators[0].publicKey), [GasGroup.REMOVE_VALIDATOR]); }); it('Remove validator with an invalid owner', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[3]).removeValidator(podResult.validators[0].publicKey)).to.be.revertedWith('ValidatorNotOwned'); + await expect(ssvNetworkContract.connect(helpers.DB.owners[3]).removeValidator(clusterResult.validators[0].publicKey)).to.be.revertedWith('ValidatorNotOwned'); }); - // THIS SHOULD PASS it('Remove validator twice', async () => { // Remove validator - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator(podResult.validators[0].publicKey), [GasGroup.REMOVE_VALIDATOR]); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator(clusterResult.validators[0].publicKey), [GasGroup.REMOVE_VALIDATOR]); // Remove validator again - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator(podResult.validators[0].publicKey)).to.be.revertedWith('ValidatorNotOwned'); + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator(clusterResult.validators[0].publicKey)).to.be.revertedWith('ValidatorNotOwned'); }); - // THIS SHOULD PASS it('Register / remove validator twice', async () => { // Remove validator - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator(podResult.validators[0].publicKey), [GasGroup.REMOVE_VALIDATOR]); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator(clusterResult.validators[0].publicKey), [GasGroup.REMOVE_VALIDATOR]); // Re-register validator await ssvNetworkContract.connect(helpers.DB.owners[4]).registerValidator( @@ -61,13 +59,13 @@ describe('Remove Validator Tests', () => { }); // UPDATE ONCE LIQUIDATE FUNCTION IS IMPLEMENTED - // it('Remove validator from a liquidated pod', async () => { + // it('Remove validator from a liquidated cluster', async () => { // // Register validator - // const { validators } = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); + // const { validators } = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.cluster.new()); - // // Liquidate pod + // // Liquidate cluster // // Progress blocks to liquidatable state - // // Liquidate pod + // // Liquidate cluster // // Remove validator // await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator( diff --git a/test/validators/transfer-bulk.ts b/test/validators/transfer-bulk.ts index 7a824768..018a7716 100644 --- a/test/validators/transfer-bulk.ts +++ b/test/validators/transfer-bulk.ts @@ -3,7 +3,7 @@ import * as helpers from '../helpers/contract-helpers'; import { expect } from 'chai'; import { trackGas, GasGroup } from '../helpers/gas-usage'; -let ssvNetworkContract: any, podResult1: any, podResult2: any, podResult3: any; +let ssvNetworkContract: any, clusterResult1: any, clusterResult2: any, clusterResult3: any; describe('Bulk Transfer Validator Tests', () => { beforeEach(async () => { @@ -18,91 +18,91 @@ describe('Bulk Transfer Validator Tests', () => { await helpers.deposit([5], ['100000']); // Register validators - podResult1 = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); - podResult2 = await helpers.registerValidators(4, 9, '10000', helpers.DataGenerator.pod.byId(podResult1.podId), [GasGroup.REGISTER_VALIDATOR_EXISTED_POD]); - podResult3 = await helpers.registerValidators(4, 1, '90000', helpers.DataGenerator.pod.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + clusterResult1 = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + clusterResult2 = await helpers.registerValidators(4, 9, '10000', helpers.DataGenerator.cluster.byId(clusterResult1.clusterId), [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]); + clusterResult3 = await helpers.registerValidators(4, 1, '90000', helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); }); it('Bulk transfer 10 validators emits BulkValidatorTransferred event', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( - [podResult1.validators[0].publicKey, ...podResult2.validators.map((validator: any) => validator.publicKey)], - podResult1.podId, - podResult3.podId, - Array(podResult2.validators.length).fill(helpers.DataGenerator.shares(0)) + [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], + clusterResult1.clusterId, + clusterResult3.clusterId, + Array(clusterResult2.validators.length).fill(helpers.DataGenerator.shares(0)) )).to.emit(ssvNetworkContract, 'BulkValidatorTransferred'); }); it('Bulk transfer validator with an invalid owner', async () => { // Transfer validator with an invalid owner await expect(ssvNetworkContract.connect(helpers.DB.owners[5]).bulkTransferValidators( - [podResult1.validators[0].publicKey, ...podResult2.validators.map((validator: any) => validator.publicKey)], - podResult1.podId, - podResult3.podId, - Array(podResult2.validators.length).fill(helpers.DataGenerator.shares(0)) + [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], + clusterResult1.clusterId, + clusterResult3.clusterId, + Array(clusterResult2.validators.length).fill(helpers.DataGenerator.shares(0)) )).to.be.revertedWith('ValidatorNotOwned'); // Transfer validator with an unowned validator - const account5Pod = await helpers.registerValidators(5, 1, '10000', helpers.DataGenerator.pod.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + const account5cluster = await helpers.registerValidators(5, 1, '10000', helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( - [podResult1.validators[0].publicKey, account5Pod.validators[0].publicKey, ...podResult2.validators.map((validator: any) => validator.publicKey)], - podResult1.podId, - podResult3.podId, - Array(podResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)) + [clusterResult1.validators[0].publicKey, account5cluster.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], + clusterResult1.clusterId, + clusterResult3.clusterId, + Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)) )).to.be.revertedWith('ValidatorNotOwned'); // Transfer with an invalid public key await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( - [podResult1.validators[0].publicKey, helpers.DataGenerator.shares(0), ...podResult2.validators.map((validator: any) => validator.publicKey)], - podResult1.podId, - podResult3.podId, - Array(podResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)) + [clusterResult1.validators[0].publicKey, helpers.DataGenerator.shares(0), ...clusterResult2.validators.map((validator: any) => validator.publicKey)], + clusterResult1.clusterId, + clusterResult3.clusterId, + Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)) )).to.be.revertedWith('ValidatorNotOwned'); }); // NEED TO MAKE NEW GAS GROUP FOR BULK TRANSFER it('Bulk transfer 10 validators', async () => { await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( - [podResult1.validators[0].publicKey, ...podResult2.validators.map((validator: any) => validator.publicKey)], - podResult1.podId, - podResult3.podId, - Array(podResult2.validators.length).fill(helpers.DataGenerator.shares(0)) - ), [GasGroup.TRANSFER_VALIDATOR_EXISTED_POD]); + [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], + clusterResult1.clusterId, + clusterResult3.clusterId, + Array(clusterResult2.validators.length).fill(helpers.DataGenerator.shares(0)) + ), [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]); }); // NEED TO MAKE NEW GAS GROUP FOR BULK TRANSFER - it('Bulk transfer 10 validators to a pod with 7 operators', async () => { + it('Bulk transfer 10 validators to a cluster with 7 operators', async () => { // Register validator with 7 operators - const { podId } = await helpers.registerValidators(4, 1, '90000', [1, 2, 3, 4, 5, 6, 7]); + const { clusterId } = await helpers.registerValidators(4, 1, '90000', [1, 2, 3, 4, 5, 6, 7]); - // Transfer validator to an existing pod + // Transfer validator to an existing cluster await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( - [podResult1.validators[0].publicKey, ...podResult2.validators.map((validator: any) => validator.publicKey)], - podResult1.podId, - podId, - Array(podResult2.validators.length).fill(helpers.DataGenerator.shares(0)) - ), [GasGroup.TRANSFER_VALIDATOR_EXISTED_POD]); + [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], + clusterResult1.clusterId, + clusterId, + Array(clusterResult2.validators.length).fill(helpers.DataGenerator.shares(0)) + ), [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]); }); - // SHOULD GIVE ERROR OF MAYBE INVALID TO POD INSTEAD OF ACCOUNT LIQUIDATABLE - it('Bulk transfer 10 validators to a non owned pod', async () => { + // SHOULD GIVE ERROR OF MAYBE INVALID TO cluster INSTEAD OF ACCOUNT LIQUIDATABLE + it('Bulk transfer 10 validators to a non owned cluster', async () => { // Register validator with 7 operators - const { podId } = await helpers.registerValidators(5, 1, '90000', helpers.DataGenerator.pod.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + const { clusterId } = await helpers.registerValidators(5, 1, '90000', helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( - [podResult1.validators[0].publicKey, ...podResult2.validators.map((validator: any) => validator.publicKey)], - podResult1.podId, - podId, - Array(podResult2.validators.length).fill(helpers.DataGenerator.shares(0)) + [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], + clusterResult1.clusterId, + clusterId, + Array(clusterResult2.validators.length).fill(helpers.DataGenerator.shares(0)) )).to.be.revertedWith('InvalidCluster'); }); - // SHOULD GIVE ERROR OF MAYBE INVALID FROM POD - it('Bulk transfer 10 validators to an invalid pod', async () => { + // SHOULD GIVE ERROR OF MAYBE INVALID FROM cluster + it('Bulk transfer 10 validators to an invalid cluster', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( - [podResult1.validators[0].publicKey, ...podResult2.validators.map((validator: any) => validator.publicKey)], - podResult1.podId.slice(0, -1) + 'a', - podResult1.podId, - Array(podResult2.validators.length).fill(helpers.DataGenerator.shares(0)) + [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], + clusterResult1.clusterId.slice(0, -1) + 'a', + clusterResult1.clusterId, + Array(clusterResult2.validators.length).fill(helpers.DataGenerator.shares(0)) )).to.be.revertedWith('InvalidCluster'); }); @@ -110,18 +110,18 @@ describe('Bulk Transfer Validator Tests', () => { it('Validator and share length mismatch', async () => { // 10 validators and 11 shares await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( - [podResult1.validators[0].publicKey, ...podResult2.validators.map((validator: any) => validator.publicKey)], - podResult1.podId, - podResult3.podId, - Array(podResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)) + [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], + clusterResult1.clusterId, + clusterResult3.clusterId, + Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)) )).to.be.revertedWith('ValidatorShareMismatch'); // 9 validators and 10 shares await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( - podResult2.validators.map((validator: any) => validator.publicKey), - podResult1.podId, - podResult3.podId, - Array(podResult2.validators.length).fill(helpers.DataGenerator.shares(0)) + clusterResult2.validators.map((validator: any) => validator.publicKey), + clusterResult1.clusterId, + clusterResult3.clusterId, + Array(clusterResult2.validators.length).fill(helpers.DataGenerator.shares(0)) )).to.be.revertedWith('ValidatorShareMismatch'); }); diff --git a/test/validators/transfer.ts b/test/validators/transfer.ts index f3d517ef..dc44c8fd 100644 --- a/test/validators/transfer.ts +++ b/test/validators/transfer.ts @@ -3,7 +3,7 @@ import * as helpers from '../helpers/contract-helpers'; import { expect } from 'chai'; import { trackGas, GasGroup } from '../helpers/gas-usage'; -let ssvNetworkContract: any, podResult1: any, podResult2: any; +let ssvNetworkContract: any, clusterResult1: any, clusterResult2: any; describe('Transfer Validator Tests', () => { beforeEach(async () => { @@ -18,55 +18,56 @@ describe('Transfer Validator Tests', () => { await helpers.deposit([5], ['100000']); // Register validators - podResult1 = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); - podResult2 = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + clusterResult1 = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + clusterResult2 = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); }); it('Transfer validator emits ValidatorTransferred event', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( - podResult1.validators[0].publicKey, - helpers.DataGenerator.pod.new(), + clusterResult1.validators[0].publicKey, + helpers.DataGenerator.cluster.new(), helpers.DataGenerator.shares(helpers.DB.validators.length), '10000' )).to.emit(ssvNetworkContract, 'ValidatorTransferred'); }); - it('Transfer validator into a new pod', async () => { + it('Transfer validator into a new cluster', async () => { const transferedValidator = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( - podResult1.validators[0].publicKey, - helpers.DataGenerator.pod.new(), + clusterResult1.validators[0].publicKey, + helpers.DataGenerator.cluster.new(), helpers.DataGenerator.shares(helpers.DB.validators.length), '10000' - ), [GasGroup.TRANSFER_VALIDATOR_NEW_POD]); + ), [GasGroup.TRANSFER_VALIDATOR_NEW_CLUSTER]); - expect(podResult1.podId).not.equals(transferedValidator.eventsByName.ValidatorTransferred[0].args.podId); + expect(clusterResult1.clusterId).not.equals(transferedValidator.eventsByName.ValidatorTransferred[0].args.clusterId); }); it('Transfer validator to an existing pod', async () => { const transfredValidator1 = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( - podResult1.validators[0].publicKey, - helpers.DataGenerator.pod.byId(podResult2.podId), + clusterResult1.validators[0].publicKey, + helpers.DataGenerator.cluster.byId(clusterResult2.clusterId), helpers.DataGenerator.shares(helpers.DB.validators.length), '10000' - ), [GasGroup.TRANSFER_VALIDATOR_EXISTED_POD]); - expect(podResult2.podId).equals(transfredValidator1.eventsByName.ValidatorTransferred[0].args.podId); + ), [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]); + expect(clusterResult2.clusterId).equals(transfredValidator1.eventsByName.ValidatorTransferred[0].args.clusterId); }); it('Transfer validator to an existing cluster', async () => { + const clusterResult3 = await helpers.registerValidators(5, 1, '10000', helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); const transfredValidator1 = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( - podResult1.validators[0].publicKey, - helpers.DataGenerator.pod.byId(podResult2.podId), + clusterResult1.validators[0].publicKey, + helpers.DataGenerator.cluster.byId(clusterResult3.clusterId), helpers.DataGenerator.shares(helpers.DB.validators.length), '10000' - ), [GasGroup.TRANSFER_VALIDATOR_EXISTED_CLUSTER]); - expect(podResult2.podId).equals(transfredValidator1.eventsByName.ValidatorTransferred[0].args.podId); + ), [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]); + expect(clusterResult2.clusterId).equals(transfredValidator1.eventsByName.ValidatorTransferred[0].args.clusterId); }); it('Transfer validator with an invalid owner', async () => { // Transfer validator with an invalid owner await expect(ssvNetworkContract.connect(helpers.DB.owners[5]).transferValidator( - podResult1.validators[0].publicKey, - helpers.DataGenerator.pod.byId(podResult2.podId), + clusterResult1.validators[0].publicKey, + helpers.DataGenerator.cluster.byId(clusterResult2.clusterId), helpers.DataGenerator.shares(helpers.DB.validators.length), '10000' )).to.be.revertedWith('ValidatorNotOwned'); @@ -74,20 +75,20 @@ describe('Transfer Validator Tests', () => { // Transfer validator with an invalid public key await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( helpers.DataGenerator.shares(0), - helpers.DataGenerator.pod.byId(podResult2.podId), + helpers.DataGenerator.cluster.byId(clusterResult2.clusterId), helpers.DataGenerator.shares(helpers.DB.validators.length), '10000' )).to.be.revertedWith('ValidatorNotOwned'); }); - it('Transfer validator to a pod with 7 operators', async () => { + it('Transfer validator to a cluster with 7 operators', async () => { // Register validator with 7 operators - const { podId } = await helpers.registerValidators(4, 1, '10000', [1, 2, 3, 4, 5, 6, 7]); + const { clusterId } = await helpers.registerValidators(4, 1, '10000', [1, 2, 3, 4, 5, 6, 7]); - // Transfer validator to an existing pod + // Transfer validator to an existing cluster await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( - podResult1.validators[0].publicKey, - helpers.DataGenerator.pod.byId(podId), + clusterResult1.validators[0].publicKey, + helpers.DataGenerator.cluster.byId(clusterId), helpers.DataGenerator.shares(helpers.DB.validators.length), '10000' )).to.emit(ssvNetworkContract, 'ValidatorTransferred'); @@ -96,35 +97,35 @@ describe('Transfer Validator Tests', () => { // THIS NEEDS SOME PROPER ERROR MESSAGE it('Transfer validator with not enough amount', async () => { // Register validator - const { podId } = await helpers.registerValidators(4, 1, '10000', [1, 2, 3, 9]); + const { clusterId } = await helpers.registerValidators(4, 1, '10000', [1, 2, 3, 9]); // Increase operator fee - await ssvNetworkContract.connect(helpers.DB.owners[7]).updateOperatorFee(9, '100000') + await ssvNetworkContract.updateOperatorFee(9, '100000') - // Transfer to pod with not enough amount + // Transfer to cluster with not enough amount await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( - podResult1.validators[0].publicKey, - helpers.DataGenerator.pod.byId(podId), + clusterResult1.validators[0].publicKey, + helpers.DataGenerator.cluster.byId(clusterId), helpers.DataGenerator.shares(helpers.DB.validators.length), '1' )).to.be.revertedWith('account liquidatable'); }); // THIS NEEDS SOME PROPER ERROR MESSAGE - it('Transfer validator with an invalid pod', async () => { + it('Transfer validator with an invalid cluster', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( - podResult1.validators[0].publicKey, - podResult2.validators[0].publicKey, + clusterResult1.validators[0].publicKey, + clusterResult2.validators[0].publicKey, helpers.DataGenerator.shares(helpers.DB.validators.length), '10000' - )).to.be.revertedWith('InvalidPod'); + )).to.be.revertedWith('Invalidcluster'); }); // THIS NEEDS SOME PROPER ERROR MESSAGE it('Transfer validator with not enough balance', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( - podResult1.validators[0].publicKey, - helpers.DataGenerator.pod.byId(podResult2.podId), + clusterResult1.validators[0].publicKey, + helpers.DataGenerator.cluster.byId(clusterResult2.clusterId), helpers.DataGenerator.shares(helpers.DB.validators.length), '100001' )).to.be.revertedWith('NotEnoughBalance'); @@ -132,11 +133,11 @@ describe('Transfer Validator Tests', () => { // MAYBE WE WILL ADD SOME VALIDITY HERE? // it('Transfer validator with an invalid share', async () => { - // await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); - // const { podId } = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); + // await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.cluster.new()); + // const { clusterId } = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.cluster.new()); // await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( // helpers.DataGenerator.publicKey(0), - // helpers.DataGenerator.pod.byId(podId), + // helpers.DataGenerator.cluster.byId(clusterId), // helpers.DataGenerator.shares(helpers.DB.validators.length), // '10000' // )).to.be.revertedWith('InvalidShares'); From 0d30b8c467aa101c7aad37410535f0fa1e335d09 Mon Sep 17 00:00:00 2001 From: AndrewBlox Date: Wed, 14 Sep 2022 17:05:55 +0300 Subject: [PATCH 069/149] update helper from cluster to pod emit --- test/helpers/contract-helpers.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/helpers/contract-helpers.ts b/test/helpers/contract-helpers.ts index ba7850e6..ed732150 100644 --- a/test/helpers/contract-helpers.ts +++ b/test/helpers/contract-helpers.ts @@ -94,7 +94,7 @@ export const registerValidators = async (ownerId: number, numberOfValidators: nu amount, ), gasGroups); - clusterId = eventsByName.ValidatorAdded[0].args.clusterId; + clusterId = eventsByName.ValidatorAdded[0].args.podId; DB.clusters[clusterId] = ({ id: clusterId, operatorIds }); DB.validators.push({ publicKey, clusterId, shares }); validators.push({ publicKey, shares }); From d263d2feb927041572db3b7d4f860ab98587ec45 Mon Sep 17 00:00:00 2001 From: AndrewBlox Date: Wed, 14 Sep 2022 19:49:36 +0300 Subject: [PATCH 070/149] small updates to tests --- test/validators/transfer-bulk.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/validators/transfer-bulk.ts b/test/validators/transfer-bulk.ts index 018a7716..4725a231 100644 --- a/test/validators/transfer-bulk.ts +++ b/test/validators/transfer-bulk.ts @@ -83,17 +83,17 @@ describe('Bulk Transfer Validator Tests', () => { ), [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]); }); - // SHOULD GIVE ERROR OF MAYBE INVALID TO cluster INSTEAD OF ACCOUNT LIQUIDATABLE - it('Bulk transfer 10 validators to a non owned cluster', async () => { + // IMPOSSIBLE TO DO WITHOUT AMOUNT PARAM + it('Bulk transfer 10 validators to cluster created by other owner', async () => { // Register validator with 7 operators const { clusterId } = await helpers.registerValidators(5, 1, '90000', helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], clusterResult1.clusterId, clusterId, Array(clusterResult2.validators.length).fill(helpers.DataGenerator.shares(0)) - )).to.be.revertedWith('InvalidCluster'); + ), [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]); }); // SHOULD GIVE ERROR OF MAYBE INVALID FROM cluster @@ -116,12 +116,12 @@ describe('Bulk Transfer Validator Tests', () => { Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)) )).to.be.revertedWith('ValidatorShareMismatch'); - // 9 validators and 10 shares + // 9 validators and 8 shares await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( clusterResult2.validators.map((validator: any) => validator.publicKey), clusterResult1.clusterId, clusterResult3.clusterId, - Array(clusterResult2.validators.length).fill(helpers.DataGenerator.shares(0)) + Array(8).fill(helpers.DataGenerator.shares(0)) )).to.be.revertedWith('ValidatorShareMismatch'); }); From 9a4517893a9a0e99826be2fe41dfe971370ee6f9 Mon Sep 17 00:00:00 2001 From: Adam Zigdon Date: Thu, 15 Sep 2022 11:58:10 +0300 Subject: [PATCH 071/149] more changes --- contracts/ISSVNetwork.sol | 5 +- contracts/SSVNetwork.sol | 78 ++++++++++++++++++++++---------- test/helpers/contract-helpers.ts | 6 +-- test/vadimToUpdate.js | 16 +++---- test/validators/register.ts | 15 +++--- test/validators/transfer-bulk.ts | 36 +++++++++------ 6 files changed, 99 insertions(+), 57 deletions(-) diff --git a/contracts/ISSVNetwork.sol b/contracts/ISSVNetwork.sol index c7210195..21e23487 100644 --- a/contracts/ISSVNetwork.sol +++ b/contracts/ISSVNetwork.sol @@ -86,6 +86,8 @@ interface ISSVNetwork { error OessDataStructureInvalid(); error ValidatorNotOwned(); error InvalidCluster(); + error ClusterAlreadyExists(); + error ParametersMismatch(); /** errors */ // error validatorWithPublicKeyNotExist(); @@ -179,7 +181,8 @@ interface ISSVNetwork { bytes[] calldata validatorPK, bytes32 fromPodId, bytes32 toPodId, - bytes[] calldata shares + bytes[] calldata shares, + uint64 amount ) external; diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index 286ad9aa..1daa3720 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -42,7 +42,6 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } struct Pod { - uint64 balance; uint64 validatorCount; Snapshot usage; } @@ -61,7 +60,6 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { mapping(uint64 => Operator) private _operators; mapping(bytes32 => Cluster) private _clusters; mapping(bytes32 => Pod) private _pods; - mapping(address => uint64) _availableBalances; mapping(bytes32 => Validator) _validatorPKs; uint64 private _networkFee; @@ -129,11 +127,6 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { { Pod memory pod; - if (_availableBalances[msg.sender] < amount) { - revert NotEnoughBalance(); - } - - _availableBalances[msg.sender] -= amount; pod = _updatePodData(clusterId, amount, hashedPod, true); { @@ -155,7 +148,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _dao = dao; } - if (_liquidatable(pod.balance, pod.validatorCount, operatorIds)) { + if (_liquidatable(pod.usage.balance, pod.validatorCount, operatorIds)) { revert AccountLiquidatable(); } @@ -188,7 +181,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _pods[hashedPod] = _updatePodData(clusterId, 0, hashedPod, false); // if (pod.validatorCount == 0) { // _availableBalances[msg.sender] += _ownerPodBalance(pod, podIndex); - // pod.balance -= _ownerPodBalance(pod, podIndex); + // pod.usage.balance -= _ownerPodBalance(pod, podIndex); // } } @@ -204,7 +197,6 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { { Pod memory pod; { - _availableBalances[msg.sender] -= amount; bytes32 hashedPodNew = keccak256(abi.encodePacked(msg.sender, newClusterId)); _pods[hashedPodNew] = _updatePodData(newClusterId, amount, hashedPodNew, true); @@ -217,7 +209,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _dao = dao; } - require(!_liquidatable(pod.balance, pod.validatorCount, operatorIds), "account liquidatable"); + require(!_liquidatable(pod.usage.balance, pod.validatorCount, operatorIds), "account liquidatable"); } emit ValidatorTransferred(publicKey, newClusterId, shares); @@ -241,14 +233,14 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { uint64 currentBlock = uint64(block.number); uint64 podIndex = _clusterCurrentIndex(clusterId); - pod.balance = _ownerPodBalance(pod, podIndex); + pod.usage.balance = _ownerPodBalance(pod, podIndex); pod.usage.index = podIndex; pod.usage.block = currentBlock; --pod.validatorCount; if (pod.validatorCount == 0) { // _availableBalances[msg.sender] += _ownerPodBalance(pod, podIndex); - // pod.balance -= _ownerPodBalance(pod, podIndex); + // pod.usage.balance -= _ownerPodBalance(pod, podIndex); } @@ -274,13 +266,33 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { emit ValidatorRemoved(validatorPK, clusterId); } + function deposit(address owner, bytes32 clusterId, uint64 amount) external { + _deposit(owner, clusterId, amount); + } + + function deposit(bytes32 clusterId, uint64 amount) external { + _deposit(msg.sender, clusterId, amount); + } + + function createCluster(uint64[] memory operatorIds) external returns (bytes32) { + bytes32 key = keccak256(abi.encodePacked(operatorIds)); + + _createCluster(key, operatorIds); + + return key; + } + function bulkTransferValidators( bytes[] calldata validatorPK, bytes32 fromClusterId, bytes32 toClusterId, - bytes[] calldata shares + bytes[] calldata shares, + uint64 amount ) external { - // _validateValidatorParams + if (validatorPK.length != shares.length) { + revert ParametersMismatch(); + } + uint64 activeValidatorCount = 0; for (uint64 index = 0; index < validatorPK.length; ++index) { @@ -311,16 +323,22 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _updateOperatorsValidatorMove(oldOperatorIds, newOperatorIds, activeValidatorCount); Pod memory pod = _pods[keccak256(abi.encodePacked(msg.sender, fromClusterId))]; - pod.usage.index = _clusterCurrentIndex(fromClusterId); + uint64 podIndex = _clusterCurrentIndex(fromClusterId); + pod.usage.balance = _ownerPodBalance(pod, podIndex) + amount; + pod.usage.index = podIndex; pod.usage.block = uint64(block.number); pod.validatorCount -= activeValidatorCount; pod = _pods[keccak256(abi.encodePacked(msg.sender, toClusterId))]; - pod.usage.index = _clusterCurrentIndex(toClusterId); + podIndex = _clusterCurrentIndex(toClusterId); + pod.usage.balance = _ownerPodBalance(pod, podIndex) + amount; + pod.usage.index = podIndex; pod.usage.block = uint64(block.number); pod.validatorCount += activeValidatorCount; - require(!_liquidatable(pod.balance, pod.validatorCount, newOperatorIds), "account liquidatable"); + if (_liquidatable(pod.usage.balance, pod.validatorCount, newOperatorIds)) { + revert AccountLiquidatable(); + } } @@ -414,7 +432,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { function _updatePodData(bytes32 clusterId, uint64 amount, bytes32 hashedPod, bool increase) private view returns (Pod memory) { Pod memory pod = _pods[hashedPod]; uint64 podIndex = _clusterCurrentIndex(clusterId); - pod.balance = _ownerPodBalance(pod, podIndex) + amount; + pod.usage.balance = _ownerPodBalance(pod, podIndex) + amount; pod.usage.index = podIndex; pod.usage.block = uint64(block.number); if (increase) { @@ -425,7 +443,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { if (pod.validatorCount == 0) { // _availableBalances[msg.sender] += _ownerPodBalance(pod, podIndex); - // pod.balance -= _ownerPodBalance(pod, podIndex); + // pod.usage.balance -= _ownerPodBalance(pod, podIndex); } return pod; } @@ -455,20 +473,30 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } } - function deposit(uint64 amount) public { - _availableBalances[msg.sender] += amount; + function _deposit(address owner, bytes32 clusterId, uint64 amount) private { + Pod storage pod = _pods[keccak256(abi.encodePacked(owner, clusterId))]; + + pod.usage.balance += amount; } - function _getOrCreateCluster(uint64[] memory operatorIds) private returns (bytes32) { // , Cluster memory + function _createCluster(bytes32 key, uint64[] memory operatorIds) private { for (uint64 i = 0; i < operatorIds.length - 1;) { require(operatorIds[i] <= operatorIds[++i]); } + if (_clusters[key].operatorIds.length == 0) { + _clusters[key] = Cluster({operatorIds: operatorIds}); + } else { + revert ClusterAlreadyExists(); + } + } + + function _getOrCreateCluster(uint64[] memory operatorIds) private returns (bytes32) { // , Cluster memory bytes32 key = keccak256(abi.encodePacked(operatorIds)); Cluster storage cluster = _clusters[key]; if (cluster.operatorIds.length == 0) { - cluster.operatorIds = operatorIds; + _createCluster(key, operatorIds); } return key; @@ -509,7 +537,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { function _ownerPodBalance(Pod memory pod, uint64 currentPodIndex) private pure returns (uint64) { - return pod.balance - (currentPodIndex - pod.usage.index) * pod.validatorCount; + return pod.usage.balance - (currentPodIndex - pod.usage.index) * pod.validatorCount; } function _burnRatePerValidator(Operator[] memory operators) private pure returns (uint64 rate) { diff --git a/test/helpers/contract-helpers.ts b/test/helpers/contract-helpers.ts index ed732150..59faf76b 100644 --- a/test/helpers/contract-helpers.ts +++ b/test/helpers/contract-helpers.ts @@ -72,9 +72,9 @@ export const registerOperators = async (ownerId: number, numberOfOperators: numb }; export const deposit = async (ownerIds: number[], amounts: string[]) => { - for (let i = 0; i < ownerIds.length; ++i) { - await DB.ssvNetwork.contract.connect(DB.owners[ownerIds[i]]).deposit(amounts[i]); - } + // for (let i = 0; i < ownerIds.length; ++i) { + // await DB.ssvNetwork.contract.connect(DB.owners[ownerIds[i]]).deposit(amounts[i]); + // } }; diff --git a/test/vadimToUpdate.js b/test/vadimToUpdate.js index 769ae622..75769ab4 100644 --- a/test/vadimToUpdate.js +++ b/test/vadimToUpdate.js @@ -60,13 +60,13 @@ describe("Validators", () => { // await deployedSSVNetworkContract.createGroup([1,2,3,4]); // await deployedSSVNetworkContract.createGroup([1,2,3,4]); - await deployedSSVNetworkContract.deposit("100000000000"); - await log({ - action: 'deposit', - operatorIds: [1, 2, 3, 4] - }); + // await deployedSSVNetworkContract.deposit("100000000000"); + // await log({ + // action: 'deposit', + // operatorIds: [1, 2, 3, 4] + // }); // validator 1 - await progressBlocks(97); + await progressBlocks(98); let resultRegister = (await (await deployedSSVNetworkContract.registerValidator( validatorPK + "f", [1,2,3,4], @@ -238,8 +238,8 @@ describe("Validators", () => { results.map(r => r.validatorPK), outputRegister.groupId, outputRegister3.groupId, - results.map(r => sharePKs[4]) - + results.map(r => sharePKs[4]), + '10000' )).wait()).logs; // await log({ diff --git a/test/validators/register.ts b/test/validators/register.ts index 85308494..20559579 100644 --- a/test/validators/register.ts +++ b/test/validators/register.ts @@ -84,7 +84,7 @@ describe('Register Validator Tests', () => { [1, 2, 3, 25], helpers.DataGenerator.shares(0), '4000' - )).to.be.revertedWith('OperatorDoesntExist'); + )).to.be.revertedWith('OperatorDoesNotExist'); }); it('Register with existing validator', async () => { @@ -96,13 +96,14 @@ describe('Register Validator Tests', () => { )).to.be.revertedWith('ValidatorAlreadyExists'); }); + // TODO: fix after connecting the token it('Not enough balance', async () => { - await expect(ssvNetworkContract.registerValidator( - helpers.DataGenerator.publicKey(0), - [1, 2, 3, 4], - helpers.DataGenerator.shares(0), - '100005' - )).to.be.revertedWith('NotEnoughBalance'); + // await expect(ssvNetworkContract.registerValidator( + // helpers.DataGenerator.publicKey(0), + // [1, 2, 3, 4], + // helpers.DataGenerator.shares(0), + // '100005' + // )).to.be.revertedWith('NotEnoughBalance'); }); // GAS AMOUNT IS ABOVE EXPECTED diff --git a/test/validators/transfer-bulk.ts b/test/validators/transfer-bulk.ts index 018a7716..32653f89 100644 --- a/test/validators/transfer-bulk.ts +++ b/test/validators/transfer-bulk.ts @@ -28,7 +28,8 @@ describe('Bulk Transfer Validator Tests', () => { [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], clusterResult1.clusterId, clusterResult3.clusterId, - Array(clusterResult2.validators.length).fill(helpers.DataGenerator.shares(0)) + Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)), + '10000' )).to.emit(ssvNetworkContract, 'BulkValidatorTransferred'); }); @@ -38,7 +39,8 @@ describe('Bulk Transfer Validator Tests', () => { [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], clusterResult1.clusterId, clusterResult3.clusterId, - Array(clusterResult2.validators.length).fill(helpers.DataGenerator.shares(0)) + Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)), + '10000' )).to.be.revertedWith('ValidatorNotOwned'); // Transfer validator with an unowned validator @@ -47,7 +49,8 @@ describe('Bulk Transfer Validator Tests', () => { [clusterResult1.validators[0].publicKey, account5cluster.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], clusterResult1.clusterId, clusterResult3.clusterId, - Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)) + Array(clusterResult2.validators.length + 2).fill(helpers.DataGenerator.shares(0)), + '10000' )).to.be.revertedWith('ValidatorNotOwned'); // Transfer with an invalid public key @@ -55,7 +58,8 @@ describe('Bulk Transfer Validator Tests', () => { [clusterResult1.validators[0].publicKey, helpers.DataGenerator.shares(0), ...clusterResult2.validators.map((validator: any) => validator.publicKey)], clusterResult1.clusterId, clusterResult3.clusterId, - Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)) + Array(clusterResult2.validators.length + 2).fill(helpers.DataGenerator.shares(0)), + '10000' )).to.be.revertedWith('ValidatorNotOwned'); }); @@ -65,7 +69,8 @@ describe('Bulk Transfer Validator Tests', () => { [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], clusterResult1.clusterId, clusterResult3.clusterId, - Array(clusterResult2.validators.length).fill(helpers.DataGenerator.shares(0)) + Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)), + '10000' ), [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]); }); @@ -79,7 +84,8 @@ describe('Bulk Transfer Validator Tests', () => { [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], clusterResult1.clusterId, clusterId, - Array(clusterResult2.validators.length).fill(helpers.DataGenerator.shares(0)) + Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)), + '10000' ), [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]); }); @@ -92,8 +98,9 @@ describe('Bulk Transfer Validator Tests', () => { [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], clusterResult1.clusterId, clusterId, - Array(clusterResult2.validators.length).fill(helpers.DataGenerator.shares(0)) - )).to.be.revertedWith('InvalidCluster'); + Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)), + '100000' + )).to.emit(ssvNetworkContract, 'BulkValidatorTransferred'); }); // SHOULD GIVE ERROR OF MAYBE INVALID FROM cluster @@ -102,7 +109,8 @@ describe('Bulk Transfer Validator Tests', () => { [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], clusterResult1.clusterId.slice(0, -1) + 'a', clusterResult1.clusterId, - Array(clusterResult2.validators.length).fill(helpers.DataGenerator.shares(0)) + Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)), + '10000' )).to.be.revertedWith('InvalidCluster'); }); @@ -113,16 +121,18 @@ describe('Bulk Transfer Validator Tests', () => { [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], clusterResult1.clusterId, clusterResult3.clusterId, - Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)) - )).to.be.revertedWith('ValidatorShareMismatch'); + Array(clusterResult2.validators.length).fill(helpers.DataGenerator.shares(0)), + '10000' + )).to.be.revertedWith('ParametersMismatch'); // 9 validators and 10 shares await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( clusterResult2.validators.map((validator: any) => validator.publicKey), clusterResult1.clusterId, clusterResult3.clusterId, - Array(clusterResult2.validators.length).fill(helpers.DataGenerator.shares(0)) - )).to.be.revertedWith('ValidatorShareMismatch'); + Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)), + '10000' + )).to.be.revertedWith('ParametersMismatch'); }); // // NEED TO IMPLEMENT AN AMOUNT From afa638c06960d7b9e532846ccd253838bbedca21 Mon Sep 17 00:00:00 2001 From: AndrewBlox Date: Thu, 15 Sep 2022 13:34:49 +0300 Subject: [PATCH 072/149] Update tests --- test/helpers/gas-usage.ts | 4 +++ test/validators/transfer-bulk.ts | 39 ++++++++++++++++----------- test/validators/transfer.ts | 46 +++++++++++++++++--------------- 3 files changed, 51 insertions(+), 38 deletions(-) diff --git a/test/helpers/gas-usage.ts b/test/helpers/gas-usage.ts index 592da29d..3fa2b0de 100644 --- a/test/helpers/gas-usage.ts +++ b/test/helpers/gas-usage.ts @@ -10,6 +10,8 @@ export enum GasGroup { TRANSFER_VALIDATOR_NEW_CLUSTER, TRANSFER_VALIDATOR, TRANSFER_VALIDATOR_NON_EXISTING_POD, + BULK_TRANSFER_VALIDATOR, + BULK_TRANSFER_VALIDATOR_NON_EXISTING_POD, } const MAX_GAS_PER_GROUP: any = { @@ -22,6 +24,8 @@ const MAX_GAS_PER_GROUP: any = { [GasGroup.TRANSFER_VALIDATOR_NEW_CLUSTER]: 400000, [GasGroup.TRANSFER_VALIDATOR]: 260000, [GasGroup.TRANSFER_VALIDATOR_NON_EXISTING_POD]: 290000, + [GasGroup.BULK_TRANSFER_VALIDATOR]: 340000, + [GasGroup.BULK_TRANSFER_VALIDATOR_NON_EXISTING_POD]: 340000, }; class GasStats { diff --git a/test/validators/transfer-bulk.ts b/test/validators/transfer-bulk.ts index 07a52a2a..6d722f64 100644 --- a/test/validators/transfer-bulk.ts +++ b/test/validators/transfer-bulk.ts @@ -12,6 +12,7 @@ describe('Bulk Transfer Validator Tests', () => { // Register operators await helpers.registerOperators(0, 12, '10'); + await helpers.registerOperators(0, 1, '1000000'); // Deposit into accounts await helpers.deposit([4], ['1000000']); @@ -63,7 +64,6 @@ describe('Bulk Transfer Validator Tests', () => { )).to.be.revertedWith('ValidatorNotOwned'); }); - // NEED TO MAKE NEW GAS GROUP FOR BULK TRANSFER it('Bulk transfer 10 validators', async () => { await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], @@ -71,10 +71,9 @@ describe('Bulk Transfer Validator Tests', () => { clusterResult3.clusterId, Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)), '10000' - ), [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]); + ), [GasGroup.BULK_TRANSFER_VALIDATOR]); }); - // NEED TO MAKE NEW GAS GROUP FOR BULK TRANSFER it('Bulk transfer 10 validators to a cluster with 7 operators', async () => { // Register validator with 7 operators const { clusterId } = await helpers.registerValidators(4, 1, '90000', [1, 2, 3, 4, 5, 6, 7]); @@ -86,10 +85,9 @@ describe('Bulk Transfer Validator Tests', () => { clusterId, Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)), '10000' - ), [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]); + ), [GasGroup.BULK_TRANSFER_VALIDATOR_NON_EXISTING_POD]); }); - // IMPOSSIBLE TO DO WITHOUT AMOUNT PARAM it('Bulk transfer 10 validators to cluster created by other owner', async () => { // Register validator with 7 operators const { clusterId } = await helpers.registerValidators(5, 1, '90000', helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); @@ -100,10 +98,9 @@ describe('Bulk Transfer Validator Tests', () => { clusterId, Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)), '100000' - ), [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]); + ), [GasGroup.BULK_TRANSFER_VALIDATOR_NON_EXISTING_POD]); }); - // SHOULD GIVE ERROR OF MAYBE INVALID FROM cluster it('Bulk transfer 10 validators to an invalid cluster', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], @@ -114,7 +111,6 @@ describe('Bulk Transfer Validator Tests', () => { )).to.be.revertedWith('InvalidCluster'); }); - // SHOULD GIVE ERROR OF MAYBE VALIDATOR SHARE MISMATCH it('Validator and share length mismatch', async () => { // 10 validators and 11 shares await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( @@ -135,13 +131,24 @@ describe('Bulk Transfer Validator Tests', () => { )).to.be.revertedWith('ParametersMismatch'); }); - // // NEED TO IMPLEMENT AN AMOUNT - // it('Transfer validator with not enough amount', async () => { - - // }); - - // // NEED TO IMPLEMENT AN AMOUNT - // it('Transfer validator with not enough balance', async () => { + it('Bulk transfer validator with not enough amount', async () => { + const { clusterId } = await helpers.registerValidators(5, 1, '90000', [10, 11, 12, 13], [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( + [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], + clusterResult1.clusterId, + clusterId, + Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)), + '1' + )).to.be.revertedWith('AccountLiquidatable'); + }); - // }); + it('Bulk transfer validator with not enough balance', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( + [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], + clusterResult1.clusterId, + clusterResult3.clusterId, + Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)), + '10000000' + )).to.be.revertedWith('NotEnoughDeposited'); + }); }); \ No newline at end of file diff --git a/test/validators/transfer.ts b/test/validators/transfer.ts index dc44c8fd..c73378dd 100644 --- a/test/validators/transfer.ts +++ b/test/validators/transfer.ts @@ -42,27 +42,6 @@ describe('Transfer Validator Tests', () => { expect(clusterResult1.clusterId).not.equals(transferedValidator.eventsByName.ValidatorTransferred[0].args.clusterId); }); - it('Transfer validator to an existing pod', async () => { - const transfredValidator1 = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( - clusterResult1.validators[0].publicKey, - helpers.DataGenerator.cluster.byId(clusterResult2.clusterId), - helpers.DataGenerator.shares(helpers.DB.validators.length), - '10000' - ), [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]); - expect(clusterResult2.clusterId).equals(transfredValidator1.eventsByName.ValidatorTransferred[0].args.clusterId); - }); - - it('Transfer validator to an existing cluster', async () => { - const clusterResult3 = await helpers.registerValidators(5, 1, '10000', helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); - const transfredValidator1 = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( - clusterResult1.validators[0].publicKey, - helpers.DataGenerator.cluster.byId(clusterResult3.clusterId), - helpers.DataGenerator.shares(helpers.DB.validators.length), - '10000' - ), [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]); - expect(clusterResult2.clusterId).equals(transfredValidator1.eventsByName.ValidatorTransferred[0].args.clusterId); - }); - it('Transfer validator with an invalid owner', async () => { // Transfer validator with an invalid owner await expect(ssvNetworkContract.connect(helpers.DB.owners[5]).transferValidator( @@ -94,6 +73,29 @@ describe('Transfer Validator Tests', () => { )).to.emit(ssvNetworkContract, 'ValidatorTransferred'); }); + // GOING ABOVE GAS LIMIT + it('Transfer validator to an existing pod', async () => { + const transfredValidator1 = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( + clusterResult1.validators[0].publicKey, + helpers.DataGenerator.cluster.byId(clusterResult2.clusterId), + helpers.DataGenerator.shares(helpers.DB.validators.length), + '10000' + ), [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]); + expect(clusterResult2.clusterId).equals(transfredValidator1.eventsByName.ValidatorTransferred[0].args.podId); + }); + + // GOING ABOVE GAS LIMIT + it('Transfer validator to an existing cluster', async () => { + const clusterResult3 = await helpers.registerValidators(5, 1, '10000', helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + const transfredValidator1 = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( + clusterResult1.validators[0].publicKey, + helpers.DataGenerator.cluster.byId(clusterResult3.clusterId), + helpers.DataGenerator.shares(helpers.DB.validators.length), + '10000' + ), [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]); + expect(clusterResult2.clusterId).equals(transfredValidator1.eventsByName.ValidatorTransferred[0].args.podId); + }); + // THIS NEEDS SOME PROPER ERROR MESSAGE it('Transfer validator with not enough amount', async () => { // Register validator @@ -127,7 +129,7 @@ describe('Transfer Validator Tests', () => { clusterResult1.validators[0].publicKey, helpers.DataGenerator.cluster.byId(clusterResult2.clusterId), helpers.DataGenerator.shares(helpers.DB.validators.length), - '100001' + '1000001' )).to.be.revertedWith('NotEnoughBalance'); }); From 30917d3b7aa02efb4dc06b6788f4d7d1af962ef4 Mon Sep 17 00:00:00 2001 From: Adam Zigdon Date: Thu, 15 Sep 2022 16:14:26 +0300 Subject: [PATCH 073/149] fixes --- contracts/ISSVNetwork.sol | 2 +- contracts/SSVNetwork.sol | 39 ++++++++++++++++++-------------- test/helpers/gas-usage.ts | 6 +++-- test/validators/transfer-bulk.ts | 20 ++++++++-------- test/validators/transfer.ts | 39 +++++++++----------------------- 5 files changed, 48 insertions(+), 58 deletions(-) diff --git a/contracts/ISSVNetwork.sol b/contracts/ISSVNetwork.sol index 21e23487..9c4b2ecd 100644 --- a/contracts/ISSVNetwork.sol +++ b/contracts/ISSVNetwork.sol @@ -88,6 +88,7 @@ interface ISSVNetwork { error InvalidCluster(); error ClusterAlreadyExists(); error ParametersMismatch(); + error NegativeBalance(); /** errors */ // error validatorWithPublicKeyNotExist(); @@ -101,7 +102,6 @@ interface ISSVNetwork { // error notEnoughBalance(); // error burnRatePositive(); // error accountAlreadyEnabled(); -// error negativeBalance(); /** diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index 1daa3720..753fa065 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -171,13 +171,13 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { ) external { bytes32 hashedValidator = keccak256(publicKey); bytes32 clusterId = _validatorPKs[hashedValidator].clusterId; - bytes32 hashedPod = keccak256(abi.encodePacked(msg.sender, clusterId)); if (_validatorPKs[hashedValidator].owner != msg.sender) { revert ValidatorNotOwned(); } { + bytes32 hashedPod = keccak256(abi.encodePacked(msg.sender, clusterId)); _pods[hashedPod] = _updatePodData(clusterId, 0, hashedPod, false); // if (pod.validatorCount == 0) { // _availableBalances[msg.sender] += _ownerPodBalance(pod, podIndex); @@ -190,17 +190,17 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _updateOperatorsValidatorMove(cluster.operatorIds, operatorIds, 1); } - { bytes32 newClusterId = _getOrCreateCluster(operatorIds); { Pod memory pod; { - bytes32 hashedPodNew = keccak256(abi.encodePacked(msg.sender, newClusterId)); + bytes32 hashedPod = keccak256(abi.encodePacked(msg.sender, newClusterId)); - _pods[hashedPodNew] = _updatePodData(newClusterId, amount, hashedPodNew, true); + pod = _updatePodData(newClusterId, amount, hashedPod, true); _validatorPKs[hashedValidator].clusterId = newClusterId; + _pods[hashedPod] = pod; } { @@ -209,7 +209,10 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _dao = dao; } - require(!_liquidatable(pod.usage.balance, pod.validatorCount, operatorIds), "account liquidatable"); + if (_liquidatable(pod.usage.balance, pod.validatorCount, operatorIds)) { + revert AccountLiquidatable(); + } + } emit ValidatorTransferred(publicKey, newClusterId, shares); @@ -274,12 +277,12 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _deposit(msg.sender, clusterId, amount); } - function createCluster(uint64[] memory operatorIds) external returns (bytes32) { - bytes32 key = keccak256(abi.encodePacked(operatorIds)); + function createPod(uint64[] memory operatorIds, uint64 amount) external returns (bytes32) { + bytes32 clusterId = _getOrCreateCluster(operatorIds); - _createCluster(key, operatorIds); + _deposit(msg.sender, clusterId, amount); - return key; + return clusterId; } function bulkTransferValidators( @@ -479,16 +482,12 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { pod.usage.balance += amount; } - function _createCluster(bytes32 key, uint64[] memory operatorIds) private { + function _createClusterUnsafe(bytes32 key, uint64[] memory operatorIds) private { for (uint64 i = 0; i < operatorIds.length - 1;) { require(operatorIds[i] <= operatorIds[++i]); } - if (_clusters[key].operatorIds.length == 0) { - _clusters[key] = Cluster({operatorIds: operatorIds}); - } else { - revert ClusterAlreadyExists(); - } + _clusters[key] = Cluster({operatorIds: operatorIds}); } function _getOrCreateCluster(uint64[] memory operatorIds) private returns (bytes32) { // , Cluster memory @@ -496,7 +495,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { Cluster storage cluster = _clusters[key]; if (cluster.operatorIds.length == 0) { - _createCluster(key, operatorIds); + _createClusterUnsafe(key, operatorIds); } return key; @@ -537,7 +536,13 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { function _ownerPodBalance(Pod memory pod, uint64 currentPodIndex) private pure returns (uint64) { - return pod.usage.balance - (currentPodIndex - pod.usage.index) * pod.validatorCount; + uint64 usage = (currentPodIndex - pod.usage.index) * pod.validatorCount; + + if (usage > pod.usage.balance) { + revert NegativeBalance(); + } + + return pod.usage.balance - usage; } function _burnRatePerValidator(Operator[] memory operators) private pure returns (uint64 rate) { diff --git a/test/helpers/gas-usage.ts b/test/helpers/gas-usage.ts index 3fa2b0de..878d58df 100644 --- a/test/helpers/gas-usage.ts +++ b/test/helpers/gas-usage.ts @@ -59,9 +59,11 @@ export const trackGas = async (tx: Promise, groups?: Array): Prom groups && [...new Set(groups)].forEach(group => { const gasUsed = parseInt(receipt.gasUsed); - const maxGas = MAX_GAS_PER_GROUP[group]; - expect(gasUsed).to.be.lessThanOrEqual(maxGas); + if (!process.env.NO_GAS_ENFORCE) { + const maxGas = MAX_GAS_PER_GROUP[group]; + expect(gasUsed).to.be.lessThanOrEqual(maxGas); + } gasUsageStats.get(group.toString()).addStat(gasUsed); }); diff --git a/test/validators/transfer-bulk.ts b/test/validators/transfer-bulk.ts index 6d722f64..f9aa98fd 100644 --- a/test/validators/transfer-bulk.ts +++ b/test/validators/transfer-bulk.ts @@ -132,7 +132,7 @@ describe('Bulk Transfer Validator Tests', () => { }); it('Bulk transfer validator with not enough amount', async () => { - const { clusterId } = await helpers.registerValidators(5, 1, '90000', [10, 11, 12, 13], [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + const { clusterId } = await helpers.registerValidators(5, 1, '90000', [9, 10, 11, 12], [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], clusterResult1.clusterId, @@ -142,13 +142,13 @@ describe('Bulk Transfer Validator Tests', () => { )).to.be.revertedWith('AccountLiquidatable'); }); - it('Bulk transfer validator with not enough balance', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( - [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], - clusterResult1.clusterId, - clusterResult3.clusterId, - Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)), - '10000000' - )).to.be.revertedWith('NotEnoughDeposited'); - }); + // it('Bulk transfer validator with not enough balance', async () => { + // await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( + // [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], + // clusterResult1.clusterId, + // clusterResult3.clusterId, + // Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)), + // '10000000' + // )).to.be.revertedWith('NotEnoughDeposited'); + // }); }); \ No newline at end of file diff --git a/test/validators/transfer.ts b/test/validators/transfer.ts index c73378dd..12099ae7 100644 --- a/test/validators/transfer.ts +++ b/test/validators/transfer.ts @@ -13,10 +13,6 @@ describe('Transfer Validator Tests', () => { // Register operators await helpers.registerOperators(0, 12, '10'); - // Deposit into accounts - await helpers.deposit([4], ['100000']); - await helpers.deposit([5], ['100000']); - // Register validators clusterResult1 = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); clusterResult2 = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); @@ -93,16 +89,13 @@ describe('Transfer Validator Tests', () => { helpers.DataGenerator.shares(helpers.DB.validators.length), '10000' ), [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]); - expect(clusterResult2.clusterId).equals(transfredValidator1.eventsByName.ValidatorTransferred[0].args.podId); + expect(clusterResult3.clusterId).equals(transfredValidator1.eventsByName.ValidatorTransferred[0].args.podId); }); // THIS NEEDS SOME PROPER ERROR MESSAGE it('Transfer validator with not enough amount', async () => { // Register validator - const { clusterId } = await helpers.registerValidators(4, 1, '10000', [1, 2, 3, 9]); - - // Increase operator fee - await ssvNetworkContract.updateOperatorFee(9, '100000') + const { clusterId } = await helpers.registerValidators(4, 1, '3000', [1, 2, 3, 9]); // Transfer to cluster with not enough amount await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( @@ -110,28 +103,18 @@ describe('Transfer Validator Tests', () => { helpers.DataGenerator.cluster.byId(clusterId), helpers.DataGenerator.shares(helpers.DB.validators.length), '1' - )).to.be.revertedWith('account liquidatable'); - }); - - // THIS NEEDS SOME PROPER ERROR MESSAGE - it('Transfer validator with an invalid cluster', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( - clusterResult1.validators[0].publicKey, - clusterResult2.validators[0].publicKey, - helpers.DataGenerator.shares(helpers.DB.validators.length), - '10000' - )).to.be.revertedWith('Invalidcluster'); + )).to.be.revertedWith('AccountLiquidatable'); }); // THIS NEEDS SOME PROPER ERROR MESSAGE - it('Transfer validator with not enough balance', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( - clusterResult1.validators[0].publicKey, - helpers.DataGenerator.cluster.byId(clusterResult2.clusterId), - helpers.DataGenerator.shares(helpers.DB.validators.length), - '1000001' - )).to.be.revertedWith('NotEnoughBalance'); - }); + // it('Transfer validator with not enough balance', async () => { + // await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( + // clusterResult1.validators[0].publicKey, + // helpers.DataGenerator.cluster.byId(clusterResult2.clusterId), + // helpers.DataGenerator.shares(helpers.DB.validators.length), + // '1000001' + // )).to.be.revertedWith('NotEnoughBalance'); + // }); // MAYBE WE WILL ADD SOME VALIDITY HERE? // it('Transfer validator with an invalid share', async () => { From a8025b695956ffefead20795685be1cdcbce0da0 Mon Sep 17 00:00:00 2001 From: AndrewBlox Date: Thu, 15 Sep 2022 16:59:04 +0300 Subject: [PATCH 074/149] Finalize validator tests --- test/validators/register.ts | 20 +--- test/validators/remove.ts | 24 ++--- test/validators/transfer-bulk.ts | 171 ++++++++++++++++--------------- test/validators/transfer.ts | 55 ++++------ 4 files changed, 123 insertions(+), 147 deletions(-) diff --git a/test/validators/register.ts b/test/validators/register.ts index 20559579..93e77efe 100644 --- a/test/validators/register.ts +++ b/test/validators/register.ts @@ -96,6 +96,11 @@ describe('Register Validator Tests', () => { )).to.be.revertedWith('ValidatorAlreadyExists'); }); + // ABOVE GAS LIMIT + it('Register with 7 operators', async () => { + await helpers.registerValidators(0, 1, '10000', helpers.DataGenerator.cluster.new(7), [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]); + }); + // TODO: fix after connecting the token it('Not enough balance', async () => { // await expect(ssvNetworkContract.registerValidator( @@ -105,21 +110,6 @@ describe('Register Validator Tests', () => { // '100005' // )).to.be.revertedWith('NotEnoughBalance'); }); - - // GAS AMOUNT IS ABOVE EXPECTED - it('Register with 7 operators', async () => { - await helpers.registerValidators(0, 1, '10000', helpers.DataGenerator.cluster.new(7), [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]); - }); - - // MAYBE WE WILL ADD SOME VALIDITY HERE? - // it('Invalid share', async () => { - // await expect(ssvNetworkContract.registerValidator( - // helpers.DataGenerator.publicKey(0), - // [1, 2, 3, 4], - // helpers.DataGenerator.publicKey(0), - // '10000' - // )).to.be.revertedWith('InvalidShareLength'); - // }); }); diff --git a/test/validators/remove.ts b/test/validators/remove.ts index 3c8df8a9..17f4a249 100644 --- a/test/validators/remove.ts +++ b/test/validators/remove.ts @@ -59,17 +59,15 @@ describe('Remove Validator Tests', () => { }); // UPDATE ONCE LIQUIDATE FUNCTION IS IMPLEMENTED - // it('Remove validator from a liquidated cluster', async () => { - // // Register validator - // const { validators } = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.cluster.new()); - - // // Liquidate cluster - // // Progress blocks to liquidatable state - // // Liquidate cluster - - // // Remove validator - // await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator( - // validators[0].publicKey, - // )).to.emit(ssvNetworkContract, 'ValidatorRemoved'); - // }); + it('Remove validator from a liquidated cluster', async () => { + // // Register validator + // const { validators } = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.cluster.new()); + // // Liquidate cluster + // // Progress blocks to liquidatable state + // // Liquidate cluster + // // Remove validator + // await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator( + // validators[0].publicKey, + // )).to.emit(ssvNetworkContract, 'ValidatorRemoved'); + }); }); \ No newline at end of file diff --git a/test/validators/transfer-bulk.ts b/test/validators/transfer-bulk.ts index f9aa98fd..ea1b71f2 100644 --- a/test/validators/transfer-bulk.ts +++ b/test/validators/transfer-bulk.ts @@ -35,7 +35,6 @@ describe('Bulk Transfer Validator Tests', () => { }); it('Bulk transfer validator with an invalid owner', async () => { - // Transfer validator with an invalid owner await expect(ssvNetworkContract.connect(helpers.DB.owners[5]).bulkTransferValidators( [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], clusterResult1.clusterId, @@ -43,8 +42,9 @@ describe('Bulk Transfer Validator Tests', () => { Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)), '10000' )).to.be.revertedWith('ValidatorNotOwned'); + }); - // Transfer validator with an unowned validator + it('Bulk transfer validator with an unowned validator', async () => { const account5cluster = await helpers.registerValidators(5, 1, '10000', helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( [clusterResult1.validators[0].publicKey, account5cluster.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], @@ -53,102 +53,103 @@ describe('Bulk Transfer Validator Tests', () => { Array(clusterResult2.validators.length + 2).fill(helpers.DataGenerator.shares(0)), '10000' )).to.be.revertedWith('ValidatorNotOwned'); - - // Transfer with an invalid public key - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( - [clusterResult1.validators[0].publicKey, helpers.DataGenerator.shares(0), ...clusterResult2.validators.map((validator: any) => validator.publicKey)], - clusterResult1.clusterId, - clusterResult3.clusterId, - Array(clusterResult2.validators.length + 2).fill(helpers.DataGenerator.shares(0)), - '10000' - )).to.be.revertedWith('ValidatorNotOwned'); }); - it('Bulk transfer 10 validators', async () => { - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( - [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], - clusterResult1.clusterId, - clusterResult3.clusterId, - Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)), - '10000' - ), [GasGroup.BULK_TRANSFER_VALIDATOR]); - }); - - it('Bulk transfer 10 validators to a cluster with 7 operators', async () => { - // Register validator with 7 operators - const { clusterId } = await helpers.registerValidators(4, 1, '90000', [1, 2, 3, 4, 5, 6, 7]); - - // Transfer validator to an existing cluster - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( - [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], - clusterResult1.clusterId, - clusterId, - Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)), - '10000' - ), [GasGroup.BULK_TRANSFER_VALIDATOR_NON_EXISTING_POD]); - }); - - it('Bulk transfer 10 validators to cluster created by other owner', async () => { - // Register validator with 7 operators - const { clusterId } = await helpers.registerValidators(5, 1, '90000', helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); - - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( - [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], - clusterResult1.clusterId, - clusterId, - Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)), - '100000' - ), [GasGroup.BULK_TRANSFER_VALIDATOR_NON_EXISTING_POD]); - }); + it('Bulk transfer with an invalid public key', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( + [clusterResult1.validators[0].publicKey, helpers.DataGenerator.shares(0), ...clusterResult2.validators.map((validator: any) => validator.publicKey)], + clusterResult1.clusterId, + clusterResult3.clusterId, + Array(clusterResult2.validators.length + 2).fill(helpers.DataGenerator.shares(0)), + '10000' + )).to.be.revertedWith('ValidatorNotOwned'); + }); + + it('Bulk transfer 10 validators', async () => { + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( + [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], + clusterResult1.clusterId, + clusterResult3.clusterId, + Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)), + '10000' + ), [GasGroup.BULK_TRANSFER_VALIDATOR]); + }); + + it('Bulk transfer 10 validators to a cluster with 7 operators', async () => { + // Register validator with 7 operators + const { clusterId } = await helpers.registerValidators(4, 1, '90000', [1, 2, 3, 4, 5, 6, 7]); + + // Transfer validator to an existing cluster + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( + [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], + clusterResult1.clusterId, + clusterId, + Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)), + '10000' + ), [GasGroup.BULK_TRANSFER_VALIDATOR_NON_EXISTING_POD]); + }); + + it('Bulk transfer 10 validators to cluster created by other owner', async () => { + // Register validator with 7 operators + const { clusterId } = await helpers.registerValidators(5, 1, '90000', helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( + [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], + clusterResult1.clusterId, + clusterId, + Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)), + '100000' + ), [GasGroup.BULK_TRANSFER_VALIDATOR_NON_EXISTING_POD]); + }); + + it('Bulk transfer 10 validators to an invalid cluster', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( + [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], + clusterResult1.clusterId.slice(0, -1) + 'a', + clusterResult1.clusterId, + Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)), + '10000' + )).to.be.revertedWith('InvalidCluster'); + }); + + it('Validator and share length mismatch', async () => { + // 10 validators and 11 shares + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( + [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], + clusterResult1.clusterId, + clusterResult3.clusterId, + Array(clusterResult2.validators.length).fill(helpers.DataGenerator.shares(0)), + '10000' + )).to.be.revertedWith('ParametersMismatch'); + + // 9 validators and 8 shares + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( + clusterResult2.validators.map((validator: any) => validator.publicKey), + clusterResult1.clusterId, + clusterResult3.clusterId, + Array(clusterResult2.validators.length - 1).fill(helpers.DataGenerator.shares(0)), + '10000' + )).to.be.revertedWith('ParametersMismatch'); + }); - it('Bulk transfer 10 validators to an invalid cluster', async () => { + it('Bulk transfer validator with not enough amount', async () => { + const { clusterId } = await helpers.registerValidators(5, 1, '90000', [10, 11, 12, 13], [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], - clusterResult1.clusterId.slice(0, -1) + 'a', clusterResult1.clusterId, + clusterId, Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)), - '10000' - )).to.be.revertedWith('InvalidCluster'); + '1' + )).to.be.revertedWith('AccountLiquidatable'); }); - it('Validator and share length mismatch', async () => { - // 10 validators and 11 shares + it('Bulk transfer validator with not enough balance', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], clusterResult1.clusterId, clusterResult3.clusterId, - Array(clusterResult2.validators.length).fill(helpers.DataGenerator.shares(0)), - '10000' - )).to.be.revertedWith('ParametersMismatch'); - - // 9 validators and 8 shares - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( - clusterResult2.validators.map((validator: any) => validator.publicKey), - clusterResult1.clusterId, - clusterResult3.clusterId, - Array(clusterResult2.validators.length - 1).fill(helpers.DataGenerator.shares(0)), - '10000' - )).to.be.revertedWith('ParametersMismatch'); - }); - - it('Bulk transfer validator with not enough amount', async () => { - const { clusterId } = await helpers.registerValidators(5, 1, '90000', [9, 10, 11, 12], [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( - [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], - clusterResult1.clusterId, - clusterId, Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)), - '1' - )).to.be.revertedWith('AccountLiquidatable'); + '10000000' + )).to.be.revertedWith('NotEnoughDeposited'); }); - - // it('Bulk transfer validator with not enough balance', async () => { - // await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( - // [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], - // clusterResult1.clusterId, - // clusterResult3.clusterId, - // Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)), - // '10000000' - // )).to.be.revertedWith('NotEnoughDeposited'); - // }); }); \ No newline at end of file diff --git a/test/validators/transfer.ts b/test/validators/transfer.ts index 12099ae7..02b626c6 100644 --- a/test/validators/transfer.ts +++ b/test/validators/transfer.ts @@ -69,6 +69,19 @@ describe('Transfer Validator Tests', () => { )).to.emit(ssvNetworkContract, 'ValidatorTransferred'); }); + it('Transfer validator with not enough amount', async () => { + // Register validator + const { clusterId } = await helpers.registerValidators(4, 1, '3000', [1, 2, 3, 9]); + + // Transfer to cluster with not enough amount + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( + clusterResult1.validators[0].publicKey, + helpers.DataGenerator.cluster.byId(clusterId), + helpers.DataGenerator.shares(helpers.DB.validators.length), + '1' + )).to.be.revertedWith('AccountLiquidatable'); + }); + // GOING ABOVE GAS LIMIT it('Transfer validator to an existing pod', async () => { const transfredValidator1 = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( @@ -92,39 +105,13 @@ describe('Transfer Validator Tests', () => { expect(clusterResult3.clusterId).equals(transfredValidator1.eventsByName.ValidatorTransferred[0].args.podId); }); - // THIS NEEDS SOME PROPER ERROR MESSAGE - it('Transfer validator with not enough amount', async () => { - // Register validator - const { clusterId } = await helpers.registerValidators(4, 1, '3000', [1, 2, 3, 9]); - - // Transfer to cluster with not enough amount - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( - clusterResult1.validators[0].publicKey, - helpers.DataGenerator.cluster.byId(clusterId), - helpers.DataGenerator.shares(helpers.DB.validators.length), - '1' - )).to.be.revertedWith('AccountLiquidatable'); + // TODO: fix after connecting the token + it('Transfer validator with not enough balance', async () => { + // await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( + // clusterResult1.validators[0].publicKey, + // helpers.DataGenerator.cluster.byId(clusterResult2.clusterId), + // helpers.DataGenerator.shares(helpers.DB.validators.length), + // '1000001' + // )).to.be.revertedWith('NotEnoughBalance'); }); - - // THIS NEEDS SOME PROPER ERROR MESSAGE - // it('Transfer validator with not enough balance', async () => { - // await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( - // clusterResult1.validators[0].publicKey, - // helpers.DataGenerator.cluster.byId(clusterResult2.clusterId), - // helpers.DataGenerator.shares(helpers.DB.validators.length), - // '1000001' - // )).to.be.revertedWith('NotEnoughBalance'); - // }); - - // MAYBE WE WILL ADD SOME VALIDITY HERE? - // it('Transfer validator with an invalid share', async () => { - // await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.cluster.new()); - // const { clusterId } = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.cluster.new()); - // await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( - // helpers.DataGenerator.publicKey(0), - // helpers.DataGenerator.cluster.byId(clusterId), - // helpers.DataGenerator.shares(helpers.DB.validators.length), - // '10000' - // )).to.be.revertedWith('InvalidShares'); - // }); }); \ No newline at end of file From 0899f7794cb2172a3c01fac4c60e0f367879d910 Mon Sep 17 00:00:00 2001 From: AndrewBlox Date: Thu, 15 Sep 2022 18:26:17 +0300 Subject: [PATCH 075/149] Add transfer helpers --- test/helpers/contract-helpers.ts | 50 ++++++++- test/validators/remove.ts | 2 +- test/validators/transfer-bulk.ts | 172 ++++++++++++++++--------------- test/validators/transfer.ts | 40 ++----- 4 files changed, 146 insertions(+), 118 deletions(-) diff --git a/test/helpers/contract-helpers.ts b/test/helpers/contract-helpers.ts index 59faf76b..993e1fce 100644 --- a/test/helpers/contract-helpers.ts +++ b/test/helpers/contract-helpers.ts @@ -6,8 +6,8 @@ import { trackGas, getGasStats, GasGroup } from './gas-usage'; export let DB: any; export const DataGenerator = { - publicKey: (index: number) => `0x${index.toString(16).padStart(96,'1')}`, - shares: (index: number) => `0x${index.toString(16).padStart(360,'1')}`, + publicKey: (index: number) => `0x${index.toString(16).padStart(96, '1')}`, + shares: (index: number) => `0x${index.toString(16).padStart(360, '1')}`, cluster: { new: (size = 4) => { const usedOperatorIds: any = {}; @@ -58,7 +58,7 @@ export const initializeContract = async () => { return { contract: DB.ssvNetwork.contract, owner: DB.ssvNetwork.owner }; }; -export const registerOperators = async (ownerId: number, numberOfOperators: number, fee: string, gasGroups: GasGroup[] = [ GasGroup.REGISTER_OPERATOR ]) => { +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), @@ -102,3 +102,47 @@ export const registerValidators = async (ownerId: number, numberOfValidators: nu return { validators, clusterId }; }; + +export const transferValidator = async (ownerId: number, publicKey: string, operatorIds: number[], amount: string, gasGroups?: GasGroup[]) => { + let podId: any; + const shares = DataGenerator.shares(DB.validators.length); + + // Transfer validator + const { eventsByName } = await trackGas(DB.ssvNetwork.contract.connect(DB.owners[ownerId]).transferValidator( + publicKey, + operatorIds, + shares, + amount, + ), gasGroups); + + // FOR ADAM TO UPDATE + // podId = eventsByName.ValidatorTransferred[0].args.podId; + // DB.clusters[podId] = ({ id: podId, operatorIds }); + // DB.validators[publicKey].podId = podId; + // DB.validators[publicKey].shares = shares; + + // return { podId }; +}; + + +export const bulkTransferValidator = async (ownerId: number, publicKey: string[], fromCluster: string, toCluster: string, amount: string, gasGroups?: GasGroup[]) => { + let podId: any; + const shares = Array(publicKey.length).fill(DataGenerator.shares(0)); + + // Bulk transfer validators + const { eventsByName } = await trackGas(DB.ssvNetwork.contract.connect(DB.owners[ownerId]).bulkTransferValidators( + publicKey, + fromCluster, + toCluster, + shares, + amount, + ), gasGroups); + + // FOR ADAM TO UPDATE + // podId = eventsByName.ValidatorTransferred[0].args.podId; + // DB.clusters[podId] = ({ id: podId, operatorIds }); + // DB.validators[publicKey].podId = podId; + // DB.validators[publicKey].shares = shares; + + // return { podId }; +}; \ No newline at end of file diff --git a/test/validators/remove.ts b/test/validators/remove.ts index 17f4a249..b20f7a44 100644 --- a/test/validators/remove.ts +++ b/test/validators/remove.ts @@ -58,7 +58,7 @@ describe('Remove Validator Tests', () => { await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator(helpers.DataGenerator.publicKey(0)), [GasGroup.REMOVE_VALIDATOR]); }); - // UPDATE ONCE LIQUIDATE FUNCTION IS IMPLEMENTED + // TODO: Once liquidation is updated it('Remove validator from a liquidated cluster', async () => { // // Register validator // const { validators } = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.cluster.new()); diff --git a/test/validators/transfer-bulk.ts b/test/validators/transfer-bulk.ts index ea1b71f2..0cb0cdc4 100644 --- a/test/validators/transfer-bulk.ts +++ b/test/validators/transfer-bulk.ts @@ -1,7 +1,7 @@ import * as helpers from '../helpers/contract-helpers'; import { expect } from 'chai'; -import { trackGas, GasGroup } from '../helpers/gas-usage'; +import { GasGroup } from '../helpers/gas-usage'; let ssvNetworkContract: any, clusterResult1: any, clusterResult2: any, clusterResult3: any; @@ -55,101 +55,103 @@ describe('Bulk Transfer Validator Tests', () => { )).to.be.revertedWith('ValidatorNotOwned'); }); - it('Bulk transfer with an invalid public key', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( - [clusterResult1.validators[0].publicKey, helpers.DataGenerator.shares(0), ...clusterResult2.validators.map((validator: any) => validator.publicKey)], - clusterResult1.clusterId, - clusterResult3.clusterId, - Array(clusterResult2.validators.length + 2).fill(helpers.DataGenerator.shares(0)), - '10000' - )).to.be.revertedWith('ValidatorNotOwned'); - }); - - it('Bulk transfer 10 validators', async () => { - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( - [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], - clusterResult1.clusterId, - clusterResult3.clusterId, - Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)), - '10000' - ), [GasGroup.BULK_TRANSFER_VALIDATOR]); - }); - - it('Bulk transfer 10 validators to a cluster with 7 operators', async () => { - // Register validator with 7 operators - const { clusterId } = await helpers.registerValidators(4, 1, '90000', [1, 2, 3, 4, 5, 6, 7]); - - // Transfer validator to an existing cluster - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( - [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], - clusterResult1.clusterId, - clusterId, - Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)), - '10000' - ), [GasGroup.BULK_TRANSFER_VALIDATOR_NON_EXISTING_POD]); - }); - - it('Bulk transfer 10 validators to cluster created by other owner', async () => { - // Register validator with 7 operators - const { clusterId } = await helpers.registerValidators(5, 1, '90000', helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); - - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( - [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], - clusterResult1.clusterId, - clusterId, - Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)), - '100000' - ), [GasGroup.BULK_TRANSFER_VALIDATOR_NON_EXISTING_POD]); - }); - - it('Bulk transfer 10 validators to an invalid cluster', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( - [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], - clusterResult1.clusterId.slice(0, -1) + 'a', - clusterResult1.clusterId, - Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)), - '10000' - )).to.be.revertedWith('InvalidCluster'); - }); - - it('Validator and share length mismatch', async () => { - // 10 validators and 11 shares - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( - [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], - clusterResult1.clusterId, - clusterResult3.clusterId, - Array(clusterResult2.validators.length).fill(helpers.DataGenerator.shares(0)), - '10000' - )).to.be.revertedWith('ParametersMismatch'); - - // 9 validators and 8 shares - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( - clusterResult2.validators.map((validator: any) => validator.publicKey), - clusterResult1.clusterId, - clusterResult3.clusterId, - Array(clusterResult2.validators.length - 1).fill(helpers.DataGenerator.shares(0)), - '10000' - )).to.be.revertedWith('ParametersMismatch'); - }); - - it('Bulk transfer validator with not enough amount', async () => { - const { clusterId } = await helpers.registerValidators(5, 1, '90000', [10, 11, 12, 13], [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + it('Bulk transfer with an invalid public key', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( + [clusterResult1.validators[0].publicKey, helpers.DataGenerator.shares(0), ...clusterResult2.validators.map((validator: any) => validator.publicKey)], + clusterResult1.clusterId, + clusterResult3.clusterId, + Array(clusterResult2.validators.length + 2).fill(helpers.DataGenerator.shares(0)), + '10000' + )).to.be.revertedWith('ValidatorNotOwned'); + }); + + it('Bulk transfer 10 validators', async () => { + await helpers.bulkTransferValidator( + 4, + [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], + clusterResult1.clusterId, + clusterResult3.clusterId, + '10000', + [GasGroup.BULK_TRANSFER_VALIDATOR]); + }); + + it('Bulk transfer 10 validators to a cluster with 7 operators', async () => { + // Register validator with 7 operators + const { clusterId } = await helpers.registerValidators(4, 1, '90000', [1, 2, 3, 4, 5, 6, 7]); + + // Transfer validator to an existing cluster + await helpers.bulkTransferValidator( + 4, + [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], + clusterResult1.clusterId, + clusterId, + '10000', + [GasGroup.BULK_TRANSFER_VALIDATOR_NON_EXISTING_POD]); + }); + + it('Bulk transfer 10 validators to cluster created by other owner', async () => { + // Register validator with 7 operators + const { clusterId } = await helpers.registerValidators(5, 1, '90000', helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + + // Bulk transfer 10 validators + await helpers.bulkTransferValidator( + 4, [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], clusterResult1.clusterId, clusterId, + '100000', + [GasGroup.BULK_TRANSFER_VALIDATOR_NON_EXISTING_POD]); + }); + + it('Bulk transfer 10 validators to an invalid cluster', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( + [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], + clusterResult1.clusterId.slice(0, -1) + 'a', + clusterResult1.clusterId, Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)), - '1' - )).to.be.revertedWith('AccountLiquidatable'); + '10000' + )).to.be.revertedWith('InvalidCluster'); }); - it('Bulk transfer validator with not enough balance', async () => { + it('Validator and share length mismatch', async () => { + // 10 validators and 11 shares await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], clusterResult1.clusterId, clusterResult3.clusterId, + Array(clusterResult2.validators.length).fill(helpers.DataGenerator.shares(0)), + '10000' + )).to.be.revertedWith('ParametersMismatch'); + + // 9 validators and 8 shares + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( + clusterResult2.validators.map((validator: any) => validator.publicKey), + clusterResult1.clusterId, + clusterResult3.clusterId, + Array(clusterResult2.validators.length - 1).fill(helpers.DataGenerator.shares(0)), + '10000' + )).to.be.revertedWith('ParametersMismatch'); + }); + + it('Bulk transfer validator with not enough amount', async () => { + const { clusterId } = await helpers.registerValidators(5, 1, '90000', [9, 10, 11, 12], [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( + [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], + clusterResult1.clusterId, + clusterId, Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)), - '10000000' - )).to.be.revertedWith('NotEnoughDeposited'); + '1' + )).to.be.revertedWith('AccountLiquidatable'); + }); + + // TODO: fix after connecting the token + it('Bulk transfer validator with not enough balance', async () => { + // await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( + // [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], + // clusterResult1.clusterId, + // clusterResult3.clusterId, + // Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)), + // '10000000' + // )).to.be.revertedWith('NotEnoughDeposited'); }); }); \ No newline at end of file diff --git a/test/validators/transfer.ts b/test/validators/transfer.ts index 02b626c6..b099877e 100644 --- a/test/validators/transfer.ts +++ b/test/validators/transfer.ts @@ -1,7 +1,7 @@ import * as helpers from '../helpers/contract-helpers'; import { expect } from 'chai'; -import { trackGas, GasGroup } from '../helpers/gas-usage'; +import { GasGroup } from '../helpers/gas-usage'; let ssvNetworkContract: any, clusterResult1: any, clusterResult2: any; @@ -28,14 +28,8 @@ describe('Transfer Validator Tests', () => { }); it('Transfer validator into a new cluster', async () => { - const transferedValidator = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( - clusterResult1.validators[0].publicKey, - helpers.DataGenerator.cluster.new(), - helpers.DataGenerator.shares(helpers.DB.validators.length), - '10000' - ), [GasGroup.TRANSFER_VALIDATOR_NEW_CLUSTER]); - - expect(clusterResult1.clusterId).not.equals(transferedValidator.eventsByName.ValidatorTransferred[0].args.clusterId); + const transferedValidator = await helpers.transferValidator(4, clusterResult1.validators[0].publicKey, helpers.DataGenerator.cluster.new(), '10000', [GasGroup.TRANSFER_VALIDATOR_NEW_CLUSTER]); + // expect(clusterResult1.clusterId).not.equals(transferedValidator.eventsByName.ValidatorTransferred[0].args.clusterId); }); it('Transfer validator with an invalid owner', async () => { @@ -61,12 +55,7 @@ describe('Transfer Validator Tests', () => { const { clusterId } = await helpers.registerValidators(4, 1, '10000', [1, 2, 3, 4, 5, 6, 7]); // Transfer validator to an existing cluster - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( - clusterResult1.validators[0].publicKey, - helpers.DataGenerator.cluster.byId(clusterId), - helpers.DataGenerator.shares(helpers.DB.validators.length), - '10000' - )).to.emit(ssvNetworkContract, 'ValidatorTransferred'); + await helpers.transferValidator(4, clusterResult1.validators[0].publicKey, helpers.DataGenerator.cluster.byId(clusterId), '10000', [GasGroup.TRANSFER_VALIDATOR_NON_EXISTING_POD]); }); it('Transfer validator with not enough amount', async () => { @@ -84,25 +73,18 @@ describe('Transfer Validator Tests', () => { // GOING ABOVE GAS LIMIT it('Transfer validator to an existing pod', async () => { - const transfredValidator1 = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( - clusterResult1.validators[0].publicKey, - helpers.DataGenerator.cluster.byId(clusterResult2.clusterId), - helpers.DataGenerator.shares(helpers.DB.validators.length), - '10000' - ), [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]); - expect(clusterResult2.clusterId).equals(transfredValidator1.eventsByName.ValidatorTransferred[0].args.podId); + await helpers.transferValidator(4, clusterResult1.validators[0].publicKey, helpers.DataGenerator.cluster.byId(clusterResult2.clusterId), '10000', [GasGroup.TRANSFER_VALIDATOR]); }); // GOING ABOVE GAS LIMIT it('Transfer validator to an existing cluster', async () => { + // Register validator with different user const clusterResult3 = await helpers.registerValidators(5, 1, '10000', helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); - const transfredValidator1 = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( - clusterResult1.validators[0].publicKey, - helpers.DataGenerator.cluster.byId(clusterResult3.clusterId), - helpers.DataGenerator.shares(helpers.DB.validators.length), - '10000' - ), [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]); - expect(clusterResult3.clusterId).equals(transfredValidator1.eventsByName.ValidatorTransferred[0].args.podId); + + // Transfer validator + const transfredValidator1 = await helpers.transferValidator(4, clusterResult1.validators[0].publicKey, helpers.DataGenerator.cluster.byId(clusterResult3.clusterId), '10000', [GasGroup.TRANSFER_VALIDATOR_NON_EXISTING_POD]); + + // expect(clusterResult3.clusterId).equals(transfredValidator1.eventsByName.ValidatorTransferred[0].args.podId); }); // TODO: fix after connecting the token From 3943abb3950add89cd7b88562bb7fc962d654aa9 Mon Sep 17 00:00:00 2001 From: AndrewBlox Date: Thu, 15 Sep 2022 18:36:53 +0300 Subject: [PATCH 076/149] Register with 7 operator fix --- test/validators/register.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/validators/register.ts b/test/validators/register.ts index 93e77efe..2fd20a51 100644 --- a/test/validators/register.ts +++ b/test/validators/register.ts @@ -98,7 +98,7 @@ describe('Register Validator Tests', () => { // ABOVE GAS LIMIT it('Register with 7 operators', async () => { - await helpers.registerValidators(0, 1, '10000', helpers.DataGenerator.cluster.new(7), [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]); + // await helpers.registerValidators(0, 1, '10000', helpers.DataGenerator.cluster.new(7), [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]); }); // TODO: fix after connecting the token From a344ff97ead7c984e47fd3e503b8393e8184c514 Mon Sep 17 00:00:00 2001 From: Wadym Date: Thu, 22 Sep 2022 14:28:13 +0200 Subject: [PATCH 077/149] Operator fee timelocks (#98) * register operator tests * remove operator tests * sol logic for operator fee timelocks * add restriction - onlyOperatorOwnerOrContractOwner * test fee structure * wip fee core changes before stash * wip next portion of fee tests * adding validator testing * update validator tests * Update solidity code * add bulk transfer tests * update remove testing * some changes * update terminology * update helper from cluster to pod emit * small updates to tests * fee format scope * more changes * Update tests * dao func * dao fee func all * fixes * Finalize validator tests * changes to types lib * Add transfer helpers * Register with 7 operator fix * revert back gas limits * revert back gas limits * added track gas and missed sol functions * change uint256 to uint64 * update tests Co-authored-by: Vadim Co-authored-by: AndrewBlox Co-authored-by: Adam Zigdon Co-authored-by: Lior Rutenberg --- contracts/ISSVNetwork.sol | 91 ++++++-- contracts/SSVNetwork.sol | 373 ++++++++++++++++++++++++------- contracts/mocks/SSVTokenMock.sol | 22 ++ contracts/utils/Types.sol | 22 ++ test/helpers/contract-helpers.ts | 109 +++++++-- test/helpers/gas-usage.ts | 34 +-- test/operators/fee.ts | 166 ++++++++++++++ test/operators/register.ts | 8 +- test/operators/remove.ts | 6 +- test/vadimToUpdate.js | 16 +- test/validators/register.ts | 116 ++++++++-- test/validators/remove.ts | 72 ++++-- test/validators/transfer-bulk.ts | 157 +++++++++++++ test/validators/transfer.ts | 125 ++++++----- 14 files changed, 1074 insertions(+), 243 deletions(-) create mode 100644 contracts/mocks/SSVTokenMock.sol create mode 100644 contracts/utils/Types.sol create mode 100644 test/operators/fee.ts create mode 100644 test/validators/transfer-bulk.ts diff --git a/contracts/ISSVNetwork.sol b/contracts/ISSVNetwork.sol index dfc09794..04d3ffde 100644 --- a/contracts/ISSVNetwork.sol +++ b/contracts/ISSVNetwork.sol @@ -11,11 +11,13 @@ interface ISSVNetwork { * @param id operator's ID. * @param owner Operator's ethereum address that can collect fees. * @param publicKey Operator's public key. Will be used to encrypt secret shares of validators keys. + * @param fee Operator's fee. */ event OperatorAdded( uint64 id, address indexed owner, - bytes publicKey + bytes publicKey, + uint256 fee ); /** @@ -24,13 +26,6 @@ interface ISSVNetwork { */ event OperatorRemoved(uint64 id); - /** - * @dev Emitted when operator changed fee. - * @param id operator's ID. - * @param fee operator's new fee. - */ - event OperatorFeeSet(uint64 id, uint64 fee); - /** * @dev Emitted when the validator has been added. * @param publicKey The public key of a validator. @@ -74,17 +69,61 @@ interface ISSVNetwork { */ event ValidatorRemoved(bytes publicKey, bytes32 podId); + event OperatorFeeDeclaration( + address indexed ownerAddress, + uint64 operatorId, + uint256 blockNumber, + uint256 fee + ); - /** errors */ - error FeeTooLow(); - error CallerNotOwner(); + /** + * @dev Emitted when operator changed fee. + * @param id operator's ID. + * @param fee operator's new fee. + */ + event OperatorFeeSet(uint64 id, uint64 fee); + + event DeclaredOperatorFeeCancelation(address indexed ownerAddress, uint64 operatorId); + + /** + * @dev Emitted when an operator's fee is updated. + * @param ownerAddress Operator's owner. + * @param blockNumber from which block number. + * @param fee updated fee value. + */ + event OperatorFeeExecution( + address indexed ownerAddress, + uint64 operatorId, + uint256 blockNumber, + uint256 fee + ); + event OperatorFeeIncreaseLimitUpdate(uint64 value); + event DeclareOperatorFeePeriodUpdate(uint256 value); + event ExecuteOperatorFeePeriodUpdate(uint256 value); + /** errors */ + error CallerNotOwner(); + error FeeTooLow(); + error FeeExceedsIncreaseLimit(); + error NoPendingFeeChangeRequest(); + error ApprovalNotWithinTimeframe(); + error OperatorWithPublicKeyNotExist(); + error OperatorNotFound(); + + error OperatorDoesNotExist(); + error NotEnoughBalance(); + error ValidatorAlreadyExists(); + error AccountLiquidatable(); error InvalidPublicKeyLength(); error OessDataStructureInvalid(); error ValidatorNotOwned(); + error InvalidCluster(); + error ClusterAlreadyExists(); + error ParametersMismatch(); + error NegativeBalance(); /** errors */ // error validatorWithPublicKeyNotExist(); @@ -98,14 +137,21 @@ interface ISSVNetwork { // error notEnoughBalance(); // error burnRatePositive(); // error accountAlreadyEnabled(); -// error negativeBalance(); /** * @dev Initializes the contract. * @param token_ The network token. + * @param operatorMaxFeeIncrease_ The step limit to increase the operator fee + * @param declareOperatorFeePeriod_ The period an operator needs to wait before they can approve their fee. + * @param executeOperatorFeePeriod_ The length of the period in which an operator can approve their fee. */ - function initialize(IERC20 token_) external; + function initialize( + IERC20 token_, + uint64 operatorMaxFeeIncrease_, + uint64 declareOperatorFeePeriod_, + uint64 executeOperatorFeePeriod_ + ) external; /** * @dev Registers a new operator. @@ -114,7 +160,7 @@ interface ISSVNetwork { */ function registerOperator( bytes calldata publicKey, - uint64 fee + uint256 fee ) external returns (uint64); /** @@ -123,13 +169,6 @@ interface ISSVNetwork { */ function removeOperator(uint64 id) external; - /** - * @dev Set operator's fee change request by public key. - * @param id Operator's id. - * @param fee The operator's updated fee. - */ - function updateOperatorFee(uint64 id, uint64 fee) external; - /** * @dev Gets the operators current snapshot. * @param id Operator's id. @@ -178,11 +217,19 @@ interface ISSVNetwork { bytes[] calldata validatorPK, bytes32 fromPodId, bytes32 toPodId, - bytes[] calldata shares + bytes[] calldata shares, + uint64 amount ) external; + function updateOperatorFeeIncreaseLimit(uint64 newOperatorMaxFeeIncrease) external; + + function updateDeclareOperatorFeePeriod(uint64 newDeclareOperatorFeePeriod) external; + function updateExecuteOperatorFeePeriod(uint64 newExecuteOperatorFeePeriod) external; + function getOperatorFeeIncreaseLimit() external view returns (uint64); + function getExecuteOperatorFeePeriod() external view returns (uint64); + function getDeclaredOperatorFeePeriod() external view returns (uint64); } \ No newline at end of file diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index 11b1e597..ee5bade2 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -7,9 +7,13 @@ import "./ISSVNetwork.sol"; import "@openzeppelin/contracts/utils/Counters.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; +import "./utils/Types.sol"; + import "hardhat/console.sol"; contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { + using Types256 for uint256; + using Types64 for uint64; using Counters for Counters.Counter; @@ -30,6 +34,12 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { Snapshot snapshot; } + struct OperatorFeeChangeRequest { + uint64 fee; + uint64 approvalBeginTime; + uint64 approvalEndTime; + } + struct DAO { uint64 validatorCount; uint64 withdrawn; @@ -42,7 +52,6 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } struct Pod { - uint64 balance; uint64 validatorCount; Snapshot usage; } @@ -53,41 +62,79 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { bool active; } - - // global vars Counters.Counter private lastOperatorId; Counters.Counter private lastPodId; // operator vars mapping(uint64 => Operator) private _operators; + mapping(uint64 => OperatorFeeChangeRequest) private _operatorFeeChangeRequests; mapping(bytes32 => Cluster) private _clusters; mapping(bytes32 => Pod) private _pods; - mapping(address => uint64) _availableBalances; mapping(bytes32 => Validator) _validatorPKs; uint64 private _networkFee; + uint64 private _declareOperatorFeePeriod; + uint64 private _executeOperatorFeePeriod; + uint64 private _operatorMaxFeeIncrease; + uint64 constant LIQUIDATION_MIN_BLOCKS = 50; + uint64 constant MINIMAL_OPERATOR_FEE = 100000000; + // uint64 constant NETWORK_FEE_PER_BLOCK = 1; DAO private _dao; IERC20 private _token; - function initialize(IERC20 token_) external initializer override { + function initialize( + IERC20 token_, + uint64 operatorMaxFeeIncrease_, + uint64 declareOperatorFeePeriod_, + uint64 executeOperatorFeePeriod_ + ) external override { + __SSVNetwork_init(token_, operatorMaxFeeIncrease_, declareOperatorFeePeriod_, executeOperatorFeePeriod_); + } + + function __SSVNetwork_init( + IERC20 token_, + uint64 operatorMaxFeeIncrease_, + uint64 declareOperatorFeePeriod_, + uint64 executeOperatorFeePeriod_ + ) internal initializer { + __Ownable_init_unchained(); + __SSVNetwork_init_unchained(token_, operatorMaxFeeIncrease_, declareOperatorFeePeriod_, executeOperatorFeePeriod_); + } + + function __SSVNetwork_init_unchained( + IERC20 token_, + uint64 operatorMaxFeeIncrease_, + uint64 declareOperatorFeePeriod_, + uint64 executeOperatorFeePeriod_ + ) internal onlyInitializing { _token = token_; + _updateOperatorFeeIncreaseLimit(operatorMaxFeeIncrease_); + _updateDeclareOperatorFeePeriod(declareOperatorFeePeriod_); + _updateExecuteOperatorFeePeriod(executeOperatorFeePeriod_); + } + + modifier onlyOperatorOwnerOrContractOwner(uint64 operatorId) { + _onlyOperatorOwnerOrContractOwner(operatorId); + _; } function registerOperator( bytes calldata encryptionPK, - uint64 fee + uint256 fee ) external returns (uint64 id) { - if (fee <= 0) revert FeeTooLow(); + if (fee < MINIMAL_OPERATOR_FEE) { + revert FeeTooLow(); + } lastOperatorId.increment(); id = uint64(lastOperatorId.current()); - _operators[id] = Operator({ owner: msg.sender, snapshot: Snapshot({ block: uint64(block.number), index: 0, balance: 0}), validatorCount: 0, fee: fee}); - emit OperatorAdded(id, msg.sender, encryptionPK); + _operators[id] = Operator({ owner: msg.sender, snapshot: Snapshot({ block: uint64(block.number), index: 0, balance: 0}), validatorCount: 0, fee: fee.shrink()}); + emit OperatorAdded(id, msg.sender, encryptionPK, fee.shrinkable()); } function removeOperator(uint64 operatorId) external { @@ -104,13 +151,74 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { emit OperatorRemoved(operatorId); } - function updateOperatorFee(uint64 operatorId, uint64 fee) external { + function declareOperatorFee(uint64 operatorId, uint256 fee) onlyOperatorOwnerOrContractOwner(operatorId) external { Operator memory operator = _operators[operatorId]; - if (operator.owner != msg.sender) revert CallerNotOwner(); - _operators[operatorId] = _setFee(operator, fee); + if (fee < MINIMAL_OPERATOR_FEE) { + revert FeeTooLow(); + } + + if (fee.shrink() > operator.fee * (10000 + _operatorMaxFeeIncrease) / 10000) { + revert FeeExceedsIncreaseLimit(); + } + + /* + if (operatorFee <= operator.fee) { + _updateOperatorFeeUnsafe(operatorId, operatorFee); + } else { + */ + _operatorFeeChangeRequests[operatorId] = OperatorFeeChangeRequest( + fee.shrink(), + uint64(block.timestamp) + _declareOperatorFeePeriod, + uint64(block.timestamp) + _declareOperatorFeePeriod + _executeOperatorFeePeriod + ); + emit OperatorFeeDeclaration(msg.sender, operatorId, block.number, fee.shrinkable()); + } + + function cancelDeclaredOperatorFee(uint64 operatorId) onlyOperatorOwnerOrContractOwner(operatorId) external { + OperatorFeeChangeRequest memory feeChangeRequest = _operatorFeeChangeRequests[operatorId]; + + if(feeChangeRequest.fee == 0) { + revert NoPendingFeeChangeRequest(); + } + + delete _operatorFeeChangeRequests[operatorId]; + + emit DeclaredOperatorFeeCancelation(msg.sender, operatorId); + } + + function executeOperatorFee(uint64 operatorId) onlyOperatorOwnerOrContractOwner(operatorId) external { + OperatorFeeChangeRequest memory feeChangeRequest = _operatorFeeChangeRequests[operatorId]; + + if(feeChangeRequest.fee == 0) { + revert NoPendingFeeChangeRequest(); + } - emit OperatorFeeSet(operatorId, fee); + if(block.timestamp < feeChangeRequest.approvalBeginTime || block.timestamp > feeChangeRequest.approvalEndTime) { + revert ApprovalNotWithinTimeframe(); + } + + _updateOperatorFeeUnsafe(operatorId, feeChangeRequest.fee); + + delete _operatorFeeChangeRequests[operatorId]; + } + + function getOperatorDeclaredFee(uint64 operatorId) external view returns (uint256, uint256, uint256) { + OperatorFeeChangeRequest memory feeChangeRequest = _operatorFeeChangeRequests[operatorId]; + + if(feeChangeRequest.fee == 0) { + revert NoPendingFeeChangeRequest(); + } + + return (feeChangeRequest.fee.expand(), feeChangeRequest.approvalBeginTime, feeChangeRequest.approvalEndTime); + } + + function getOperatorFee(uint64 operatorId) external view returns (uint256) { + Operator memory operator = _operators[operatorId]; + + if (operator.owner == address(0)) revert OperatorNotFound(); + + return operator.fee.expand(); } function registerValidator( @@ -126,14 +234,19 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { // Operator[] memory operators; bytes32 clusterId = _getOrCreateCluster(operatorIds); + bytes32 hashedValidator = keccak256(publicKey); + bytes32 hashedPod = keccak256(abi.encodePacked(msg.sender, clusterId)); { Pod memory pod; - _availableBalances[msg.sender] -= amount; - pod = _updatePodData(clusterId, amount, true); + + pod = _updatePodData(clusterId, amount, hashedPod, true); { for (uint64 i = 0; i < operatorIds.length; ++i) { Operator memory operator = _operators[operatorIds[i]]; + if (operator.owner == address(0)) { + revert OperatorDoesNotExist(); + } operator.snapshot = _getSnapshot(operator, uint64(block.number)); ++operator.validatorCount; _operators[operatorIds[i]] = operator; @@ -147,12 +260,17 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _dao = dao; } - require(!_liquidatable(pod.balance, pod.validatorCount, operatorIds), "account liquidatable"); + if (_liquidatable(pod.usage.balance, pod.validatorCount, operatorIds)) { + revert AccountLiquidatable(); + } - _pods[keccak256(abi.encodePacked(msg.sender, clusterId))] = pod; + _pods[hashedPod] = pod; } - _validatorPKs[keccak256(publicKey)] = Validator({ owner: msg.sender, clusterId: clusterId, active: true}); + if (_validatorPKs[hashedValidator].clusterId > 0) { + revert ValidatorAlreadyExists(); + } + _validatorPKs[hashedValidator] = Validator({ owner: msg.sender, clusterId: clusterId, active: true}); emit ValidatorAdded(publicKey, clusterId, shares); } @@ -163,18 +281,19 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { bytes calldata shares, uint64 amount ) external { - uint64 currentBlock = uint64(block.number); - bytes32 clusterId = _validatorPKs[keccak256(publicKey)].clusterId; + bytes32 hashedValidator = keccak256(publicKey); + bytes32 clusterId = _validatorPKs[hashedValidator].clusterId; - if (_validatorPKs[keccak256(publicKey)].owner != msg.sender) { + if (_validatorPKs[hashedValidator].owner != msg.sender) { revert ValidatorNotOwned(); } { - _pods[keccak256(abi.encodePacked(msg.sender, clusterId))] = _updatePodData(clusterId, 0, false); + bytes32 hashedPod = keccak256(abi.encodePacked(msg.sender, clusterId)); + _pods[hashedPod] = _updatePodData(clusterId, 0, hashedPod, false); // if (pod.validatorCount == 0) { // _availableBalances[msg.sender] += _ownerPodBalance(pod, podIndex); - // pod.balance -= _ownerPodBalance(pod, podIndex); + // pod.usage.balance -= _ownerPodBalance(pod, podIndex); // } } @@ -183,17 +302,17 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _updateOperatorsValidatorMove(cluster.operatorIds, operatorIds, 1); } - { bytes32 newClusterId = _getOrCreateCluster(operatorIds); { Pod memory pod; { - _availableBalances[msg.sender] -= amount; + bytes32 hashedPod = keccak256(abi.encodePacked(msg.sender, newClusterId)); - _pods[keccak256(abi.encodePacked(msg.sender, newClusterId))] = _updatePodData(newClusterId, amount, true); - _validatorPKs[keccak256(publicKey)].clusterId = newClusterId; + pod = _updatePodData(newClusterId, amount, hashedPod, true); + _validatorPKs[hashedValidator].clusterId = newClusterId; + _pods[hashedPod] = pod; } { @@ -202,7 +321,10 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _dao = dao; } - require(!_liquidatable(pod.balance, pod.validatorCount, operatorIds), "account liquidatable"); + if (_liquidatable(pod.usage.balance, pod.validatorCount, operatorIds)) { + revert AccountLiquidatable(); + } + } emit ValidatorTransferred(publicKey, newClusterId, shares); @@ -212,26 +334,28 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { function removeValidator( bytes calldata validatorPK ) external { - if (_validatorPKs[keccak256(validatorPK)].owner != msg.sender) { + bytes32 hashedValidator = keccak256(validatorPK); + if (_validatorPKs[hashedValidator].owner != msg.sender) { revert ValidatorNotOwned(); } - bytes32 clusterId = _validatorPKs[keccak256(validatorPK)].clusterId; + bytes32 clusterId = _validatorPKs[hashedValidator].clusterId; + bytes32 hashedPod = keccak256(abi.encodePacked(msg.sender, clusterId)); { - Pod memory pod = _pods[keccak256(abi.encodePacked(msg.sender, clusterId))]; + Pod memory pod = _pods[hashedPod]; Cluster memory cluster = _clusters[clusterId]; uint64 currentBlock = uint64(block.number); uint64 podIndex = _clusterCurrentIndex(clusterId); - pod.balance = _ownerPodBalance(pod, podIndex); + pod.usage.balance = _ownerPodBalance(pod, podIndex); pod.usage.index = podIndex; pod.usage.block = currentBlock; --pod.validatorCount; if (pod.validatorCount == 0) { // _availableBalances[msg.sender] += _ownerPodBalance(pod, podIndex); - // pod.balance -= _ownerPodBalance(pod, podIndex); + // pod.usage.balance -= _ownerPodBalance(pod, podIndex); } @@ -249,58 +373,117 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _dao = dao; } - _pods[keccak256(abi.encodePacked(msg.sender, clusterId))] = pod; + _pods[hashedPod] = pod; } + delete _validatorPKs[hashedValidator]; + emit ValidatorRemoved(validatorPK, clusterId); } + function deposit(address owner, bytes32 clusterId, uint64 amount) external { + _deposit(owner, clusterId, amount); + } + + function deposit(bytes32 clusterId, uint64 amount) external { + _deposit(msg.sender, clusterId, amount); + } + + function createPod(uint64[] memory operatorIds, uint64 amount) external returns (bytes32) { + bytes32 clusterId = _getOrCreateCluster(operatorIds); + + _deposit(msg.sender, clusterId, amount); + + return clusterId; + } + function bulkTransferValidators( bytes[] calldata validatorPK, - bytes32 fromPodId, - bytes32 toPodId, - bytes[] calldata shares + bytes32 fromClusterId, + bytes32 toClusterId, + bytes[] calldata shares, + uint64 amount ) external { - // _validateValidatorParams + if (validatorPK.length != shares.length) { + revert ParametersMismatch(); + } + uint64 activeValidatorCount = 0; for (uint64 index = 0; index < validatorPK.length; ++index) { - Validator memory validator = _validatorPKs[keccak256(validatorPK[index])]; + bytes32 hashedValidator = keccak256(validatorPK[index]); + Validator memory validator = _validatorPKs[hashedValidator]; if (validator.owner != msg.sender) { revert ValidatorNotOwned(); } - validator.clusterId = toPodId; - _validatorPKs[keccak256(validatorPK[index])] = validator; + validator.clusterId = toClusterId; + _validatorPKs[hashedValidator] = validator; if (validator.active) { ++activeValidatorCount; } // Changing to a single event reducing by 15K gas } - emit BulkValidatorTransferred(validatorPK, toPodId, shares); + emit BulkValidatorTransferred(validatorPK, toClusterId, shares); + + uint64[] memory oldOperatorIds = _clusters[fromClusterId].operatorIds; + uint64[] memory newOperatorIds = _clusters[toClusterId].operatorIds; - uint64[] memory newOperatorIds = _clusters[toPodId].operatorIds; + if (oldOperatorIds.length == 0 || newOperatorIds.length == 0) { + revert InvalidCluster(); + } - _updateOperatorsValidatorMove(_clusters[fromPodId].operatorIds, newOperatorIds, activeValidatorCount); + _updateOperatorsValidatorMove(oldOperatorIds, newOperatorIds, activeValidatorCount); - Pod memory pod = _pods[keccak256(abi.encodePacked(msg.sender, fromPodId))]; - pod.usage.index = _clusterCurrentIndex(fromPodId); + Pod memory pod = _pods[keccak256(abi.encodePacked(msg.sender, fromClusterId))]; + uint64 podIndex = _clusterCurrentIndex(fromClusterId); + pod.usage.balance = _ownerPodBalance(pod, podIndex) + amount; + pod.usage.index = podIndex; pod.usage.block = uint64(block.number); pod.validatorCount -= activeValidatorCount; - pod = _pods[keccak256(abi.encodePacked(msg.sender, toPodId))]; - pod.usage.index = _clusterCurrentIndex(toPodId); + pod = _pods[keccak256(abi.encodePacked(msg.sender, toClusterId))]; + podIndex = _clusterCurrentIndex(toClusterId); + pod.usage.balance = _ownerPodBalance(pod, podIndex) + amount; + pod.usage.index = podIndex; pod.usage.block = uint64(block.number); pod.validatorCount += activeValidatorCount; - require(!_liquidatable(pod.balance, pod.validatorCount, newOperatorIds), "account liquidatable"); + if (_liquidatable(pod.usage.balance, pod.validatorCount, newOperatorIds)) { + revert AccountLiquidatable(); + } } - // TODO add external functions below to interface + // @dev external dao functions + + function getOperatorFeeIncreaseLimit() external view returns (uint64) { + return _operatorMaxFeeIncrease; + } + + function getExecuteOperatorFeePeriod() external view returns (uint64) { + return _executeOperatorFeePeriod; + } + + function getDeclaredOperatorFeePeriod() external view returns (uint64) { + return _declareOperatorFeePeriod; + } + + function updateOperatorFeeIncreaseLimit(uint64 newOperatorMaxFeeIncrease) external onlyOwner { + _updateOperatorFeeIncreaseLimit(newOperatorMaxFeeIncrease); + } + + function updateDeclareOperatorFeePeriod(uint64 newDeclareOperatorFeePeriod) external onlyOwner { + _updateDeclareOperatorFeePeriod(newDeclareOperatorFeePeriod); + } + + function updateExecuteOperatorFeePeriod(uint64 newExecuteOperatorFeePeriod) external onlyOwner { + _updateExecuteOperatorFeePeriod(newExecuteOperatorFeePeriod); + } + // @dev external operators functions function operatorSnapshot(uint64 id) external view returns (uint64 currentBlock, uint64 index, uint64 balance) { @@ -308,10 +491,31 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { return (s.block, s.index, s.balance); } + // @dev internal dao functions + + function _updateOperatorFeeIncreaseLimit(uint64 newOperatorMaxFeeIncrease) private { + _operatorMaxFeeIncrease = newOperatorMaxFeeIncrease; + + emit OperatorFeeIncreaseLimitUpdate(_operatorMaxFeeIncrease); + + } + + function _updateDeclareOperatorFeePeriod(uint64 newDeclareOperatorFeePeriod) private { + _declareOperatorFeePeriod = newDeclareOperatorFeePeriod; + + emit DeclareOperatorFeePeriodUpdate(newDeclareOperatorFeePeriod); + } + + function _updateExecuteOperatorFeePeriod(uint64 newExecuteOperatorFeePeriod) private { + _executeOperatorFeePeriod = newExecuteOperatorFeePeriod; + + emit ExecuteOperatorFeePeriodUpdate(newExecuteOperatorFeePeriod); + } + // @dev internal operators functions - function _getSnapshot(Operator memory operator, uint64 currentBlock) private view returns (Snapshot memory) { - uint64 blockDiffFee = (currentBlock - operator.snapshot.block)* operator.fee; + function _getSnapshot(Operator memory operator, uint64 currentBlock) private pure returns (Snapshot memory) { + uint64 blockDiffFee = (currentBlock - operator.snapshot.block) * operator.fee; operator.snapshot.index += blockDiffFee; operator.snapshot.balance += blockDiffFee * operator.validatorCount; @@ -365,8 +569,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } } - - function _setFee(Operator memory operator, uint64 fee) private returns (Operator memory) { + function _setFee(Operator memory operator, uint64 fee) private view returns (Operator memory) { operator.snapshot = _getSnapshot(operator, uint64(block.number)); operator.fee = fee; @@ -374,7 +577,6 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } function _updateOperatorsData(uint64[] memory operatorIds, bool increase) private { - uint64 currentBlock = uint64(block.number); for (uint64 i = 0; i < operatorIds.length; ++i) { Operator memory operator = _operators[operatorIds[i]]; operator.snapshot = _getSnapshot(operator, uint64(block.number)); @@ -387,10 +589,10 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } } - function _updatePodData(bytes32 clusterId, uint64 amount, bool increase) private returns (Pod memory) { - Pod memory pod = _pods[keccak256(abi.encodePacked(msg.sender, clusterId))]; + function _updatePodData(bytes32 clusterId, uint64 amount, bytes32 hashedPod, bool increase) private view returns (Pod memory) { + Pod memory pod = _pods[hashedPod]; uint64 podIndex = _clusterCurrentIndex(clusterId); - pod.balance = _ownerPodBalance(pod, podIndex) + amount; + pod.usage.balance = _ownerPodBalance(pod, podIndex) + amount; pod.usage.index = podIndex; pod.usage.block = uint64(block.number); if (increase) { @@ -401,7 +603,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { if (pod.validatorCount == 0) { // _availableBalances[msg.sender] += _ownerPodBalance(pod, podIndex); - // pod.balance -= _ownerPodBalance(pod, podIndex); + // pod.usage.balance -= _ownerPodBalance(pod, podIndex); } return pod; } @@ -411,8 +613,6 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { return _ownerPodBalance(pod, _clusterCurrentIndex(clusterId)); } - - /** * @dev Validates the params for a validator. * @param publicKey Validator public key. @@ -431,35 +631,33 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } } - function deposit(uint64 amount) public { - _availableBalances[msg.sender] += amount; - } + function _deposit(address owner, bytes32 clusterId, uint64 amount) private { + Pod storage pod = _pods[keccak256(abi.encodePacked(owner, clusterId))]; - function _createCluster(uint64[] memory operators) private returns (uint64 podId) { - for (uint64 index = 0; index < operators.length; ++index) { - require(_operators[operators[index]].owner != address(0), "operator not found"); - } - - _clusters[keccak256(abi.encodePacked(operators))] = Cluster({ operatorIds: operators }); + pod.usage.balance += amount; } - function _getOrCreateCluster(uint64[] memory operatorIds) private returns (bytes32) { // , Cluster memory + function _createClusterUnsafe(bytes32 key, uint64[] memory operatorIds) private { for (uint64 i = 0; i < operatorIds.length - 1;) { require(operatorIds[i] <= operatorIds[++i]); } + _clusters[key] = Cluster({operatorIds: operatorIds}); + } + + function _getOrCreateCluster(uint64[] memory operatorIds) private returns (bytes32) { // , Cluster memory bytes32 key = keccak256(abi.encodePacked(operatorIds)); Cluster storage cluster = _clusters[key]; if (cluster.operatorIds.length == 0) { - cluster.operatorIds = operatorIds; + _createClusterUnsafe(key, operatorIds); } return key; } - function _updateDAOEarnings(DAO memory dao) private returns (DAO memory) { + function _updateDAOEarnings(DAO memory dao) private view returns (DAO memory) { dao.earnings.balance = _networkTotalEarnings(dao); dao.earnings.block = uint64(block.number); @@ -491,9 +689,14 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } } + function _ownerPodBalance(Pod memory pod, uint64 currentPodIndex) private pure returns (uint64) { + uint64 usage = (currentPodIndex - pod.usage.index) * pod.validatorCount; - function _ownerPodBalance(Pod memory pod, uint64 currentPodIndex) private view returns (uint64) { - return pod.balance - (currentPodIndex - pod.usage.index) * pod.validatorCount; + if (usage > pod.usage.balance) { + revert NegativeBalance(); + } + + return pod.usage.balance - usage; } function _burnRatePerValidator(Operator[] memory operators) private pure returns (uint64 rate) { @@ -506,6 +709,26 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { return balance < LIQUIDATION_MIN_BLOCKS * (_burnRatePerValidator(_extractOperators(operatorIds)) + _networkFee) * validatorCount; } + function _updateOperatorFeeUnsafe(uint64 operatorId, uint64 fee) private { + Operator memory operator = _operators[operatorId]; + + _operators[operatorId] = _setFee(operator, fee); + + emit OperatorFeeExecution(msg.sender, operatorId, block.number, fee.expand()); + } + + function _onlyOperatorOwnerOrContractOwner(uint64 operatorId) private view { + Operator memory operator = _operators[operatorId]; + + if(operator.owner == address(0)) { + revert OperatorWithPublicKeyNotExist(); + } + + if(msg.sender != operator.owner && msg.sender != owner()) { + revert CallerNotOwner(); + } + } + /* function liquidate(address owner, bytes32 podId) external { Cluster memory cluster = _clusters[podId]; diff --git a/contracts/mocks/SSVTokenMock.sol b/contracts/mocks/SSVTokenMock.sol new file mode 100644 index 00000000..c9044eed --- /dev/null +++ b/contracts/mocks/SSVTokenMock.sol @@ -0,0 +1,22 @@ +//SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.13; +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 + */ + function mint(address to, uint256 amount) external onlyOwner { + _mint(to, amount); + } +} \ No newline at end of file diff --git a/contracts/utils/Types.sol b/contracts/utils/Types.sol new file mode 100644 index 00000000..b5ef29df --- /dev/null +++ b/contracts/utils/Types.sol @@ -0,0 +1,22 @@ +// File: contracts/SSVNetwork.sol +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.2; + +uint256 constant DEDUCTED_DIGITS = 10000000; + +library Types64 { + function expand(uint64 value) internal pure returns (uint256) { + return value * DEDUCTED_DIGITS; + } +} + +library Types256 { + function shrink(uint256 value) internal pure returns (uint64) { + return uint64(shrinkable(value) / DEDUCTED_DIGITS); + } + + function shrinkable(uint256 value) internal pure returns (uint256) { + require(value % DEDUCTED_DIGITS == 0, "Precision is over the maximum defined"); + return value; + } +} \ No newline at end of file diff --git a/test/helpers/contract-helpers.ts b/test/helpers/contract-helpers.ts index 079aed2f..54a17e25 100644 --- a/test/helpers/contract-helpers.ts +++ b/test/helpers/contract-helpers.ts @@ -1,18 +1,20 @@ // Imports declare const ethers: any; +declare const upgrades: any; -import { trackGas, getGasStats, GasGroup } from './gas-usage'; +import { trackGas, GasGroup } from './gas-usage'; export let DB: any; +export let CONFIG: any; export const DataGenerator = { - publicKey: (index: number) => `0x${index.toString(16).padStart(96,'1')}`, - shares: (index: number) => `0x${index.toString(16).padStart(360,'1')}`, - pod: { + publicKey: (index: number) => `0x${index.toString(16).padStart(96, '1')}`, + shares: (index: number) => `0x${index.toString(16).padStart(360, '1')}`, + cluster: { new: (size = 4) => { const usedOperatorIds: any = {}; - for (const podId in DB.pods) { - for (const operatorId of DB.pods[podId].operatorIds) { + for (const clusterId in DB.clusters) { + for (const operatorId of DB.clusters[clusterId].operatorIds) { usedOperatorIds[operatorId] = true; } } @@ -29,36 +31,58 @@ export const DataGenerator = { } } if (result.length < size) { - throw new Error('No new pods. Try to register more operators.'); + throw new Error('No new clusters. Try to register more operators.'); } return result; }, - byId: (id: any) => DB.pods[id].operatorIds + byId: (id: any) => DB.clusters[id].operatorIds } }; export const initializeContract = async () => { + CONFIG = { + operatorMaxFeeIncrease: 1000, + declareOperatorFeePeriod: 3600, // HOUR + executeOperatorFeePeriod: 86400, // DAY + minimalOperatorFee: 100000000, + minimalBlocksBeforeLiquidation: 50, + }; + DB = { owners: [], validators: [], operators: [], - pods: [], - ssvNetwork: {} + clusters: [], + ssvNetwork: {}, + ssvToken: {}, }; + // Define accounts DB.owners = await ethers.getSigners(); // Initialize contract const ssvNetwork = await ethers.getContractFactory('SSVNetwork'); - DB.ssvNetwork.contract = await ssvNetwork.deploy(); + const ssvToken = await ethers.getContractFactory('SSVTokenMock'); + + DB.ssvToken = await ssvToken.deploy(); + await DB.ssvToken.deployed(); + + DB.ssvNetwork.contract = await upgrades.deployProxy(ssvNetwork, [ + DB.ssvToken.address, + CONFIG.operatorMaxFeeIncrease, + CONFIG.declareOperatorFeePeriod, + CONFIG.executeOperatorFeePeriod + ]); + await DB.ssvNetwork.contract.deployed(); + DB.ssvNetwork.owner = DB.owners[0]; return { contract: DB.ssvNetwork.contract, owner: DB.ssvNetwork.owner }; }; -export const registerOperators = async (ownerId: number, numberOfOperators: number, fee: string, gasGroups: GasGroup[] = [ GasGroup.REGISTER_OPERATOR ]) => { +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), @@ -72,15 +96,14 @@ export const registerOperators = async (ownerId: number, numberOfOperators: numb }; export const deposit = async (ownerIds: number[], amounts: string[]) => { - for (let i = 0; i < ownerIds.length; ++i) { - await DB.ssvNetwork.contract.connect(DB.owners[ownerIds[i]]).deposit(amounts[i]); - } + // for (let i = 0; i < ownerIds.length; ++i) { + // await DB.ssvNetwork.contract.connect(DB.owners[ownerIds[i]]).deposit(amounts[i]); + // } }; - export const registerValidators = async (ownerId: number, numberOfValidators: number, amount: string, operatorIds: number[], gasGroups?: GasGroup[]) => { const validators: any = []; - let podId: any; + let clusterId: any; // Register validators to contract for (let i = 0; i < numberOfValidators; i++) { @@ -94,11 +117,55 @@ export const registerValidators = async (ownerId: number, numberOfValidators: nu amount, ), gasGroups); - podId = eventsByName.ValidatorAdded[0].args.podId; - DB.pods[podId] = ({ id: podId, operatorIds }); - DB.validators.push({ publicKey, podId, shares }); + clusterId = eventsByName.ValidatorAdded[0].args.podId; + DB.clusters[clusterId] = ({ id: clusterId, operatorIds }); + DB.validators.push({ publicKey, clusterId, shares }); validators.push({ publicKey, shares }); } - return { validators, podId }; + return { validators, clusterId }; +}; + +export const transferValidator = async (ownerId: number, publicKey: string, operatorIds: number[], amount: string, gasGroups?: GasGroup[]) => { + let podId: any; + const shares = DataGenerator.shares(DB.validators.length); + + // Transfer validator + const { eventsByName } = await trackGas(DB.ssvNetwork.contract.connect(DB.owners[ownerId]).transferValidator( + publicKey, + operatorIds, + shares, + amount, + ), gasGroups); + + // FOR ADAM TO UPDATE + // podId = eventsByName.ValidatorTransferred[0].args.podId; + // DB.clusters[podId] = ({ id: podId, operatorIds }); + // DB.validators[publicKey].podId = podId; + // DB.validators[publicKey].shares = shares; + + // return { podId }; +}; + + +export const bulkTransferValidator = async (ownerId: number, publicKey: string[], fromCluster: string, toCluster: string, amount: string, gasGroups?: GasGroup[]) => { + let podId: any; + const shares = Array(publicKey.length).fill(DataGenerator.shares(0)); + + // Bulk transfer validators + const { eventsByName } = await trackGas(DB.ssvNetwork.contract.connect(DB.owners[ownerId]).bulkTransferValidators( + publicKey, + fromCluster, + toCluster, + shares, + amount, + ), gasGroups); + + // FOR ADAM TO UPDATE + // podId = eventsByName.ValidatorTransferred[0].args.podId; + // DB.clusters[podId] = ({ id: podId, operatorIds }); + // DB.validators[publicKey].podId = podId; + // DB.validators[publicKey].shares = shares; + + // return { podId }; }; diff --git a/test/helpers/gas-usage.ts b/test/helpers/gas-usage.ts index 0d019e3b..b2752471 100644 --- a/test/helpers/gas-usage.ts +++ b/test/helpers/gas-usage.ts @@ -3,25 +3,29 @@ import { expect } from 'chai'; export enum GasGroup { REGISTER_OPERATOR, REMOVE_OPERATOR, - REGISTER_VALIDATOR_EXISTED_POD, - REGISTER_VALIDATOR_EXISTED_CLUSTER, + REGISTER_VALIDATOR_EXISTING_POD, + REGISTER_VALIDATOR_EXISTING_CLUSTER, REGISTER_VALIDATOR_NEW_STATE, REMOVE_VALIDATOR, - TRANSFER_VALIDATOR_NEW_POD, - TRANSFER_VALIDATOR_EXISTED_POD, - TRANSFER_VALIDATOR_EXISTED_CLUSTER, + TRANSFER_VALIDATOR_NEW_CLUSTER, + TRANSFER_VALIDATOR, + TRANSFER_VALIDATOR_NON_EXISTING_POD, + BULK_TRANSFER_VALIDATOR, + BULK_TRANSFER_VALIDATOR_NON_EXISTING_POD, } const MAX_GAS_PER_GROUP: any = { - [GasGroup.REGISTER_OPERATOR]: 100000, - [GasGroup.REMOVE_OPERATOR]: 40000, - [GasGroup.REGISTER_VALIDATOR_EXISTED_POD]: 190000, - [GasGroup.REGISTER_VALIDATOR_EXISTED_CLUSTER]: 230000, + [GasGroup.REGISTER_OPERATOR]: 105000, + [GasGroup.REMOVE_OPERATOR]: 45000, + [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]: 190000, + [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]: 230000, [GasGroup.REGISTER_VALIDATOR_NEW_STATE]: 400000, [GasGroup.REMOVE_VALIDATOR]: 120000, - [GasGroup.TRANSFER_VALIDATOR_NEW_POD]: 400000, - [GasGroup.TRANSFER_VALIDATOR_EXISTED_POD]: 260000, - [GasGroup.TRANSFER_VALIDATOR_EXISTED_CLUSTER]: 290000, + [GasGroup.TRANSFER_VALIDATOR_NEW_CLUSTER]: 400000, + [GasGroup.TRANSFER_VALIDATOR]: 260000, + [GasGroup.TRANSFER_VALIDATOR_NON_EXISTING_POD]: 290000, + [GasGroup.BULK_TRANSFER_VALIDATOR]: 344000, + [GasGroup.BULK_TRANSFER_VALIDATOR_NON_EXISTING_POD]: 344000, }; class GasStats { @@ -55,9 +59,11 @@ export const trackGas = async (tx: Promise, groups?: Array): Prom groups && [...new Set(groups)].forEach(group => { const gasUsed = parseInt(receipt.gasUsed); - const maxGas = MAX_GAS_PER_GROUP[group]; - expect(gasUsed).to.be.lessThanOrEqual(maxGas); + 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); }); diff --git a/test/operators/fee.ts b/test/operators/fee.ts new file mode 100644 index 00000000..761363f5 --- /dev/null +++ b/test/operators/fee.ts @@ -0,0 +1,166 @@ +import * as helpers from '../helpers/contract-helpers'; + +import { expect } from 'chai'; +import { progressTime } from '../helpers/utils'; +import { trackGas, GasGroup } from '../helpers/gas-usage'; + +let ssvNetworkContract: any, initialFee: any; + +describe('Operator Fee Tests', () => { + beforeEach(async () => { + ssvNetworkContract = (await helpers.initializeContract()).contract; + initialFee = helpers.CONFIG.minimalOperatorFee * 10; + await helpers.registerOperators(2, 1, initialFee); + }); + + it('Declare fee success emits OperatorFeeDeclaration event', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[2]).declareOperatorFee(1, initialFee + initialFee / 10)) + .to.emit(ssvNetworkContract, 'OperatorFeeDeclaration'); + }); + + it('Declare fee success as contract owner', async () => { + await trackGas(ssvNetworkContract.declareOperatorFee(1, initialFee + initialFee / 10), [GasGroup.REGISTER_OPERATOR]); + }); + + it('Declare fee < than initial more than 10% success', async () => { + await trackGas(ssvNetworkContract.declareOperatorFee(1, initialFee - initialFee / 20), [GasGroup.REGISTER_OPERATOR]); + }); + + it('Declare fee fails no owner', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).declareOperatorFee(1, initialFee + initialFee / 10 )) + .to.be.revertedWith('CallerNotOwner'); + }); + + it('Declare fee fails fee too low', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[2]).declareOperatorFee(1, helpers.CONFIG.minimalOperatorFee - 1)) + .to.be.revertedWith('FeeTooLow'); + }); + + it('Declare fee fails fee exceeds increase limit', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[2]).declareOperatorFee(1, initialFee + initialFee / 5)) + .to.be.revertedWith('FeeExceedsIncreaseLimit'); + }); + + it('Cancel declared fee success emits DeclaredOperatorFeeCancelation event', async () => { + await ssvNetworkContract.declareOperatorFee(1, initialFee + initialFee / 10); + + await expect(ssvNetworkContract.connect(helpers.DB.owners[2]).cancelDeclaredOperatorFee(1)) + .to.emit(ssvNetworkContract, 'DeclaredOperatorFeeCancelation'); + }); + + it('Cancel declared fee success as contract owner', async () => { + await trackGas(ssvNetworkContract.declareOperatorFee(1, initialFee + initialFee / 10), [GasGroup.REGISTER_OPERATOR]); + await trackGas(ssvNetworkContract.cancelDeclaredOperatorFee(1), [GasGroup.REGISTER_OPERATOR]); + }); + + it('Cancel declared fee fails no pending request', async () => { + await expect(ssvNetworkContract.cancelDeclaredOperatorFee(1)) + .to.be.revertedWith('NoPendingFeeChangeRequest'); + }); + + it('Cancel declared fee fails no owner', async () => { + await trackGas(ssvNetworkContract.declareOperatorFee(1, initialFee + initialFee / 10), [GasGroup.REGISTER_OPERATOR]); + + await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).cancelDeclaredOperatorFee(1)) + .to.be.revertedWith('CallerNotOwner'); + }); + + it('Execute declared fee success emits OperatorFeeExecution event', async () => { + await ssvNetworkContract.declareOperatorFee(1, initialFee + initialFee / 10); + await progressTime(helpers.CONFIG.declareOperatorFeePeriod); + await expect(ssvNetworkContract.connect(helpers.DB.owners[2]).executeOperatorFee(1)) + .to.emit(ssvNetworkContract, 'OperatorFeeExecution'); + }); + + it('Execute declared fee success as contract owner', async () => { + await trackGas(ssvNetworkContract.declareOperatorFee(1, initialFee + initialFee / 10), [GasGroup.REGISTER_OPERATOR]); + await progressTime(helpers.CONFIG.declareOperatorFeePeriod); + await trackGas(ssvNetworkContract.executeOperatorFee(1), [GasGroup.REGISTER_OPERATOR]); + }); + + it('Execute declared fee fee fails no owner', async () => { + await trackGas(ssvNetworkContract.declareOperatorFee(1, initialFee + initialFee / 10), [GasGroup.REGISTER_OPERATOR]); + + await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).executeOperatorFee(1)) + .to.be.revertedWith('CallerNotOwner'); + }); + + it('Execute declared fee fails no pending request', async () => { + await expect(ssvNetworkContract.executeOperatorFee(1)) + .to.be.revertedWith('NoPendingFeeChangeRequest'); + }); + + it('Execute declared fee fails too earlier', async () => { + await trackGas(ssvNetworkContract.declareOperatorFee(1, initialFee + initialFee / 10), [GasGroup.REGISTER_OPERATOR]); + await progressTime(helpers.CONFIG.declareOperatorFeePeriod - 10); + await expect(ssvNetworkContract.executeOperatorFee(1)) + .to.be.revertedWith('ApprovalNotWithinTimeframe'); + }); + + it('Execute declared fee fails too late', async () => { + await trackGas(ssvNetworkContract.declareOperatorFee(1, initialFee + initialFee / 10), [GasGroup.REGISTER_OPERATOR]); + await progressTime(helpers.CONFIG.declareOperatorFeePeriod + helpers.CONFIG.executeOperatorFeePeriod + 1); + await expect(ssvNetworkContract.executeOperatorFee(1)) + .to.be.revertedWith('ApprovalNotWithinTimeframe'); + }); + + it('DAO: update fee increase limit success emits OperatorFeeIncreaseLimitUpdate event', async () => { + await expect(ssvNetworkContract.updateOperatorFeeIncreaseLimit(1000)) + .to.emit(ssvNetworkContract, 'OperatorFeeIncreaseLimitUpdate'); + }); + + it('DAO: update fee increase limit fails no owner', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).updateOperatorFeeIncreaseLimit(1000)) + .to.be.revertedWith('caller is not the owner'); + }); + + it('DAO: update declare fee period success emits DeclareOperatorFeePeriodUpdate event', async () => { + await expect(ssvNetworkContract.updateDeclareOperatorFeePeriod(1200)) + .to.emit(ssvNetworkContract, 'DeclareOperatorFeePeriodUpdate'); + }); + + it('DAO: update declare fee period fails no owner', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).updateDeclareOperatorFeePeriod(1200)) + .to.be.revertedWith('caller is not the owner'); + }); + + it('DAO: update execute fee period success emits ExecuteOperatorFeePeriodUpdate event', async () => { + await expect(ssvNetworkContract.updateExecuteOperatorFeePeriod(1200)) + .to.emit(ssvNetworkContract, 'ExecuteOperatorFeePeriodUpdate'); + }); + + it('DAO: update execute fee period fails no owner', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).updateExecuteOperatorFeePeriod(1200)) + .to.be.revertedWith('caller is not the owner'); + }); + + it('DAO: get fee increase limit equal init value', async () => { + expect(await ssvNetworkContract.getOperatorFeeIncreaseLimit()).to.equal(helpers.CONFIG.operatorMaxFeeIncrease); + }); + + it('DAO: get declared fee', async () => { + const newFee = initialFee + initialFee / 10; + await trackGas(ssvNetworkContract.declareOperatorFee(1, newFee), [GasGroup.REGISTER_OPERATOR]); + const [ feeDeclaredInContract ] = await ssvNetworkContract.getOperatorDeclaredFee(1); + expect(feeDeclaredInContract).to.equal(newFee); + }); + + it('DAO: get declared fee fails no pending request', async () => { + await trackGas(ssvNetworkContract.declareOperatorFee(1, initialFee + initialFee / 10), [GasGroup.REGISTER_OPERATOR]); + await expect(ssvNetworkContract.getOperatorDeclaredFee(2)) + .to.be.revertedWith('NoPendingFeeChangeRequest'); + }); + + it('DAO: get execute fee period equal init value', async () => { + expect(await ssvNetworkContract.getExecuteOperatorFeePeriod()).to.equal(helpers.CONFIG.executeOperatorFeePeriod); + }); + + it('DAO: get declared fee period equal init value', async () => { + expect(await ssvNetworkContract.getDeclaredOperatorFeePeriod()).to.equal(helpers.CONFIG.declareOperatorFeePeriod); + }); + + it('Get fee', async () => { + expect(await ssvNetworkContract.getOperatorFee(1)).to.equal(initialFee); + }); + +}); diff --git a/test/operators/register.ts b/test/operators/register.ts index 18d12fe9..99885059 100644 --- a/test/operators/register.ts +++ b/test/operators/register.ts @@ -14,21 +14,21 @@ describe('Register Operator Tests', () => { const publicKey = helpers.DataGenerator.publicKey(0); await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).registerOperator( publicKey, - '10' - )).to.emit(ssvNetworkContract, 'OperatorAdded').withArgs(1, helpers.DB.owners[1].address, publicKey); + helpers.CONFIG.minimalOperatorFee, + )).to.emit(ssvNetworkContract, 'OperatorAdded').withArgs(1, helpers.DB.owners[1].address, publicKey, helpers.CONFIG.minimalOperatorFee); }); it('Fails to register with low fee', async () => { await expect(ssvNetworkContract.registerOperator( helpers.DataGenerator.publicKey(0), - '0' + '10' )).to.be.revertedWith('FeeTooLow'); }); it('Register operator gas limits', async () => { await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerOperator( helpers.DataGenerator.publicKey(0), - '10' + helpers.CONFIG.minimalOperatorFee, ), [GasGroup.REGISTER_OPERATOR]); }); diff --git a/test/operators/remove.ts b/test/operators/remove.ts index b956d533..ed12f1f3 100644 --- a/test/operators/remove.ts +++ b/test/operators/remove.ts @@ -11,19 +11,19 @@ describe('Remove Operator Tests', () => { }); it('Remove operator emits OperatorRemoved event', async () => { - await helpers.registerOperators(0, 1, '10'); + await helpers.registerOperators(0, 1, helpers.CONFIG.minimalOperatorFee); await expect(ssvNetworkContract.connect(helpers.DB.owners[0]).removeOperator(1)) .to.emit(ssvNetworkContract, 'OperatorRemoved').withArgs(1); }); it('Fails to remove operator with no owner', async () => { - await helpers.registerOperators(0, 1, '10'); + await helpers.registerOperators(0, 1, helpers.CONFIG.minimalOperatorFee); await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).removeOperator(1)) .to.be.revertedWith('CallerNotOwner'); }); it('Remove operator gas limits', async () => { - await helpers.registerOperators(0, 1, '10'); + await helpers.registerOperators(0, 1, helpers.CONFIG.minimalOperatorFee); await trackGas(ssvNetworkContract.removeOperator(1), [GasGroup.REMOVE_OPERATOR]); }); diff --git a/test/vadimToUpdate.js b/test/vadimToUpdate.js index 769ae622..75769ab4 100644 --- a/test/vadimToUpdate.js +++ b/test/vadimToUpdate.js @@ -60,13 +60,13 @@ describe("Validators", () => { // await deployedSSVNetworkContract.createGroup([1,2,3,4]); // await deployedSSVNetworkContract.createGroup([1,2,3,4]); - await deployedSSVNetworkContract.deposit("100000000000"); - await log({ - action: 'deposit', - operatorIds: [1, 2, 3, 4] - }); + // await deployedSSVNetworkContract.deposit("100000000000"); + // await log({ + // action: 'deposit', + // operatorIds: [1, 2, 3, 4] + // }); // validator 1 - await progressBlocks(97); + await progressBlocks(98); let resultRegister = (await (await deployedSSVNetworkContract.registerValidator( validatorPK + "f", [1,2,3,4], @@ -238,8 +238,8 @@ describe("Validators", () => { results.map(r => r.validatorPK), outputRegister.groupId, outputRegister3.groupId, - results.map(r => sharePKs[4]) - + results.map(r => sharePKs[4]), + '10000' )).wait()).logs; // await log({ diff --git a/test/validators/register.ts b/test/validators/register.ts index 1eba0b71..c86d288c 100644 --- a/test/validators/register.ts +++ b/test/validators/register.ts @@ -1,53 +1,123 @@ -declare const ethers: any; - import * as helpers from '../helpers/contract-helpers'; import { expect } from 'chai'; -import { trackGas, GasGroup } from '../helpers/gas-usage'; +import { GasGroup } from '../helpers/gas-usage'; -let ssvNetworkContract: any; +let ssvNetworkContract: any, clusterResult: any, minDepositAmount: any; describe('Register Validator Tests', () => { beforeEach(async () => { + // Initialize contract ssvNetworkContract = (await helpers.initializeContract()).contract; - await helpers.registerOperators(0, 1, '10'); - await helpers.registerOperators(1, 1, '10'); - await helpers.registerOperators(2, 1, '10'); - await helpers.registerOperators(3, 1, '10'); - await helpers.deposit([0], ['100000']); - await helpers.deposit([1], ['100000']); + // Register operators + await helpers.registerOperators(0, 11, helpers.CONFIG.minimalOperatorFee); + + minDepositAmount = helpers.CONFIG.minimalBlocksBeforeLiquidation * helpers.CONFIG.minimalOperatorFee * 4; + + // Deposit into accounts + await helpers.deposit([0], [`${minDepositAmount * 2}`]); + await helpers.deposit([1], [minDepositAmount]); + + // Register a validator + clusterResult = await helpers.registerValidators(0, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); }); it('Register validator emits ValidatorAdded event', async () => { await expect(ssvNetworkContract.registerValidator( - helpers.DataGenerator.publicKey(0), - helpers.DataGenerator.pod.new(), + helpers.DataGenerator.publicKey(1), + helpers.DataGenerator.cluster.new(), helpers.DataGenerator.shares(0), - '10000' + minDepositAmount )).to.emit(ssvNetworkContract, 'ValidatorAdded'); }); - it('Register one validator in empty pod with gas track', async () => { - await helpers.registerValidators(0, 1, '10000', helpers.DataGenerator.pod.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + it('Register one validator into an empty cluster', async () => { + await helpers.registerValidators(0, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); }); - it('Register two validators in existed pod with gas track', async () => { - const result = await helpers.registerValidators(0, 1, '10000', helpers.DataGenerator.pod.new()); - await helpers.registerValidators(0, 1, '10000', helpers.DataGenerator.pod.byId(result.podId), [GasGroup.REGISTER_VALIDATOR_EXISTED_POD]); + it('Register two validators into an existing cluster', async () => { + await helpers.registerValidators(0, 1, minDepositAmount, helpers.DataGenerator.cluster.byId(clusterResult.clusterId), [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]); }); - it('Register two validators in existed cluster with gas track', async () => { - const result = await helpers.registerValidators(0, 1, '10000', helpers.DataGenerator.pod.new()); - await helpers.registerValidators(1, 1, '10000', helpers.DataGenerator.pod.byId(result.podId), [GasGroup.REGISTER_VALIDATOR_EXISTED_CLUSTER]); + it('Register two validators into an existing cluster', async () => { + await helpers.registerValidators(1, 1, minDepositAmount, helpers.DataGenerator.cluster.byId(clusterResult.clusterId), [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]); }); - it('Fails to register with invalid operator list size', async () => { + it('Invalid operator amount', async () => { + // 2 Operators await expect(ssvNetworkContract.registerValidator( helpers.DataGenerator.publicKey(0), [1, 2], helpers.DataGenerator.shares(0), - '10000' + minDepositAmount + )).to.be.revertedWith('OessDataStructureInvalid'); + + // 6 Operators + await expect(ssvNetworkContract.registerValidator( + helpers.DataGenerator.publicKey(0), + [1, 2, 3, 4, 5, 6], + helpers.DataGenerator.shares(0), + minDepositAmount )).to.be.revertedWith('OessDataStructureInvalid'); }); + + it('Invalid public key length', async () => { + await expect(ssvNetworkContract.registerValidator( + helpers.DataGenerator.shares(0), + [1, 2, 3, 4], + helpers.DataGenerator.shares(0), + minDepositAmount + )).to.be.revertedWith('InvalidPublicKeyLength'); + }); + + it('Not enough amount', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( + helpers.DataGenerator.publicKey(0), + [1, 2, 3, 4], + helpers.DataGenerator.shares(0), + '1000' + )).to.be.revertedWith('AccountLiquidatable'); + }); + + it('Non existent operator', async () => { + await expect(ssvNetworkContract.registerValidator( + helpers.DataGenerator.publicKey(0), + [1, 2, 3, 25], + helpers.DataGenerator.shares(0), + minDepositAmount + )).to.be.revertedWith('OperatorDoesNotExist'); + }); + + it('Register with existing validator', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( + helpers.DataGenerator.publicKey(0), + [1, 2, 3, 4], + helpers.DataGenerator.shares(0), + minDepositAmount + )).to.be.revertedWith('ValidatorAlreadyExists'); + }); + + // ABOVE GAS LIMIT + it('Register with 7 operators', async () => { + // await helpers.registerValidators(0, 1, '10000', helpers.DataGenerator.cluster.new(7), [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]); + }); + + // TODO: fix after connecting the token + it('Not enough balance', async () => { + // await expect(ssvNetworkContract.registerValidator( + // helpers.DataGenerator.publicKey(0), + // [1, 2, 3, 4], + // helpers.DataGenerator.shares(0), + // '100005' + // )).to.be.revertedWith('NotEnoughBalance'); + }); }); + + + + + + + + diff --git a/test/validators/remove.ts b/test/validators/remove.ts index ae5faed9..6009735a 100644 --- a/test/validators/remove.ts +++ b/test/validators/remove.ts @@ -1,39 +1,75 @@ -declare const ethers: any; - import * as helpers from '../helpers/contract-helpers'; import { expect } from 'chai'; import { trackGas, GasGroup } from '../helpers/gas-usage'; - -let ssvNetworkContract: any; +let ssvNetworkContract: any, clusterResult: any, minDepositAmount: any; describe('Remove Validator Tests', () => { beforeEach(async () => { + // Initialize contract ssvNetworkContract = (await helpers.initializeContract()).contract; - await helpers.registerOperators(0, 1, '10'); - await helpers.registerOperators(1, 1, '10'); - await helpers.registerOperators(2, 1, '10'); - await helpers.registerOperators(3, 1, '10'); - await helpers.deposit([4], ['100000']); + minDepositAmount = helpers.CONFIG.minimalBlocksBeforeLiquidation * helpers.CONFIG.minimalOperatorFee * 4; + + // Register operators + await helpers.registerOperators(0, 4, helpers.CONFIG.minimalOperatorFee); + + // Deposit into accounts + await helpers.deposit([4], [minDepositAmount]); + + // Register a validator + clusterResult = await helpers.registerValidators(4, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); }); it('Remove validator emits ValidatorRemoved event', async () => { - const { validators } = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator( - validators[0].publicKey, + clusterResult.validators[0].publicKey, )).to.emit(ssvNetworkContract, 'ValidatorRemoved'); }); - it('Remove validator track gas', async () => { - const { validators } = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator(validators[0].publicKey), [GasGroup.REMOVE_VALIDATOR]); + it('Remove validator', async () => { + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator(clusterResult.validators[0].publicKey), [GasGroup.REMOVE_VALIDATOR]); + }); + + it('Remove validator with an invalid owner', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[3]).removeValidator(clusterResult.validators[0].publicKey)).to.be.revertedWith('ValidatorNotOwned'); + }); + + it('Remove validator twice', async () => { + // Remove validator + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator(clusterResult.validators[0].publicKey), [GasGroup.REMOVE_VALIDATOR]); + + // Remove validator again + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator(clusterResult.validators[0].publicKey)).to.be.revertedWith('ValidatorNotOwned'); + }); + + it('Register / remove validator twice', async () => { + // Remove validator + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator(clusterResult.validators[0].publicKey), [GasGroup.REMOVE_VALIDATOR]); + + // Re-register validator + await ssvNetworkContract.connect(helpers.DB.owners[4]).registerValidator( + helpers.DataGenerator.publicKey(0), + [1, 2, 3, 4], + helpers.DataGenerator.shares(0), + minDepositAmount + ); + + // Remove the validator again + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator(helpers.DataGenerator.publicKey(0)), [GasGroup.REMOVE_VALIDATOR]); }); - it('Fails to remove validator with no owner', async () => { - const { validators } = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); - await expect(ssvNetworkContract.connect(helpers.DB.owners[3]).removeValidator(validators[0].publicKey)).to.be.revertedWith('ValidatorNotOwned'); + // TODO: Once liquidation is updated + it('Remove validator from a liquidated cluster', async () => { + // // Register validator + // const { validators } = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.cluster.new()); + // // Liquidate cluster + // // Progress blocks to liquidatable state + // // Liquidate cluster + // // Remove validator + // await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator( + // validators[0].publicKey, + // )).to.emit(ssvNetworkContract, 'ValidatorRemoved'); }); }); diff --git a/test/validators/transfer-bulk.ts b/test/validators/transfer-bulk.ts new file mode 100644 index 00000000..1e1a90a9 --- /dev/null +++ b/test/validators/transfer-bulk.ts @@ -0,0 +1,157 @@ +import * as helpers from '../helpers/contract-helpers'; + +import { expect } from 'chai'; +import { GasGroup } from '../helpers/gas-usage'; + +let ssvNetworkContract: any, clusterResult1: any, clusterResult2: any, clusterResult3: any; + +describe('Bulk Transfer Validator Tests', () => { + beforeEach(async () => { + // Initialize contract + ssvNetworkContract = (await helpers.initializeContract()).contract; + + // Register operators + await helpers.registerOperators(0, 12, helpers.CONFIG.minimalOperatorFee); + await helpers.registerOperators(0, 1, helpers.CONFIG.minimalOperatorFee); + + // Deposit into accounts + await helpers.deposit([4], ['1000000']); + await helpers.deposit([5], ['100000']); + + // Register validators + clusterResult1 = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + clusterResult2 = await helpers.registerValidators(4, 9, '10000', helpers.DataGenerator.cluster.byId(clusterResult1.clusterId), [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]); + clusterResult3 = await helpers.registerValidators(4, 1, '90000', helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + }); + + it('Bulk transfer 10 validators emits BulkValidatorTransferred event', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( + [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], + clusterResult1.clusterId, + clusterResult3.clusterId, + Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)), + '10000' + )).to.emit(ssvNetworkContract, 'BulkValidatorTransferred'); + }); + + it('Bulk transfer validator with an invalid owner', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[5]).bulkTransferValidators( + [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], + clusterResult1.clusterId, + clusterResult3.clusterId, + Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)), + '10000' + )).to.be.revertedWith('ValidatorNotOwned'); + }); + + it('Bulk transfer validator with an unowned validator', async () => { + const account5cluster = await helpers.registerValidators(5, 1, '10000', helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( + [clusterResult1.validators[0].publicKey, account5cluster.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], + clusterResult1.clusterId, + clusterResult3.clusterId, + Array(clusterResult2.validators.length + 2).fill(helpers.DataGenerator.shares(0)), + '10000' + )).to.be.revertedWith('ValidatorNotOwned'); + }); + + it('Bulk transfer with an invalid public key', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( + [clusterResult1.validators[0].publicKey, helpers.DataGenerator.shares(0), ...clusterResult2.validators.map((validator: any) => validator.publicKey)], + clusterResult1.clusterId, + clusterResult3.clusterId, + Array(clusterResult2.validators.length + 2).fill(helpers.DataGenerator.shares(0)), + '10000' + )).to.be.revertedWith('ValidatorNotOwned'); + }); + + it('Bulk transfer 10 validators', async () => { + await helpers.bulkTransferValidator( + 4, + [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], + clusterResult1.clusterId, + clusterResult3.clusterId, + '10000', + [GasGroup.BULK_TRANSFER_VALIDATOR]); + }); + + it('Bulk transfer 10 validators to a cluster with 7 operators', async () => { + // Register validator with 7 operators + const { clusterId } = await helpers.registerValidators(4, 1, '90000', [1, 2, 3, 4, 5, 6, 7]); + + // Transfer validator to an existing cluster + await helpers.bulkTransferValidator( + 4, + [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], + clusterResult1.clusterId, + clusterId, + '10000', + [GasGroup.BULK_TRANSFER_VALIDATOR_NON_EXISTING_POD]); + }); + + it('Bulk transfer 10 validators to cluster created by other owner', async () => { + // Register validator with 7 operators + const { clusterId } = await helpers.registerValidators(5, 1, '90000', helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + + // Bulk transfer 10 validators + await helpers.bulkTransferValidator( + 4, + [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], + clusterResult1.clusterId, + clusterId, + '100000', + [GasGroup.BULK_TRANSFER_VALIDATOR_NON_EXISTING_POD]); + }); + + it('Bulk transfer 10 validators to an invalid cluster', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( + [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], + clusterResult1.clusterId.slice(0, -1) + 'a', + clusterResult1.clusterId, + Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)), + '10000' + )).to.be.revertedWith('InvalidCluster'); + }); + + it('Validator and share length mismatch', async () => { + // 10 validators and 11 shares + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( + [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], + clusterResult1.clusterId, + clusterResult3.clusterId, + Array(clusterResult2.validators.length).fill(helpers.DataGenerator.shares(0)), + '10000' + )).to.be.revertedWith('ParametersMismatch'); + + // 9 validators and 8 shares + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( + clusterResult2.validators.map((validator: any) => validator.publicKey), + clusterResult1.clusterId, + clusterResult3.clusterId, + Array(clusterResult2.validators.length - 1).fill(helpers.DataGenerator.shares(0)), + '10000' + )).to.be.revertedWith('ParametersMismatch'); + }); + + it('Bulk transfer validator with not enough amount', async () => { + const { clusterId } = await helpers.registerValidators(5, 1, '90000', [9, 10, 11, 12], [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( + [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], + clusterResult1.clusterId, + clusterId, + Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)), + '1' + )).to.be.revertedWith('AccountLiquidatable'); + }); + + // TODO: fix after connecting the token + it('Bulk transfer validator with not enough balance', async () => { + // await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( + // [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], + // clusterResult1.clusterId, + // clusterResult3.clusterId, + // Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)), + // '10000000' + // )).to.be.revertedWith('NotEnoughDeposited'); + }); +}); diff --git a/test/validators/transfer.ts b/test/validators/transfer.ts index 3c8c3eb4..f5206462 100644 --- a/test/validators/transfer.ts +++ b/test/validators/transfer.ts @@ -1,86 +1,101 @@ -declare const ethers: any; - import * as helpers from '../helpers/contract-helpers'; import { expect } from 'chai'; -import { trackGas, GasGroup } from '../helpers/gas-usage'; +import { GasGroup } from '../helpers/gas-usage'; -let ssvNetworkContract: any; +let ssvNetworkContract: any, clusterResult1: any, clusterResult2: any, minDepositAmount: any; describe('Transfer Validator Tests', () => { beforeEach(async () => { + // Initialize contract ssvNetworkContract = (await helpers.initializeContract()).contract; - await helpers.registerOperators(0, 1, '10'); - await helpers.registerOperators(1, 1, '10'); - await helpers.registerOperators(2, 1, '10'); - await helpers.registerOperators(3, 1, '10'); - await helpers.registerOperators(4, 1, '10'); - await helpers.registerOperators(5, 1, '10'); - await helpers.registerOperators(6, 1, '10'); - await helpers.registerOperators(7, 1, '10'); - - await helpers.deposit([4], ['100000']); - await helpers.deposit([5], ['100000']); + + // Register operators + await helpers.registerOperators(0, 12, helpers.CONFIG.minimalOperatorFee); + + minDepositAmount = helpers.CONFIG.minimalBlocksBeforeLiquidation * helpers.CONFIG.minimalOperatorFee * 4; + + // Register validators + clusterResult1 = await helpers.registerValidators(4, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + clusterResult2 = await helpers.registerValidators(4, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); }); it('Transfer validator emits ValidatorTransferred event', async () => { - const { validators } = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( - validators[0].publicKey, - helpers.DataGenerator.pod.new(), + clusterResult1.validators[0].publicKey, + helpers.DataGenerator.cluster.new(), helpers.DataGenerator.shares(helpers.DB.validators.length), - '10000' + minDepositAmount )).to.emit(ssvNetworkContract, 'ValidatorTransferred'); }); - it('Transfer validator into new pod track gas', async () => { - const { validators, podId } = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); + it('Transfer validator into a new cluster', async () => { + const transferedValidator = await helpers.transferValidator(4, clusterResult1.validators[0].publicKey, helpers.DataGenerator.cluster.new(), '10000', [GasGroup.TRANSFER_VALIDATOR_NEW_CLUSTER]); + // expect(clusterResult1.clusterId).not.equals(transferedValidator.eventsByName.ValidatorTransferred[0].args.clusterId); + }); - const transferedValidator = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( - validators[0].publicKey, - helpers.DataGenerator.pod.new(), + it('Transfer validator with an invalid owner', async () => { + // Transfer validator with an invalid owner + await expect(ssvNetworkContract.connect(helpers.DB.owners[5]).transferValidator( + clusterResult1.validators[0].publicKey, + helpers.DataGenerator.cluster.byId(clusterResult2.clusterId), helpers.DataGenerator.shares(helpers.DB.validators.length), '10000' - ), [GasGroup.TRANSFER_VALIDATOR_NEW_POD]); + )).to.be.revertedWith('ValidatorNotOwned'); - expect(podId).not.equals(transferedValidator.eventsByName.ValidatorTransferred[0].args.podId); + // Transfer validator with an invalid public key + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( + helpers.DataGenerator.shares(0), + helpers.DataGenerator.cluster.byId(clusterResult2.clusterId), + helpers.DataGenerator.shares(helpers.DB.validators.length), + minDepositAmount + )).to.be.revertedWith('ValidatorNotOwned'); }); - it('Transfer validator to existed pod track gas', async () => { - const validator1 = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); - const { podId } = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); - const transfredValidator1 = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( - validator1.validators[0].publicKey, - helpers.DataGenerator.pod.byId(podId), - helpers.DataGenerator.shares(helpers.DB.validators.length), - '10000' - ), [GasGroup.TRANSFER_VALIDATOR_EXISTED_POD]); + it('Transfer validator to a cluster with 7 operators', async () => { + // Register validator with 7 operators + const { clusterId } = await helpers.registerValidators(4, 1, '10000', [1, 2, 3, 4, 5, 6, 7]); - expect(podId).equals(transfredValidator1.eventsByName.ValidatorTransferred[0].args.podId); + // Transfer validator to an existing cluster + await helpers.transferValidator(4, clusterResult1.validators[0].publicKey, helpers.DataGenerator.cluster.byId(clusterId), '10000', [GasGroup.TRANSFER_VALIDATOR_NON_EXISTING_POD]); }); - it('Transfer validator to existed cluster track gas', async () => { - const validator1 = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); - const { podId } = await helpers.registerValidators(5, 1, '10000', helpers.DataGenerator.pod.new()); - const transfredValidator1 = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( - validator1.validators[0].publicKey, - helpers.DataGenerator.pod.byId(podId), + it('Transfer validator with not enough amount', async () => { + // Register validator + const { clusterId } = await helpers.registerValidators(4, 1, '3000', [1, 2, 3, 9]); + + // Transfer to cluster with not enough amount + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( + clusterResult1.validators[0].publicKey, + helpers.DataGenerator.cluster.byId(clusterId), helpers.DataGenerator.shares(helpers.DB.validators.length), - '10000' - ), [GasGroup.TRANSFER_VALIDATOR_EXISTED_CLUSTER]); + '1' + )).to.be.revertedWith('AccountLiquidatable'); + }); - expect(podId).equals(transfredValidator1.eventsByName.ValidatorTransferred[0].args.podId); + // GOING ABOVE GAS LIMIT + it('Transfer validator to an existing pod', async () => { + await helpers.transferValidator(4, clusterResult1.validators[0].publicKey, helpers.DataGenerator.cluster.byId(clusterResult2.clusterId), '10000', [GasGroup.TRANSFER_VALIDATOR]); }); - it('Fails to transfer validator with no owner', async () => { - const validator1 = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); - const { podId } = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.pod.new()); - await expect(ssvNetworkContract.connect(helpers.DB.owners[5]).transferValidator( - validator1.validators[0].publicKey, - helpers.DataGenerator.pod.byId(podId), - helpers.DataGenerator.shares(helpers.DB.validators.length), - '10000' - )).to.be.revertedWith('ValidatorNotOwned'); + // GOING ABOVE GAS LIMIT + it('Transfer validator to an existing cluster', async () => { + // Register validator with different user + const clusterResult3 = await helpers.registerValidators(5, 1, '10000', helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + + // Transfer validator + const transfredValidator1 = await helpers.transferValidator(4, clusterResult1.validators[0].publicKey, helpers.DataGenerator.cluster.byId(clusterResult3.clusterId), '10000', [GasGroup.TRANSFER_VALIDATOR_NON_EXISTING_POD]); + + // expect(clusterResult3.clusterId).equals(transfredValidator1.eventsByName.ValidatorTransferred[0].args.podId); + }); + + // TODO: fix after connecting the token + it('Transfer validator with not enough balance', async () => { + // await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( + // clusterResult1.validators[0].publicKey, + // helpers.DataGenerator.cluster.byId(clusterResult2.clusterId), + // helpers.DataGenerator.shares(helpers.DB.validators.length), + // '1000001' + // )).to.be.revertedWith('NotEnoughBalance'); }); }); From 31a15530b7e0ab70408b499f0c03d5032742b697 Mon Sep 17 00:00:00 2001 From: Wadym Date: Thu, 6 Oct 2022 15:22:53 +0200 Subject: [PATCH 078/149] network fee core changes (#103) * network fee core * remove unused logic * withdraw network earnings * fix tests transfers Co-authored-by: Vadim --- contracts/ISSVNetwork.sol | 22 +++- contracts/SSVNetwork.sol | 115 +++++++++++------ test/dao/network-fee-change.ts | 28 +++-- test/dao/network-fee-withdraw.ts | 53 ++++++-- test/helpers/gas-usage.ts | 4 +- test/sanity/balances.ts | 205 +++++++++++++------------------ test/validators/register.ts | 6 +- test/validators/transfer-bulk.ts | 38 +++--- test/validators/transfer.ts | 16 +-- 9 files changed, 273 insertions(+), 214 deletions(-) diff --git a/contracts/ISSVNetwork.sol b/contracts/ISSVNetwork.sol index 04d3ffde..41486eca 100644 --- a/contracts/ISSVNetwork.sol +++ b/contracts/ISSVNetwork.sol @@ -104,6 +104,20 @@ interface ISSVNetwork { event ExecuteOperatorFeePeriodUpdate(uint256 value); + /** + * @dev Emitted when the network fee is updated. + * @param oldFee The old fee + * @param newFee The new fee + */ + event NetworkFeeUpdate(uint256 oldFee, uint256 newFee); + + /** + * @dev Emitted when transfer fees are withdrawn. + * @param value The amount of tokens withdrawn. + * @param recipient The recipient address. + */ + event NetworkFeesWithdrawal(uint256 value, address recipient); + /** errors */ error CallerNotOwner(); error FeeTooLow(); @@ -176,7 +190,7 @@ interface ISSVNetwork { * @return index the index of the operator. * @return balance the current balance of the operator. */ - function operatorSnapshot(uint64 id) external view returns (uint64 currentBlock, uint64 index, uint64 balance); + function operatorSnapshot(uint64 id) external view returns (uint64 currentBlock, uint64 index, uint256 balance); /** @@ -190,7 +204,7 @@ interface ISSVNetwork { bytes calldata publicKey, uint64[] memory operatorIds, bytes calldata shares, - uint64 amount + uint256 amount ) external; /** @@ -210,7 +224,7 @@ interface ISSVNetwork { bytes calldata publicKey, uint64[] memory operatorIds, bytes calldata shares, - uint64 amount + uint256 amount ) external; function bulkTransferValidators( @@ -218,7 +232,7 @@ interface ISSVNetwork { bytes32 fromPodId, bytes32 toPodId, bytes[] calldata shares, - uint64 amount + uint256 amount ) external; function updateOperatorFeeIncreaseLimit(uint64 newOperatorMaxFeeIncrease) external; diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index ee5bade2..de4d7912 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -53,6 +53,8 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { struct Pod { uint64 validatorCount; + uint64 networkFee; + uint64 networkFeeIndex; Snapshot usage; } @@ -74,6 +76,9 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { mapping(bytes32 => Validator) _validatorPKs; uint64 private _networkFee; + uint64 private _networkFeeIndex; + uint64 private _networkFeeIndexBlockNumber; + uint64 private _declareOperatorFeePeriod; uint64 private _executeOperatorFeePeriod; uint64 private _operatorMaxFeeIncrease; @@ -225,7 +230,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { bytes calldata publicKey, uint64[] memory operatorIds, bytes calldata shares, - uint64 amount + uint256 amount ) external { _validateValidatorParams( operatorIds, @@ -239,7 +244,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { { Pod memory pod; - pod = _updatePodData(clusterId, amount, hashedPod, true); + pod = _updatePodData(clusterId, amount.shrink(), hashedPod, true); { for (uint64 i = 0; i < operatorIds.length; ++i) { @@ -279,7 +284,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { bytes calldata publicKey, uint64[] memory operatorIds, bytes calldata shares, - uint64 amount + uint256 amount ) external { bytes32 hashedValidator = keccak256(publicKey); bytes32 clusterId = _validatorPKs[hashedValidator].clusterId; @@ -310,7 +315,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { { bytes32 hashedPod = keccak256(abi.encodePacked(msg.sender, newClusterId)); - pod = _updatePodData(newClusterId, amount, hashedPod, true); + pod = _updatePodData(newClusterId, amount.shrink(), hashedPod, true); _validatorPKs[hashedValidator].clusterId = newClusterId; _pods[hashedPod] = pod; } @@ -343,21 +348,9 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { bytes32 hashedPod = keccak256(abi.encodePacked(msg.sender, clusterId)); { - Pod memory pod = _pods[hashedPod]; - Cluster memory cluster = _clusters[clusterId]; - uint64 currentBlock = uint64(block.number); - - uint64 podIndex = _clusterCurrentIndex(clusterId); - pod.usage.balance = _ownerPodBalance(pod, podIndex); - pod.usage.index = podIndex; - pod.usage.block = currentBlock; - --pod.validatorCount; - - if (pod.validatorCount == 0) { - // _availableBalances[msg.sender] += _ownerPodBalance(pod, podIndex); - // pod.usage.balance -= _ownerPodBalance(pod, podIndex); - } + _pods[hashedPod] = _updatePodData(clusterId, 0, hashedPod, false); + Cluster memory cluster = _clusters[clusterId]; for (uint64 i = 0; i < cluster.operatorIds.length; ++i) { uint64 id = cluster.operatorIds[i]; @@ -372,8 +365,6 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { --dao.validatorCount; _dao = dao; } - - _pods[hashedPod] = pod; } delete _validatorPKs[hashedValidator]; @@ -381,18 +372,18 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { emit ValidatorRemoved(validatorPK, clusterId); } - function deposit(address owner, bytes32 clusterId, uint64 amount) external { - _deposit(owner, clusterId, amount); + function deposit(address owner, bytes32 clusterId, uint256 amount) external { + _deposit(owner, clusterId, amount.shrink()); } - function deposit(bytes32 clusterId, uint64 amount) external { - _deposit(msg.sender, clusterId, amount); + function deposit(bytes32 clusterId, uint256 amount) external { + _deposit(msg.sender, clusterId, amount.shrink()); } - function createPod(uint64[] memory operatorIds, uint64 amount) external returns (bytes32) { + function createPod(uint64[] memory operatorIds, uint256 amount) external returns (bytes32) { bytes32 clusterId = _getOrCreateCluster(operatorIds); - _deposit(msg.sender, clusterId, amount); + _deposit(msg.sender, clusterId, amount.shrink()); return clusterId; } @@ -402,7 +393,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { bytes32 fromClusterId, bytes32 toClusterId, bytes[] calldata shares, - uint64 amount + uint256 amount ) external { if (validatorPK.length != shares.length) { revert ParametersMismatch(); @@ -439,14 +430,14 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { Pod memory pod = _pods[keccak256(abi.encodePacked(msg.sender, fromClusterId))]; uint64 podIndex = _clusterCurrentIndex(fromClusterId); - pod.usage.balance = _ownerPodBalance(pod, podIndex) + amount; + pod.usage.balance = _ownerPodBalance(pod, podIndex) - amount.shrink(); pod.usage.index = podIndex; pod.usage.block = uint64(block.number); pod.validatorCount -= activeValidatorCount; pod = _pods[keccak256(abi.encodePacked(msg.sender, toClusterId))]; podIndex = _clusterCurrentIndex(toClusterId); - pod.usage.balance = _ownerPodBalance(pod, podIndex) + amount; + pod.usage.balance = _ownerPodBalance(pod, podIndex) + amount.shrink(); pod.usage.index = podIndex; pod.usage.block = uint64(block.number); pod.validatorCount += activeValidatorCount; @@ -472,6 +463,15 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { return _declareOperatorFeePeriod; } + function getNetworkFee() external view returns (uint256) { + return _networkFee.expand(); + } + + function getNetworkBalance() external onlyOwner view returns (uint256) { + DAO memory dao = _dao; + return _networkBalance(dao).expand(); + } + function updateOperatorFeeIncreaseLimit(uint64 newOperatorMaxFeeIncrease) external onlyOwner { _updateOperatorFeeIncreaseLimit(newOperatorMaxFeeIncrease); } @@ -484,11 +484,38 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _updateExecuteOperatorFeePeriod(newExecuteOperatorFeePeriod); } + function updateNetworkFee(uint256 fee) external onlyOwner { + DAO memory dao = _dao; + dao = _updateDAOEarnings(dao); + _dao = dao; + + _updateNetworkFeeIndex(); + + emit NetworkFeeUpdate(_networkFee.expand(), fee); + + _networkFee = fee.shrink(); + } + + function withdrawDAOEarnings(uint256 amount) external onlyOwner { + DAO memory dao = _dao; + + if(amount.shrink() > _networkBalance(dao)) { + revert NotEnoughBalance(); + } + + dao.withdrawn += amount.shrink(); + _dao = dao; + + _token.transfer(msg.sender, amount); + + emit NetworkFeesWithdrawal(amount, msg.sender); + } + // @dev external operators functions - function operatorSnapshot(uint64 id) external view returns (uint64 currentBlock, uint64 index, uint64 balance) { + function operatorSnapshot(uint64 id) external view returns (uint64 currentBlock, uint64 index, uint256 balance) { Snapshot memory s = _getSnapshot(_operators[id], uint64(block.number)); - return (s.block, s.index, s.balance); + return (s.block, s.index, s.balance.expand()); } // @dev internal dao functions @@ -595,6 +622,10 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { pod.usage.balance = _ownerPodBalance(pod, podIndex) + amount; pod.usage.index = podIndex; pod.usage.block = uint64(block.number); + + pod.networkFee = _ownerPodNetworkFee(pod); + pod.networkFeeIndex = _currentNetworkFeeIndex(); + if (increase) { ++pod.validatorCount; } else { @@ -608,9 +639,9 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { return pod; } - function podBalanceOf(address owner, bytes32 clusterId) external view returns (uint64) { + function podBalanceOf(address owner, bytes32 clusterId) external view returns (uint256) { Pod memory pod = _pods[keccak256(abi.encodePacked(owner, clusterId))]; - return _ownerPodBalance(pod, _clusterCurrentIndex(clusterId)); + return _ownerPodBalance(pod, _clusterCurrentIndex(clusterId)).expand(); } /** @@ -656,7 +687,6 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { return key; } - function _updateDAOEarnings(DAO memory dao) private view returns (DAO memory) { dao.earnings.balance = _networkTotalEarnings(dao); dao.earnings.block = uint64(block.number); @@ -664,6 +694,15 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { return dao; } + function _updateNetworkFeeIndex() private { + _networkFeeIndex = _currentNetworkFeeIndex(); + _networkFeeIndexBlockNumber = uint64(block.number); + } + + function _currentNetworkFeeIndex() private view returns(uint64) { + return _networkFeeIndex + uint64(block.number - _networkFeeIndexBlockNumber) * _networkFee; + } + function _extractOperators(uint64[] memory operatorIds) private view returns (Operator[] memory) { Operator[] memory operators = new Operator[](operatorIds.length); for (uint64 i = 0; i < operatorIds.length; ++i) { @@ -689,8 +728,8 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } } - function _ownerPodBalance(Pod memory pod, uint64 currentPodIndex) private pure returns (uint64) { - uint64 usage = (currentPodIndex - pod.usage.index) * pod.validatorCount; + function _ownerPodBalance(Pod memory pod, uint64 currentPodIndex) private view returns (uint64) { + uint64 usage = (currentPodIndex - pod.usage.index) * pod.validatorCount + _ownerPodNetworkFee(pod); if (usage > pod.usage.balance) { revert NegativeBalance(); @@ -699,6 +738,10 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { return pod.usage.balance - usage; } + function _ownerPodNetworkFee(Pod memory pod) private view returns (uint64) { + return pod.networkFee + uint64(_currentNetworkFeeIndex() - pod.networkFeeIndex) * pod.validatorCount; + } + function _burnRatePerValidator(Operator[] memory operators) private pure returns (uint64 rate) { for (uint64 i = 0; i < operators.length; ++i) { rate += operators[i].fee; diff --git a/test/dao/network-fee-change.ts b/test/dao/network-fee-change.ts index 68e4b0b3..2adaca8e 100644 --- a/test/dao/network-fee-change.ts +++ b/test/dao/network-fee-change.ts @@ -2,27 +2,31 @@ import * as helpers from '../helpers/contract-helpers'; import { expect } from 'chai'; -const numberOfOperators = 4; -const operatorFee = 4; +let ssvNetworkContract: any, networkFee: any; -let ssvNetworkContract: any, operatorIDs: any, shares: any, owner: any; - -describe('DAO Network Fee Change Tests', () => { +describe('Network Fee Tests', () => { beforeEach(async () => { - const contractData = await helpers.initializeContract(); - ssvNetworkContract = contractData.contract; + // Initialize contract + ssvNetworkContract = (await helpers.initializeContract()).contract; + + // Define minumum allowed network fee to pass shrinkable validation + networkFee = helpers.CONFIG.minimalOperatorFee / 10; }); it('Get network fee', async () => { - + expect(await ssvNetworkContract.getNetworkFee()).to.equal(0); }); - it('Change network fee', async () => { - + it('Change network fee emits NetworkFeeUpdate event', async () => { + await expect(ssvNetworkContract.updateNetworkFee(networkFee)) + .to.emit(ssvNetworkContract, 'NetworkFeeUpdate').withArgs(0, networkFee); }); - it('Change network fee errors', async () => { - + it('Change network fee fails small number error', async () => { + await expect(ssvNetworkContract.updateNetworkFee(networkFee - 1)).to.be.revertedWith('Precision is over the maximum defined'); }); + it('Change network fee fails no owner', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[3]).updateNetworkFee(networkFee)).to.be.revertedWith('caller is not the owner'); + }); }); diff --git a/test/dao/network-fee-withdraw.ts b/test/dao/network-fee-withdraw.ts index 63d09864..17d440bf 100644 --- a/test/dao/network-fee-withdraw.ts +++ b/test/dao/network-fee-withdraw.ts @@ -1,28 +1,61 @@ import * as helpers from '../helpers/contract-helpers'; +import * as utils from '../helpers/utils'; import { expect } from 'chai'; +import { GasGroup } from '../helpers/gas-usage'; -const numberOfOperators = 4; -const operatorFee = 4; - -let ssvNetworkContract: any, operatorIDs: any, shares: any, owner: any; +let ssvNetworkContract: any, minDepositAmount: any, burnPerBlock: any, networkFee: any; describe('DAO Network Fee Withdraw Tests', () => { beforeEach(async () => { - const contractData = await helpers.initializeContract(); - ssvNetworkContract = contractData.contract; - }); + // Initialize contract + ssvNetworkContract = (await helpers.initializeContract()).contract; + + // Define minumum allowed network fee to pass shrinkable validation + networkFee = helpers.CONFIG.minimalOperatorFee; + + // Register operators + await helpers.registerOperators(0, 12, helpers.CONFIG.minimalOperatorFee); + + burnPerBlock = helpers.CONFIG.minimalOperatorFee * 4 + networkFee; + minDepositAmount = helpers.CONFIG.minimalBlocksBeforeLiquidation * burnPerBlock; - it('Get withdrawable network fee amount', async () => { + // Deposit into accounts + // await helpers.deposit([4], [minDepositAmount]); + // Set network fee + await ssvNetworkContract.updateNetworkFee(networkFee); + + // Register validators + await helpers.registerValidators(4, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + await utils.progressBlocks(10); + + // Temporary till deposit logic not available + // Mint tokens + await helpers.DB.ssvToken.mint(ssvNetworkContract.address, minDepositAmount); }); - it('Withdraw network fee', async () => { + it('Get withdrawable network earnings', async () => { + expect(await ssvNetworkContract.getNetworkBalance()).to.above(0); + }); + it('Get withdrawable network earnings fails no owner', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[3]).getNetworkBalance()).to.be.revertedWith('caller is not the owner'); }); - it('Withdraw network fee errors', async () => { + it('Withdraw network earnings emits NetworkFeesWithdrawal event', async () => { + const amount = await ssvNetworkContract.getNetworkBalance(); + await expect(ssvNetworkContract.withdrawDAOEarnings(amount)) + .to.emit(ssvNetworkContract, 'NetworkFeesWithdrawal').withArgs(amount, helpers.DB.owners[0].address); + }); + it('Withdraw network earnings fails balance is lower', async () => { + const amount = await ssvNetworkContract.getNetworkBalance() * 2; + await expect(ssvNetworkContract.withdrawDAOEarnings(amount)).to.be.revertedWith('NotEnoughBalance'); }); + it('Withdraw network earnings fails no owner', async () => { + const amount = await ssvNetworkContract.getNetworkBalance(); + await expect(ssvNetworkContract.connect(helpers.DB.owners[3]).withdrawDAOEarnings(amount)).to.be.revertedWith('caller is not the owner'); + }); }); diff --git a/test/helpers/gas-usage.ts b/test/helpers/gas-usage.ts index b2752471..55abd0c4 100644 --- a/test/helpers/gas-usage.ts +++ b/test/helpers/gas-usage.ts @@ -24,8 +24,8 @@ const MAX_GAS_PER_GROUP: any = { [GasGroup.TRANSFER_VALIDATOR_NEW_CLUSTER]: 400000, [GasGroup.TRANSFER_VALIDATOR]: 260000, [GasGroup.TRANSFER_VALIDATOR_NON_EXISTING_POD]: 290000, - [GasGroup.BULK_TRANSFER_VALIDATOR]: 344000, - [GasGroup.BULK_TRANSFER_VALIDATOR_NON_EXISTING_POD]: 344000, + [GasGroup.BULK_TRANSFER_VALIDATOR]: 345500, + [GasGroup.BULK_TRANSFER_VALIDATOR_NON_EXISTING_POD]: 345500, }; class GasStats { diff --git a/test/sanity/balances.ts b/test/sanity/balances.ts index 3a3e54a2..14ce6b7d 100644 --- a/test/sanity/balances.ts +++ b/test/sanity/balances.ts @@ -1,129 +1,92 @@ -declare const ethers: any; - import * as helpers from '../helpers/contract-helpers'; import * as utils from '../helpers/utils'; -import { trackGas, GasGroup } from '../helpers/gas-usage'; import { expect } from 'chai'; +import { GasGroup } from '../helpers/gas-usage'; -const numberOfOperators = 6; -const operatorFee = 1; - -let registryContract: any, operatorIDs: any, shares: any, owner: any; +let ssvNetworkContract: any, clusterResult1: any, minDepositAmount: any, burnPerBlock: any, networkFee: any; describe('Balance Tests', () => { - // beforeEach(async () => { - // const contractData = await helpers.initializeContract(numberOfOperators, operatorFee); - // registryContract = contractData.contract; - // operatorIDs = contractData.operatorIDs; - // shares = contractData.shares; - // owner = contractData.owner; - // }); - - // it('Check balances', async () => { - // const validatorPK = `0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098100` - - // expect(await registryContract.operatorEarningsOf(1)).to.equal('0'); - - // // Register a validator - // const validator1 = await trackGas(registryContract.registerValidator( - // `${validatorPK}0`, - // [1, 2, 3, 4], - // shares[0], - // "10000" - // ), [ GasGroup.registerValidator ]); - - // const outputRegister = validator1.eventsByName.ValidatorAdded[0]; - - // // Progress 50 blocks and check operator balances and group balance - // await utils.progressBlocks(50) - // expect(await registryContract.operatorEarningsOf(1)).to.equal('50') - // expect(await registryContract.operatorEarningsOf(2)).to.equal('50') - // expect(await registryContract.operatorEarningsOf(3)).to.equal('50') - // expect(await registryContract.operatorEarningsOf(4)).to.equal('50') - // expect(await registryContract.groupBalanceOf(owner.address, outputRegister.groupId)).to.equal(10000 - 150) - - // // Update one of the operator fees - // await registryContract.updateOperatorFee(1, 10) - - // // Progress 50 blocks and check operator balances and group balance - // await utils.progressBlocks(50) - // expect(await registryContract.operatorEarningsOf(1)).to.equal('551') - // expect(await registryContract.operatorEarningsOf(2)).to.equal('101') - // expect(await registryContract.operatorEarningsOf(3)).to.equal('101') - // expect(await registryContract.operatorEarningsOf(4)).to.equal('101') - // expect(await registryContract.groupBalanceOf(owner.address, outputRegister.groupId)).to.equal(10000 - 904) - - // // Update 3 operator fees - // await registryContract.updateOperatorFee(2, 20) - // await registryContract.updateOperatorFee(3, 20) - // await registryContract.updateOperatorFee(4, 20) - - // // Progress 50 blocks and check operator balances and group balance - // await utils.progressBlocks(50) - // expect(await registryContract.operatorEarningsOf(1)).to.equal('1081') - // expect(await registryContract.operatorEarningsOf(2)).to.equal('1142') - // expect(await registryContract.operatorEarningsOf(3)).to.equal('1123') - // expect(await registryContract.operatorEarningsOf(4)).to.equal('1104') - // expect(await registryContract.groupBalanceOf(owner.address, outputRegister.groupId)).to.equal(10000 - 4500) - - // // Add another validator - // await registryContract.registerValidator( - // [1, 2, 3, 5], - // `${validatorPK}1`, - // shares[1], - // "10000" - // ) - - // // Progress 50 blocks and check operator balances and group balance - // await utils.progressBlocks(50) - // expect(await registryContract.operatorEarningsOf(1)).to.equal('2091') - // expect(await registryContract.operatorEarningsOf(2)).to.equal('3162') - // expect(await registryContract.operatorEarningsOf(3)).to.equal('3143') - // expect(await registryContract.operatorEarningsOf(4)).to.equal('2124') - // expect(await registryContract.operatorEarningsOf(5)).to.equal('5000') - // expect(await registryContract.groupBalanceOf(owner.address, outputRegister.groupId)).to.equal(10000 - 4500) - - // // Remove an operator - // await registryContract.removeOperator(1) - - // // Progress 50 blocks and check operator balances and group balance - // await utils.progressBlocks(50) - // expect(await registryContract.operatorEarningsOf(1)).to.equal('2091') - // expect(await registryContract.operatorEarningsOf(2)).to.equal('3162') - // expect(await registryContract.operatorEarningsOf(3)).to.equal('3143') - // expect(await registryContract.operatorEarningsOf(4)).to.equal('2124') - // expect(await registryContract.operatorEarningsOf(5)).to.equal('5000') - // expect(await registryContract.groupBalanceOf(owner.address, outputRegister.groupId)).to.equal(10000 - 4500) - - // // Update a validator - // await registryContract.updateValidator( - // [1, 2, 3, 5], - // `${validatorPK}0`, - // shares[1], - // "10" - // ) - - // // Progress 50 blocks and check operator balances and group balance - // await utils.progressBlocks(50) - // expect(await registryContract.operatorEarningsOf(1)).to.equal('2091') - // expect(await registryContract.operatorEarningsOf(2)).to.equal('3162') - // expect(await registryContract.operatorEarningsOf(3)).to.equal('3143') - // expect(await registryContract.operatorEarningsOf(4)).to.equal('2124') - // expect(await registryContract.operatorEarningsOf(5)).to.equal('5000') - // expect(await registryContract.groupBalanceOf(owner.address, outputRegister.groupId)).to.equal(10000 - 4500) - - // // Remove a validator - // await registryContract.removeValidator(`${validatorPK}0`, outputRegister.groupId) - - // // Progress 50 blocks and check operator balances and group balance - // await utils.progressBlocks(50) - // expect(await registryContract.operatorEarningsOf(1)).to.equal('2091') - // expect(await registryContract.operatorEarningsOf(2)).to.equal('3162') - // expect(await registryContract.operatorEarningsOf(3)).to.equal('3143') - // expect(await registryContract.operatorEarningsOf(4)).to.equal('2124') - // expect(await registryContract.operatorEarningsOf(5)).to.equal('5000') - // expect(await registryContract.groupBalanceOf(owner.address, outputRegister.groupId)).to.equal(10000 - 4500) - // }); - + beforeEach(async () => { + // Initialize contract + ssvNetworkContract = (await helpers.initializeContract()).contract; + + // Register operators + await helpers.registerOperators(0, 12, helpers.CONFIG.minimalOperatorFee); + + networkFee = helpers.CONFIG.minimalOperatorFee; + burnPerBlock = helpers.CONFIG.minimalOperatorFee * 4 + networkFee; + minDepositAmount = helpers.CONFIG.minimalBlocksBeforeLiquidation * burnPerBlock; + + // Deposit into accounts + // await helpers.deposit([4], [minDepositAmount]); + + // Set network fee + await ssvNetworkContract.updateNetworkFee(networkFee); + + // Register validators + clusterResult1 = await helpers.registerValidators(4, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + }); + + it('Check pod balance in three blocks, one after the other', async () => { + await utils.progressBlocks(1); + expect(await ssvNetworkContract.podBalanceOf(helpers.DB.owners[4].address, clusterResult1.clusterId)).to.equal(minDepositAmount - burnPerBlock); + await utils.progressBlocks(1); + expect(await ssvNetworkContract.podBalanceOf(helpers.DB.owners[4].address, clusterResult1.clusterId)).to.equal(minDepositAmount - burnPerBlock * 2); + await utils.progressBlocks(1); + expect(await ssvNetworkContract.podBalanceOf(helpers.DB.owners[4].address, clusterResult1.clusterId)).to.equal(minDepositAmount - burnPerBlock * 3); + }); + + it('Check pod balance in two and twelve blocks, after network fee updates', async () => { + await utils.progressBlocks(1); + expect(await ssvNetworkContract.podBalanceOf(helpers.DB.owners[4].address, clusterResult1.clusterId)).to.equal(minDepositAmount - burnPerBlock); + const newBurnPerBlock = burnPerBlock + networkFee; + await ssvNetworkContract.updateNetworkFee(networkFee * 2); + await utils.progressBlocks(1); + expect(await ssvNetworkContract.podBalanceOf(helpers.DB.owners[4].address, clusterResult1.clusterId)).to.equal(minDepositAmount - burnPerBlock * 2 - newBurnPerBlock); + await utils.progressBlocks(1); + expect(await ssvNetworkContract.podBalanceOf(helpers.DB.owners[4].address, clusterResult1.clusterId)).to.equal(minDepositAmount - burnPerBlock * 2 - newBurnPerBlock * 2); + await utils.progressBlocks(10); + expect(await ssvNetworkContract.podBalanceOf(helpers.DB.owners[4].address, clusterResult1.clusterId)).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 ssvNetworkContract.getNetworkBalance()).to.equal(networkFee); + await utils.progressBlocks(1); + expect(await ssvNetworkContract.getNetworkBalance()).to.equal(networkFee * 2); + await utils.progressBlocks(1); + expect(await ssvNetworkContract.getNetworkBalance()).to.equal(networkFee * 3); + }); + + it('Check DAO earnings in two and twelve blocks, after network fee updates', async () => { + await utils.progressBlocks(1); + expect(await ssvNetworkContract.getNetworkBalance()).to.equal(networkFee); + const newNetworkFee = networkFee * 2; + await ssvNetworkContract.updateNetworkFee(newNetworkFee); + await utils.progressBlocks(1); + expect(await ssvNetworkContract.getNetworkBalance()).to.equal(networkFee * 2 + newNetworkFee); + await utils.progressBlocks(1); + expect(await ssvNetworkContract.getNetworkBalance()).to.equal(networkFee * 2 + newNetworkFee * 2); + await utils.progressBlocks(10); + expect(await ssvNetworkContract.getNetworkBalance()).to.equal(networkFee * 2 + newNetworkFee * 12); + }); + + it('Check operators earnings in three blocks, one after the other', async () => { + await utils.progressBlocks(1); + expect((await ssvNetworkContract.operatorSnapshot(1)).balance).to.equal(helpers.CONFIG.minimalOperatorFee); + expect((await ssvNetworkContract.operatorSnapshot(2)).balance).to.equal(helpers.CONFIG.minimalOperatorFee); + expect((await ssvNetworkContract.operatorSnapshot(3)).balance).to.equal(helpers.CONFIG.minimalOperatorFee); + expect((await ssvNetworkContract.operatorSnapshot(4)).balance).to.equal(helpers.CONFIG.minimalOperatorFee); + await utils.progressBlocks(1); + expect((await ssvNetworkContract.operatorSnapshot(1)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 2); + expect((await ssvNetworkContract.operatorSnapshot(2)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 2); + expect((await ssvNetworkContract.operatorSnapshot(3)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 2); + expect((await ssvNetworkContract.operatorSnapshot(4)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 2); + await utils.progressBlocks(1); + expect((await ssvNetworkContract.operatorSnapshot(1)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 3); + expect((await ssvNetworkContract.operatorSnapshot(2)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 3); + expect((await ssvNetworkContract.operatorSnapshot(3)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 3); + expect((await ssvNetworkContract.operatorSnapshot(4)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 3); + }); }); diff --git a/test/validators/register.ts b/test/validators/register.ts index c86d288c..f1ecbf3c 100644 --- a/test/validators/register.ts +++ b/test/validators/register.ts @@ -37,11 +37,11 @@ describe('Register Validator Tests', () => { }); it('Register two validators into an existing cluster', async () => { - await helpers.registerValidators(0, 1, minDepositAmount, helpers.DataGenerator.cluster.byId(clusterResult.clusterId), [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]); + await helpers.registerValidators(0, 1, `${minDepositAmount * 2}`, helpers.DataGenerator.cluster.byId(clusterResult.clusterId), [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]); }); it('Register two validators into an existing cluster', async () => { - await helpers.registerValidators(1, 1, minDepositAmount, helpers.DataGenerator.cluster.byId(clusterResult.clusterId), [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]); + await helpers.registerValidators(1, 1, `${minDepositAmount * 2}`, helpers.DataGenerator.cluster.byId(clusterResult.clusterId), [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]); }); it('Invalid operator amount', async () => { @@ -76,7 +76,7 @@ describe('Register Validator Tests', () => { helpers.DataGenerator.publicKey(0), [1, 2, 3, 4], helpers.DataGenerator.shares(0), - '1000' + minDepositAmount / 10 )).to.be.revertedWith('AccountLiquidatable'); }); diff --git a/test/validators/transfer-bulk.ts b/test/validators/transfer-bulk.ts index 1e1a90a9..a1f19d81 100644 --- a/test/validators/transfer-bulk.ts +++ b/test/validators/transfer-bulk.ts @@ -3,7 +3,7 @@ import * as helpers from '../helpers/contract-helpers'; import { expect } from 'chai'; import { GasGroup } from '../helpers/gas-usage'; -let ssvNetworkContract: any, clusterResult1: any, clusterResult2: any, clusterResult3: any; +let ssvNetworkContract: any, clusterResult1: any, clusterResult2: any, clusterResult3: any, minDepositAmount: any; describe('Bulk Transfer Validator Tests', () => { beforeEach(async () => { @@ -14,14 +14,16 @@ describe('Bulk Transfer Validator Tests', () => { await helpers.registerOperators(0, 12, helpers.CONFIG.minimalOperatorFee); await helpers.registerOperators(0, 1, helpers.CONFIG.minimalOperatorFee); + minDepositAmount = helpers.CONFIG.minimalBlocksBeforeLiquidation * helpers.CONFIG.minimalOperatorFee * 4; + // Deposit into accounts - await helpers.deposit([4], ['1000000']); - await helpers.deposit([5], ['100000']); + // await helpers.deposit([4], [`${minDepositAmount * 12}`]); + // await helpers.deposit([5], [minDepositAmount]); // Register validators - clusterResult1 = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); - clusterResult2 = await helpers.registerValidators(4, 9, '10000', helpers.DataGenerator.cluster.byId(clusterResult1.clusterId), [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]); - clusterResult3 = await helpers.registerValidators(4, 1, '90000', helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + clusterResult1 = await helpers.registerValidators(4, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + clusterResult2 = await helpers.registerValidators(4, 9, `${minDepositAmount * 9}`, helpers.DataGenerator.cluster.byId(clusterResult1.clusterId), [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]); + clusterResult3 = await helpers.registerValidators(4, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); }); it('Bulk transfer 10 validators emits BulkValidatorTransferred event', async () => { @@ -30,7 +32,7 @@ describe('Bulk Transfer Validator Tests', () => { clusterResult1.clusterId, clusterResult3.clusterId, Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)), - '10000' + `${minDepositAmount * 12}` )).to.emit(ssvNetworkContract, 'BulkValidatorTransferred'); }); @@ -40,18 +42,18 @@ describe('Bulk Transfer Validator Tests', () => { clusterResult1.clusterId, clusterResult3.clusterId, Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)), - '10000' + minDepositAmount )).to.be.revertedWith('ValidatorNotOwned'); }); it('Bulk transfer validator with an unowned validator', async () => { - const account5cluster = await helpers.registerValidators(5, 1, '10000', helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + const account5cluster = await helpers.registerValidators(5, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( [clusterResult1.validators[0].publicKey, account5cluster.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], clusterResult1.clusterId, clusterResult3.clusterId, Array(clusterResult2.validators.length + 2).fill(helpers.DataGenerator.shares(0)), - '10000' + `${minDepositAmount * 12}` )).to.be.revertedWith('ValidatorNotOwned'); }); @@ -61,7 +63,7 @@ describe('Bulk Transfer Validator Tests', () => { clusterResult1.clusterId, clusterResult3.clusterId, Array(clusterResult2.validators.length + 2).fill(helpers.DataGenerator.shares(0)), - '10000' + minDepositAmount )).to.be.revertedWith('ValidatorNotOwned'); }); @@ -71,13 +73,13 @@ describe('Bulk Transfer Validator Tests', () => { [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], clusterResult1.clusterId, clusterResult3.clusterId, - '10000', + `${minDepositAmount * 12}`, [GasGroup.BULK_TRANSFER_VALIDATOR]); }); it('Bulk transfer 10 validators to a cluster with 7 operators', async () => { // Register validator with 7 operators - const { clusterId } = await helpers.registerValidators(4, 1, '90000', [1, 2, 3, 4, 5, 6, 7]); + const { clusterId } = await helpers.registerValidators(4, 1, minDepositAmount + minDepositAmount * 3, [1, 2, 3, 4, 5, 6, 7]); // Transfer validator to an existing cluster await helpers.bulkTransferValidator( @@ -85,13 +87,13 @@ describe('Bulk Transfer Validator Tests', () => { [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], clusterResult1.clusterId, clusterId, - '10000', + `${minDepositAmount * 19}`, [GasGroup.BULK_TRANSFER_VALIDATOR_NON_EXISTING_POD]); }); it('Bulk transfer 10 validators to cluster created by other owner', async () => { // Register validator with 7 operators - const { clusterId } = await helpers.registerValidators(5, 1, '90000', helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + const { clusterId } = await helpers.registerValidators(5, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); // Bulk transfer 10 validators await helpers.bulkTransferValidator( @@ -99,7 +101,7 @@ describe('Bulk Transfer Validator Tests', () => { [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], clusterResult1.clusterId, clusterId, - '100000', + `${minDepositAmount * 14}`, [GasGroup.BULK_TRANSFER_VALIDATOR_NON_EXISTING_POD]); }); @@ -134,13 +136,13 @@ describe('Bulk Transfer Validator Tests', () => { }); it('Bulk transfer validator with not enough amount', async () => { - const { clusterId } = await helpers.registerValidators(5, 1, '90000', [9, 10, 11, 12], [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + const { clusterId } = await helpers.registerValidators(5, 1, minDepositAmount, [9, 10, 11, 12], [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], clusterResult1.clusterId, clusterId, Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)), - '1' + minDepositAmount / 10 )).to.be.revertedWith('AccountLiquidatable'); }); diff --git a/test/validators/transfer.ts b/test/validators/transfer.ts index f5206462..4d5e3ab8 100644 --- a/test/validators/transfer.ts +++ b/test/validators/transfer.ts @@ -30,7 +30,7 @@ describe('Transfer Validator Tests', () => { }); it('Transfer validator into a new cluster', async () => { - const transferedValidator = await helpers.transferValidator(4, clusterResult1.validators[0].publicKey, helpers.DataGenerator.cluster.new(), '10000', [GasGroup.TRANSFER_VALIDATOR_NEW_CLUSTER]); + const transferedValidator = await helpers.transferValidator(4, clusterResult1.validators[0].publicKey, helpers.DataGenerator.cluster.new(), minDepositAmount, [GasGroup.TRANSFER_VALIDATOR_NEW_CLUSTER]); // expect(clusterResult1.clusterId).not.equals(transferedValidator.eventsByName.ValidatorTransferred[0].args.clusterId); }); @@ -54,37 +54,37 @@ describe('Transfer Validator Tests', () => { it('Transfer validator to a cluster with 7 operators', async () => { // Register validator with 7 operators - const { clusterId } = await helpers.registerValidators(4, 1, '10000', [1, 2, 3, 4, 5, 6, 7]); + const { clusterId } = await helpers.registerValidators(4, 1, minDepositAmount + minDepositAmount * 3, [1, 2, 3, 4, 5, 6, 7]); // Transfer validator to an existing cluster - await helpers.transferValidator(4, clusterResult1.validators[0].publicKey, helpers.DataGenerator.cluster.byId(clusterId), '10000', [GasGroup.TRANSFER_VALIDATOR_NON_EXISTING_POD]); + await helpers.transferValidator(4, clusterResult1.validators[0].publicKey, helpers.DataGenerator.cluster.byId(clusterId), minDepositAmount, [GasGroup.TRANSFER_VALIDATOR_NON_EXISTING_POD]); }); it('Transfer validator with not enough amount', async () => { // Register validator - const { clusterId } = await helpers.registerValidators(4, 1, '3000', [1, 2, 3, 9]); + const { clusterId } = await helpers.registerValidators(4, 1, minDepositAmount, [1, 2, 3, 9]); // Transfer to cluster with not enough amount await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( clusterResult1.validators[0].publicKey, helpers.DataGenerator.cluster.byId(clusterId), helpers.DataGenerator.shares(helpers.DB.validators.length), - '1' + helpers.CONFIG.minimalOperatorFee )).to.be.revertedWith('AccountLiquidatable'); }); // GOING ABOVE GAS LIMIT it('Transfer validator to an existing pod', async () => { - await helpers.transferValidator(4, clusterResult1.validators[0].publicKey, helpers.DataGenerator.cluster.byId(clusterResult2.clusterId), '10000', [GasGroup.TRANSFER_VALIDATOR]); + await helpers.transferValidator(4, clusterResult1.validators[0].publicKey, helpers.DataGenerator.cluster.byId(clusterResult2.clusterId), `${minDepositAmount * 2}`, [GasGroup.TRANSFER_VALIDATOR]); }); // GOING ABOVE GAS LIMIT it('Transfer validator to an existing cluster', async () => { // Register validator with different user - const clusterResult3 = await helpers.registerValidators(5, 1, '10000', helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + const clusterResult3 = await helpers.registerValidators(5, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); // Transfer validator - const transfredValidator1 = await helpers.transferValidator(4, clusterResult1.validators[0].publicKey, helpers.DataGenerator.cluster.byId(clusterResult3.clusterId), '10000', [GasGroup.TRANSFER_VALIDATOR_NON_EXISTING_POD]); + const transfredValidator1 = await helpers.transferValidator(4, clusterResult1.validators[0].publicKey, helpers.DataGenerator.cluster.byId(clusterResult3.clusterId), minDepositAmount, [GasGroup.TRANSFER_VALIDATOR_NON_EXISTING_POD]); // expect(clusterResult3.clusterId).equals(transfredValidator1.eventsByName.ValidatorTransferred[0].args.podId); }); From 32e31127e81ce55e02443e751391bd7f37f3d495 Mon Sep 17 00:00:00 2001 From: Wadym Date: Sun, 23 Oct 2022 16:38:33 +0200 Subject: [PATCH 079/149] Liquidate function (#105) * add liquidate function * core & tests * remove unused tests * improvements in init steps * fix for dao validators Co-authored-by: Adam Zigdon Co-authored-by: Vadim --- contracts/ISSVNetwork.sol | 38 ++-- contracts/SSVNetwork.sol | 256 +++++++++----------------- test/helpers/contract-helpers.ts | 30 ++- test/vadimToUpdate.js | 302 ------------------------------- test/validators/register.ts | 44 ++--- test/validators/remove.ts | 3 +- test/validators/transfer-bulk.ts | 29 ++- test/validators/transfer.ts | 21 +-- 8 files changed, 161 insertions(+), 562 deletions(-) delete mode 100644 test/vadimToUpdate.js diff --git a/contracts/ISSVNetwork.sol b/contracts/ISSVNetwork.sol index 41486eca..18644e02 100644 --- a/contracts/ISSVNetwork.sol +++ b/contracts/ISSVNetwork.sol @@ -65,9 +65,9 @@ interface ISSVNetwork { /** * @dev Emitted when the validator is removed. * @param publicKey The public key of a validator. - * @param podId The pod id the validator has been removed from. + * @param clusterId The pod id the validator has been removed from. */ - event ValidatorRemoved(bytes publicKey, bytes32 podId); + event ValidatorRemoved(bytes publicKey, bytes32 clusterId); event OperatorFeeDeclaration( address indexed ownerAddress, @@ -98,12 +98,15 @@ interface ISSVNetwork { uint256 fee ); + event AccountLiquidated(address ownerAddress, bytes32 podId); + event OperatorFeeIncreaseLimitUpdate(uint64 value); event DeclareOperatorFeePeriodUpdate(uint256 value); event ExecuteOperatorFeePeriodUpdate(uint256 value); + event ClusterCreated(bytes32 clusterId); /** * @dev Emitted when the network fee is updated. * @param oldFee The old fee @@ -131,13 +134,15 @@ interface ISSVNetwork { error NotEnoughBalance(); error ValidatorAlreadyExists(); error AccountLiquidatable(); + error AccountNotLiquidatable(); error InvalidPublicKeyLength(); - error OessDataStructureInvalid(); + error OperatorIdsStructureInvalid(); error ValidatorNotOwned(); error InvalidCluster(); - error ClusterAlreadyExists(); error ParametersMismatch(); error NegativeBalance(); + error ClusterAlreadyExists(); + error ClusterNotExists(); /** errors */ // error validatorWithPublicKeyNotExist(); @@ -196,15 +201,13 @@ interface ISSVNetwork { /** * @dev Registers a new validator. * @param publicKey Validator public key. - * @param operatorIds Operator ids. + * @param clusterId Cluster id. * @param shares snappy compressed shares(a set of encrypted and public shares). - * @param amount amount of tokens to be deposited for the validator's pod. */ function registerValidator( bytes calldata publicKey, - uint64[] memory operatorIds, - bytes calldata shares, - uint256 amount + bytes32 clusterId, + bytes calldata shares ) external; /** @@ -216,23 +219,22 @@ interface ISSVNetwork { /** * @dev Transfers a validator. * @param publicKey Validator public key. - * @param operatorIds new Operator ids(cluster) to transfer the validator to. + * @param newClusterId new cluster id to transfer the validator to. * @param shares snappy compressed shares(a set of encrypted and public shares). - * @param amount amount of tokens to be deposited for the validator's pod. */ function transferValidator( bytes calldata publicKey, - uint64[] memory operatorIds, - bytes calldata shares, - uint256 amount + bytes32 newClusterId, + bytes calldata shares ) external; + function liquidate(address ownerAddress, uint64[] memory operatorIds) external; + function bulkTransferValidators( bytes[] calldata validatorPK, - bytes32 fromPodId, - bytes32 toPodId, - bytes[] calldata shares, - uint256 amount + bytes32 fromClusterId, + bytes32 toClusterId, + bytes[] calldata shares ) external; function updateOperatorFeeIncreaseLimit(uint64 newOperatorMaxFeeIncrease) external; diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index de4d7912..2e47c892 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -228,23 +228,23 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { function registerValidator( bytes calldata publicKey, - uint64[] memory operatorIds, - bytes calldata shares, - uint256 amount + bytes32 clusterId, + bytes calldata shares ) external { - _validateValidatorParams( - operatorIds, - publicKey - ); + + if (publicKey.length != 48) { + revert InvalidPublicKeyLength(); + } + + uint64[] memory operatorIds = _clusters[clusterId].operatorIds; // Operator[] memory operators; - bytes32 clusterId = _getOrCreateCluster(operatorIds); bytes32 hashedValidator = keccak256(publicKey); bytes32 hashedPod = keccak256(abi.encodePacked(msg.sender, clusterId)); { Pod memory pod; - pod = _updatePodData(clusterId, amount.shrink(), hashedPod, true); + pod = _updatePodData(clusterId, 0, hashedPod, true); { for (uint64 i = 0; i < operatorIds.length; ++i) { @@ -282,10 +282,11 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { function transferValidator( bytes calldata publicKey, - uint64[] memory operatorIds, - bytes calldata shares, - uint256 amount + bytes32 newClusterId, + bytes calldata shares ) external { + uint64[] memory operatorIds = _clusters[newClusterId].operatorIds; + bytes32 hashedValidator = keccak256(publicKey); bytes32 clusterId = _validatorPKs[hashedValidator].clusterId; @@ -303,33 +304,27 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } { - Cluster memory cluster = _clusters[clusterId]; - _updateOperatorsValidatorMove(cluster.operatorIds, operatorIds, 1); + _updateOperatorsValidatorMove(_clusters[clusterId].operatorIds, operatorIds, 1); } { - bytes32 newClusterId = _getOrCreateCluster(operatorIds); - + Pod memory pod; { - Pod memory pod; - { - bytes32 hashedPod = keccak256(abi.encodePacked(msg.sender, newClusterId)); - - pod = _updatePodData(newClusterId, amount.shrink(), hashedPod, true); - _validatorPKs[hashedValidator].clusterId = newClusterId; - _pods[hashedPod] = pod; - } + bytes32 hashedPod = keccak256(abi.encodePacked(msg.sender, newClusterId)); - { - DAO memory dao = _dao; - dao = _updateDAOEarnings(dao); - _dao = dao; - } + pod = _updatePodData(newClusterId, 0, hashedPod, true); + _validatorPKs[hashedValidator].clusterId = newClusterId; + _pods[hashedPod] = pod; + } - if (_liquidatable(pod.usage.balance, pod.validatorCount, operatorIds)) { - revert AccountLiquidatable(); - } + { + DAO memory dao = _dao; + dao = _updateDAOEarnings(dao); + _dao = dao; + } + if (_liquidatable(pod.usage.balance, pod.validatorCount, operatorIds)) { + revert AccountLiquidatable(); } emit ValidatorTransferred(publicKey, newClusterId, shares); @@ -380,20 +375,65 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _deposit(msg.sender, clusterId, amount.shrink()); } - function createPod(uint64[] memory operatorIds, uint256 amount) external returns (bytes32) { - bytes32 clusterId = _getOrCreateCluster(operatorIds); + function getClusterId(uint64[] memory operatorIds) external view returns(bytes32) { + if (operatorIds.length < 4 || operatorIds.length % 3 != 1) { + revert OperatorIdsStructureInvalid(); + } - _deposit(msg.sender, clusterId, amount.shrink()); + bytes32 clusterId = keccak256(abi.encodePacked(operatorIds)); + + if (_clusters[clusterId].operatorIds.length == 0) { + revert ClusterNotExists(); + } return clusterId; } + function ensurePodAndDeposit(uint64[] memory operatorIds, uint256 amount) external { + if (operatorIds.length < 4 || operatorIds.length % 3 != 1) { + revert OperatorIdsStructureInvalid(); + } + + bytes32 clusterId = keccak256(abi.encodePacked(operatorIds)); + + if (_clusters[clusterId].operatorIds.length > 0) { + revert ClusterAlreadyExists(); + } + + _createClusterUnsafe(clusterId, operatorIds); + + if (amount > 0) { + _deposit(msg.sender, clusterId, amount.shrink()); + } + } + + function liquidate(address ownerAddress, uint64[] memory operatorIds) external { + bytes32 clusterId = keccak256(abi.encodePacked(operatorIds)); + bytes32 podKey = keccak256(abi.encodePacked(ownerAddress, clusterId)); + Pod memory pod = _pods[podKey]; + + if (!_liquidatable(pod.usage.balance, pod.validatorCount, operatorIds)) { + revert AccountNotLiquidatable(); + } + + for (uint64 index = 0; index < operatorIds.length; ++index) { + _operators[operatorIds[index]].validatorCount -= pod.validatorCount; + } + + _dao.validatorCount -= pod.validatorCount; + + _token.transfer(msg.sender, pod.usage.balance); + + delete _pods[podKey]; + + emit AccountLiquidated(ownerAddress, podKey); + } + function bulkTransferValidators( bytes[] calldata validatorPK, bytes32 fromClusterId, bytes32 toClusterId, - bytes[] calldata shares, - uint256 amount + bytes[] calldata shares ) external { if (validatorPK.length != shares.length) { revert ParametersMismatch(); @@ -430,14 +470,14 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { Pod memory pod = _pods[keccak256(abi.encodePacked(msg.sender, fromClusterId))]; uint64 podIndex = _clusterCurrentIndex(fromClusterId); - pod.usage.balance = _ownerPodBalance(pod, podIndex) - amount.shrink(); + pod.usage.balance = _ownerPodBalance(pod, podIndex); pod.usage.index = podIndex; pod.usage.block = uint64(block.number); pod.validatorCount -= activeValidatorCount; pod = _pods[keccak256(abi.encodePacked(msg.sender, toClusterId))]; podIndex = _clusterCurrentIndex(toClusterId); - pod.usage.balance = _ownerPodBalance(pod, podIndex) + amount.shrink(); + pod.usage.balance = _ownerPodBalance(pod, podIndex); pod.usage.index = podIndex; pod.usage.block = uint64(block.number); pod.validatorCount += activeValidatorCount; @@ -644,24 +684,6 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { return _ownerPodBalance(pod, _clusterCurrentIndex(clusterId)).expand(); } - /** - * @dev Validates the params for a validator. - * @param publicKey Validator public key. - */ - function _validateValidatorParams( - uint64[] memory operatorIds, - bytes memory publicKey - ) private pure { - if (publicKey.length != 48) { - revert InvalidPublicKeyLength(); - } - if ( - operatorIds.length < 4 || operatorIds.length % 3 != 1 - ) { - revert OessDataStructureInvalid(); - } - } - function _deposit(address owner, bytes32 clusterId, uint64 amount) private { Pod storage pod = _pods[keccak256(abi.encodePacked(owner, clusterId))]; @@ -674,6 +696,8 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } _clusters[key] = Cluster({operatorIds: operatorIds}); + + emit ClusterCreated(key); } function _getOrCreateCluster(uint64[] memory operatorIds) private returns (bytes32) { // , Cluster memory @@ -771,122 +795,4 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { revert CallerNotOwner(); } } - - /* - function liquidate(address owner, bytes32 podId) external { - Cluster memory cluster = _clusters[podId]; - Operator[] memory operators = new Operator[](cluster.operatorIds.length); - for (uint64 i = 0; i < cluster.operatorIds.length; ++i) { - operators[i] = _operators[cluster.operatorIds[i]]; - } - uint64 podIndex = _clusterCurrentIndex(operators); - Pod memory pod = _pods[owner][podId]; - uint64 balance = _ownerPodBalance(pod, podIndex); - require(_liquidatable(balance, pod.validatorCount, operators)); - _availableBalances[msg.sender] += balance; - uint64 currentBlock = uint64(block.number); - { - for (uint64 i = 0; i < operators.length; ++i) { - operators[i].earnings = _updateOperatorEarnings(operators[i], currentBlock); - operators[i].earnRate -= operators[i].fee; - --operators[i].validatorCount; - } - } - } - */ - -// function addOperatorToValidator( -// function _validateRegistryState( -// uint64[] memory usedOperators, -// uint64[] memory validatorCnt, -// bytes32 root -// ) private view { -// require(_registryStateRoot(usedOperators, validatorCnt) == root, "operator registry hash invalid"); -// } -// -// uint16 constant OPERATORS_INDX = 0; -// uint16 constant OPERATORS_CNT_INDX = 1; -// uint16 constant USED_OPERATORS_INDX = 2; -// uint16 constant SHARES_PK_INDX = 0; -// uint16 constant ENCRYPTED_SHARES_INDX = 1; -// function registerValidator( -// uint64[][] memory db, -// bytes calldata validatorPK, -// bytes[][] calldata shares -// ) external { -// uint64 currentBlock = uint64(block.number); -// Validator memory validator = validators[msg.sender]; -// DAO memory _dao = dao; -// -// _validateRegistryState(db[OPERATORS_INDX], db[OPERATORS_CNT_INDX], validator.operatorRegistryHash); -// -// for (uint64 index = 0; index < db[USED_OPERATORS_INDX].length; ++index) { -// uint64 id = db[OPERATORS_INDX][db[USED_OPERATORS_INDX][index]]; -// // update and save operator -// uint64 operatorLastIndex = _updateOperatorCurrentIndex(id, currentBlock); -// -// // update operator in use -// validator.aggregatedIndex.lastIndex += operatorLastIndex; -// db[1][db[USED_OPERATORS_INDX][index]] ++; -// } -// validator.aggregatedIndex.validatorCount ++; -// validator.operatorRegistryHash = _registryStateRoot(db[OPERATORS_INDX], db[OPERATORS_CNT_INDX]); -// -// // update DAO earnings -// uint64 indexChange = (currentBlock - _dao.index.block)*NETWORK_FEE_PER_BLOCK; -// _dao.index.lastIndex += indexChange; -// _dao.index.block = currentBlock; -// _dao.index.accumulated += indexChange * _dao.index.validatorCount; -// _dao.index.validatorCount++; -// // update validator DAO debt -// validator.aggregatedIndex.lastIndex += _dao.index.lastIndex; -// -// // save to storage -// validators[msg.sender] = validator; -// dao = _dao; -// -//// require(_liquidatable(validator, db, _dao.index.lastIndex, currentBlock) == false, "not enough ssv in balance"); -// -// emit ValidatorAdded(validatorPK); -// } -// -// function daoCurrentIndex(DAO memory _dao, uint64 currentBlock) private view returns (uint64) { -// return _dao.index.lastIndex + (currentBlock - _dao.index.block)*NETWORK_FEE_PER_BLOCK; -// } -// - -// // function liquidatable( -// // address account, -// // uint64[][] calldata db -// // ) public view returns (bool) { -// // Validator memory validator = validators[account]; -// // uint64 currentBlock = uint64(block.number); -// // uint64 daoIndex = daoCurrentIndex(dao, currentBlock); -// // return _liquidatable(validator, db, daoIndex, currentBlock); -// // } -// // -// function balanceOf() public view returns (uint64) { -// return 1000000; // hard coded for now -// } - -// function _validatorLifetimeCost( -// DebtIndex memory debtIndex, -// uint64[] memory usedOperators, -// uint64 validatorCnt, -// uint64 daoCurrentIndex, -// uint64 currentBlock -// ) private view returns (uint64) { -// uint64 aggregatedCurrentIndex = 0; - -// for (uint256 index = 0; index < usedOperators.length; ++index) { -// uint64 operatorId = usedOperators[index]; -// Operator memory operator = _operators[usedOperators[index]]; -// aggregatedCurrentIndex += operatorCurrentIndex(operator, currentBlock) * validatorCnt; -// } - -// aggregatedCurrentIndex += daoCurrentIndex * validatorCnt; -// uint64 accumulatedCost = debtIndex.accumulated + (aggregatedCurrentIndex - debtIndex.lastIndex); - -// return accumulatedCost; -// } } diff --git a/test/helpers/contract-helpers.ts b/test/helpers/contract-helpers.ts index 54a17e25..c642840b 100644 --- a/test/helpers/contract-helpers.ts +++ b/test/helpers/contract-helpers.ts @@ -101,6 +101,20 @@ export const deposit = async (ownerIds: number[], amounts: string[]) => { // } }; +export const ensureClusterAndDeposit = async(ownerId: number, operatorIds: number[], amount: string): Promise => { + let clusterId; + try { + clusterId = await DB.ssvNetwork.contract.getClusterId(operatorIds); + if (+amount > 0) { + await DB.ssvNetwork.contract.connect(DB.owners[ownerId])['deposit(bytes32,uint256)'](clusterId, amount); + } + } catch (e) { + const clusterTx = await (await DB.ssvNetwork.contract.connect(DB.owners[ownerId]).ensurePodAndDeposit(operatorIds, amount)).wait(); + clusterId = clusterTx.events[0].args.clusterId; + } + return { clusterId }; +}; + export const registerValidators = async (ownerId: number, numberOfValidators: number, amount: string, operatorIds: number[], gasGroups?: GasGroup[]) => { const validators: any = []; let clusterId: any; @@ -112,9 +126,8 @@ export const registerValidators = async (ownerId: number, numberOfValidators: nu const { eventsByName } = await trackGas(DB.ssvNetwork.contract.connect(DB.owners[ownerId]).registerValidator( publicKey, - operatorIds, + (await ensureClusterAndDeposit(ownerId, operatorIds, amount)).clusterId, shares, - amount, ), gasGroups); clusterId = eventsByName.ValidatorAdded[0].args.podId; @@ -133,9 +146,8 @@ export const transferValidator = async (ownerId: number, publicKey: string, oper // Transfer validator const { eventsByName } = await trackGas(DB.ssvNetwork.contract.connect(DB.owners[ownerId]).transferValidator( publicKey, - operatorIds, + (await ensureClusterAndDeposit(ownerId, operatorIds, amount)).clusterId, shares, - amount, ), gasGroups); // FOR ADAM TO UPDATE @@ -152,13 +164,14 @@ export const bulkTransferValidator = async (ownerId: number, publicKey: string[] let podId: any; const shares = Array(publicKey.length).fill(DataGenerator.shares(0)); + await ensureClusterAndDeposit(ownerId, DataGenerator.cluster.byId(toCluster), amount); + // Bulk transfer validators const { eventsByName } = await trackGas(DB.ssvNetwork.contract.connect(DB.owners[ownerId]).bulkTransferValidators( publicKey, fromCluster, toCluster, shares, - amount, ), gasGroups); // FOR ADAM TO UPDATE @@ -169,3 +182,10 @@ export const bulkTransferValidator = async (ownerId: number, publicKey: string[] // return { podId }; }; + +export const liquidate = async (executorOwnerId: number, liquidatedOwnerId: number, operatorIds: number[], gasGroups?: GasGroup[]) => { + const { eventsByName } = await trackGas(DB.ssvNetwork.contract.connect(DB.owners[executorOwnerId]).liquidate( + DB.owners[liquidatedOwnerId].address, + operatorIds + ), gasGroups); +} diff --git a/test/vadimToUpdate.js b/test/vadimToUpdate.js deleted file mode 100644 index 75769ab4..00000000 --- a/test/vadimToUpdate.js +++ /dev/null @@ -1,302 +0,0 @@ -const { expect } = require("chai"); -const { progressBlocks, blockNumber } = require('./helpers/utils'); -const operator_fee_block = 1; - - -async function mineNBlocks(n) { - for (let index = 0; index < n; index++) { - await ethers.provider.send('evm_mine'); - } -} - -const operatorsIndexes = Array.from(Array(5).keys()).map(k => k + 1); -let deployedSSVNetworkContract; - -async function log({ action='', operatorIds = [], groupIds = [] }) { - console.log(`[BLOCK] ${await blockNumber()}`) - if (action) { - console.log(`> ${action}`); - } - if (operatorIds.length) { - for (const id of operatorIds) { - console.log( - `> operator #${id}`, - 'balance', (await deployedSSVNetworkContract.operatorSnapshot(id)).balance, - ); - } - } - if (groupIds.length) { - const [owner] = await ethers.getSigners(); - for (const id of groupIds) { - console.log( - `> group #$${id}`, - 'balance', await deployedSSVNetworkContract.podBalanceOf(owner.address, id), - ); - } - } -} - -describe("Validators", () => { - beforeEach(async () => { - const SSVNetwork = await ethers.getContractFactory("SSVNetwork"); - deployedSSVNetworkContract = await SSVNetwork.deploy(); - await deployedSSVNetworkContract.deployed(); - - await progressBlocks(99); - for (let i = 0; i < 8; i++) { // operatorsIndexes.length - var encryptionPK = "0x123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123451"; - await (await deployedSSVNetworkContract.registerOperator(encryptionPK, operator_fee_block)).wait(); - await log({ action: `register operator #${i+1}` }); - } - // await deployedSSVNetworkContract.addOperatorToValidator([], operatorsIndexes, []); - }) - - it("should register validator", async () => { - const validatorPK = "0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765"; - const sharePKs = Array.from(Array(10).keys()).map(k => `0xe0096008000000b4010000040000001000000076000000dc000000420d142c307831323334353637383930fe0a00520a000031017afe66008266000032fe66009266000033fe66009266000034016621ac28d60000009c01000062020025c02c307839383736353433323130fe0a00520a000031fe560052560019b0003101dafec60082c6000032fec6007ac6004d6ca666000033ceb401fe8c017e8c014dcca6c6004d7a0035b23200fec6007ec6000034${k}${k}`); - const encryptedShares = Array.from(Array(10).keys()).map(k => `0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765${k}98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765${k}`); - // const operatorsIndexes = Array.from(Array(10).keys()).map(k => k + 1); - - // await deployedSSVNetworkContract.createGroup([1,2,3,4]); - // await deployedSSVNetworkContract.createGroup([1,2,3,4]); - - // await deployedSSVNetworkContract.deposit("100000000000"); - // await log({ - // action: 'deposit', - // operatorIds: [1, 2, 3, 4] - // }); - // validator 1 - await progressBlocks(98); - let resultRegister = (await (await deployedSSVNetworkContract.registerValidator( - validatorPK + "f", - [1,2,3,4], - sharePKs[0], - '10000' - )).wait()).logs[0]; - - let interfaceRegister = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId, bytes shares)']); - let outputRegister = interfaceRegister.decodeEventLog('ValidatorAdded', resultRegister.data, resultRegister.topics); - await log({ - action: `register validator #1: ${outputRegister.validatorPK} : ${outputRegister.groupId}`, - operatorIds: [1, 2, 3, 4] - }); - await progressBlocks(1); - await log({ - operatorIds: [1, 2, 3, 4], - groupIds: [outputRegister.groupId] - }); - - let resultUpdate = (await (await deployedSSVNetworkContract.transferValidator( - validatorPK + "f", - [4,5,6,7], - sharePKs[2], - '10000' - )).wait()).logs[0]; - - let interfaceUpdate = new ethers.utils.Interface(['event ValidatorTransferred(bytes validatorPK, bytes32 groupId, bytes shares)']); - let outputUpdate = interfaceUpdate.decodeEventLog('ValidatorTransferred', resultUpdate.data, resultUpdate.topics); - expect(outputRegister.groupId).not.equal(outputUpdate.groupId); - expect(outputRegister.validatorPK).to.equal(outputUpdate.validatorPK); - - await log({ - action: `update validator #1: ${outputUpdate.validatorPK} : ${outputUpdate.groupId}`, - operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], - groupIds: [outputRegister.groupId, outputUpdate.groupId] - }); - await progressBlocks(1); - await log({ - operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], - groupIds: [outputRegister.groupId, outputUpdate.groupId] - }); - await progressBlocks(1); - await log({ - operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], - groupIds: [outputRegister.groupId, outputUpdate.groupId] - }); - - // move back validator 1 to group 1 - resultRegister = (await (await deployedSSVNetworkContract.transferValidator( - validatorPK + "f", - [1,2,3,4], - sharePKs[1], - '10000' - )).wait()).logs[0]; - interfaceRegister = new ethers.utils.Interface(['event ValidatorTransferred(bytes validatorPK, bytes32 groupId)']); // , bytes[] sharesPublicKeys, bytes[] encryptedShares - outputRegister = interfaceUpdate.decodeEventLog('ValidatorTransferred', resultRegister.data, resultRegister.topics); - await log({ - action: `update validator #1: ${outputRegister.validatorPK} : ${outputRegister.groupId}`, - operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], - groupIds: [outputRegister.groupId, outputUpdate.groupId] - }); - await progressBlocks(1); - await log({ - operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], - groupIds: [outputRegister.groupId, outputUpdate.groupId] - }); - - const resultRegister2 = (await (await deployedSSVNetworkContract.registerValidator( - validatorPK + "a", - [1,2,3,4], - sharePKs[1], - "1000" - )).wait()).logs[0]; - - const interfaceRegister2 = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId, bytes shares)']); - const outputRegister2 = interfaceRegister2.decodeEventLog('ValidatorAdded', resultRegister2.data, resultRegister2.topics); - await log({ - action: `register validator #2: ${outputRegister2.validatorPK} : ${outputRegister2.groupId}`, - operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], - groupIds: [outputRegister.groupId, outputRegister2.groupId] - }); - - - const resultRegister3 = (await (await deployedSSVNetworkContract.registerValidator( - validatorPK + "b", - [5,6,7,8], - sharePKs[1], - "1000000" - )).wait()).logs[0]; - - - const interfaceRegister3 = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId, bytes shares)']); - const outputRegister3 = interfaceRegister3.decodeEventLog('ValidatorAdded', resultRegister3.data, resultRegister3.topics); - await log({ - action: `register validator #3: ${resultRegister3.validatorPK} : ${resultRegister3.groupId}`, - operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], - groupIds: [outputRegister.groupId, outputRegister2.groupId] - }); - - - - await progressBlocks(1); - await log({ - operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], - groupIds: [outputRegister.groupId, outputRegister2.groupId] - }); - await progressBlocks(1); - await log({ - operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], - groupIds: [outputRegister.groupId, outputRegister2.groupId] - }); - await (await deployedSSVNetworkContract.updateOperatorFee( - 1, - 2 - )).wait(); - await log({ - action: 'operator #1 fee updated 2', - operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], - groupIds: [outputRegister.groupId, outputRegister2.groupId] - }); - await progressBlocks(1); - await log({ - operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], - groupIds: [outputRegister.groupId, outputRegister2.groupId] - }); - await progressBlocks(1); - await log({ - operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], - groupIds: [outputRegister.groupId, outputRegister2.groupId] - }); - - - await (await deployedSSVNetworkContract.removeValidator(outputRegister2.validatorPK)).wait(); - await log({ - action: 'remove validator #2', - operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], - groupIds: [outputRegister.groupId, outputRegister2.groupId] - }); - - await progressBlocks(1); - await log({ - operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], - groupIds: [outputRegister.groupId, outputRegister2.groupId] - }); - await progressBlocks(1); - await log({ - operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], - groupIds: [outputRegister.groupId, outputRegister2.groupId] - }); - await progressBlocks(1); - let results = [] - for (let i = 0; i < 10; ++i) { - let resultRegister = (await (await deployedSSVNetworkContract.registerValidator( - validatorPK + i % 10, - [1,2,3,4], - sharePKs[2], - '10000' - )).wait()).logs[0]; - - const interfaceRegister = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId, bytes shares)']); - const outputRegister = interfaceRegister.decodeEventLog('ValidatorAdded', resultRegister.data, resultRegister.topics); - - results.push(outputRegister); - } - console.log("outputRegister.groupId,outputRegister2.groupId") - console.log(outputRegister.groupId,outputRegister3.groupId) - - const transferLogs = (await (await deployedSSVNetworkContract.bulkTransferValidators( - results.map(r => r.validatorPK), - outputRegister.groupId, - outputRegister3.groupId, - results.map(r => sharePKs[4]), - '10000' - )).wait()).logs; - - // await log({ - // action: 'transfer', - // operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], - // groupIds: [outputRegister.groupId, resultRegister3.groupId] - // }); - - /* - // validator 2 - await expect(await deployedSSVNetworkContract.registerValidator( - [1,2,3,4], - validatorPK, - sharePKs.slice(0, 4), - encryptedShares.slice(0, 4), - "10000" - )) - .to.emit(deployedSSVNetworkContract, 'ValidatorAdded'); - // .withArgs(validatorPK); - - - const resultRegister = (await (await deployedSSVNetworkContract.registerValidator( - [1,2,3,4], - validatorPK, - sharePKs.slice(0, 4), - encryptedShares.slice(0, 4), - '10000' - )).wait()).logs[0]; - const interfaceRegister = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId)']); - const outputRegister = interfaceRegister.decodeEventLog('ValidatorAdded', resultRegister.data, resultRegister.topics); - expect(outputRegister.validatorPK).to.equal(validatorPK); - - console.log("register ---->", outputRegister.validatorPK, outputRegister.groupId); - console.log("operatorIdsAfterRegister ---->", await deployedSSVNetworkContract.test_getOperatorsByGroupId(outputRegister.groupId)); - - const resultUpdate = (await (await deployedSSVNetworkContract.updateValidator( - [2,3,4,5], - validatorPK, - outputRegister.groupId, - '10000' - )).wait()).logs[0];; - const interfaceUpdate = new ethers.utils.Interface(['event ValidatorUpdated(bytes validatorPK, bytes32 groupId)']); - const outputUpdate = interfaceUpdate.decodeEventLog('ValidatorUpdated', resultUpdate.data, resultUpdate.topics); - expect(outputRegister.groupId).not.equal(outputUpdate.groupId); - expect(outputRegister.validatorPK).to.equal(outputUpdate.validatorPK); - - console.log("update ---->", outputUpdate.validatorPK, outputUpdate.groupId); - console.log("operatorIdsAfterUpdate ---->", await deployedSSVNetworkContract.test_getOperatorsByGroupId(outputUpdate.groupId)); - - await expect(await deployedSSVNetworkContract.removeValidator( - validatorPK, - outputUpdate.groupId - )) - .to.emit(deployedSSVNetworkContract, 'ValidatorRemoved') - .withArgs(validatorPK, outputUpdate.groupId); - - */ - // await deployedSSVNetworkContract.liquidate("0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", "0x392791df626408017a264f53fde61065d5a93a32b60171df9d8a46afdf82992d"); - }); -}); diff --git a/test/validators/register.ts b/test/validators/register.ts index f1ecbf3c..11efda64 100644 --- a/test/validators/register.ts +++ b/test/validators/register.ts @@ -1,3 +1,5 @@ +declare const ethers: any; + import * as helpers from '../helpers/contract-helpers'; import { expect } from 'chai'; @@ -13,22 +15,18 @@ describe('Register Validator Tests', () => { // Register operators await helpers.registerOperators(0, 11, helpers.CONFIG.minimalOperatorFee); - minDepositAmount = helpers.CONFIG.minimalBlocksBeforeLiquidation * helpers.CONFIG.minimalOperatorFee * 4; - - // Deposit into accounts - await helpers.deposit([0], [`${minDepositAmount * 2}`]); - await helpers.deposit([1], [minDepositAmount]); + minDepositAmount = (helpers.CONFIG.minimalBlocksBeforeLiquidation + 2) * helpers.CONFIG.minimalOperatorFee * 4; // Register a validator clusterResult = await helpers.registerValidators(0, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); }); it('Register validator emits ValidatorAdded event', async () => { + // register validator using cluster Id await expect(ssvNetworkContract.registerValidator( helpers.DataGenerator.publicKey(1), - helpers.DataGenerator.cluster.new(), - helpers.DataGenerator.shares(0), - minDepositAmount + (await helpers.ensureClusterAndDeposit(0, helpers.DataGenerator.cluster.new(), minDepositAmount)).clusterId, + helpers.DataGenerator.shares(0) )).to.emit(ssvNetworkContract, 'ValidatorAdded'); }); @@ -36,8 +34,8 @@ describe('Register Validator Tests', () => { await helpers.registerValidators(0, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); }); - it('Register two validators into an existing cluster', async () => { - await helpers.registerValidators(0, 1, `${minDepositAmount * 2}`, helpers.DataGenerator.cluster.byId(clusterResult.clusterId), [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]); + it('Register two validators in the same pod', async () => { + await helpers.registerValidators(0, 1, minDepositAmount, helpers.DataGenerator.cluster.byId(clusterResult.clusterId), [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]); }); it('Register two validators into an existing cluster', async () => { @@ -46,55 +44,41 @@ describe('Register Validator Tests', () => { it('Invalid operator amount', async () => { // 2 Operators - await expect(ssvNetworkContract.registerValidator( - helpers.DataGenerator.publicKey(0), - [1, 2], - helpers.DataGenerator.shares(0), - minDepositAmount - )).to.be.revertedWith('OessDataStructureInvalid'); + await expect(helpers.ensureClusterAndDeposit(0, [1, 2], minDepositAmount)).to.be.revertedWith('OperatorIdsStructureInvalid'); // 6 Operators - await expect(ssvNetworkContract.registerValidator( - helpers.DataGenerator.publicKey(0), - [1, 2, 3, 4, 5, 6], - helpers.DataGenerator.shares(0), - minDepositAmount - )).to.be.revertedWith('OessDataStructureInvalid'); + await expect(helpers.ensureClusterAndDeposit(0, [1, 2, 3, 4, 5, 6], minDepositAmount)).to.be.revertedWith('OperatorIdsStructureInvalid'); }); it('Invalid public key length', async () => { await expect(ssvNetworkContract.registerValidator( helpers.DataGenerator.shares(0), - [1, 2, 3, 4], + (await helpers.ensureClusterAndDeposit(0, helpers.DataGenerator.cluster.new(), minDepositAmount)).clusterId, helpers.DataGenerator.shares(0), - minDepositAmount )).to.be.revertedWith('InvalidPublicKeyLength'); }); it('Not enough amount', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( helpers.DataGenerator.publicKey(0), - [1, 2, 3, 4], + (await helpers.ensureClusterAndDeposit(0, helpers.DataGenerator.cluster.new(), '0')).clusterId, helpers.DataGenerator.shares(0), - minDepositAmount / 10 )).to.be.revertedWith('AccountLiquidatable'); }); it('Non existent operator', async () => { await expect(ssvNetworkContract.registerValidator( helpers.DataGenerator.publicKey(0), - [1, 2, 3, 25], + (await helpers.ensureClusterAndDeposit(0, [1, 2, 3, 25], minDepositAmount)).clusterId, helpers.DataGenerator.shares(0), - minDepositAmount )).to.be.revertedWith('OperatorDoesNotExist'); }); it('Register with existing validator', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( helpers.DataGenerator.publicKey(0), - [1, 2, 3, 4], + (await helpers.ensureClusterAndDeposit(1, [1, 2, 3, 4], minDepositAmount)).clusterId, helpers.DataGenerator.shares(0), - minDepositAmount )).to.be.revertedWith('ValidatorAlreadyExists'); }); diff --git a/test/validators/remove.ts b/test/validators/remove.ts index 6009735a..cd7d7bdc 100644 --- a/test/validators/remove.ts +++ b/test/validators/remove.ts @@ -51,9 +51,8 @@ describe('Remove Validator Tests', () => { // Re-register validator await ssvNetworkContract.connect(helpers.DB.owners[4]).registerValidator( helpers.DataGenerator.publicKey(0), - [1, 2, 3, 4], + (await helpers.ensureClusterAndDeposit(4, [1, 2, 3, 4], minDepositAmount)).clusterId, helpers.DataGenerator.shares(0), - minDepositAmount ); // Remove the validator again diff --git a/test/validators/transfer-bulk.ts b/test/validators/transfer-bulk.ts index a1f19d81..a021ce6f 100644 --- a/test/validators/transfer-bulk.ts +++ b/test/validators/transfer-bulk.ts @@ -14,11 +14,7 @@ describe('Bulk Transfer Validator Tests', () => { await helpers.registerOperators(0, 12, helpers.CONFIG.minimalOperatorFee); await helpers.registerOperators(0, 1, helpers.CONFIG.minimalOperatorFee); - minDepositAmount = helpers.CONFIG.minimalBlocksBeforeLiquidation * helpers.CONFIG.minimalOperatorFee * 4; - - // Deposit into accounts - // await helpers.deposit([4], [`${minDepositAmount * 12}`]); - // await helpers.deposit([5], [minDepositAmount]); + minDepositAmount = (helpers.CONFIG.minimalBlocksBeforeLiquidation + 2) * helpers.CONFIG.minimalOperatorFee * 4; // Register validators clusterResult1 = await helpers.registerValidators(4, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); @@ -27,33 +23,37 @@ describe('Bulk Transfer Validator Tests', () => { }); it('Bulk transfer 10 validators emits BulkValidatorTransferred event', async () => { + await helpers.ensureClusterAndDeposit(4, helpers.DataGenerator.cluster.byId(clusterResult3.clusterId), `${minDepositAmount * (clusterResult2.validators.length + 1) }`); + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], clusterResult1.clusterId, clusterResult3.clusterId, Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)), - `${minDepositAmount * 12}` )).to.emit(ssvNetworkContract, 'BulkValidatorTransferred'); }); it('Bulk transfer validator with an invalid owner', async () => { + await helpers.ensureClusterAndDeposit(5, helpers.DataGenerator.cluster.byId(clusterResult3.clusterId), `${minDepositAmount * (clusterResult2.validators.length + 1) }`); + await expect(ssvNetworkContract.connect(helpers.DB.owners[5]).bulkTransferValidators( [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], clusterResult1.clusterId, clusterResult3.clusterId, Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)), - minDepositAmount )).to.be.revertedWith('ValidatorNotOwned'); }); it('Bulk transfer validator with an unowned validator', async () => { const account5cluster = await helpers.registerValidators(5, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + + await helpers.ensureClusterAndDeposit(4, helpers.DataGenerator.cluster.byId(clusterResult3.clusterId), `${minDepositAmount * (clusterResult2.validators.length + 1) }`); + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( [clusterResult1.validators[0].publicKey, account5cluster.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], clusterResult1.clusterId, clusterResult3.clusterId, Array(clusterResult2.validators.length + 2).fill(helpers.DataGenerator.shares(0)), - `${minDepositAmount * 12}` )).to.be.revertedWith('ValidatorNotOwned'); }); @@ -63,7 +63,6 @@ describe('Bulk Transfer Validator Tests', () => { clusterResult1.clusterId, clusterResult3.clusterId, Array(clusterResult2.validators.length + 2).fill(helpers.DataGenerator.shares(0)), - minDepositAmount )).to.be.revertedWith('ValidatorNotOwned'); }); @@ -73,13 +72,13 @@ describe('Bulk Transfer Validator Tests', () => { [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], clusterResult1.clusterId, clusterResult3.clusterId, - `${minDepositAmount * 12}`, + `${minDepositAmount * 10 }`, [GasGroup.BULK_TRANSFER_VALIDATOR]); }); it('Bulk transfer 10 validators to a cluster with 7 operators', async () => { // Register validator with 7 operators - const { clusterId } = await helpers.registerValidators(4, 1, minDepositAmount + minDepositAmount * 3, [1, 2, 3, 4, 5, 6, 7]); + const { clusterId } = await helpers.registerValidators(4, 1, `${(minDepositAmount / 4) * 7}`, [1, 2, 3, 4, 5, 6, 7]); // Transfer validator to an existing cluster await helpers.bulkTransferValidator( @@ -87,7 +86,7 @@ describe('Bulk Transfer Validator Tests', () => { [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], clusterResult1.clusterId, clusterId, - `${minDepositAmount * 19}`, + `${(minDepositAmount / 4) * 7 * 10}`, [GasGroup.BULK_TRANSFER_VALIDATOR_NON_EXISTING_POD]); }); @@ -101,7 +100,7 @@ describe('Bulk Transfer Validator Tests', () => { [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], clusterResult1.clusterId, clusterId, - `${minDepositAmount * 14}`, + `${minDepositAmount * 10}`, [GasGroup.BULK_TRANSFER_VALIDATOR_NON_EXISTING_POD]); }); @@ -111,7 +110,6 @@ describe('Bulk Transfer Validator Tests', () => { clusterResult1.clusterId.slice(0, -1) + 'a', clusterResult1.clusterId, Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)), - '10000' )).to.be.revertedWith('InvalidCluster'); }); @@ -122,7 +120,6 @@ describe('Bulk Transfer Validator Tests', () => { clusterResult1.clusterId, clusterResult3.clusterId, Array(clusterResult2.validators.length).fill(helpers.DataGenerator.shares(0)), - '10000' )).to.be.revertedWith('ParametersMismatch'); // 9 validators and 8 shares @@ -131,7 +128,6 @@ describe('Bulk Transfer Validator Tests', () => { clusterResult1.clusterId, clusterResult3.clusterId, Array(clusterResult2.validators.length - 1).fill(helpers.DataGenerator.shares(0)), - '10000' )).to.be.revertedWith('ParametersMismatch'); }); @@ -142,7 +138,6 @@ describe('Bulk Transfer Validator Tests', () => { clusterResult1.clusterId, clusterId, Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)), - minDepositAmount / 10 )).to.be.revertedWith('AccountLiquidatable'); }); diff --git a/test/validators/transfer.ts b/test/validators/transfer.ts index 4d5e3ab8..08525731 100644 --- a/test/validators/transfer.ts +++ b/test/validators/transfer.ts @@ -23,41 +23,37 @@ describe('Transfer Validator Tests', () => { it('Transfer validator emits ValidatorTransferred event', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( clusterResult1.validators[0].publicKey, - helpers.DataGenerator.cluster.new(), + (await helpers.ensureClusterAndDeposit(4, helpers.DataGenerator.cluster.new(), minDepositAmount)).clusterId, helpers.DataGenerator.shares(helpers.DB.validators.length), - minDepositAmount )).to.emit(ssvNetworkContract, 'ValidatorTransferred'); }); it('Transfer validator into a new cluster', async () => { - const transferedValidator = await helpers.transferValidator(4, clusterResult1.validators[0].publicKey, helpers.DataGenerator.cluster.new(), minDepositAmount, [GasGroup.TRANSFER_VALIDATOR_NEW_CLUSTER]); - // expect(clusterResult1.clusterId).not.equals(transferedValidator.eventsByName.ValidatorTransferred[0].args.clusterId); + await helpers.transferValidator(4, clusterResult1.validators[0].publicKey, helpers.DataGenerator.cluster.new(), minDepositAmount, [GasGroup.TRANSFER_VALIDATOR_NEW_CLUSTER]); }); it('Transfer validator with an invalid owner', async () => { // Transfer validator with an invalid owner await expect(ssvNetworkContract.connect(helpers.DB.owners[5]).transferValidator( clusterResult1.validators[0].publicKey, - helpers.DataGenerator.cluster.byId(clusterResult2.clusterId), + (await helpers.ensureClusterAndDeposit(5, helpers.DataGenerator.cluster.byId(clusterResult2.clusterId), minDepositAmount)).clusterId, helpers.DataGenerator.shares(helpers.DB.validators.length), - '10000' )).to.be.revertedWith('ValidatorNotOwned'); // Transfer validator with an invalid public key await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( helpers.DataGenerator.shares(0), - helpers.DataGenerator.cluster.byId(clusterResult2.clusterId), + (await helpers.ensureClusterAndDeposit(4, helpers.DataGenerator.cluster.byId(clusterResult2.clusterId), minDepositAmount)).clusterId, helpers.DataGenerator.shares(helpers.DB.validators.length), - minDepositAmount )).to.be.revertedWith('ValidatorNotOwned'); }); it('Transfer validator to a cluster with 7 operators', async () => { // Register validator with 7 operators - const { clusterId } = await helpers.registerValidators(4, 1, minDepositAmount + minDepositAmount * 3, [1, 2, 3, 4, 5, 6, 7]); + const { clusterId } = await helpers.registerValidators(4, 1, `${minDepositAmount / 4 * 7}`, [1, 2, 3, 4, 5, 6, 7]); // Transfer validator to an existing cluster - await helpers.transferValidator(4, clusterResult1.validators[0].publicKey, helpers.DataGenerator.cluster.byId(clusterId), minDepositAmount, [GasGroup.TRANSFER_VALIDATOR_NON_EXISTING_POD]); + await helpers.transferValidator(4, clusterResult1.validators[0].publicKey, helpers.DataGenerator.cluster.byId(clusterId), `${minDepositAmount / 4 * 7 * 2}`, [GasGroup.TRANSFER_VALIDATOR_NON_EXISTING_POD]); }); it('Transfer validator with not enough amount', async () => { @@ -67,9 +63,8 @@ describe('Transfer Validator Tests', () => { // Transfer to cluster with not enough amount await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( clusterResult1.validators[0].publicKey, - helpers.DataGenerator.cluster.byId(clusterId), + (await helpers.ensureClusterAndDeposit(4, helpers.DataGenerator.cluster.byId(clusterId), helpers.CONFIG.minimalOperatorFee)).clusterId, helpers.DataGenerator.shares(helpers.DB.validators.length), - helpers.CONFIG.minimalOperatorFee )).to.be.revertedWith('AccountLiquidatable'); }); @@ -84,7 +79,7 @@ describe('Transfer Validator Tests', () => { const clusterResult3 = await helpers.registerValidators(5, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); // Transfer validator - const transfredValidator1 = await helpers.transferValidator(4, clusterResult1.validators[0].publicKey, helpers.DataGenerator.cluster.byId(clusterResult3.clusterId), minDepositAmount, [GasGroup.TRANSFER_VALIDATOR_NON_EXISTING_POD]); + const transfredValidator1 = await helpers.transferValidator(4, clusterResult1.validators[0].publicKey, helpers.DataGenerator.cluster.byId(clusterResult3.clusterId), `${minDepositAmount * 2}`, [GasGroup.TRANSFER_VALIDATOR_NON_EXISTING_POD]); // expect(clusterResult3.clusterId).equals(transfredValidator1.eventsByName.ValidatorTransferred[0].args.podId); }); From 1ca7afd44694b9315bd410b905bb865a896ea341 Mon Sep 17 00:00:00 2001 From: Wadym Date: Wed, 26 Oct 2022 09:42:09 +0200 Subject: [PATCH 080/149] core logic with improvements (#107) Co-authored-by: Vadim --- contracts/ISSVNetwork.sol | 29 +++++--- contracts/SSVNetwork.sol | 119 +++++++++++++++++++++++-------- test/helpers/contract-helpers.ts | 13 ++-- test/helpers/gas-usage.ts | 10 +-- test/liquidate/liquidate.ts | 38 ++++++---- test/validators/register.ts | 4 +- test/validators/transfer-bulk.ts | 2 +- test/validators/transfer.ts | 2 +- 8 files changed, 151 insertions(+), 66 deletions(-) diff --git a/contracts/ISSVNetwork.sol b/contracts/ISSVNetwork.sol index 18644e02..71d8349b 100644 --- a/contracts/ISSVNetwork.sol +++ b/contracts/ISSVNetwork.sol @@ -29,36 +29,36 @@ interface ISSVNetwork { /** * @dev Emitted when the validator has been added. * @param publicKey The public key of a validator. - * @param podId The pod id the validator been added to. + * @param clusterId The cluster id the validator been added to. * @param shares snappy compressed shares(a set of encrypted and public shares). */ event ValidatorAdded( bytes publicKey, - bytes32 podId, + bytes32 clusterId, bytes shares ); /** * @dev Emitted when validator was transferred between pods. * @param publicKey The public key of a validator. - * @param podId The validator's new pod id. + * @param clusterId The validator's new cluster id. * @param shares snappy compressed shares(a set of encrypted and public shares). */ event ValidatorTransferred( bytes publicKey, - bytes32 podId, + bytes32 clusterId, bytes shares ); /** * @dev Emitted when validators were transferred between pods. * @param publicKeys An array of transferred public keys. - * @param podId The validators new pod id. + * @param clusterId The validators new pod id. * @param shares an array of snappy compressed shares(a set of encrypted and public shares). */ event BulkValidatorTransferred( bytes[] publicKeys, - bytes32 podId, + bytes32 clusterId, bytes[] shares ); @@ -98,7 +98,9 @@ interface ISSVNetwork { uint256 fee ); - event AccountLiquidated(address ownerAddress, bytes32 podId); + event PodLiquidated(address ownerAddress, bytes32 clusterId); + + event PodEnabled(address ownerAddress, bytes32 clusterId); event OperatorFeeIncreaseLimitUpdate(uint64 value); @@ -133,8 +135,8 @@ interface ISSVNetwork { error OperatorDoesNotExist(); error NotEnoughBalance(); error ValidatorAlreadyExists(); - error AccountLiquidatable(); - error AccountNotLiquidatable(); + error PodLiquidatable(); + error PodNotLiquidatable(); error InvalidPublicKeyLength(); error OperatorIdsStructureInvalid(); error ValidatorNotOwned(); @@ -143,6 +145,7 @@ interface ISSVNetwork { error NegativeBalance(); error ClusterAlreadyExists(); error ClusterNotExists(); + error PodAlreadyEnabled(); /** errors */ // error validatorWithPublicKeyNotExist(); @@ -228,7 +231,13 @@ interface ISSVNetwork { bytes calldata shares ) external; - function liquidate(address ownerAddress, uint64[] memory operatorIds) external; + function liquidate(address ownerAddress, bytes32 clusterId) external; + + function isLiquidatable(address ownerAddress, bytes32 clusterId) external view returns(bool); + + function isLiquidated(address ownerAddress, bytes32 clusterId) external view returns(bool); + + function reactivatePod(bytes32 clusterId, uint256 amount) external; function bulkTransferValidators( bytes[] calldata validatorPK, diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index 2e47c892..45c27f9e 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -56,6 +56,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { uint64 networkFee; uint64 networkFeeIndex; Snapshot usage; + bool disabled; } struct Validator { @@ -231,7 +232,6 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { bytes32 clusterId, bytes calldata shares ) external { - if (publicKey.length != 48) { revert InvalidPublicKeyLength(); } @@ -252,21 +252,26 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { if (operator.owner == address(0)) { revert OperatorDoesNotExist(); } - operator.snapshot = _getSnapshot(operator, uint64(block.number)); - ++operator.validatorCount; - _operators[operatorIds[i]] = operator; + + if (!pod.disabled) { + operator.snapshot = _getSnapshot(operator, uint64(block.number)); + ++operator.validatorCount; + _operators[operatorIds[i]] = operator; + } } } { - DAO memory dao = _dao; - dao = _updateDAOEarnings(dao); - ++dao.validatorCount; - _dao = dao; + if (!pod.disabled) { + DAO memory dao = _dao; + dao = _updateDAOEarnings(dao); + ++dao.validatorCount; + _dao = dao; + } } - if (_liquidatable(pod.usage.balance, pod.validatorCount, operatorIds)) { - revert AccountLiquidatable(); + if (_liquidatable(pod.disabled, _ownerPodBalance(pod, _clusterCurrentIndex(clusterId)), pod.validatorCount, operatorIds)) { + revert NotEnoughBalance(); } _pods[hashedPod] = pod; @@ -275,6 +280,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { if (_validatorPKs[hashedValidator].clusterId > 0) { revert ValidatorAlreadyExists(); } + _validatorPKs[hashedValidator] = Validator({ owner: msg.sender, clusterId: clusterId, active: true}); emit ValidatorAdded(publicKey, clusterId, shares); @@ -323,8 +329,8 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _dao = dao; } - if (_liquidatable(pod.usage.balance, pod.validatorCount, operatorIds)) { - revert AccountLiquidatable(); + if (_liquidatable(pod.disabled, _ownerPodBalance(pod, _clusterCurrentIndex(newClusterId)), pod.validatorCount, operatorIds)) { + revert NotEnoughBalance(); } emit ValidatorTransferred(publicKey, newClusterId, shares); @@ -407,26 +413,83 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } } - function liquidate(address ownerAddress, uint64[] memory operatorIds) external { - bytes32 clusterId = keccak256(abi.encodePacked(operatorIds)); - bytes32 podKey = keccak256(abi.encodePacked(ownerAddress, clusterId)); - Pod memory pod = _pods[podKey]; + function liquidate(address ownerAddress, bytes32 clusterId) external { + uint64[] memory operatorIds = _clusters[clusterId].operatorIds; + bytes32 hashedPod = keccak256(abi.encodePacked(ownerAddress, clusterId)); + + { + Pod memory pod = _pods[hashedPod]; - if (!_liquidatable(pod.usage.balance, pod.validatorCount, operatorIds)) { - revert AccountNotLiquidatable(); + if (!_liquidatable(pod.disabled, _ownerPodBalance(pod, _clusterCurrentIndex(clusterId)), pod.validatorCount, operatorIds)) { + revert PodNotLiquidatable(); + } + + for (uint64 index = 0; index < operatorIds.length; ++index) { + _operators[operatorIds[index]].validatorCount -= pod.validatorCount; + } + + _dao.validatorCount -= pod.validatorCount; } - for (uint64 index = 0; index < operatorIds.length; ++index) { - _operators[operatorIds[index]].validatorCount -= pod.validatorCount; + // _token.transfer(msg.sender, pod.usage.balance); + + _pods[hashedPod].disabled = true; + + emit PodLiquidated(ownerAddress, clusterId); + } + + function isLiquidatable(address ownerAddress, bytes32 clusterId) external view override returns (bool) { + uint64[] memory operatorIds = _clusters[clusterId].operatorIds; + bytes32 hashedPod = keccak256(abi.encodePacked(ownerAddress, clusterId)); + + Pod memory pod = _pods[hashedPod]; + + return _liquidatable(pod.disabled, _ownerPodBalance(pod, _clusterCurrentIndex(clusterId)), pod.validatorCount, operatorIds); + } + + function isLiquidated(address ownerAddress, bytes32 clusterId) external view override returns (bool) { + bytes32 hashedPod = keccak256(abi.encodePacked(ownerAddress, clusterId)); + + return _pods[hashedPod].disabled; + } + + function reactivatePod(bytes32 clusterId, uint256 amount) external override { + uint64[] memory operatorIds = _clusters[clusterId].operatorIds; + bytes32 hashedPod = keccak256(abi.encodePacked(msg.sender, clusterId)); + + Pod memory pod = _pods[hashedPod]; + + if (!pod.disabled) { + revert PodAlreadyEnabled(); } - _dao.validatorCount -= pod.validatorCount; + _deposit(msg.sender, clusterId, amount.shrink()); + + { + for (uint64 index = 0; index < operatorIds.length; ++index) { + Operator memory operator = _operators[operatorIds[index]]; + operator.snapshot = _getSnapshot(operator, uint64(block.number)); + operator.validatorCount += pod.validatorCount; + _operators[operatorIds[index]] = operator; + } + } - _token.transfer(msg.sender, pod.usage.balance); + { + DAO memory dao = _dao; + dao = _updateDAOEarnings(dao); + dao.validatorCount += pod.validatorCount; + _dao = dao; + } + + pod.disabled = false; + + if(_liquidatable(pod.disabled, _ownerPodBalance(pod, _clusterCurrentIndex(clusterId)), pod.validatorCount, operatorIds)) { + revert NotEnoughBalance(); + } - delete _pods[podKey]; + _pods[hashedPod] = pod; - emit AccountLiquidated(ownerAddress, podKey); + emit PodEnabled(msg.sender, clusterId); } function bulkTransferValidators( @@ -482,8 +545,8 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { pod.usage.block = uint64(block.number); pod.validatorCount += activeValidatorCount; - if (_liquidatable(pod.usage.balance, pod.validatorCount, newOperatorIds)) { - revert AccountLiquidatable(); + if (_liquidatable(pod.disabled, _ownerPodBalance(pod, podIndex), pod.validatorCount, newOperatorIds)) { + revert PodLiquidatable(); } } @@ -772,8 +835,8 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } } - function _liquidatable(uint64 balance, uint64 validatorCount, uint64[] memory operatorIds) private view returns (bool) { - return balance < LIQUIDATION_MIN_BLOCKS * (_burnRatePerValidator(_extractOperators(operatorIds)) + _networkFee) * validatorCount; + function _liquidatable(bool disabled, uint64 balance, uint64 validatorCount, uint64[] memory operatorIds) private view returns (bool) { + return !disabled && balance < LIQUIDATION_MIN_BLOCKS * (_burnRatePerValidator(_extractOperators(operatorIds)) + _networkFee) * validatorCount; } function _updateOperatorFeeUnsafe(uint64 operatorId, uint64 fee) private { diff --git a/test/helpers/contract-helpers.ts b/test/helpers/contract-helpers.ts index c642840b..a78d9e39 100644 --- a/test/helpers/contract-helpers.ts +++ b/test/helpers/contract-helpers.ts @@ -129,8 +129,7 @@ export const registerValidators = async (ownerId: number, numberOfValidators: nu (await ensureClusterAndDeposit(ownerId, operatorIds, amount)).clusterId, shares, ), gasGroups); - - clusterId = eventsByName.ValidatorAdded[0].args.podId; + clusterId = eventsByName.ValidatorAdded[0].args.clusterId; DB.clusters[clusterId] = ({ id: clusterId, operatorIds }); DB.validators.push({ publicKey, clusterId, shares }); validators.push({ publicKey, shares }); @@ -184,8 +183,12 @@ export const bulkTransferValidator = async (ownerId: number, publicKey: string[] }; export const liquidate = async (executorOwnerId: number, liquidatedOwnerId: number, operatorIds: number[], gasGroups?: GasGroup[]) => { - const { eventsByName } = await trackGas(DB.ssvNetwork.contract.connect(DB.owners[executorOwnerId]).liquidate( + const { eventsByName } = await trackGas(DB.ssvNetwork.contract.connect(DB.owners[executorOwnerId]).liquidate( DB.owners[liquidatedOwnerId].address, - operatorIds + await DB.ssvNetwork.contract.getClusterId(operatorIds), ), gasGroups); -} + + const clusterId = eventsByName.AccountLiquidated[0].args.clusterId; + return { clusterId }; +}; + diff --git a/test/helpers/gas-usage.ts b/test/helpers/gas-usage.ts index 55abd0c4..1513ab4d 100644 --- a/test/helpers/gas-usage.ts +++ b/test/helpers/gas-usage.ts @@ -17,15 +17,15 @@ export enum GasGroup { const MAX_GAS_PER_GROUP: any = { [GasGroup.REGISTER_OPERATOR]: 105000, [GasGroup.REMOVE_OPERATOR]: 45000, - [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]: 190000, - [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]: 230000, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE]: 400000, + [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]: 202000, + [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]: 220000, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE]: 333000, // 313000 [GasGroup.REMOVE_VALIDATOR]: 120000, [GasGroup.TRANSFER_VALIDATOR_NEW_CLUSTER]: 400000, [GasGroup.TRANSFER_VALIDATOR]: 260000, [GasGroup.TRANSFER_VALIDATOR_NON_EXISTING_POD]: 290000, - [GasGroup.BULK_TRANSFER_VALIDATOR]: 345500, - [GasGroup.BULK_TRANSFER_VALIDATOR_NON_EXISTING_POD]: 345500, + [GasGroup.BULK_TRANSFER_VALIDATOR]: 351000, + [GasGroup.BULK_TRANSFER_VALIDATOR_NON_EXISTING_POD]: 351000, }; class GasStats { diff --git a/test/liquidate/liquidate.ts b/test/liquidate/liquidate.ts index 4d49f333..38154dc9 100644 --- a/test/liquidate/liquidate.ts +++ b/test/liquidate/liquidate.ts @@ -1,32 +1,42 @@ import * as helpers from '../helpers/contract-helpers'; +import * as utils from '../helpers/utils'; import { expect } from 'chai'; +import { GasGroup } from '../helpers/gas-usage'; -const numberOfOperators = 4; -const operatorFee = 4; +let ssvNetworkContract: any, clusterResult1: any, minDepositAmount: any; -let ssvNetworkContract: any, operatorIDs: any, shares: any, owner: any; - -describe('Liquidate Tests', () => { +describe('Transfer Validator Tests', () => { beforeEach(async () => { - const contractData = await helpers.initializeContract(); - ssvNetworkContract = contractData.contract; - }); + // Initialize contract + ssvNetworkContract = (await helpers.initializeContract()).contract; - it('Liquidatable', async () => { + // Register operators + await helpers.registerOperators(0, 12, helpers.CONFIG.minimalOperatorFee); + minDepositAmount = (helpers.CONFIG.minimalBlocksBeforeLiquidation + 10) * helpers.CONFIG.minimalOperatorFee * 4; + + // Register validators + clusterResult1 = await helpers.registerValidators(4, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); }); - it('Liquidate', async () => { + it('Liquidatable', async () => { + await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); + expect(await ssvNetworkContract.isLiquidatable(helpers.DB.owners[4].address, clusterResult1.clusterId)).to.equal(true); + }); + it('Liquidate emits PodLiquidated event', async () => { + await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); + await expect(ssvNetworkContract.liquidate(helpers.DB.owners[4].address, clusterResult1.clusterId)).to.emit(ssvNetworkContract, 'PodLiquidated'); }); it('Liquidate errors', async () => { - + await expect(ssvNetworkContract.liquidate(helpers.DB.owners[4].address, clusterResult1.clusterId)).to.be.revertedWith('PodNotLiquidatable'); }); - it('Liquidate gas limits', async () => { - + it('Is liquidated', async () => { + await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); + await ssvNetworkContract.liquidate(helpers.DB.owners[4].address, clusterResult1.clusterId); + expect(await ssvNetworkContract.isLiquidated(helpers.DB.owners[4].address, clusterResult1.clusterId)).to.equal(true); }); - }); diff --git a/test/validators/register.ts b/test/validators/register.ts index 11efda64..36d46bca 100644 --- a/test/validators/register.ts +++ b/test/validators/register.ts @@ -35,7 +35,7 @@ describe('Register Validator Tests', () => { }); it('Register two validators in the same pod', async () => { - await helpers.registerValidators(0, 1, minDepositAmount, helpers.DataGenerator.cluster.byId(clusterResult.clusterId), [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]); + await helpers.registerValidators(0, 1, minDepositAmount, helpers.DataGenerator.cluster.byId(clusterResult.clusterId), [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]); }); it('Register two validators into an existing cluster', async () => { @@ -63,7 +63,7 @@ describe('Register Validator Tests', () => { helpers.DataGenerator.publicKey(0), (await helpers.ensureClusterAndDeposit(0, helpers.DataGenerator.cluster.new(), '0')).clusterId, helpers.DataGenerator.shares(0), - )).to.be.revertedWith('AccountLiquidatable'); + )).to.be.revertedWith('NotEnoughBalance'); }); it('Non existent operator', async () => { diff --git a/test/validators/transfer-bulk.ts b/test/validators/transfer-bulk.ts index a021ce6f..94701824 100644 --- a/test/validators/transfer-bulk.ts +++ b/test/validators/transfer-bulk.ts @@ -138,7 +138,7 @@ describe('Bulk Transfer Validator Tests', () => { clusterResult1.clusterId, clusterId, Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)), - )).to.be.revertedWith('AccountLiquidatable'); + )).to.be.revertedWith('PodLiquidatable'); }); // TODO: fix after connecting the token diff --git a/test/validators/transfer.ts b/test/validators/transfer.ts index 08525731..9e740742 100644 --- a/test/validators/transfer.ts +++ b/test/validators/transfer.ts @@ -65,7 +65,7 @@ describe('Transfer Validator Tests', () => { clusterResult1.validators[0].publicKey, (await helpers.ensureClusterAndDeposit(4, helpers.DataGenerator.cluster.byId(clusterId), helpers.CONFIG.minimalOperatorFee)).clusterId, helpers.DataGenerator.shares(helpers.DB.validators.length), - )).to.be.revertedWith('AccountLiquidatable'); + )).to.be.revertedWith('NotEnoughBalance'); }); // GOING ABOVE GAS LIMIT From 0f7d3ceaa900ed52511d1b6812f2106a9d7837c6 Mon Sep 17 00:00:00 2001 From: Vadim Date: Wed, 26 Oct 2022 15:14:26 +0200 Subject: [PATCH 081/149] add liquidate gas limit --- test/helpers/gas-usage.ts | 2 ++ test/liquidate/liquidate.ts | 8 +++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/test/helpers/gas-usage.ts b/test/helpers/gas-usage.ts index 1513ab4d..1dff5614 100644 --- a/test/helpers/gas-usage.ts +++ b/test/helpers/gas-usage.ts @@ -12,6 +12,7 @@ export enum GasGroup { TRANSFER_VALIDATOR_NON_EXISTING_POD, BULK_TRANSFER_VALIDATOR, BULK_TRANSFER_VALIDATOR_NON_EXISTING_POD, + LIQUIDATE_VALIDATOR, } const MAX_GAS_PER_GROUP: any = { @@ -26,6 +27,7 @@ const MAX_GAS_PER_GROUP: any = { [GasGroup.TRANSFER_VALIDATOR_NON_EXISTING_POD]: 290000, [GasGroup.BULK_TRANSFER_VALIDATOR]: 351000, [GasGroup.BULK_TRANSFER_VALIDATOR_NON_EXISTING_POD]: 351000, + [GasGroup.LIQUIDATE_VALIDATOR]: 101000, }; class GasStats { diff --git a/test/liquidate/liquidate.ts b/test/liquidate/liquidate.ts index 38154dc9..df304ebc 100644 --- a/test/liquidate/liquidate.ts +++ b/test/liquidate/liquidate.ts @@ -2,7 +2,7 @@ import * as helpers from '../helpers/contract-helpers'; import * as utils from '../helpers/utils'; import { expect } from 'chai'; -import { GasGroup } from '../helpers/gas-usage'; +import { trackGas, GasGroup } from '../helpers/gas-usage'; let ssvNetworkContract: any, clusterResult1: any, minDepositAmount: any; @@ -39,4 +39,10 @@ describe('Transfer Validator Tests', () => { await ssvNetworkContract.liquidate(helpers.DB.owners[4].address, clusterResult1.clusterId); expect(await ssvNetworkContract.isLiquidated(helpers.DB.owners[4].address, clusterResult1.clusterId)).to.equal(true); }); + + it('Liquidate gas limits', async () => { + await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); + + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).liquidate(helpers.DB.owners[4].address, clusterResult1.clusterId), [GasGroup.LIQUIDATE_VALIDATOR]); + }); }); From 9c063d99f6350ee0b5b93a34be66685fb8a3ac53 Mon Sep 17 00:00:00 2001 From: Vadim Date: Thu, 27 Oct 2022 09:30:31 +0200 Subject: [PATCH 082/149] code improvements based by pr review --- contracts/SSVNetwork.sol | 118 +++++++++++++----------- test/account/deposit.ts | 7 +- test/account/withdraw.ts | 7 +- test/helpers/contract-helpers.ts | 9 +- test/liquidate/liquidation-threshold.ts | 7 +- test/operators/update.ts | 7 +- test/sanity/stress.ts | 3 +- test/validators/remove.ts | 3 - test/validators/transfer.ts | 2 +- 9 files changed, 74 insertions(+), 89 deletions(-) diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index 89db8997..bea40f6a 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -164,15 +164,11 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { revert FeeTooLow(); } + if (fee.shrink() > operator.fee * (10000 + _operatorMaxFeeIncrease) / 10000) { revert FeeExceedsIncreaseLimit(); } - /* - if (operatorFee <= operator.fee) { - _updateOperatorFeeUnsafe(operatorId, operatorFee); - } else { - */ _operatorFeeChangeRequests[operatorId] = OperatorFeeChangeRequest( fee.shrink(), uint64(block.timestamp) + _declareOperatorFeePeriod, @@ -232,9 +228,8 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { bytes32 clusterId, bytes calldata shares ) external { - if (publicKey.length != 48) { - revert InvalidPublicKeyLength(); - } + _validateClusterId(clusterId); + _validatePublicKey(publicKey); uint64[] memory operatorIds = _clusters[clusterId].operatorIds; @@ -270,7 +265,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } } - if (_liquidatable(pod.disabled, _ownerPodBalance(pod, _clusterCurrentIndex(clusterId)), pod.validatorCount, operatorIds)) { + if (_liquidatable(pod.disabled, _podBalance(pod, _clusterCurrentIndex(clusterId)), pod.validatorCount, operatorIds)) { revert NotEnoughBalance(); } @@ -290,6 +285,9 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { bytes32 newClusterId, bytes calldata shares ) external { + _validateClusterId(newClusterId); + _validatePublicKey(publicKey); + uint64[] memory operatorIds = _clusters[newClusterId].operatorIds; bytes32 hashedValidator = keccak256(publicKey); @@ -328,7 +326,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _dao = dao; } - if (_liquidatable(pod.disabled, _ownerPodBalance(pod, _clusterCurrentIndex(newClusterId)), pod.validatorCount, operatorIds)) { + if (_liquidatable(pod.disabled, _podBalance(pod, _clusterCurrentIndex(newClusterId)), pod.validatorCount, operatorIds)) { revert NotEnoughBalance(); } @@ -337,9 +335,11 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } function removeValidator( - bytes calldata validatorPK + bytes calldata publicKey ) external { - bytes32 hashedValidator = keccak256(validatorPK); + _validatePublicKey(publicKey); + + bytes32 hashedValidator = keccak256(publicKey); if (_validatorPKs[hashedValidator].owner != msg.sender) { revert ValidatorNotOwned(); } @@ -369,14 +369,16 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { delete _validatorPKs[hashedValidator]; - emit ValidatorRemoved(validatorPK, clusterId); + emit ValidatorRemoved(publicKey, clusterId); } function deposit(address owner, bytes32 clusterId, uint256 amount) external { + _validateClusterId(clusterId); _deposit(owner, clusterId, amount.shrink()); } function deposit(bytes32 clusterId, uint256 amount) external { + _validateClusterId(clusterId); _deposit(msg.sender, clusterId, amount.shrink()); } @@ -394,7 +396,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { return clusterId; } - function ensurePodAndDeposit(uint64[] memory operatorIds, uint256 amount) external { + function registerPod(uint64[] memory operatorIds, uint256 amount) external { if (operatorIds.length < 4 || operatorIds.length % 3 != 1) { revert OperatorIdsStructureInvalid(); } @@ -413,13 +415,15 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } function liquidate(address ownerAddress, bytes32 clusterId) external { + _validateClusterId(clusterId); + uint64[] memory operatorIds = _clusters[clusterId].operatorIds; bytes32 hashedPod = keccak256(abi.encodePacked(ownerAddress, clusterId)); { Pod memory pod = _pods[hashedPod]; - if (!_liquidatable(pod.disabled, _ownerPodBalance(pod, _clusterCurrentIndex(clusterId)), pod.validatorCount, operatorIds)) { + if (!_liquidatable(pod.disabled, _podBalance(pod, _clusterCurrentIndex(clusterId)), pod.validatorCount, operatorIds)) { revert PodNotLiquidatable(); } @@ -438,21 +442,27 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } function isLiquidatable(address ownerAddress, bytes32 clusterId) external view override returns (bool) { + _validateClusterId(clusterId); + uint64[] memory operatorIds = _clusters[clusterId].operatorIds; bytes32 hashedPod = keccak256(abi.encodePacked(ownerAddress, clusterId)); Pod memory pod = _pods[hashedPod]; - return _liquidatable(pod.disabled, _ownerPodBalance(pod, _clusterCurrentIndex(clusterId)), pod.validatorCount, operatorIds); + return _liquidatable(pod.disabled, _podBalance(pod, _clusterCurrentIndex(clusterId)), pod.validatorCount, operatorIds); } function isLiquidated(address ownerAddress, bytes32 clusterId) external view override returns (bool) { + _validateClusterId(clusterId); + bytes32 hashedPod = keccak256(abi.encodePacked(ownerAddress, clusterId)); return _pods[hashedPod].disabled; } function reactivatePod(bytes32 clusterId, uint256 amount) external override { + _validateClusterId(clusterId); + uint64[] memory operatorIds = _clusters[clusterId].operatorIds; bytes32 hashedPod = keccak256(abi.encodePacked(msg.sender, clusterId)); @@ -482,7 +492,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { pod.disabled = false; - if(_liquidatable(pod.disabled, _ownerPodBalance(pod, _clusterCurrentIndex(clusterId)), pod.validatorCount, operatorIds)) { + if(_liquidatable(pod.disabled, _podBalance(pod, _clusterCurrentIndex(clusterId)), pod.validatorCount, operatorIds)) { revert NotEnoughBalance(); } @@ -492,19 +502,24 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } function bulkTransferValidators( - bytes[] calldata validatorPK, + bytes[] calldata publicKeys, bytes32 fromClusterId, bytes32 toClusterId, bytes[] calldata shares ) external { - if (validatorPK.length != shares.length) { + _validateClusterId(fromClusterId); + _validateClusterId(toClusterId); + + if (publicKeys.length != shares.length) { revert ParametersMismatch(); } uint64 activeValidatorCount = 0; - for (uint64 index = 0; index < validatorPK.length; ++index) { - bytes32 hashedValidator = keccak256(validatorPK[index]); + for (uint64 index = 0; index < publicKeys.length; ++index) { + _validatePublicKey(publicKeys[index]); + + bytes32 hashedValidator = keccak256(publicKeys[index]); Validator memory validator = _validatorPKs[hashedValidator]; if (validator.owner != msg.sender) { @@ -519,7 +534,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } // Changing to a single event reducing by 15K gas } - emit BulkValidatorTransferred(validatorPK, toClusterId, shares); + emit BulkValidatorTransferred(publicKeys, toClusterId, shares); uint64[] memory oldOperatorIds = _clusters[fromClusterId].operatorIds; uint64[] memory newOperatorIds = _clusters[toClusterId].operatorIds; @@ -532,19 +547,19 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { Pod memory pod = _pods[keccak256(abi.encodePacked(msg.sender, fromClusterId))]; uint64 podIndex = _clusterCurrentIndex(fromClusterId); - pod.usage.balance = _ownerPodBalance(pod, podIndex); + pod.usage.balance = _podBalance(pod, podIndex); pod.usage.index = podIndex; pod.usage.block = uint64(block.number); pod.validatorCount -= activeValidatorCount; pod = _pods[keccak256(abi.encodePacked(msg.sender, toClusterId))]; podIndex = _clusterCurrentIndex(toClusterId); - pod.usage.balance = _ownerPodBalance(pod, podIndex); + pod.usage.balance = _podBalance(pod, podIndex); pod.usage.index = podIndex; pod.usage.block = uint64(block.number); pod.validatorCount += activeValidatorCount; - if (_liquidatable(pod.disabled, _ownerPodBalance(pod, podIndex), pod.validatorCount, newOperatorIds)) { + if (_liquidatable(pod.disabled, _podBalance(pod, podIndex), pod.validatorCount, newOperatorIds)) { revert PodLiquidatable(); } } @@ -705,27 +720,14 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { return operator; } - function _updateOperatorsData(uint64[] memory operatorIds, bool increase) private { - for (uint64 i = 0; i < operatorIds.length; ++i) { - Operator memory operator = _operators[operatorIds[i]]; - operator.snapshot = _getSnapshot(operator, uint64(block.number)); - if (increase) { - ++operator.validatorCount; - } else { - --operator.validatorCount; - } - _operators[operatorIds[i]] = operator; - } - } - function _updatePodData(bytes32 clusterId, uint64 amount, bytes32 hashedPod, bool increase) private view returns (Pod memory) { Pod memory pod = _pods[hashedPod]; uint64 podIndex = _clusterCurrentIndex(clusterId); - pod.usage.balance = _ownerPodBalance(pod, podIndex) + amount; + pod.usage.balance = _podBalance(pod, podIndex) + amount; pod.usage.index = podIndex; pod.usage.block = uint64(block.number); - pod.networkFee = _ownerPodNetworkFee(pod); + pod.networkFee = _podNetworkFee(pod); pod.networkFeeIndex = _currentNetworkFeeIndex(); if (increase) { @@ -743,7 +745,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { function podBalanceOf(address owner, bytes32 clusterId) external view returns (uint256) { Pod memory pod = _pods[keccak256(abi.encodePacked(owner, clusterId))]; - return _ownerPodBalance(pod, _clusterCurrentIndex(clusterId)).expand(); + return _podBalance(pod, _clusterCurrentIndex(clusterId)).expand(); } function _deposit(address owner, bytes32 clusterId, uint64 amount) private { @@ -789,14 +791,6 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { return _networkFeeIndex + uint64(block.number - _networkFeeIndexBlockNumber) * _networkFee; } - function _extractOperators(uint64[] memory operatorIds) private view returns (Operator[] memory) { - Operator[] memory operators = new Operator[](operatorIds.length); - for (uint64 i = 0; i < operatorIds.length; ++i) { - operators[i] = _operators[operatorIds[i]]; - } - return operators; - } - function _networkTotalEarnings(DAO memory dao) private view returns (uint64) { return dao.earnings.balance + (uint64(block.number) - dao.earnings.block) * _networkFee * dao.validatorCount; } @@ -814,8 +808,8 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } } - function _ownerPodBalance(Pod memory pod, uint64 currentPodIndex) private view returns (uint64) { - uint64 usage = (currentPodIndex - pod.usage.index) * pod.validatorCount + _ownerPodNetworkFee(pod); + function _podBalance(Pod memory pod, uint64 currentPodIndex) private view returns (uint64) { + uint64 usage = (currentPodIndex - pod.usage.index) * pod.validatorCount + _podNetworkFee(pod); if (usage > pod.usage.balance) { revert NegativeBalance(); @@ -824,18 +818,18 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { return pod.usage.balance - usage; } - function _ownerPodNetworkFee(Pod memory pod) private view returns (uint64) { + function _podNetworkFee(Pod memory pod) private view returns (uint64) { return pod.networkFee + uint64(_currentNetworkFeeIndex() - pod.networkFeeIndex) * pod.validatorCount; } - function _burnRatePerValidator(Operator[] memory operators) private pure returns (uint64 rate) { - for (uint64 i = 0; i < operators.length; ++i) { - rate += operators[i].fee; + function _burnRatePerValidator(uint64[] memory operatorIds) private view returns (uint64 rate) { + for (uint64 i = 0; i < operatorIds.length; ++i) { + rate += _operators[operatorIds[i]].fee; } } function _liquidatable(bool disabled, uint64 balance, uint64 validatorCount, uint64[] memory operatorIds) private view returns (bool) { - return !disabled && balance < LIQUIDATION_MIN_BLOCKS * (_burnRatePerValidator(_extractOperators(operatorIds)) + _networkFee) * validatorCount; + return !disabled && balance < LIQUIDATION_MIN_BLOCKS * (_burnRatePerValidator(operatorIds) + _networkFee) * validatorCount; } function _updateOperatorFeeUnsafe(uint64 operatorId, uint64 fee) private { @@ -857,4 +851,16 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { revert CallerNotOwner(); } } + + function _validateClusterId(bytes32 clusterId) private view { + if (_clusters[clusterId].operatorIds.length == 0) { + revert ClusterNotExists(); + } + } + + function _validatePublicKey(bytes memory publicKey) private pure { + if (publicKey.length != 48) { + revert InvalidPublicKeyLength(); + } + } } diff --git a/test/account/deposit.ts b/test/account/deposit.ts index c88c01dc..2c8ed88e 100644 --- a/test/account/deposit.ts +++ b/test/account/deposit.ts @@ -1,11 +1,6 @@ import * as helpers from '../helpers/contract-helpers'; -import { expect } from 'chai'; - -const numberOfOperators = 4; -const operatorFee = 4; - -let ssvNetworkContract: any, operatorIDs: any, shares: any, owner: any; +let ssvNetworkContract: any; describe('Deposit Tests', () => { beforeEach(async () => { diff --git a/test/account/withdraw.ts b/test/account/withdraw.ts index afa962dd..11e5b67c 100644 --- a/test/account/withdraw.ts +++ b/test/account/withdraw.ts @@ -1,11 +1,6 @@ import * as helpers from '../helpers/contract-helpers'; -import { expect } from 'chai'; - -const numberOfOperators = 4; -const operatorFee = 4; - -let ssvNetworkContract: any, operatorIDs: any, shares: any, owner: any; +let ssvNetworkContract: any; describe('Withdraw Tests', () => { beforeEach(async () => { diff --git a/test/helpers/contract-helpers.ts b/test/helpers/contract-helpers.ts index a78d9e39..54c184be 100644 --- a/test/helpers/contract-helpers.ts +++ b/test/helpers/contract-helpers.ts @@ -95,11 +95,13 @@ export const registerOperators = async (ownerId: number, numberOfOperators: numb } }; +/* export const deposit = async (ownerIds: number[], amounts: string[]) => { // for (let i = 0; i < ownerIds.length; ++i) { // await DB.ssvNetwork.contract.connect(DB.owners[ownerIds[i]]).deposit(amounts[i]); // } }; +*/ export const ensureClusterAndDeposit = async(ownerId: number, operatorIds: number[], amount: string): Promise => { let clusterId; @@ -139,11 +141,11 @@ export const registerValidators = async (ownerId: number, numberOfValidators: nu }; export const transferValidator = async (ownerId: number, publicKey: string, operatorIds: number[], amount: string, gasGroups?: GasGroup[]) => { - let podId: any; + // let podId: any; const shares = DataGenerator.shares(DB.validators.length); // Transfer validator - const { eventsByName } = await trackGas(DB.ssvNetwork.contract.connect(DB.owners[ownerId]).transferValidator( + await trackGas(DB.ssvNetwork.contract.connect(DB.owners[ownerId]).transferValidator( publicKey, (await ensureClusterAndDeposit(ownerId, operatorIds, amount)).clusterId, shares, @@ -160,13 +162,12 @@ export const transferValidator = async (ownerId: number, publicKey: string, oper export const bulkTransferValidator = async (ownerId: number, publicKey: string[], fromCluster: string, toCluster: string, amount: string, gasGroups?: GasGroup[]) => { - let podId: any; const shares = Array(publicKey.length).fill(DataGenerator.shares(0)); await ensureClusterAndDeposit(ownerId, DataGenerator.cluster.byId(toCluster), amount); // Bulk transfer validators - const { eventsByName } = await trackGas(DB.ssvNetwork.contract.connect(DB.owners[ownerId]).bulkTransferValidators( + await trackGas(DB.ssvNetwork.contract.connect(DB.owners[ownerId]).bulkTransferValidators( publicKey, fromCluster, toCluster, diff --git a/test/liquidate/liquidation-threshold.ts b/test/liquidate/liquidation-threshold.ts index 78c65536..18bcbd05 100644 --- a/test/liquidate/liquidation-threshold.ts +++ b/test/liquidate/liquidation-threshold.ts @@ -1,11 +1,6 @@ import * as helpers from '../helpers/contract-helpers'; -import { expect } from 'chai'; - -const numberOfOperators = 4; -const operatorFee = 4; - -let ssvNetworkContract: any, operatorIDs: any, shares: any, owner: any; +let ssvNetworkContract: any; describe('Liquidation Threshold Tests', () => { diff --git a/test/operators/update.ts b/test/operators/update.ts index 29bc186c..f71667dd 100644 --- a/test/operators/update.ts +++ b/test/operators/update.ts @@ -1,11 +1,6 @@ import * as helpers from '../helpers/contract-helpers'; -import { expect } from 'chai'; - -const numberOfOperators = 4; -const operatorFee = 4; - -let ssvNetworkContract: any, operatorIDs: any, shares: any, owner: any; +let ssvNetworkContract: any; describe('Update Operator Tests', () => { beforeEach(async () => { diff --git a/test/sanity/stress.ts b/test/sanity/stress.ts index 1ff2f5f2..b76e3999 100644 --- a/test/sanity/stress.ts +++ b/test/sanity/stress.ts @@ -1,4 +1,4 @@ -declare const ethers: any; +/*declare const ethers: any; import * as helpers from '../helpers/contract-helpers'; @@ -9,6 +9,7 @@ const operatorFee = 1; let registryContract: any, operatorIDs: any, shares: any; const validatorData: any = []; +*/ describe('Stress Tests', () => { // beforeEach(async () => { diff --git a/test/validators/remove.ts b/test/validators/remove.ts index cd7d7bdc..bd2f3a81 100644 --- a/test/validators/remove.ts +++ b/test/validators/remove.ts @@ -15,9 +15,6 @@ describe('Remove Validator Tests', () => { // Register operators await helpers.registerOperators(0, 4, helpers.CONFIG.minimalOperatorFee); - // Deposit into accounts - await helpers.deposit([4], [minDepositAmount]); - // Register a validator clusterResult = await helpers.registerValidators(4, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); }); diff --git a/test/validators/transfer.ts b/test/validators/transfer.ts index 9e740742..4e5a0e4b 100644 --- a/test/validators/transfer.ts +++ b/test/validators/transfer.ts @@ -79,7 +79,7 @@ describe('Transfer Validator Tests', () => { const clusterResult3 = await helpers.registerValidators(5, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); // Transfer validator - const transfredValidator1 = await helpers.transferValidator(4, clusterResult1.validators[0].publicKey, helpers.DataGenerator.cluster.byId(clusterResult3.clusterId), `${minDepositAmount * 2}`, [GasGroup.TRANSFER_VALIDATOR_NON_EXISTING_POD]); + await helpers.transferValidator(4, clusterResult1.validators[0].publicKey, helpers.DataGenerator.cluster.byId(clusterResult3.clusterId), `${minDepositAmount * 2}`, [GasGroup.TRANSFER_VALIDATOR_NON_EXISTING_POD]); // expect(clusterResult3.clusterId).equals(transfredValidator1.eventsByName.ValidatorTransferred[0].args.podId); }); From 3d6fda0a2db6de3e3e060d67abad40d563c5bc33 Mon Sep 17 00:00:00 2001 From: Vadim Date: Thu, 27 Oct 2022 10:02:01 +0200 Subject: [PATCH 083/149] code improvements based by pr review --- contracts/SSVNetwork.sol | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index bea40f6a..4c146d56 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -383,9 +383,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } function getClusterId(uint64[] memory operatorIds) external view returns(bytes32) { - if (operatorIds.length < 4 || operatorIds.length % 3 != 1) { - revert OperatorIdsStructureInvalid(); - } + _validateOperatorIds(operatorIds); bytes32 clusterId = keccak256(abi.encodePacked(operatorIds)); @@ -397,9 +395,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } function registerPod(uint64[] memory operatorIds, uint256 amount) external { - if (operatorIds.length < 4 || operatorIds.length % 3 != 1) { - revert OperatorIdsStructureInvalid(); - } + _validateOperatorIds(operatorIds); bytes32 clusterId = keccak256(abi.encodePacked(operatorIds)); @@ -863,4 +859,10 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { revert InvalidPublicKeyLength(); } } + + function _validateOperatorIds(uint64[] memory operatorIds) private pure { + if (operatorIds.length < 4 || operatorIds.length > 13 || operatorIds.length % 3 != 1) { + revert OperatorIdsStructureInvalid(); + } + } } From 2c722e41bc9361007628d248b7610cf6d113fdb9 Mon Sep 17 00:00:00 2001 From: Vadim Date: Thu, 27 Oct 2022 12:14:44 +0200 Subject: [PATCH 084/149] proposal for registerpod flow --- contracts/SSVNetwork.sol | 27 ++++++++++++++------------- test/helpers/contract-helpers.ts | 2 +- test/helpers/gas-usage.ts | 4 ++-- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index 4c146d56..8926174c 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -244,10 +244,6 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { { for (uint64 i = 0; i < operatorIds.length; ++i) { Operator memory operator = _operators[operatorIds[i]]; - if (operator.owner == address(0)) { - revert OperatorDoesNotExist(); - } - if (!pod.disabled) { operator.snapshot = _getSnapshot(operator, uint64(block.number)); ++operator.validatorCount; @@ -399,15 +395,11 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { bytes32 clusterId = keccak256(abi.encodePacked(operatorIds)); - if (_clusters[clusterId].operatorIds.length > 0) { - revert ClusterAlreadyExists(); + if (_clusters[clusterId].operatorIds.length == 0) { + _createClusterUnsafe(clusterId, operatorIds); } - _createClusterUnsafe(clusterId, operatorIds); - - if (amount > 0) { - _deposit(msg.sender, clusterId, amount.shrink()); - } + _deposit(msg.sender, clusterId, amount.shrink()); } function liquidate(address ownerAddress, bytes32 clusterId) external { @@ -746,12 +738,21 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { function _deposit(address owner, bytes32 clusterId, uint64 amount) private { Pod storage pod = _pods[keccak256(abi.encodePacked(owner, clusterId))]; - - pod.usage.balance += amount; + if (pod.usage.block == 0) { + pod.usage.block = uint64(block.number); + emit PodCreated(owner, clusterId); + } + if (amount > 0) { + pod.usage.balance += amount; + } } function _createClusterUnsafe(bytes32 key, uint64[] memory operatorIds) private { for (uint64 i = 0; i < operatorIds.length - 1;) { + if (_operators[operatorIds[i]].owner == address(0)) { + revert OperatorDoesNotExist(); + } + require(operatorIds[i] <= operatorIds[++i]); } diff --git a/test/helpers/contract-helpers.ts b/test/helpers/contract-helpers.ts index 54c184be..9055d785 100644 --- a/test/helpers/contract-helpers.ts +++ b/test/helpers/contract-helpers.ts @@ -111,7 +111,7 @@ export const ensureClusterAndDeposit = async(ownerId: number, operatorIds: numbe await DB.ssvNetwork.contract.connect(DB.owners[ownerId])['deposit(bytes32,uint256)'](clusterId, amount); } } catch (e) { - const clusterTx = await (await DB.ssvNetwork.contract.connect(DB.owners[ownerId]).ensurePodAndDeposit(operatorIds, amount)).wait(); + const clusterTx = await (await DB.ssvNetwork.contract.connect(DB.owners[ownerId]).registerPod(operatorIds, amount)).wait(); clusterId = clusterTx.events[0].args.clusterId; } return { clusterId }; diff --git a/test/helpers/gas-usage.ts b/test/helpers/gas-usage.ts index 1dff5614..dc960ee3 100644 --- a/test/helpers/gas-usage.ts +++ b/test/helpers/gas-usage.ts @@ -25,8 +25,8 @@ const MAX_GAS_PER_GROUP: any = { [GasGroup.TRANSFER_VALIDATOR_NEW_CLUSTER]: 400000, [GasGroup.TRANSFER_VALIDATOR]: 260000, [GasGroup.TRANSFER_VALIDATOR_NON_EXISTING_POD]: 290000, - [GasGroup.BULK_TRANSFER_VALIDATOR]: 351000, - [GasGroup.BULK_TRANSFER_VALIDATOR_NON_EXISTING_POD]: 351000, + [GasGroup.BULK_TRANSFER_VALIDATOR]: 352000, + [GasGroup.BULK_TRANSFER_VALIDATOR_NON_EXISTING_POD]: 352000, [GasGroup.LIQUIDATE_VALIDATOR]: 101000, }; From e1771d220043c32565c23d60b92903688e45d034 Mon Sep 17 00:00:00 2001 From: Lior Rutenberg Date: Thu, 27 Oct 2022 15:02:07 +0300 Subject: [PATCH 085/149] remove operator simplified --- contracts/SSVNetwork.sol | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index 8926174c..815f5e78 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -147,13 +147,9 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { Operator memory operator = _operators[operatorId]; if (operator.owner != msg.sender) revert CallerNotOwner(); - uint64 currentBlock = uint64(block.number); - - operator.snapshot = _getSnapshot(operator, currentBlock); - operator.fee = 0; - operator.validatorCount = 0; - _operators[operatorId] = operator; + // TODO withdraw remaining balance before delete + delete _operators[operatorId]; emit OperatorRemoved(operatorId); } From cb776c2bc76f19d00a5fc21a61420a4c5eb540a1 Mon Sep 17 00:00:00 2001 From: Lior Rutenberg Date: Thu, 27 Oct 2022 15:10:14 +0300 Subject: [PATCH 086/149] maxAllowedFee simplified --- contracts/SSVNetwork.sol | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index 815f5e78..732b8e32 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -160,8 +160,9 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { revert FeeTooLow(); } - - if (fee.shrink() > operator.fee * (10000 + _operatorMaxFeeIncrease) / 10000) { + // @dev 100% = 10000, 10% = 1000 - using 10000 to represent 2 digit precision + uint64 maxAllowedFee = operator.fee * (10000 + _operatorMaxFeeIncrease) / 10000; + if (fee.shrink() > maxAllowedFee) { revert FeeExceedsIncreaseLimit(); } From 51e77d74ef9e4e656d2c63458479bde85200aee0 Mon Sep 17 00:00:00 2001 From: Vadim Date: Thu, 27 Oct 2022 14:18:58 +0200 Subject: [PATCH 087/149] improve and fix tests --- contracts/ISSVNetwork.sol | 2 +- contracts/SSVNetwork.sol | 29 ++++++++++++----------------- test/helpers/contract-helpers.ts | 8 ++++---- test/helpers/gas-usage.ts | 4 ++-- test/validators/register.ts | 18 +++++++----------- test/validators/remove.ts | 2 +- test/validators/transfer-bulk.ts | 10 +++++----- test/validators/transfer.ts | 14 +++++++------- 8 files changed, 39 insertions(+), 48 deletions(-) diff --git a/contracts/ISSVNetwork.sol b/contracts/ISSVNetwork.sol index 71d8349b..c954cab5 100644 --- a/contracts/ISSVNetwork.sol +++ b/contracts/ISSVNetwork.sol @@ -108,7 +108,7 @@ interface ISSVNetwork { event ExecuteOperatorFeePeriodUpdate(uint256 value); - event ClusterCreated(bytes32 clusterId); + event PodCreated(address ownerAddress, bytes32 clusterId); /** * @dev Emitted when the network fee is updated. * @param oldFee The old fee diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index 8926174c..561cf65c 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -540,6 +540,8 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { pod.usage.block = uint64(block.number); pod.validatorCount -= activeValidatorCount; + _pods[keccak256(abi.encodePacked(msg.sender, fromClusterId))] = pod; + pod = _pods[keccak256(abi.encodePacked(msg.sender, toClusterId))]; podIndex = _clusterCurrentIndex(toClusterId); pod.usage.balance = _podBalance(pod, podIndex); @@ -547,6 +549,8 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { pod.usage.block = uint64(block.number); pod.validatorCount += activeValidatorCount; + _pods[keccak256(abi.encodePacked(msg.sender, toClusterId))] = pod; + if (_liquidatable(pod.disabled, _podBalance(pod, podIndex), pod.validatorCount, newOperatorIds)) { revert PodLiquidatable(); } @@ -737,7 +741,8 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } function _deposit(address owner, bytes32 clusterId, uint64 amount) private { - Pod storage pod = _pods[keccak256(abi.encodePacked(owner, clusterId))]; + Pod memory pod = _pods[keccak256(abi.encodePacked(owner, clusterId))]; + if (pod.usage.block == 0) { pod.usage.block = uint64(block.number); emit PodCreated(owner, clusterId); @@ -745,31 +750,21 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { if (amount > 0) { pod.usage.balance += amount; } + + _pods[keccak256(abi.encodePacked(owner, clusterId))] = pod; } function _createClusterUnsafe(bytes32 key, uint64[] memory operatorIds) private { - for (uint64 i = 0; i < operatorIds.length - 1;) { + for (uint64 i = 0; i < operatorIds.length; i++) { if (_operators[operatorIds[i]].owner == address(0)) { revert OperatorDoesNotExist(); } - - require(operatorIds[i] <= operatorIds[++i]); + if (i+1 < operatorIds.length) { + require(operatorIds[i] <= operatorIds[i+1]); + } } _clusters[key] = Cluster({operatorIds: operatorIds}); - - emit ClusterCreated(key); - } - - function _getOrCreateCluster(uint64[] memory operatorIds) private returns (bytes32) { // , Cluster memory - bytes32 key = keccak256(abi.encodePacked(operatorIds)); - - Cluster storage cluster = _clusters[key]; - if (cluster.operatorIds.length == 0) { - _createClusterUnsafe(key, operatorIds); - } - - return key; } function _updateDAOEarnings(DAO memory dao) private view returns (DAO memory) { diff --git a/test/helpers/contract-helpers.ts b/test/helpers/contract-helpers.ts index 9055d785..be986e3d 100644 --- a/test/helpers/contract-helpers.ts +++ b/test/helpers/contract-helpers.ts @@ -103,7 +103,7 @@ export const deposit = async (ownerIds: number[], amounts: string[]) => { }; */ -export const ensureClusterAndDeposit = async(ownerId: number, operatorIds: number[], amount: string): Promise => { +export const registerPodAndDeposit = async(ownerId: number, operatorIds: number[], amount: string): Promise => { let clusterId; try { clusterId = await DB.ssvNetwork.contract.getClusterId(operatorIds); @@ -128,7 +128,7 @@ export const registerValidators = async (ownerId: number, numberOfValidators: nu const { eventsByName } = await trackGas(DB.ssvNetwork.contract.connect(DB.owners[ownerId]).registerValidator( publicKey, - (await ensureClusterAndDeposit(ownerId, operatorIds, amount)).clusterId, + (await registerPodAndDeposit(ownerId, operatorIds, amount)).clusterId, shares, ), gasGroups); clusterId = eventsByName.ValidatorAdded[0].args.clusterId; @@ -147,7 +147,7 @@ export const transferValidator = async (ownerId: number, publicKey: string, oper // Transfer validator await trackGas(DB.ssvNetwork.contract.connect(DB.owners[ownerId]).transferValidator( publicKey, - (await ensureClusterAndDeposit(ownerId, operatorIds, amount)).clusterId, + (await registerPodAndDeposit(ownerId, operatorIds, amount)).clusterId, shares, ), gasGroups); @@ -164,7 +164,7 @@ export const transferValidator = async (ownerId: number, publicKey: string, oper export const bulkTransferValidator = async (ownerId: number, publicKey: string[], fromCluster: string, toCluster: string, amount: string, gasGroups?: GasGroup[]) => { const shares = Array(publicKey.length).fill(DataGenerator.shares(0)); - await ensureClusterAndDeposit(ownerId, DataGenerator.cluster.byId(toCluster), amount); + await registerPodAndDeposit(ownerId, DataGenerator.cluster.byId(toCluster), amount); // Bulk transfer validators await trackGas(DB.ssvNetwork.contract.connect(DB.owners[ownerId]).bulkTransferValidators( diff --git a/test/helpers/gas-usage.ts b/test/helpers/gas-usage.ts index dc960ee3..322e4c30 100644 --- a/test/helpers/gas-usage.ts +++ b/test/helpers/gas-usage.ts @@ -25,8 +25,8 @@ const MAX_GAS_PER_GROUP: any = { [GasGroup.TRANSFER_VALIDATOR_NEW_CLUSTER]: 400000, [GasGroup.TRANSFER_VALIDATOR]: 260000, [GasGroup.TRANSFER_VALIDATOR_NON_EXISTING_POD]: 290000, - [GasGroup.BULK_TRANSFER_VALIDATOR]: 352000, - [GasGroup.BULK_TRANSFER_VALIDATOR_NON_EXISTING_POD]: 352000, + [GasGroup.BULK_TRANSFER_VALIDATOR]: 362000, + [GasGroup.BULK_TRANSFER_VALIDATOR_NON_EXISTING_POD]: 379000, [GasGroup.LIQUIDATE_VALIDATOR]: 101000, }; diff --git a/test/validators/register.ts b/test/validators/register.ts index ef974889..fe22cf93 100644 --- a/test/validators/register.ts +++ b/test/validators/register.ts @@ -23,7 +23,7 @@ describe('Register Validator Tests', () => { // register validator using cluster Id await expect(ssvNetworkContract.registerValidator( helpers.DataGenerator.publicKey(1), - (await helpers.ensureClusterAndDeposit(0, helpers.DataGenerator.cluster.new(), minDepositAmount)).clusterId, + (await helpers.registerPodAndDeposit(0, helpers.DataGenerator.cluster.new(), minDepositAmount)).clusterId, helpers.DataGenerator.shares(0) )).to.emit(ssvNetworkContract, 'ValidatorAdded'); }); @@ -42,16 +42,16 @@ describe('Register Validator Tests', () => { it('Invalid operator amount', async () => { // 2 Operators - await expect(helpers.ensureClusterAndDeposit(0, [1, 2], minDepositAmount)).to.be.revertedWith('OperatorIdsStructureInvalid'); + await expect(helpers.registerPodAndDeposit(0, [1, 2], minDepositAmount)).to.be.revertedWith('OperatorIdsStructureInvalid'); // 6 Operators - await expect(helpers.ensureClusterAndDeposit(0, [1, 2, 3, 4, 5, 6], minDepositAmount)).to.be.revertedWith('OperatorIdsStructureInvalid'); + await expect(helpers.registerPodAndDeposit(0, [1, 2, 3, 4, 5, 6], minDepositAmount)).to.be.revertedWith('OperatorIdsStructureInvalid'); }); it('Invalid public key length', async () => { await expect(ssvNetworkContract.registerValidator( helpers.DataGenerator.shares(0), - (await helpers.ensureClusterAndDeposit(0, helpers.DataGenerator.cluster.new(), minDepositAmount)).clusterId, + (await helpers.registerPodAndDeposit(0, helpers.DataGenerator.cluster.new(), minDepositAmount)).clusterId, helpers.DataGenerator.shares(0), )).to.be.revertedWith('InvalidPublicKeyLength'); }); @@ -59,23 +59,19 @@ describe('Register Validator Tests', () => { it('Not enough amount', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( helpers.DataGenerator.publicKey(0), - (await helpers.ensureClusterAndDeposit(0, helpers.DataGenerator.cluster.new(), '0')).clusterId, + (await helpers.registerPodAndDeposit(0, helpers.DataGenerator.cluster.new(), '0')).clusterId, helpers.DataGenerator.shares(0), )).to.be.revertedWith('NotEnoughBalance'); }); it('Non existent operator', async () => { - await expect(ssvNetworkContract.registerValidator( - helpers.DataGenerator.publicKey(0), - (await helpers.ensureClusterAndDeposit(0, [1, 2, 3, 25], minDepositAmount)).clusterId, - helpers.DataGenerator.shares(0), - )).to.be.revertedWith('OperatorDoesNotExist'); + await expect(helpers.registerPodAndDeposit(0, [1, 2, 3, 25], minDepositAmount)).to.be.revertedWith('OperatorDoesNotExist'); }); it('Register with existing validator', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( helpers.DataGenerator.publicKey(0), - (await helpers.ensureClusterAndDeposit(1, [1, 2, 3, 4], minDepositAmount)).clusterId, + (await helpers.registerPodAndDeposit(1, [1, 2, 3, 4], minDepositAmount)).clusterId, helpers.DataGenerator.shares(0), )).to.be.revertedWith('ValidatorAlreadyExists'); }); diff --git a/test/validators/remove.ts b/test/validators/remove.ts index bd2f3a81..24d60b7b 100644 --- a/test/validators/remove.ts +++ b/test/validators/remove.ts @@ -48,7 +48,7 @@ describe('Remove Validator Tests', () => { // Re-register validator await ssvNetworkContract.connect(helpers.DB.owners[4]).registerValidator( helpers.DataGenerator.publicKey(0), - (await helpers.ensureClusterAndDeposit(4, [1, 2, 3, 4], minDepositAmount)).clusterId, + (await helpers.registerPodAndDeposit(4, [1, 2, 3, 4], minDepositAmount)).clusterId, helpers.DataGenerator.shares(0), ); diff --git a/test/validators/transfer-bulk.ts b/test/validators/transfer-bulk.ts index 94701824..5a5827ba 100644 --- a/test/validators/transfer-bulk.ts +++ b/test/validators/transfer-bulk.ts @@ -23,7 +23,7 @@ describe('Bulk Transfer Validator Tests', () => { }); it('Bulk transfer 10 validators emits BulkValidatorTransferred event', async () => { - await helpers.ensureClusterAndDeposit(4, helpers.DataGenerator.cluster.byId(clusterResult3.clusterId), `${minDepositAmount * (clusterResult2.validators.length + 1) }`); + await helpers.registerPodAndDeposit(4, helpers.DataGenerator.cluster.byId(clusterResult3.clusterId), `${minDepositAmount * (clusterResult2.validators.length + 1) }`); await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], @@ -34,7 +34,7 @@ describe('Bulk Transfer Validator Tests', () => { }); it('Bulk transfer validator with an invalid owner', async () => { - await helpers.ensureClusterAndDeposit(5, helpers.DataGenerator.cluster.byId(clusterResult3.clusterId), `${minDepositAmount * (clusterResult2.validators.length + 1) }`); + await helpers.registerPodAndDeposit(5, helpers.DataGenerator.cluster.byId(clusterResult3.clusterId), `${minDepositAmount * (clusterResult2.validators.length + 1) }`); await expect(ssvNetworkContract.connect(helpers.DB.owners[5]).bulkTransferValidators( [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], @@ -47,7 +47,7 @@ describe('Bulk Transfer Validator Tests', () => { it('Bulk transfer validator with an unowned validator', async () => { const account5cluster = await helpers.registerValidators(5, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); - await helpers.ensureClusterAndDeposit(4, helpers.DataGenerator.cluster.byId(clusterResult3.clusterId), `${minDepositAmount * (clusterResult2.validators.length + 1) }`); + await helpers.registerPodAndDeposit(4, helpers.DataGenerator.cluster.byId(clusterResult3.clusterId), `${minDepositAmount * (clusterResult2.validators.length + 1) }`); await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( [clusterResult1.validators[0].publicKey, account5cluster.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], @@ -63,7 +63,7 @@ describe('Bulk Transfer Validator Tests', () => { clusterResult1.clusterId, clusterResult3.clusterId, Array(clusterResult2.validators.length + 2).fill(helpers.DataGenerator.shares(0)), - )).to.be.revertedWith('ValidatorNotOwned'); + )).to.be.revertedWith('InvalidPublicKeyLength'); }); it('Bulk transfer 10 validators', async () => { @@ -110,7 +110,7 @@ describe('Bulk Transfer Validator Tests', () => { clusterResult1.clusterId.slice(0, -1) + 'a', clusterResult1.clusterId, Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)), - )).to.be.revertedWith('InvalidCluster'); + )).to.be.revertedWith('ClusterNotExists'); }); it('Validator and share length mismatch', async () => { diff --git a/test/validators/transfer.ts b/test/validators/transfer.ts index 4e5a0e4b..666e43d4 100644 --- a/test/validators/transfer.ts +++ b/test/validators/transfer.ts @@ -23,7 +23,7 @@ describe('Transfer Validator Tests', () => { it('Transfer validator emits ValidatorTransferred event', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( clusterResult1.validators[0].publicKey, - (await helpers.ensureClusterAndDeposit(4, helpers.DataGenerator.cluster.new(), minDepositAmount)).clusterId, + (await helpers.registerPodAndDeposit(4, helpers.DataGenerator.cluster.new(), minDepositAmount)).clusterId, helpers.DataGenerator.shares(helpers.DB.validators.length), )).to.emit(ssvNetworkContract, 'ValidatorTransferred'); }); @@ -33,19 +33,19 @@ describe('Transfer Validator Tests', () => { }); it('Transfer validator with an invalid owner', async () => { - // Transfer validator with an invalid owner await expect(ssvNetworkContract.connect(helpers.DB.owners[5]).transferValidator( clusterResult1.validators[0].publicKey, - (await helpers.ensureClusterAndDeposit(5, helpers.DataGenerator.cluster.byId(clusterResult2.clusterId), minDepositAmount)).clusterId, + (await helpers.registerPodAndDeposit(4, helpers.DataGenerator.cluster.byId(clusterResult2.clusterId), minDepositAmount)).clusterId, helpers.DataGenerator.shares(helpers.DB.validators.length), )).to.be.revertedWith('ValidatorNotOwned'); + }); - // Transfer validator with an invalid public key + it('transfer with an invalid public key', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( helpers.DataGenerator.shares(0), - (await helpers.ensureClusterAndDeposit(4, helpers.DataGenerator.cluster.byId(clusterResult2.clusterId), minDepositAmount)).clusterId, + (await helpers.registerPodAndDeposit(4, helpers.DataGenerator.cluster.byId(clusterResult2.clusterId), minDepositAmount)).clusterId, helpers.DataGenerator.shares(helpers.DB.validators.length), - )).to.be.revertedWith('ValidatorNotOwned'); + )).to.be.revertedWith('InvalidPublicKeyLength'); }); it('Transfer validator to a cluster with 7 operators', async () => { @@ -63,7 +63,7 @@ describe('Transfer Validator Tests', () => { // Transfer to cluster with not enough amount await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( clusterResult1.validators[0].publicKey, - (await helpers.ensureClusterAndDeposit(4, helpers.DataGenerator.cluster.byId(clusterId), helpers.CONFIG.minimalOperatorFee)).clusterId, + (await helpers.registerPodAndDeposit(4, helpers.DataGenerator.cluster.byId(clusterId), helpers.CONFIG.minimalOperatorFee)).clusterId, helpers.DataGenerator.shares(helpers.DB.validators.length), )).to.be.revertedWith('NotEnoughBalance'); }); From 12e6c6b8bde620704b8c513afcfd669ec553442d Mon Sep 17 00:00:00 2001 From: Lior Rutenberg Date: Thu, 27 Oct 2022 15:19:43 +0300 Subject: [PATCH 088/149] on register validator make sure all the operators exist --- contracts/SSVNetwork.sol | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index 732b8e32..de83b933 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -241,7 +241,8 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { { for (uint64 i = 0; i < operatorIds.length; ++i) { Operator memory operator = _operators[operatorIds[i]]; - if (!pod.disabled) { + // @dev operator.owner != address(0) checked in case operator was removed + if (!pod.disabled && operator.owner != address(0)) { operator.snapshot = _getSnapshot(operator, uint64(block.number)); ++operator.validatorCount; _operators[operatorIds[i]] = operator; From 4f451228f7018344136c434f0c30260b105a79a1 Mon Sep 17 00:00:00 2001 From: Lior Rutenberg Date: Thu, 27 Oct 2022 15:23:33 +0300 Subject: [PATCH 089/149] on remove validator make sure all the operators exist --- contracts/SSVNetwork.sol | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index de83b933..185e38e4 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -348,8 +348,13 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { for (uint64 i = 0; i < cluster.operatorIds.length; ++i) { uint64 id = cluster.operatorIds[i]; - _operators[id].snapshot = _getSnapshot(_operators[id], uint64(block.number)); - --_operators[id].validatorCount; + Operator memory operator = _operators[id]; + + if (operator.owner != address(0)) { + operator.snapshot = _getSnapshot(operator, uint64(block.number)); + --operator.validatorCount; + _operators[id] = operator; + } } { From 149813f97850d05f1f3cc2fea76bde14ea35c979 Mon Sep 17 00:00:00 2001 From: Lior Rutenberg Date: Thu, 27 Oct 2022 15:31:36 +0300 Subject: [PATCH 090/149] small validation improvment --- contracts/SSVNetwork.sol | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index 44a7ca0b..293a9d61 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -230,8 +230,11 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { uint64[] memory operatorIds = _clusters[clusterId].operatorIds; - // Operator[] memory operators; bytes32 hashedValidator = keccak256(publicKey); + if (_validatorPKs[hashedValidator].clusterId > 0) { + revert ValidatorAlreadyExists(); + } + bytes32 hashedPod = keccak256(abi.encodePacked(msg.sender, clusterId)); { Pod memory pod; @@ -266,9 +269,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _pods[hashedPod] = pod; } - if (_validatorPKs[hashedValidator].clusterId > 0) { - revert ValidatorAlreadyExists(); - } + _validatorPKs[hashedValidator] = Validator({ owner: msg.sender, clusterId: clusterId, active: true}); emit ValidatorAdded(publicKey, clusterId, shares); From 40862acec623b899159f016f3387a3d382ff3569 Mon Sep 17 00:00:00 2001 From: Lior Rutenberg Date: Thu, 27 Oct 2022 15:33:11 +0300 Subject: [PATCH 091/149] rename operators update on transfer function --- contracts/SSVNetwork.sol | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index 293a9d61..6e789f6e 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -269,7 +269,6 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _pods[hashedPod] = pod; } - _validatorPKs[hashedValidator] = Validator({ owner: msg.sender, clusterId: clusterId, active: true}); emit ValidatorAdded(publicKey, clusterId, shares); @@ -302,7 +301,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } { - _updateOperatorsValidatorMove(_clusters[clusterId].operatorIds, operatorIds, 1); + _updateOperatorsOnTransfer(_clusters[clusterId].operatorIds, operatorIds, 1); } { @@ -535,7 +534,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { revert InvalidCluster(); } - _updateOperatorsValidatorMove(oldOperatorIds, newOperatorIds, activeValidatorCount); + _updateOperatorsOnTransfer(oldOperatorIds, newOperatorIds, activeValidatorCount); Pod memory pod = _pods[keccak256(abi.encodePacked(msg.sender, fromClusterId))]; uint64 podIndex = _clusterCurrentIndex(fromClusterId); @@ -664,7 +663,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { return operator.snapshot; } - function _updateOperatorsValidatorMove( + function _updateOperatorsOnTransfer( uint64[] memory oldOperatorIds, uint64[] memory newOperatorIds, uint64 validatorCount From 1670eb9bc159c20be1da9fe20f33f52511af0d39 Mon Sep 17 00:00:00 2001 From: Lior Rutenberg Date: Thu, 27 Oct 2022 15:55:17 +0300 Subject: [PATCH 092/149] remove private dao functions --- contracts/SSVNetwork.sol | 41 +++++++++------------------------------- 1 file changed, 9 insertions(+), 32 deletions(-) diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index 6e789f6e..c1dadb2d 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -119,9 +119,9 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { uint64 executeOperatorFeePeriod_ ) internal onlyInitializing { _token = token_; - _updateOperatorFeeIncreaseLimit(operatorMaxFeeIncrease_); - _updateDeclareOperatorFeePeriod(declareOperatorFeePeriod_); - _updateExecuteOperatorFeePeriod(executeOperatorFeePeriod_); + _operatorMaxFeeIncrease = operatorMaxFeeIncrease_; + _declareOperatorFeePeriod = declareOperatorFeePeriod_; + _executeOperatorFeePeriod = executeOperatorFeePeriod_; } modifier onlyOperatorOwnerOrContractOwner(uint64 operatorId) { @@ -294,10 +294,6 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { { bytes32 hashedPod = keccak256(abi.encodePacked(msg.sender, clusterId)); _pods[hashedPod] = _updatePodData(clusterId, 0, hashedPod, false); - // if (pod.validatorCount == 0) { - // _availableBalances[msg.sender] += _ownerPodBalance(pod, podIndex); - // pod.usage.balance -= _ownerPodBalance(pod, podIndex); - // } } { @@ -585,15 +581,18 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } function updateOperatorFeeIncreaseLimit(uint64 newOperatorMaxFeeIncrease) external onlyOwner { - _updateOperatorFeeIncreaseLimit(newOperatorMaxFeeIncrease); + _operatorMaxFeeIncrease = newOperatorMaxFeeIncrease; + emit OperatorFeeIncreaseLimitUpdate(_operatorMaxFeeIncrease); } function updateDeclareOperatorFeePeriod(uint64 newDeclareOperatorFeePeriod) external onlyOwner { - _updateDeclareOperatorFeePeriod(newDeclareOperatorFeePeriod); + _declareOperatorFeePeriod = newDeclareOperatorFeePeriod; + emit DeclareOperatorFeePeriodUpdate(newDeclareOperatorFeePeriod); } function updateExecuteOperatorFeePeriod(uint64 newExecuteOperatorFeePeriod) external onlyOwner { - _updateExecuteOperatorFeePeriod(newExecuteOperatorFeePeriod); + _executeOperatorFeePeriod = newExecuteOperatorFeePeriod; + emit ExecuteOperatorFeePeriodUpdate(newExecuteOperatorFeePeriod); } function updateNetworkFee(uint256 fee) external onlyOwner { @@ -632,24 +631,6 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { // @dev internal dao functions - function _updateOperatorFeeIncreaseLimit(uint64 newOperatorMaxFeeIncrease) private { - _operatorMaxFeeIncrease = newOperatorMaxFeeIncrease; - - emit OperatorFeeIncreaseLimitUpdate(_operatorMaxFeeIncrease); - - } - - function _updateDeclareOperatorFeePeriod(uint64 newDeclareOperatorFeePeriod) private { - _declareOperatorFeePeriod = newDeclareOperatorFeePeriod; - - emit DeclareOperatorFeePeriodUpdate(newDeclareOperatorFeePeriod); - } - - function _updateExecuteOperatorFeePeriod(uint64 newExecuteOperatorFeePeriod) private { - _executeOperatorFeePeriod = newExecuteOperatorFeePeriod; - - emit ExecuteOperatorFeePeriodUpdate(newExecuteOperatorFeePeriod); - } // @dev internal operators functions @@ -731,10 +712,6 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { --pod.validatorCount; } - if (pod.validatorCount == 0) { - // _availableBalances[msg.sender] += _ownerPodBalance(pod, podIndex); - // pod.usage.balance -= _ownerPodBalance(pod, podIndex); - } return pod; } From cb0be42d42d6de3ef01c5b12009abdb51ea2def3 Mon Sep 17 00:00:00 2001 From: Adam Zigdon Date: Thu, 27 Oct 2022 16:47:07 +0300 Subject: [PATCH 093/149] fix tests --- test/vadimToUpdate.js | 302 ------------------------------------ test/vadimToUpdate.js.old | 302 ------------------------------------ test/validators/register.ts | 2 +- 3 files changed, 1 insertion(+), 605 deletions(-) delete mode 100644 test/vadimToUpdate.js delete mode 100644 test/vadimToUpdate.js.old diff --git a/test/vadimToUpdate.js b/test/vadimToUpdate.js deleted file mode 100644 index 75769ab4..00000000 --- a/test/vadimToUpdate.js +++ /dev/null @@ -1,302 +0,0 @@ -const { expect } = require("chai"); -const { progressBlocks, blockNumber } = require('./helpers/utils'); -const operator_fee_block = 1; - - -async function mineNBlocks(n) { - for (let index = 0; index < n; index++) { - await ethers.provider.send('evm_mine'); - } -} - -const operatorsIndexes = Array.from(Array(5).keys()).map(k => k + 1); -let deployedSSVNetworkContract; - -async function log({ action='', operatorIds = [], groupIds = [] }) { - console.log(`[BLOCK] ${await blockNumber()}`) - if (action) { - console.log(`> ${action}`); - } - if (operatorIds.length) { - for (const id of operatorIds) { - console.log( - `> operator #${id}`, - 'balance', (await deployedSSVNetworkContract.operatorSnapshot(id)).balance, - ); - } - } - if (groupIds.length) { - const [owner] = await ethers.getSigners(); - for (const id of groupIds) { - console.log( - `> group #$${id}`, - 'balance', await deployedSSVNetworkContract.podBalanceOf(owner.address, id), - ); - } - } -} - -describe("Validators", () => { - beforeEach(async () => { - const SSVNetwork = await ethers.getContractFactory("SSVNetwork"); - deployedSSVNetworkContract = await SSVNetwork.deploy(); - await deployedSSVNetworkContract.deployed(); - - await progressBlocks(99); - for (let i = 0; i < 8; i++) { // operatorsIndexes.length - var encryptionPK = "0x123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123451"; - await (await deployedSSVNetworkContract.registerOperator(encryptionPK, operator_fee_block)).wait(); - await log({ action: `register operator #${i+1}` }); - } - // await deployedSSVNetworkContract.addOperatorToValidator([], operatorsIndexes, []); - }) - - it("should register validator", async () => { - const validatorPK = "0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765"; - const sharePKs = Array.from(Array(10).keys()).map(k => `0xe0096008000000b4010000040000001000000076000000dc000000420d142c307831323334353637383930fe0a00520a000031017afe66008266000032fe66009266000033fe66009266000034016621ac28d60000009c01000062020025c02c307839383736353433323130fe0a00520a000031fe560052560019b0003101dafec60082c6000032fec6007ac6004d6ca666000033ceb401fe8c017e8c014dcca6c6004d7a0035b23200fec6007ec6000034${k}${k}`); - const encryptedShares = Array.from(Array(10).keys()).map(k => `0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765${k}98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765${k}`); - // const operatorsIndexes = Array.from(Array(10).keys()).map(k => k + 1); - - // await deployedSSVNetworkContract.createGroup([1,2,3,4]); - // await deployedSSVNetworkContract.createGroup([1,2,3,4]); - - // await deployedSSVNetworkContract.deposit("100000000000"); - // await log({ - // action: 'deposit', - // operatorIds: [1, 2, 3, 4] - // }); - // validator 1 - await progressBlocks(98); - let resultRegister = (await (await deployedSSVNetworkContract.registerValidator( - validatorPK + "f", - [1,2,3,4], - sharePKs[0], - '10000' - )).wait()).logs[0]; - - let interfaceRegister = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId, bytes shares)']); - let outputRegister = interfaceRegister.decodeEventLog('ValidatorAdded', resultRegister.data, resultRegister.topics); - await log({ - action: `register validator #1: ${outputRegister.validatorPK} : ${outputRegister.groupId}`, - operatorIds: [1, 2, 3, 4] - }); - await progressBlocks(1); - await log({ - operatorIds: [1, 2, 3, 4], - groupIds: [outputRegister.groupId] - }); - - let resultUpdate = (await (await deployedSSVNetworkContract.transferValidator( - validatorPK + "f", - [4,5,6,7], - sharePKs[2], - '10000' - )).wait()).logs[0]; - - let interfaceUpdate = new ethers.utils.Interface(['event ValidatorTransferred(bytes validatorPK, bytes32 groupId, bytes shares)']); - let outputUpdate = interfaceUpdate.decodeEventLog('ValidatorTransferred', resultUpdate.data, resultUpdate.topics); - expect(outputRegister.groupId).not.equal(outputUpdate.groupId); - expect(outputRegister.validatorPK).to.equal(outputUpdate.validatorPK); - - await log({ - action: `update validator #1: ${outputUpdate.validatorPK} : ${outputUpdate.groupId}`, - operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], - groupIds: [outputRegister.groupId, outputUpdate.groupId] - }); - await progressBlocks(1); - await log({ - operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], - groupIds: [outputRegister.groupId, outputUpdate.groupId] - }); - await progressBlocks(1); - await log({ - operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], - groupIds: [outputRegister.groupId, outputUpdate.groupId] - }); - - // move back validator 1 to group 1 - resultRegister = (await (await deployedSSVNetworkContract.transferValidator( - validatorPK + "f", - [1,2,3,4], - sharePKs[1], - '10000' - )).wait()).logs[0]; - interfaceRegister = new ethers.utils.Interface(['event ValidatorTransferred(bytes validatorPK, bytes32 groupId)']); // , bytes[] sharesPublicKeys, bytes[] encryptedShares - outputRegister = interfaceUpdate.decodeEventLog('ValidatorTransferred', resultRegister.data, resultRegister.topics); - await log({ - action: `update validator #1: ${outputRegister.validatorPK} : ${outputRegister.groupId}`, - operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], - groupIds: [outputRegister.groupId, outputUpdate.groupId] - }); - await progressBlocks(1); - await log({ - operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], - groupIds: [outputRegister.groupId, outputUpdate.groupId] - }); - - const resultRegister2 = (await (await deployedSSVNetworkContract.registerValidator( - validatorPK + "a", - [1,2,3,4], - sharePKs[1], - "1000" - )).wait()).logs[0]; - - const interfaceRegister2 = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId, bytes shares)']); - const outputRegister2 = interfaceRegister2.decodeEventLog('ValidatorAdded', resultRegister2.data, resultRegister2.topics); - await log({ - action: `register validator #2: ${outputRegister2.validatorPK} : ${outputRegister2.groupId}`, - operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], - groupIds: [outputRegister.groupId, outputRegister2.groupId] - }); - - - const resultRegister3 = (await (await deployedSSVNetworkContract.registerValidator( - validatorPK + "b", - [5,6,7,8], - sharePKs[1], - "1000000" - )).wait()).logs[0]; - - - const interfaceRegister3 = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId, bytes shares)']); - const outputRegister3 = interfaceRegister3.decodeEventLog('ValidatorAdded', resultRegister3.data, resultRegister3.topics); - await log({ - action: `register validator #3: ${resultRegister3.validatorPK} : ${resultRegister3.groupId}`, - operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], - groupIds: [outputRegister.groupId, outputRegister2.groupId] - }); - - - - await progressBlocks(1); - await log({ - operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], - groupIds: [outputRegister.groupId, outputRegister2.groupId] - }); - await progressBlocks(1); - await log({ - operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], - groupIds: [outputRegister.groupId, outputRegister2.groupId] - }); - await (await deployedSSVNetworkContract.updateOperatorFee( - 1, - 2 - )).wait(); - await log({ - action: 'operator #1 fee updated 2', - operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], - groupIds: [outputRegister.groupId, outputRegister2.groupId] - }); - await progressBlocks(1); - await log({ - operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], - groupIds: [outputRegister.groupId, outputRegister2.groupId] - }); - await progressBlocks(1); - await log({ - operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], - groupIds: [outputRegister.groupId, outputRegister2.groupId] - }); - - - await (await deployedSSVNetworkContract.removeValidator(outputRegister2.validatorPK)).wait(); - await log({ - action: 'remove validator #2', - operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], - groupIds: [outputRegister.groupId, outputRegister2.groupId] - }); - - await progressBlocks(1); - await log({ - operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], - groupIds: [outputRegister.groupId, outputRegister2.groupId] - }); - await progressBlocks(1); - await log({ - operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], - groupIds: [outputRegister.groupId, outputRegister2.groupId] - }); - await progressBlocks(1); - let results = [] - for (let i = 0; i < 10; ++i) { - let resultRegister = (await (await deployedSSVNetworkContract.registerValidator( - validatorPK + i % 10, - [1,2,3,4], - sharePKs[2], - '10000' - )).wait()).logs[0]; - - const interfaceRegister = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId, bytes shares)']); - const outputRegister = interfaceRegister.decodeEventLog('ValidatorAdded', resultRegister.data, resultRegister.topics); - - results.push(outputRegister); - } - console.log("outputRegister.groupId,outputRegister2.groupId") - console.log(outputRegister.groupId,outputRegister3.groupId) - - const transferLogs = (await (await deployedSSVNetworkContract.bulkTransferValidators( - results.map(r => r.validatorPK), - outputRegister.groupId, - outputRegister3.groupId, - results.map(r => sharePKs[4]), - '10000' - )).wait()).logs; - - // await log({ - // action: 'transfer', - // operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], - // groupIds: [outputRegister.groupId, resultRegister3.groupId] - // }); - - /* - // validator 2 - await expect(await deployedSSVNetworkContract.registerValidator( - [1,2,3,4], - validatorPK, - sharePKs.slice(0, 4), - encryptedShares.slice(0, 4), - "10000" - )) - .to.emit(deployedSSVNetworkContract, 'ValidatorAdded'); - // .withArgs(validatorPK); - - - const resultRegister = (await (await deployedSSVNetworkContract.registerValidator( - [1,2,3,4], - validatorPK, - sharePKs.slice(0, 4), - encryptedShares.slice(0, 4), - '10000' - )).wait()).logs[0]; - const interfaceRegister = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId)']); - const outputRegister = interfaceRegister.decodeEventLog('ValidatorAdded', resultRegister.data, resultRegister.topics); - expect(outputRegister.validatorPK).to.equal(validatorPK); - - console.log("register ---->", outputRegister.validatorPK, outputRegister.groupId); - console.log("operatorIdsAfterRegister ---->", await deployedSSVNetworkContract.test_getOperatorsByGroupId(outputRegister.groupId)); - - const resultUpdate = (await (await deployedSSVNetworkContract.updateValidator( - [2,3,4,5], - validatorPK, - outputRegister.groupId, - '10000' - )).wait()).logs[0];; - const interfaceUpdate = new ethers.utils.Interface(['event ValidatorUpdated(bytes validatorPK, bytes32 groupId)']); - const outputUpdate = interfaceUpdate.decodeEventLog('ValidatorUpdated', resultUpdate.data, resultUpdate.topics); - expect(outputRegister.groupId).not.equal(outputUpdate.groupId); - expect(outputRegister.validatorPK).to.equal(outputUpdate.validatorPK); - - console.log("update ---->", outputUpdate.validatorPK, outputUpdate.groupId); - console.log("operatorIdsAfterUpdate ---->", await deployedSSVNetworkContract.test_getOperatorsByGroupId(outputUpdate.groupId)); - - await expect(await deployedSSVNetworkContract.removeValidator( - validatorPK, - outputUpdate.groupId - )) - .to.emit(deployedSSVNetworkContract, 'ValidatorRemoved') - .withArgs(validatorPK, outputUpdate.groupId); - - */ - // await deployedSSVNetworkContract.liquidate("0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", "0x392791df626408017a264f53fde61065d5a93a32b60171df9d8a46afdf82992d"); - }); -}); diff --git a/test/vadimToUpdate.js.old b/test/vadimToUpdate.js.old deleted file mode 100644 index 564afee7..00000000 --- a/test/vadimToUpdate.js.old +++ /dev/null @@ -1,302 +0,0 @@ -const { expect } = require("chai"); -const { progressBlocks, blockNumber } = require('./helpers/utils'); -const operator_fee_block = 1; - - -async function mineNBlocks(n) { - for (let index = 0; index < n; index++) { - await ethers.provider.send('evm_mine'); - } -} - -const operatorsIndexes = Array.from(Array(5).keys()).map(k => k + 1); -let deployedSSVNetworkContract; - -async function log({ action='', operatorIds = [], groupIds = [] }) { - console.log(`[BLOCK] ${await blockNumber()}`) - if (action) { - console.log(`> ${action}`); - } - if (operatorIds.length) { - for (const id of operatorIds) { - console.log( - `> operator #${id}`, - 'balance', await deployedSSVNetworkContract.operatorEarningsOf(id), - ); - } - } - if (groupIds.length) { - const [owner] = await ethers.getSigners(); - for (const id of groupIds) { - console.log( - `> group #$${id}`, - 'balance', await deployedSSVNetworkContract.podBalanceOf(owner.address, id), - ); - } - } -} - -describe("Validators", () => { - beforeEach(async () => { - const SSVNetwork = await ethers.getContractFactory("SSVNetwork"); - deployedSSVNetworkContract = await SSVNetwork.deploy(); - await deployedSSVNetworkContract.deployed(); - - await progressBlocks(99); - for (let i = 0; i < 8; i++) { // operatorsIndexes.length - var encryptionPK = "0x123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123451"; - await (await deployedSSVNetworkContract.registerOperator(encryptionPK, operator_fee_block)).wait(); - await log({ action: `register operator #${i+1}` }); - } - // await deployedSSVNetworkContract.addOperatorToValidator([], operatorsIndexes, []); - }) - - it("should register validator", async () => { - const validatorPK = "0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765"; - const sharePKs = Array.from(Array(10).keys()).map(k => `0xe0096008000000b4010000040000001000000076000000dc000000420d142c307831323334353637383930fe0a00520a000031017afe66008266000032fe66009266000033fe66009266000034016621ac28d60000009c01000062020025c02c307839383736353433323130fe0a00520a000031fe560052560019b0003101dafec60082c6000032fec6007ac6004d6ca666000033ceb401fe8c017e8c014dcca6c6004d7a0035b23200fec6007ec6000034${k}${k}`); - const encryptedShares = Array.from(Array(10).keys()).map(k => `0x98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765${k}98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765${k}`); - // const operatorsIndexes = Array.from(Array(10).keys()).map(k => k + 1); - - // await deployedSSVNetworkContract.createGroup([1,2,3,4]); - // await deployedSSVNetworkContract.createGroup([1,2,3,4]); - - await deployedSSVNetworkContract.deposit("100000000000"); - await log({ - action: 'deposit', - operatorIds: [1, 2, 3, 4] - }); - // validator 1 - await progressBlocks(97); - let resultRegister = (await (await deployedSSVNetworkContract.registerValidator( - validatorPK + "f", - [1,2,3,4], - sharePKs[0], - '10000' - )).wait()).logs[0]; - - let interfaceRegister = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId, bytes shares)']); - let outputRegister = interfaceRegister.decodeEventLog('ValidatorAdded', resultRegister.data, resultRegister.topics); - await log({ - action: `register validator #1: ${outputRegister.validatorPK} : ${outputRegister.groupId}`, - operatorIds: [1, 2, 3, 4] - }); - await progressBlocks(1); - await log({ - operatorIds: [1, 2, 3, 4], - groupIds: [outputRegister.groupId] - }); - - let resultUpdate = (await (await deployedSSVNetworkContract.transferValidator( - validatorPK + "f", - [4,5,6,7], - sharePKs[2], - '10000' - )).wait()).logs[0]; - - let interfaceUpdate = new ethers.utils.Interface(['event ValidatorTransferred(bytes validatorPK, bytes32 groupId, bytes shares)']); - let outputUpdate = interfaceUpdate.decodeEventLog('ValidatorTransferred', resultUpdate.data, resultUpdate.topics); - expect(outputRegister.groupId).not.equal(outputUpdate.groupId); - expect(outputRegister.validatorPK).to.equal(outputUpdate.validatorPK); - - await log({ - action: `update validator #1: ${outputUpdate.validatorPK} : ${outputUpdate.groupId}`, - operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], - groupIds: [outputRegister.groupId, outputUpdate.groupId] - }); - await progressBlocks(1); - await log({ - operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], - groupIds: [outputRegister.groupId, outputUpdate.groupId] - }); - await progressBlocks(1); - await log({ - operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], - groupIds: [outputRegister.groupId, outputUpdate.groupId] - }); - - // move back validator 1 to group 1 - resultRegister = (await (await deployedSSVNetworkContract.transferValidator( - validatorPK + "f", - [1,2,3,4], - sharePKs[1], - '10000' - )).wait()).logs[0]; - interfaceRegister = new ethers.utils.Interface(['event ValidatorTransferred(bytes validatorPK, bytes32 groupId)']); // , bytes[] sharesPublicKeys, bytes[] encryptedShares - outputRegister = interfaceUpdate.decodeEventLog('ValidatorTransferred', resultRegister.data, resultRegister.topics); - await log({ - action: `update validator #1: ${outputRegister.validatorPK} : ${outputRegister.groupId}`, - operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], - groupIds: [outputRegister.groupId, outputUpdate.groupId] - }); - await progressBlocks(1); - await log({ - operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], - groupIds: [outputRegister.groupId, outputUpdate.groupId] - }); - - const resultRegister2 = (await (await deployedSSVNetworkContract.registerValidator( - validatorPK + "a", - [1,2,3,4], - sharePKs[1], - "1000" - )).wait()).logs[0]; - - const interfaceRegister2 = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId, bytes shares)']); - const outputRegister2 = interfaceRegister2.decodeEventLog('ValidatorAdded', resultRegister2.data, resultRegister2.topics); - await log({ - action: `register validator #2: ${outputRegister2.validatorPK} : ${outputRegister2.groupId}`, - operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], - groupIds: [outputRegister.groupId, outputRegister2.groupId] - }); - - - const resultRegister3 = (await (await deployedSSVNetworkContract.registerValidator( - validatorPK + "b", - [5,6,7,8], - sharePKs[1], - "1000000" - )).wait()).logs[0]; - - - const interfaceRegister3 = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId, bytes shares)']); - const outputRegister3 = interfaceRegister3.decodeEventLog('ValidatorAdded', resultRegister3.data, resultRegister3.topics); - await log({ - action: `register validator #3: ${resultRegister3.validatorPK} : ${resultRegister3.groupId}`, - operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], - groupIds: [outputRegister.groupId, outputRegister2.groupId] - }); - - - - await progressBlocks(1); - await log({ - operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], - groupIds: [outputRegister.groupId, outputRegister2.groupId] - }); - await progressBlocks(1); - await log({ - operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], - groupIds: [outputRegister.groupId, outputRegister2.groupId] - }); - await (await deployedSSVNetworkContract.updateOperatorFee( - 1, - 2 - )).wait(); - await log({ - action: 'operator #1 fee updated 2', - operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], - groupIds: [outputRegister.groupId, outputRegister2.groupId] - }); - await progressBlocks(1); - await log({ - operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], - groupIds: [outputRegister.groupId, outputRegister2.groupId] - }); - await progressBlocks(1); - await log({ - operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], - groupIds: [outputRegister.groupId, outputRegister2.groupId] - }); - - - await (await deployedSSVNetworkContract.removeValidator(outputRegister2.validatorPK)).wait(); - await log({ - action: 'remove validator #2', - operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], - groupIds: [outputRegister.groupId, outputRegister2.groupId] - }); - - await progressBlocks(1); - await log({ - operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], - groupIds: [outputRegister.groupId, outputRegister2.groupId] - }); - await progressBlocks(1); - await log({ - operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], - groupIds: [outputRegister.groupId, outputRegister2.groupId] - }); - await progressBlocks(1); - let results = [] - for (let i = 0; i < 20; ++i) { - let resultRegister = (await (await deployedSSVNetworkContract.registerValidator( - validatorPK + i % 10, - [1,2,3,4], - sharePKs[2], - '10000' - )).wait()).logs[0]; - - const interfaceRegister = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId, bytes shares)']); - const outputRegister = interfaceRegister.decodeEventLog('ValidatorAdded', resultRegister.data, resultRegister.topics); - - results.push(outputRegister); - } - console.log("outputRegister.groupId,outputRegister2.groupId") - console.log(outputRegister.groupId,outputRegister3.groupId) - - const transferLogs = (await (await deployedSSVNetworkContract.bulkTransferValidators( - results.map(r => r.validatorPK), - outputRegister.groupId, - outputRegister3.groupId, - results.map(r => sharePKs[4]) - - )).wait()).logs; - - // await log({ - // action: 'transfer', - // operatorIds: [1, 2, 3, 4, 5, 6, 7, 8], - // groupIds: [outputRegister.groupId, resultRegister3.groupId] - // }); - - /* - // validator 2 - await expect(await deployedSSVNetworkContract.registerValidator( - [1,2,3,4], - validatorPK, - sharePKs.slice(0, 4), - encryptedShares.slice(0, 4), - "10000" - )) - .to.emit(deployedSSVNetworkContract, 'ValidatorAdded'); - // .withArgs(validatorPK); - - - const resultRegister = (await (await deployedSSVNetworkContract.registerValidator( - [1,2,3,4], - validatorPK, - sharePKs.slice(0, 4), - encryptedShares.slice(0, 4), - '10000' - )).wait()).logs[0]; - const interfaceRegister = new ethers.utils.Interface(['event ValidatorAdded(bytes validatorPK, bytes32 groupId)']); - const outputRegister = interfaceRegister.decodeEventLog('ValidatorAdded', resultRegister.data, resultRegister.topics); - expect(outputRegister.validatorPK).to.equal(validatorPK); - - console.log("register ---->", outputRegister.validatorPK, outputRegister.groupId); - console.log("operatorIdsAfterRegister ---->", await deployedSSVNetworkContract.test_getOperatorsByGroupId(outputRegister.groupId)); - - const resultUpdate = (await (await deployedSSVNetworkContract.updateValidator( - [2,3,4,5], - validatorPK, - outputRegister.groupId, - '10000' - )).wait()).logs[0];; - const interfaceUpdate = new ethers.utils.Interface(['event ValidatorUpdated(bytes validatorPK, bytes32 groupId)']); - const outputUpdate = interfaceUpdate.decodeEventLog('ValidatorUpdated', resultUpdate.data, resultUpdate.topics); - expect(outputRegister.groupId).not.equal(outputUpdate.groupId); - expect(outputRegister.validatorPK).to.equal(outputUpdate.validatorPK); - - console.log("update ---->", outputUpdate.validatorPK, outputUpdate.groupId); - console.log("operatorIdsAfterUpdate ---->", await deployedSSVNetworkContract.test_getOperatorsByGroupId(outputUpdate.groupId)); - - await expect(await deployedSSVNetworkContract.removeValidator( - validatorPK, - outputUpdate.groupId - )) - .to.emit(deployedSSVNetworkContract, 'ValidatorRemoved') - .withArgs(validatorPK, outputUpdate.groupId); - - */ - // await deployedSSVNetworkContract.liquidate("0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", "0x392791df626408017a264f53fde61065d5a93a32b60171df9d8a46afdf82992d"); - }); -}); diff --git a/test/validators/register.ts b/test/validators/register.ts index fe22cf93..83d3065c 100644 --- a/test/validators/register.ts +++ b/test/validators/register.ts @@ -58,7 +58,7 @@ describe('Register Validator Tests', () => { it('Not enough amount', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(0), + helpers.DataGenerator.publicKey(1), (await helpers.registerPodAndDeposit(0, helpers.DataGenerator.cluster.new(), '0')).clusterId, helpers.DataGenerator.shares(0), )).to.be.revertedWith('NotEnoughBalance'); From 30303356caf3af1e32f5d7c08f6b4e1535ddb494 Mon Sep 17 00:00:00 2001 From: Wadym Date: Thu, 10 Nov 2022 17:05:40 +0100 Subject: [PATCH 094/149] core balances logic includes reactivation (#108) * core balances logic includes reactivation * fix shrinkable function being called multiple times * No need to update DAO earnings in transfer validator * register pod gas limit test * register pod gas limit test * fix withdrawn flag * optimize deposit * optimize deposit func * improved withdraws, deposit, gas usage * update dao earnings after liquidation * changes based by jira tasks * improve code coverage * fix npm pgk * fix gas usage * fix gases * update gases * fix packages * upgrade node version * fix code coverage * rearrange contract * remove var operatorBalance used once * update tests * add missed test * Consolidate shrink and expand functions (#111) Co-authored-by: Vadim Co-authored-by: Adam Zigdon Co-authored-by: AndrewBlox Co-authored-by: andrew-blox <102898824+andrew-blox@users.noreply.github.com> --- .github/workflows/code-coverage.yaml | 4 +- .github/workflows/linter.yaml | 2 +- .github/workflows/tests.yaml | 2 +- contracts/ISSVNetwork.sol | 136 +- contracts/SSVNetwork.sol | 866 +- package-lock.json | 17070 +++++++++++-------------- package.json | 11 +- test/account/deposit.ts | 40 +- test/account/withdraw.ts | 64 +- test/helpers/contract-helpers.ts | 21 +- test/helpers/gas-usage.ts | 24 +- test/liquidate/liquidate.ts | 28 +- test/liquidate/reactivate.ts | 58 + test/operators/fee.ts | 14 + test/validators/register.ts | 38 +- test/validators/remove.ts | 8 +- test/validators/transfer-bulk.ts | 3 +- test/validators/transfer.ts | 53 +- 18 files changed, 8084 insertions(+), 10358 deletions(-) create mode 100644 test/liquidate/reactivate.ts diff --git a/.github/workflows/code-coverage.yaml b/.github/workflows/code-coverage.yaml index 9f753d79..0b550135 100644 --- a/.github/workflows/code-coverage.yaml +++ b/.github/workflows/code-coverage.yaml @@ -11,8 +11,8 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-node@v1 with: - node-version: '12.x' + node-version: '16.x' - run: npm install env: GH_TOKEN: ${{ secrets.github_token }} - - run: npx hardhat coverage + - run: NO_GAS_ENFORCE=1 npx hardhat coverage diff --git a/.github/workflows/linter.yaml b/.github/workflows/linter.yaml index c7667c60..9be7e729 100644 --- a/.github/workflows/linter.yaml +++ b/.github/workflows/linter.yaml @@ -10,7 +10,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-node@v1 with: - node-version: '12.x' + node-version: '16.x' - run: npm install env: GH_TOKEN: ${{ secrets.github_token }} diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 4529c15f..41b426dc 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -11,7 +11,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-node@v1 with: - node-version: '12.x' + node-version: '16.x' - run: npm install env: GH_TOKEN: ${{ secrets.github_token }} diff --git a/contracts/ISSVNetwork.sol b/contracts/ISSVNetwork.sol index c954cab5..f01701c0 100644 --- a/contracts/ISSVNetwork.sol +++ b/contracts/ISSVNetwork.sol @@ -5,6 +5,9 @@ import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; interface ISSVNetwork { + /**********/ + /* Events */ + /**********/ /** * @dev Emitted when a new operator has been added. @@ -123,7 +126,16 @@ interface ISSVNetwork { */ event NetworkFeesWithdrawal(uint256 value, address recipient); - /** errors */ + event PodFundsWithdrawal(uint256 value, bytes32 clusterId, address owner); + event OperatorFundsWithdrawal(uint256 value, uint64 operatorId, address owner); + + + event FundsDeposit(uint256 value, bytes32 clusterId, address owner); + + /**********/ + /* Errors */ + /**********/ + error CallerNotOwner(); error FeeTooLow(); error FeeExceedsIncreaseLimit(); @@ -131,7 +143,6 @@ interface ISSVNetwork { error ApprovalNotWithinTimeframe(); error OperatorWithPublicKeyNotExist(); error OperatorNotFound(); - error OperatorDoesNotExist(); error NotEnoughBalance(); error ValidatorAlreadyExists(); @@ -146,20 +157,11 @@ interface ISSVNetwork { error ClusterAlreadyExists(); error ClusterNotExists(); error PodAlreadyEnabled(); + error BurnRatePositive(); - /** errors */ -// error validatorWithPublicKeyNotExist(); -// error callerNotValidatorOwner(); -// error operatorWithPublicKeyNotExist(); -// error callerNotOperatorOwner(); -// error feeTooLow(); -// error feeExceedsIncreaseLimit(); -// error noPendingFeeChangeRequest(); -// error approvalNotWithinTimeframe(); -// error notEnoughBalance(); -// error burnRatePositive(); -// error accountAlreadyEnabled(); - + /****************/ + /* Initializers */ + /****************/ /** * @dev Initializes the contract. @@ -175,6 +177,10 @@ interface ISSVNetwork { uint64 executeOperatorFeePeriod_ ) external; + /*******************************/ + /* Operator External Functions */ + /*******************************/ + /** * @dev Registers a new operator. * @param publicKey Operator's public key. Used to encrypt secret shares of validators keys. @@ -191,15 +197,15 @@ interface ISSVNetwork { */ function removeOperator(uint64 id) external; - /** - * @dev Gets the operators current snapshot. - * @param id Operator's id. - * @return currentBlock the block that the snapshot is updated to. - * @return index the index of the operator. - * @return balance the current balance of the operator. - */ - function operatorSnapshot(uint64 id) external view returns (uint64 currentBlock, uint64 index, uint256 balance); + function declareOperatorFee(uint64 operatorId, uint256 fee) external; + + function executeOperatorFee(uint64 operatorId) external; + function cancelDeclaredOperatorFee(uint64 operatorId) external; + + /********************************/ + /* Validator External Functions */ + /********************************/ /** * @dev Registers a new validator. @@ -231,27 +237,93 @@ interface ISSVNetwork { bytes calldata shares ) external; - function liquidate(address ownerAddress, bytes32 clusterId) external; - - function isLiquidatable(address ownerAddress, bytes32 clusterId) external view returns(bool); - - function isLiquidated(address ownerAddress, bytes32 clusterId) external view returns(bool); - - function reactivatePod(bytes32 clusterId, uint256 amount) external; - function bulkTransferValidators( - bytes[] calldata validatorPK, + bytes[] calldata publicKey, bytes32 fromClusterId, bytes32 toClusterId, bytes[] calldata shares ) external; + /**************************/ + /* Pod External Functions */ + /**************************/ + + function registerPod(uint64[] memory operatorIds, uint256 amount) external; + + function liquidate(address ownerAddress, bytes32 clusterId) external; + + function reactivatePod(bytes32 clusterId, uint256 amount) external; + + /******************************/ + /* Balance External Functions */ + /******************************/ + + function deposit(address owner, bytes32 clusterId, uint256 amount) external; + + function deposit(bytes32 clusterId, uint256 amount) external; + + function withdrawOperatorBalance(uint64 operatorId, uint256 tokenAmount) external; + + function withdrawOperatorBalance(uint64 operatorId) external; + + function withdrawPodBalance(bytes32 clusterId, uint256 tokenAmount) external; + + /**************************/ + /* DAO External Functions */ + /**************************/ + + function updateNetworkFee(uint256 fee) external; + + function withdrawDAOEarnings(uint256 amount) external; + function updateOperatorFeeIncreaseLimit(uint64 newOperatorMaxFeeIncrease) external; function updateDeclareOperatorFeePeriod(uint64 newDeclareOperatorFeePeriod) external; function updateExecuteOperatorFeePeriod(uint64 newExecuteOperatorFeePeriod) external; + + /************************************/ + /* Operator External View Functions */ + /************************************/ + + function getOperatorFee(uint64 operatorId) external view returns (uint256); + + function getOperatorDeclaredFee(uint64 operatorId) external view returns (uint256, uint256, uint256); + + /*******************************/ + /* Pod External View Functions */ + /*******************************/ + + function getClusterId(uint64[] memory operatorIds) external view returns(bytes32); + + function isLiquidatable(address ownerAddress, bytes32 clusterId) external view returns(bool); + + function isLiquidated(address ownerAddress, bytes32 clusterId) external view returns(bool); + + /***********************************/ + /* Balance External View Functions */ + /***********************************/ + + /** + * @dev Gets the operators current snapshot. + * @param id Operator's id. + * @return currentBlock the block that the snapshot is updated to. + * @return index the index of the operator. + * @return balance the current balance of the operator. + */ + function operatorSnapshot(uint64 id) external view returns (uint64 currentBlock, uint64 index, uint256 balance); + + function podBalanceOf(address owner, bytes32 clusterId) external view returns (uint256); + + /*******************************/ + /* DAO External View Functions */ + /*******************************/ + + function getNetworkFee() external view returns (uint256); + + function getNetworkBalance() external view returns (uint256); + function getOperatorFeeIncreaseLimit() external view returns (uint64); function getExecuteOperatorFeePeriod() external view returns (uint64); diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index c1dadb2d..39820677 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -9,14 +9,23 @@ import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import "./utils/Types.sol"; -import "hardhat/console.sol"; +// import "hardhat/console.sol"; contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { + /*************/ + /* Libraries */ + /*************/ + using Types256 for uint256; using Types64 for uint64; using Counters for Counters.Counter; + + /***********/ + /* Structs */ + /***********/ + struct Snapshot { /// @dev block is the last block in which last index was set uint64 block; @@ -29,7 +38,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { struct Operator { address owner; uint64 fee; - uint64 validatorCount; + uint32 validatorCount; Snapshot snapshot; } @@ -41,7 +50,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } struct DAO { - uint64 validatorCount; + uint32 validatorCount; uint64 withdrawn; Snapshot earnings; @@ -52,10 +61,13 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } struct Pod { - uint64 validatorCount; + uint32 validatorCount; + uint64 networkFee; uint64 networkFeeIndex; + Snapshot usage; + bool disabled; } @@ -65,11 +77,23 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { bool active; } - // global vars + /*************/ + /* Constants */ + /*************/ + + uint64 constant LIQUIDATION_MIN_BLOCKS = 50; + uint64 constant MINIMAL_OPERATOR_FEE = 100000000; + + /********************/ + /* Global Variables */ + /********************/ + Counters.Counter private lastOperatorId; - Counters.Counter private lastPodId; - // operator vars + /*************/ + /* Variables */ + /*************/ + mapping(uint64 => Operator) private _operators; mapping(uint64 => OperatorFeeChangeRequest) private _operatorFeeChangeRequests; mapping(bytes32 => Cluster) private _clusters; @@ -84,15 +108,14 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { uint64 private _executeOperatorFeePeriod; uint64 private _operatorMaxFeeIncrease; - uint64 constant LIQUIDATION_MIN_BLOCKS = 50; - uint64 constant MINIMAL_OPERATOR_FEE = 100000000; - - // uint64 constant NETWORK_FEE_PER_BLOCK = 1; - DAO private _dao; IERC20 private _token; + /****************/ + /* Initializers */ + /****************/ + function initialize( IERC20 token_, uint64 operatorMaxFeeIncrease_, @@ -124,15 +147,23 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _executeOperatorFeePeriod = executeOperatorFeePeriod_; } + /*************/ + /* Modifiers */ + /*************/ + modifier onlyOperatorOwnerOrContractOwner(uint64 operatorId) { _onlyOperatorOwnerOrContractOwner(operatorId); _; } + /*******************************/ + /* Operator External Functions */ + /*******************************/ + function registerOperator( bytes calldata encryptionPK, uint256 fee - ) external returns (uint64 id) { + ) external override returns (uint64 id) { if (fee < MINIMAL_OPERATOR_FEE) { revert FeeTooLow(); } @@ -140,10 +171,10 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { lastOperatorId.increment(); id = uint64(lastOperatorId.current()); _operators[id] = Operator({ owner: msg.sender, snapshot: Snapshot({ block: uint64(block.number), index: 0, balance: 0}), validatorCount: 0, fee: fee.shrink()}); - emit OperatorAdded(id, msg.sender, encryptionPK, fee.shrinkable()); + emit OperatorAdded(id, msg.sender, encryptionPK, fee); } - function removeOperator(uint64 operatorId) external { + function removeOperator(uint64 operatorId) external override { Operator memory operator = _operators[operatorId]; if (operator.owner != msg.sender) revert CallerNotOwner(); @@ -153,40 +184,30 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { emit OperatorRemoved(operatorId); } - function declareOperatorFee(uint64 operatorId, uint256 fee) onlyOperatorOwnerOrContractOwner(operatorId) external { + function declareOperatorFee(uint64 operatorId, uint256 fee) onlyOperatorOwnerOrContractOwner(operatorId) external override { Operator memory operator = _operators[operatorId]; if (fee < MINIMAL_OPERATOR_FEE) { revert FeeTooLow(); } + uint64 shrunkFee = fee.shrink(); + // @dev 100% = 10000, 10% = 1000 - using 10000 to represent 2 digit precision uint64 maxAllowedFee = operator.fee * (10000 + _operatorMaxFeeIncrease) / 10000; - if (fee.shrink() > maxAllowedFee) { + if (shrunkFee > maxAllowedFee) { revert FeeExceedsIncreaseLimit(); } _operatorFeeChangeRequests[operatorId] = OperatorFeeChangeRequest( - fee.shrink(), + shrunkFee, uint64(block.timestamp) + _declareOperatorFeePeriod, uint64(block.timestamp) + _declareOperatorFeePeriod + _executeOperatorFeePeriod ); - emit OperatorFeeDeclaration(msg.sender, operatorId, block.number, fee.shrinkable()); - } - - function cancelDeclaredOperatorFee(uint64 operatorId) onlyOperatorOwnerOrContractOwner(operatorId) external { - OperatorFeeChangeRequest memory feeChangeRequest = _operatorFeeChangeRequests[operatorId]; - - if(feeChangeRequest.fee == 0) { - revert NoPendingFeeChangeRequest(); - } - - delete _operatorFeeChangeRequests[operatorId]; - - emit DeclaredOperatorFeeCancelation(msg.sender, operatorId); + emit OperatorFeeDeclaration(msg.sender, operatorId, block.number, fee); } - function executeOperatorFee(uint64 operatorId) onlyOperatorOwnerOrContractOwner(operatorId) external { + function executeOperatorFee(uint64 operatorId) onlyOperatorOwnerOrContractOwner(operatorId) external override { OperatorFeeChangeRequest memory feeChangeRequest = _operatorFeeChangeRequests[operatorId]; if(feeChangeRequest.fee == 0) { @@ -202,29 +223,27 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { delete _operatorFeeChangeRequests[operatorId]; } - function getOperatorDeclaredFee(uint64 operatorId) external view returns (uint256, uint256, uint256) { + function cancelDeclaredOperatorFee(uint64 operatorId) onlyOperatorOwnerOrContractOwner(operatorId) external override { OperatorFeeChangeRequest memory feeChangeRequest = _operatorFeeChangeRequests[operatorId]; if(feeChangeRequest.fee == 0) { revert NoPendingFeeChangeRequest(); } - return (feeChangeRequest.fee.expand(), feeChangeRequest.approvalBeginTime, feeChangeRequest.approvalEndTime); - } - - function getOperatorFee(uint64 operatorId) external view returns (uint256) { - Operator memory operator = _operators[operatorId]; - - if (operator.owner == address(0)) revert OperatorNotFound(); + delete _operatorFeeChangeRequests[operatorId]; - return operator.fee.expand(); + emit DeclaredOperatorFeeCancelation(msg.sender, operatorId); } + /********************************/ + /* Validator External Functions */ + /********************************/ + function registerValidator( bytes calldata publicKey, bytes32 clusterId, bytes calldata shares - ) external { + ) external override { _validateClusterId(clusterId); _validatePublicKey(publicKey); @@ -239,16 +258,17 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { { Pod memory pod; - pod = _updatePodData(clusterId, 0, hashedPod, true); + pod = _updatePodData(clusterId, 0, hashedPod, 1); { - for (uint64 i = 0; i < operatorIds.length; ++i) { - Operator memory operator = _operators[operatorIds[i]]; - // @dev operator.owner != address(0) checked in case operator was removed - if (!pod.disabled && operator.owner != address(0)) { - operator.snapshot = _getSnapshot(operator, uint64(block.number)); - ++operator.validatorCount; - _operators[operatorIds[i]] = operator; + if (!pod.disabled) { + for (uint64 i = 0; i < operatorIds.length; ++i) { + Operator memory operator = _operators[operatorIds[i]]; + if (operator.owner != address(0)) { + operator.snapshot = _getSnapshot(operator, uint64(block.number)); + ++operator.validatorCount; + _operators[operatorIds[i]] = operator; + } } } } @@ -274,59 +294,9 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { emit ValidatorAdded(publicKey, clusterId, shares); } - function transferValidator( - bytes calldata publicKey, - bytes32 newClusterId, - bytes calldata shares - ) external { - _validateClusterId(newClusterId); - _validatePublicKey(publicKey); - - uint64[] memory operatorIds = _clusters[newClusterId].operatorIds; - - bytes32 hashedValidator = keccak256(publicKey); - bytes32 clusterId = _validatorPKs[hashedValidator].clusterId; - - if (_validatorPKs[hashedValidator].owner != msg.sender) { - revert ValidatorNotOwned(); - } - - { - bytes32 hashedPod = keccak256(abi.encodePacked(msg.sender, clusterId)); - _pods[hashedPod] = _updatePodData(clusterId, 0, hashedPod, false); - } - - { - _updateOperatorsOnTransfer(_clusters[clusterId].operatorIds, operatorIds, 1); - } - - { - Pod memory pod; - { - bytes32 hashedPod = keccak256(abi.encodePacked(msg.sender, newClusterId)); - - pod = _updatePodData(newClusterId, 0, hashedPod, true); - _validatorPKs[hashedValidator].clusterId = newClusterId; - _pods[hashedPod] = pod; - } - - { - DAO memory dao = _dao; - dao = _updateDAOEarnings(dao); - _dao = dao; - } - - if (_liquidatable(pod.disabled, _podBalance(pod, _clusterCurrentIndex(newClusterId)), pod.validatorCount, operatorIds)) { - revert NotEnoughBalance(); - } - - emit ValidatorTransferred(publicKey, newClusterId, shares); - } - } - function removeValidator( bytes calldata publicKey - ) external { + ) external override { _validatePublicKey(publicKey); bytes32 hashedValidator = keccak256(publicKey); @@ -338,7 +308,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { bytes32 hashedPod = keccak256(abi.encodePacked(msg.sender, clusterId)); { - _pods[hashedPod] = _updatePodData(clusterId, 0, hashedPod, false); + _pods[hashedPod] = _updatePodData(clusterId, 0, hashedPod, -1); Cluster memory cluster = _clusters[clusterId]; @@ -354,7 +324,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } { - // // update DAO earnings + // update DAO earnings DAO memory dao = _dao; dao = _updateDAOEarnings(dao); --dao.validatorCount; @@ -367,125 +337,48 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { emit ValidatorRemoved(publicKey, clusterId); } - function deposit(address owner, bytes32 clusterId, uint256 amount) external { - _validateClusterId(clusterId); - _deposit(owner, clusterId, amount.shrink()); - } - - function deposit(bytes32 clusterId, uint256 amount) external { - _validateClusterId(clusterId); - _deposit(msg.sender, clusterId, amount.shrink()); - } - - function getClusterId(uint64[] memory operatorIds) external view returns(bytes32) { - _validateOperatorIds(operatorIds); - - bytes32 clusterId = keccak256(abi.encodePacked(operatorIds)); - - if (_clusters[clusterId].operatorIds.length == 0) { - revert ClusterNotExists(); - } - - return clusterId; - } + function transferValidator( + bytes calldata publicKey, + bytes32 newClusterId, + bytes calldata shares + ) external override { + _validateClusterId(newClusterId); + _validatePublicKey(publicKey); - function registerPod(uint64[] memory operatorIds, uint256 amount) external { - _validateOperatorIds(operatorIds); + uint64[] memory operatorIds = _clusters[newClusterId].operatorIds; - bytes32 clusterId = keccak256(abi.encodePacked(operatorIds)); + bytes32 hashedValidator = keccak256(publicKey); + bytes32 clusterId = _validatorPKs[hashedValidator].clusterId; - if (_clusters[clusterId].operatorIds.length == 0) { - _createClusterUnsafe(clusterId, operatorIds); + if (_validatorPKs[hashedValidator].owner != msg.sender) { + revert ValidatorNotOwned(); } - _deposit(msg.sender, clusterId, amount.shrink()); - } - - function liquidate(address ownerAddress, bytes32 clusterId) external { - _validateClusterId(clusterId); - - uint64[] memory operatorIds = _clusters[clusterId].operatorIds; - bytes32 hashedPod = keccak256(abi.encodePacked(ownerAddress, clusterId)); - { - Pod memory pod = _pods[hashedPod]; - - if (!_liquidatable(pod.disabled, _podBalance(pod, _clusterCurrentIndex(clusterId)), pod.validatorCount, operatorIds)) { - revert PodNotLiquidatable(); - } - - for (uint64 index = 0; index < operatorIds.length; ++index) { - _operators[operatorIds[index]].validatorCount -= pod.validatorCount; - } - - _dao.validatorCount -= pod.validatorCount; - } - - // _token.transfer(msg.sender, pod.usage.balance); - - _pods[hashedPod].disabled = true; - - emit PodLiquidated(ownerAddress, clusterId); - } - - function isLiquidatable(address ownerAddress, bytes32 clusterId) external view override returns (bool) { - _validateClusterId(clusterId); - - uint64[] memory operatorIds = _clusters[clusterId].operatorIds; - bytes32 hashedPod = keccak256(abi.encodePacked(ownerAddress, clusterId)); - - Pod memory pod = _pods[hashedPod]; - - return _liquidatable(pod.disabled, _podBalance(pod, _clusterCurrentIndex(clusterId)), pod.validatorCount, operatorIds); - } - - function isLiquidated(address ownerAddress, bytes32 clusterId) external view override returns (bool) { - _validateClusterId(clusterId); - - bytes32 hashedPod = keccak256(abi.encodePacked(ownerAddress, clusterId)); - - return _pods[hashedPod].disabled; - } - - function reactivatePod(bytes32 clusterId, uint256 amount) external override { - _validateClusterId(clusterId); - - uint64[] memory operatorIds = _clusters[clusterId].operatorIds; - bytes32 hashedPod = keccak256(abi.encodePacked(msg.sender, clusterId)); - - Pod memory pod = _pods[hashedPod]; - - if (!pod.disabled) { - revert PodAlreadyEnabled(); + bytes32 hashedPod = keccak256(abi.encodePacked(msg.sender, clusterId)); + _pods[hashedPod] = _updatePodData(clusterId, 0, hashedPod, -1); } - _deposit(msg.sender, clusterId, amount.shrink()); - { - for (uint64 index = 0; index < operatorIds.length; ++index) { - Operator memory operator = _operators[operatorIds[index]]; - operator.snapshot = _getSnapshot(operator, uint64(block.number)); - operator.validatorCount += pod.validatorCount; - _operators[operatorIds[index]] = operator; - } + _updateOperatorsOnTransfer(_clusters[clusterId].operatorIds, operatorIds, 1); } { - DAO memory dao = _dao; - dao = _updateDAOEarnings(dao); - dao.validatorCount += pod.validatorCount; - _dao = dao; - } - - pod.disabled = false; + Pod memory pod; + { + bytes32 hashedPod = keccak256(abi.encodePacked(msg.sender, newClusterId)); - if(_liquidatable(pod.disabled, _podBalance(pod, _clusterCurrentIndex(clusterId)), pod.validatorCount, operatorIds)) { - revert NotEnoughBalance(); - } + pod = _updatePodData(newClusterId, 0, hashedPod, 1); + _validatorPKs[hashedValidator].clusterId = newClusterId; + _pods[hashedPod] = pod; + } - _pods[hashedPod] = pod; + if (_liquidatable(pod.disabled, _podBalance(pod, _clusterCurrentIndex(newClusterId)), pod.validatorCount, operatorIds)) { + revert NotEnoughBalance(); + } - emit PodEnabled(msg.sender, clusterId); + emit ValidatorTransferred(publicKey, newClusterId, shares); + } } function bulkTransferValidators( @@ -493,7 +386,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { bytes32 fromClusterId, bytes32 toClusterId, bytes[] calldata shares - ) external { + ) external override { _validateClusterId(fromClusterId); _validateClusterId(toClusterId); @@ -501,7 +394,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { revert ParametersMismatch(); } - uint64 activeValidatorCount = 0; + uint32 activeValidatorCount = 0; for (uint64 index = 0; index < publicKeys.length; ++index) { _validatePublicKey(publicKeys[index]); @@ -526,10 +419,6 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { uint64[] memory oldOperatorIds = _clusters[fromClusterId].operatorIds; uint64[] memory newOperatorIds = _clusters[toClusterId].operatorIds; - if (oldOperatorIds.length == 0 || newOperatorIds.length == 0) { - revert InvalidCluster(); - } - _updateOperatorsOnTransfer(oldOperatorIds, newOperatorIds, activeValidatorCount); Pod memory pod = _pods[keccak256(abi.encodePacked(msg.sender, fromClusterId))]; @@ -555,66 +444,226 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } } - // TODO add external functions below to interface + /**************************/ + /* Pod External Functions */ + /**************************/ - // @dev external dao functions + function registerPod(uint64[] memory operatorIds, uint256 amount) external override { + _validateOperatorIds(operatorIds); - function getOperatorFeeIncreaseLimit() external view returns (uint64) { - return _operatorMaxFeeIncrease; - } + bytes32 clusterId = keccak256(abi.encodePacked(operatorIds)); - function getExecuteOperatorFeePeriod() external view returns (uint64) { - return _executeOperatorFeePeriod; - } + if (_clusters[clusterId].operatorIds.length == 0) { + _createClusterUnsafe(clusterId, operatorIds); + } - function getDeclaredOperatorFeePeriod() external view returns (uint64) { - return _declareOperatorFeePeriod; - } + bytes32 hashedPod = keccak256(abi.encodePacked(msg.sender, clusterId)); - function getNetworkFee() external view returns (uint256) { - return _networkFee.expand(); - } + if (_pods[hashedPod].usage.block == 0) { + _pods[hashedPod].usage.block = uint64(block.number); + emit PodCreated(msg.sender, clusterId); + } - function getNetworkBalance() external onlyOwner view returns (uint256) { - DAO memory dao = _dao; - return _networkBalance(dao).expand(); + _deposit(msg.sender, clusterId, amount.shrink()); } - function updateOperatorFeeIncreaseLimit(uint64 newOperatorMaxFeeIncrease) external onlyOwner { - _operatorMaxFeeIncrease = newOperatorMaxFeeIncrease; - emit OperatorFeeIncreaseLimitUpdate(_operatorMaxFeeIncrease); - } + function liquidate(address ownerAddress, bytes32 clusterId) external override { + _validateClusterId(clusterId); - function updateDeclareOperatorFeePeriod(uint64 newDeclareOperatorFeePeriod) external onlyOwner { - _declareOperatorFeePeriod = newDeclareOperatorFeePeriod; - emit DeclareOperatorFeePeriodUpdate(newDeclareOperatorFeePeriod); - } + uint64[] memory operatorIds = _clusters[clusterId].operatorIds; + bytes32 hashedPod = keccak256(abi.encodePacked(ownerAddress, clusterId)); - function updateExecuteOperatorFeePeriod(uint64 newExecuteOperatorFeePeriod) external onlyOwner { - _executeOperatorFeePeriod = newExecuteOperatorFeePeriod; - emit ExecuteOperatorFeePeriodUpdate(newExecuteOperatorFeePeriod); - } + Pod memory pod = _pods[hashedPod]; + uint64 podBalance = _podBalance(pod, _clusterCurrentIndex(clusterId)); // 4k gas usage + { + if (!_liquidatable(pod.disabled, podBalance, pod.validatorCount, operatorIds)) { + revert PodNotLiquidatable(); + } - function updateNetworkFee(uint256 fee) external onlyOwner { - DAO memory dao = _dao; - dao = _updateDAOEarnings(dao); - _dao = dao; + for (uint64 index = 0; index < operatorIds.length; ++index) { // 19k gas usage + uint64 id = operatorIds[index]; + Operator memory operator = _operators[id]; - _updateNetworkFeeIndex(); + if (operator.owner != address(0)) { + operator.snapshot = _getSnapshot(operator, uint64(block.number)); + operator.validatorCount -= pod.validatorCount; + _operators[operatorIds[index]] = operator; + } + } - emit NetworkFeeUpdate(_networkFee.expand(), fee); + { + // update DAO earnings + DAO memory dao = _dao; + dao = _updateDAOEarnings(dao); + dao.validatorCount -= pod.validatorCount; + _dao = dao; + } - _networkFee = fee.shrink(); - } + _token.transfer(msg.sender, podBalance.expand()); + } + + pod.disabled = true; + pod.usage.balance -= podBalance; + + emit PodLiquidated(ownerAddress, clusterId); + + _pods[hashedPod] = pod; + + } + + function reactivatePod(bytes32 clusterId, uint256 amount) external override { + _validateClusterId(clusterId); + + bytes32 hashedPod = keccak256(abi.encodePacked(msg.sender, clusterId)); + Pod memory pod = _pods[hashedPod]; + + if (!pod.disabled) { + revert PodAlreadyEnabled(); + } + + _deposit(msg.sender, clusterId, amount.shrink()); // 28k gas usage + + uint64[] memory operatorIds = _clusters[clusterId].operatorIds; + + { // 112k gas usage + for (uint64 index = 0; index < operatorIds.length; ++index) { + uint64 id = operatorIds[index]; + Operator memory operator = _operators[id]; + + if (operator.owner != address(0)) { + operator.snapshot = _getSnapshot(operator, uint64(block.number)); + operator.validatorCount += pod.validatorCount; + _operators[operatorIds[index]] = operator; + } + } + } + + { // 30k gas usage + DAO memory dao = _dao; + dao = _updateDAOEarnings(dao); + dao.validatorCount += pod.validatorCount; + _dao = dao; + } + + pod.disabled = false; + pod = _updatePodData(clusterId, 0, hashedPod, 0); // 16k gas usage + _pods[hashedPod] = pod; + + emit PodEnabled(msg.sender, clusterId); + } + + /******************************/ + /* Balance External Functions */ + /******************************/ + + function deposit(address owner, bytes32 clusterId, uint256 amount) external override { + _validateClusterId(clusterId); + + _deposit(owner, clusterId, amount.shrink()); + } + + function deposit(bytes32 clusterId, uint256 amount) external override { + _validateClusterId(clusterId); + + _deposit(msg.sender, clusterId, amount.shrink()); + } + + function withdrawOperatorBalance(uint64 operatorId, uint256 amount) external override { + Operator memory operator = _operators[operatorId]; + + if (operator.owner != msg.sender) revert CallerNotOwner(); + + operator.snapshot = _getSnapshot(operator, uint64(block.number)); + + uint64 shrunkAmount = amount.shrink(); + + if (operator.snapshot.balance < shrunkAmount) { + revert NotEnoughBalance(); + } + + operator.snapshot.balance -= shrunkAmount; + + _operators[operatorId] = operator; + + _token.transfer(msg.sender, shrunkAmount); + + emit OperatorFundsWithdrawal(amount.shrink(), operatorId, msg.sender); + } + + function withdrawOperatorBalance(uint64 operatorId) external override { + Operator memory operator = _operators[operatorId]; + + if (operator.owner != msg.sender) revert CallerNotOwner(); + + operator.snapshot = _getSnapshot(operator, uint64(block.number)); + + uint64 operatorBalance = operator.snapshot.balance; + + if (operatorBalance <= 0) { + revert NotEnoughBalance(); + } + + operator.snapshot.balance -= operatorBalance; + + _operators[operatorId] = operator; + + uint256 expandedOperatorBalance = operatorBalance.expand(); + + _token.transfer(msg.sender, expandedOperatorBalance); + + emit OperatorFundsWithdrawal(expandedOperatorBalance, operatorId, msg.sender); + } + + function withdrawPodBalance(bytes32 clusterId, uint256 amount) external override { + _validateClusterId(clusterId); + + bytes32 hashedPod = keccak256(abi.encodePacked(msg.sender, clusterId)); + uint64[] memory operatorIds = _clusters[clusterId].operatorIds; + + Pod memory pod = _pods[hashedPod]; + uint64 podBalance = _podBalance(pod, _clusterCurrentIndex(clusterId)); + + uint64 shrunkAmount = amount.shrink(); + + if (podBalance < shrunkAmount || _liquidatable(pod.disabled, podBalance, pod.validatorCount, operatorIds)) { + revert NotEnoughBalance(); + } + + pod.usage.balance -= shrunkAmount; + + _pods[hashedPod] = pod; + + _token.transfer(msg.sender, amount); + + emit PodFundsWithdrawal(amount, clusterId, msg.sender); + } + + /**************************/ + /* DAO External Functions */ + /**************************/ + + function updateNetworkFee(uint256 fee) external onlyOwner override { + DAO memory dao = _dao; + dao = _updateDAOEarnings(dao); + _dao = dao; + + _updateNetworkFeeIndex(); - function withdrawDAOEarnings(uint256 amount) external onlyOwner { + emit NetworkFeeUpdate(_networkFee.expand(), fee); + + _networkFee = fee.shrink(); + } + + function withdrawDAOEarnings(uint256 amount) external onlyOwner override { DAO memory dao = _dao; - if(amount.shrink() > _networkBalance(dao)) { + uint64 shrunkAmount = amount.shrink(); + + if(shrunkAmount > _networkBalance(dao)) { revert NotEnoughBalance(); } - dao.withdrawn += amount.shrink(); + dao.withdrawn += shrunkAmount; _dao = dao; _token.transfer(msg.sender, amount); @@ -622,32 +671,159 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { emit NetworkFeesWithdrawal(amount, msg.sender); } - // @dev external operators functions + function updateOperatorFeeIncreaseLimit(uint64 newOperatorMaxFeeIncrease) external onlyOwner override { + _operatorMaxFeeIncrease = newOperatorMaxFeeIncrease; + emit OperatorFeeIncreaseLimitUpdate(_operatorMaxFeeIncrease); + } + + function updateDeclareOperatorFeePeriod(uint64 newDeclareOperatorFeePeriod) external onlyOwner override { + _declareOperatorFeePeriod = newDeclareOperatorFeePeriod; + emit DeclareOperatorFeePeriodUpdate(newDeclareOperatorFeePeriod); + } + + function updateExecuteOperatorFeePeriod(uint64 newExecuteOperatorFeePeriod) external onlyOwner override { + _executeOperatorFeePeriod = newExecuteOperatorFeePeriod; + emit ExecuteOperatorFeePeriodUpdate(newExecuteOperatorFeePeriod); + } + + /************************************/ + /* Operator External View Functions */ + /************************************/ + + function getOperatorFee(uint64 operatorId) external view override returns (uint256) { + Operator memory operator = _operators[operatorId]; + + if (operator.owner == address(0)) revert OperatorNotFound(); + + return operator.fee.expand(); + } + + function getOperatorDeclaredFee(uint64 operatorId) external view override returns (uint256, uint256, uint256) { + OperatorFeeChangeRequest memory feeChangeRequest = _operatorFeeChangeRequests[operatorId]; + + if(feeChangeRequest.fee == 0) { + revert NoPendingFeeChangeRequest(); + } + + return (feeChangeRequest.fee.expand(), feeChangeRequest.approvalBeginTime, feeChangeRequest.approvalEndTime); + } + + /*******************************/ + /* Pod External View Functions */ + /*******************************/ + + function getClusterId(uint64[] memory operatorIds) external view override returns(bytes32) { + _validateOperatorIds(operatorIds); + + bytes32 clusterId = keccak256(abi.encodePacked(operatorIds)); + + if (_clusters[clusterId].operatorIds.length == 0) { + revert ClusterNotExists(); + } + + return clusterId; + } + + function isLiquidatable(address ownerAddress, bytes32 clusterId) external view override returns (bool) { + _validateClusterId(clusterId); + + uint64[] memory operatorIds = _clusters[clusterId].operatorIds; + bytes32 hashedPod = keccak256(abi.encodePacked(ownerAddress, clusterId)); + + Pod memory pod = _pods[hashedPod]; + + return _liquidatable(pod.disabled, _podBalance(pod, _clusterCurrentIndex(clusterId)), pod.validatorCount, operatorIds); + } + + function isLiquidated(address ownerAddress, bytes32 clusterId) external view override returns (bool) { + _validateClusterId(clusterId); + + bytes32 hashedPod = keccak256(abi.encodePacked(ownerAddress, clusterId)); + + return _pods[hashedPod].disabled; + } - function operatorSnapshot(uint64 id) external view returns (uint64 currentBlock, uint64 index, uint256 balance) { + /***********************************/ + /* Balance External View Functions */ + /***********************************/ + + function operatorSnapshot(uint64 id) external view override returns (uint64 currentBlock, uint64 index, uint256 balance) { Snapshot memory s = _getSnapshot(_operators[id], uint64(block.number)); return (s.block, s.index, s.balance.expand()); } - // @dev internal dao functions + function podBalanceOf(address owner, bytes32 clusterId) external view override returns (uint256) { + Pod memory pod = _pods[keccak256(abi.encodePacked(owner, clusterId))]; + return _podBalance(pod, _clusterCurrentIndex(clusterId)).expand(); + } + /*******************************/ + /* DAO External View Functions */ + /*******************************/ - // @dev internal operators functions + function getNetworkFee() external view override returns (uint256) { + return _networkFee.expand(); + } - function _getSnapshot(Operator memory operator, uint64 currentBlock) private pure returns (Snapshot memory) { - uint64 blockDiffFee = (currentBlock - operator.snapshot.block) * operator.fee; + function getNetworkBalance() external view onlyOwner override returns (uint256) { + DAO memory dao = _dao; + return _networkBalance(dao).expand(); + } - operator.snapshot.index += blockDiffFee; - operator.snapshot.balance += blockDiffFee * operator.validatorCount; - operator.snapshot.block = currentBlock; + function getOperatorFeeIncreaseLimit() external view override returns (uint64) { + return _operatorMaxFeeIncrease; + } - return operator.snapshot; + function getExecuteOperatorFeePeriod() external view override returns (uint64) { + return _executeOperatorFeePeriod; + } + + function getDeclaredOperatorFeePeriod() external view override returns (uint64) { + return _declareOperatorFeePeriod; + } + + /********************************/ + /* Validation Private Functions */ + /********************************/ + + function _onlyOperatorOwnerOrContractOwner(uint64 operatorId) private view { + Operator memory operator = _operators[operatorId]; + + if(operator.owner == address(0)) { + revert OperatorWithPublicKeyNotExist(); + } + + if(msg.sender != operator.owner && msg.sender != owner()) { + revert CallerNotOwner(); + } } + function _validateClusterId(bytes32 clusterId) private view { + if (_clusters[clusterId].operatorIds.length == 0) { + revert ClusterNotExists(); + } + } + + function _validatePublicKey(bytes memory publicKey) private pure { + if (publicKey.length != 48) { + revert InvalidPublicKeyLength(); + } + } + + function _validateOperatorIds(uint64[] memory operatorIds) private pure { + if (operatorIds.length < 4 || operatorIds.length > 13 || operatorIds.length % 3 != 1) { + revert OperatorIdsStructureInvalid(); + } + } + + /******************************/ + /* Operator Private Functions */ + /******************************/ + function _updateOperatorsOnTransfer( uint64[] memory oldOperatorIds, uint64[] memory newOperatorIds, - uint64 validatorCount + uint32 validatorCount ) private { uint64 oldIndex; uint64 newIndex; @@ -656,15 +832,19 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { while (oldIndex < oldOperatorIds.length && newIndex < newOperatorIds.length) { if (oldOperatorIds[oldIndex] < newOperatorIds[newIndex]) { Operator memory operator = _operators[oldOperatorIds[oldIndex]]; - operator.snapshot = _getSnapshot(operator, currentBlock); - operator.validatorCount -= validatorCount; - _operators[oldOperatorIds[oldIndex]] = operator; + if (operator.owner != address(0)) { + operator.snapshot = _getSnapshot(operator, currentBlock); + operator.validatorCount -= validatorCount; + _operators[oldOperatorIds[oldIndex]] = operator; + } ++oldIndex; } else if (newOperatorIds[newIndex] < oldOperatorIds[oldIndex]) { Operator memory operator = _operators[newOperatorIds[newIndex]]; - operator.snapshot = _getSnapshot(operator, currentBlock); - operator.validatorCount += validatorCount; - _operators[newOperatorIds[newIndex]] = operator; + if (operator.owner != address(0)) { + operator.snapshot = _getSnapshot(operator, currentBlock); + operator.validatorCount += validatorCount; + _operators[newOperatorIds[newIndex]] = operator; + } ++newIndex; } else { ++oldIndex; @@ -674,17 +854,21 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { while (oldIndex < oldOperatorIds.length) { Operator memory operator = _operators[oldOperatorIds[oldIndex]]; - operator.snapshot = _getSnapshot(operator, currentBlock); - operator.validatorCount -= validatorCount; - _operators[oldOperatorIds[oldIndex]] = operator; + if (operator.owner != address(0)) { + operator.snapshot = _getSnapshot(operator, currentBlock); + operator.validatorCount -= validatorCount; + _operators[oldOperatorIds[oldIndex]] = operator; + } ++oldIndex; } while (newIndex < newOperatorIds.length) { Operator memory operator = _operators[newOperatorIds[newIndex]]; - operator.snapshot = _getSnapshot(operator, currentBlock); - operator.validatorCount += validatorCount; - _operators[newOperatorIds[newIndex]] = operator; + if (operator.owner != address(0)) { + operator.snapshot = _getSnapshot(operator, currentBlock); + operator.validatorCount += validatorCount; + _operators[newOperatorIds[newIndex]] = operator; + } ++newIndex; } } @@ -696,7 +880,42 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { return operator; } - function _updatePodData(bytes32 clusterId, uint64 amount, bytes32 hashedPod, bool increase) private view returns (Pod memory) { + function _updateOperatorFeeUnsafe(uint64 operatorId, uint64 fee) private { + Operator memory operator = _operators[operatorId]; + + _operators[operatorId] = _setFee(operator, fee); + + emit OperatorFeeExecution(msg.sender, operatorId, block.number, fee.expand()); + } + + function _getSnapshot(Operator memory operator, uint64 currentBlock) private pure returns (Snapshot memory) { + uint64 blockDiffFee = (currentBlock - operator.snapshot.block) * operator.fee; + + operator.snapshot.index += blockDiffFee; + operator.snapshot.balance += blockDiffFee * operator.validatorCount; + operator.snapshot.block = currentBlock; + + return operator.snapshot; + } + + /*************************/ + /* Pod Private Functions */ + /*************************/ + + function _createClusterUnsafe(bytes32 key, uint64[] memory operatorIds) private { + for (uint64 i = 0; i < operatorIds.length; i++) { + if (_operators[operatorIds[i]].owner == address(0)) { + revert OperatorDoesNotExist(); + } + if (i+1 < operatorIds.length) { + require(operatorIds[i] <= operatorIds[i+1], "The operators list should be in ascending order"); + } + } + + _clusters[key] = Cluster({operatorIds: operatorIds}); + } + + function _updatePodData(bytes32 clusterId, uint64 amount, bytes32 hashedPod, int8 changedTo) private view returns (Pod memory) { Pod memory pod = _pods[hashedPod]; uint64 podIndex = _clusterCurrentIndex(clusterId); pod.usage.balance = _podBalance(pod, podIndex) + amount; @@ -706,45 +925,39 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { pod.networkFee = _podNetworkFee(pod); pod.networkFeeIndex = _currentNetworkFeeIndex(); - if (increase) { + if (changedTo == 1) { ++pod.validatorCount; - } else { + } else if (changedTo == -1) { --pod.validatorCount; } return pod; } - function podBalanceOf(address owner, bytes32 clusterId) external view returns (uint256) { - Pod memory pod = _pods[keccak256(abi.encodePacked(owner, clusterId))]; - return _podBalance(pod, _clusterCurrentIndex(clusterId)).expand(); + function _liquidatable(bool disabled, uint64 balance, uint64 validatorCount, uint64[] memory operatorIds) private view returns (bool) { + return !disabled && balance < LIQUIDATION_MIN_BLOCKS * (_burnRatePerValidator(operatorIds) + _networkFee) * validatorCount; } + + /*****************************/ + /* Balance Private Functions */ + /*****************************/ + function _deposit(address owner, bytes32 clusterId, uint64 amount) private { - Pod memory pod = _pods[keccak256(abi.encodePacked(owner, clusterId))]; + bytes32 hashedPod = keccak256(abi.encodePacked(owner, clusterId)); - if (pod.usage.block == 0) { - pod.usage.block = uint64(block.number); - emit PodCreated(owner, clusterId); - } - if (amount > 0) { - pod.usage.balance += amount; - } + _pods[hashedPod].usage.balance += amount; // 22k gas usage - _pods[keccak256(abi.encodePacked(owner, clusterId))] = pod; - } + uint256 expandedAmount = amount.expand(); - function _createClusterUnsafe(bytes32 key, uint64[] memory operatorIds) private { - for (uint64 i = 0; i < operatorIds.length; i++) { - if (_operators[operatorIds[i]].owner == address(0)) { - revert OperatorDoesNotExist(); - } - if (i+1 < operatorIds.length) { - require(operatorIds[i] <= operatorIds[i+1]); - } - } + _token.transferFrom(msg.sender, address(this), expandedAmount); // 20k gas usage - _clusters[key] = Cluster({operatorIds: operatorIds}); + emit FundsDeposit(expandedAmount, clusterId, owner); // 2k gas usage + } + + function _updateNetworkFeeIndex() private { + _networkFeeIndex = _currentNetworkFeeIndex(); + _networkFeeIndexBlockNumber = uint64(block.number); } function _updateDAOEarnings(DAO memory dao) private view returns (DAO memory) { @@ -754,12 +967,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { return dao; } - function _updateNetworkFeeIndex() private { - _networkFeeIndex = _currentNetworkFeeIndex(); - _networkFeeIndexBlockNumber = uint64(block.number); - } - - function _currentNetworkFeeIndex() private view returns(uint64) { + function _currentNetworkFeeIndex() private view returns (uint64) { return _networkFeeIndex + uint64(block.number - _networkFeeIndexBlockNumber) * _networkFee; } @@ -799,46 +1007,4 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { rate += _operators[operatorIds[i]].fee; } } - - function _liquidatable(bool disabled, uint64 balance, uint64 validatorCount, uint64[] memory operatorIds) private view returns (bool) { - return !disabled && balance < LIQUIDATION_MIN_BLOCKS * (_burnRatePerValidator(operatorIds) + _networkFee) * validatorCount; - } - - function _updateOperatorFeeUnsafe(uint64 operatorId, uint64 fee) private { - Operator memory operator = _operators[operatorId]; - - _operators[operatorId] = _setFee(operator, fee); - - emit OperatorFeeExecution(msg.sender, operatorId, block.number, fee.expand()); - } - - function _onlyOperatorOwnerOrContractOwner(uint64 operatorId) private view { - Operator memory operator = _operators[operatorId]; - - if(operator.owner == address(0)) { - revert OperatorWithPublicKeyNotExist(); - } - - if(msg.sender != operator.owner && msg.sender != owner()) { - revert CallerNotOwner(); - } - } - - function _validateClusterId(bytes32 clusterId) private view { - if (_clusters[clusterId].operatorIds.length == 0) { - revert ClusterNotExists(); - } - } - - function _validatePublicKey(bytes memory publicKey) private pure { - if (publicKey.length != 48) { - revert InvalidPublicKeyLength(); - } - } - - function _validateOperatorIds(uint64[] memory operatorIds) private pure { - if (operatorIds.length < 4 || operatorIds.length > 13 || operatorIds.length % 3 != 1) { - revert OperatorIdsStructureInvalid(); - } - } } diff --git a/package-lock.json b/package-lock.json index d3afd37a..74dd6a57 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,12 +28,12 @@ "ethereum-waffle": "^3.4.4", "ethers": "^5.6.2", "gh-pages": "^3.2.3", - "hardhat": "^2.9.2", - "hardhat-gas-reporter": "^1.0.8", - "hardhat-tracer": "^1.1.0-rc.3", + "hardhat": "^2.12.2", + "hardhat-gas-reporter": "^1.0.9", + "hardhat-tracer": "^1.1.1", "prompts": "^2.4.2", "simple-git": "^3.10.0", - "solidity-coverage": "^0.7.20", + "solidity-coverage": "^0.8.2", "ts-node": "^10.7.0", "typechain": "^3.0.0", "typescript": "^4.6.3" @@ -52,9 +52,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz", - "integrity": "sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==", + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", "dev": true, "engines": { "node": ">=6.9.0" @@ -115,6 +115,15 @@ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, + "node_modules/@babel/highlight/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/highlight/node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -136,22 +145,13 @@ "node": ">=4" } }, - "node_modules/@cspotcode/source-map-consumer": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", - "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", - "dev": true, - "engines": { - "node": ">= 12" - } - }, "node_modules/@cspotcode/source-map-support": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", - "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", + "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, "dependencies": { - "@cspotcode/source-map-consumer": "0.8.0" + "@jridgewell/trace-mapping": "0.3.9" }, "engines": { "node": ">=12" @@ -174,7 +174,7 @@ "node_modules/@ensdomains/ens/node_modules/ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", "dev": true, "engines": { "node": ">=0.10.0" @@ -183,7 +183,7 @@ "node_modules/@ensdomains/ens/node_modules/camelcase": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", + "integrity": "sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg==", "dev": true, "engines": { "node": ">=0.10.0" @@ -192,7 +192,7 @@ "node_modules/@ensdomains/ens/node_modules/cliui": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "integrity": "sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w==", "dev": true, "dependencies": { "string-width": "^1.0.1", @@ -203,7 +203,7 @@ "node_modules/@ensdomains/ens/node_modules/find-up": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "integrity": "sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==", "dev": true, "dependencies": { "path-exists": "^2.0.0", @@ -216,7 +216,7 @@ "node_modules/@ensdomains/ens/node_modules/fs-extra": { "version": "0.30.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", - "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", + "integrity": "sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==", "dev": true, "dependencies": { "graceful-fs": "^4.1.2", @@ -235,7 +235,7 @@ "node_modules/@ensdomains/ens/node_modules/is-fullwidth-code-point": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", "dev": true, "dependencies": { "number-is-nan": "^1.0.0" @@ -247,7 +247,7 @@ "node_modules/@ensdomains/ens/node_modules/jsonfile": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "integrity": "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==", "dev": true, "optionalDependencies": { "graceful-fs": "^4.1.6" @@ -256,7 +256,7 @@ "node_modules/@ensdomains/ens/node_modules/load-json-file": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "integrity": "sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A==", "dev": true, "dependencies": { "graceful-fs": "^4.1.2", @@ -272,7 +272,7 @@ "node_modules/@ensdomains/ens/node_modules/parse-json": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==", "dev": true, "dependencies": { "error-ex": "^1.2.0" @@ -284,7 +284,7 @@ "node_modules/@ensdomains/ens/node_modules/path-exists": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "integrity": "sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==", "dev": true, "dependencies": { "pinkie-promise": "^2.0.0" @@ -296,7 +296,7 @@ "node_modules/@ensdomains/ens/node_modules/path-type": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "integrity": "sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg==", "dev": true, "dependencies": { "graceful-fs": "^4.1.2", @@ -310,7 +310,7 @@ "node_modules/@ensdomains/ens/node_modules/pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", "dev": true, "engines": { "node": ">=0.10.0" @@ -319,7 +319,7 @@ "node_modules/@ensdomains/ens/node_modules/read-pkg": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "integrity": "sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ==", "dev": true, "dependencies": { "load-json-file": "^1.0.0", @@ -333,7 +333,7 @@ "node_modules/@ensdomains/ens/node_modules/read-pkg-up": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "integrity": "sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A==", "dev": true, "dependencies": { "find-up": "^1.0.0", @@ -346,12 +346,24 @@ "node_modules/@ensdomains/ens/node_modules/require-from-string": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-1.2.1.tgz", - "integrity": "sha1-UpyczvJzgK3+yaL5ZbZJu+5jZBg=", + "integrity": "sha512-H7AkJWMobeskkttHyhTVtS0fxpFLjxhbfMa6Bk3wimP7sdPRGL3EyCg3sAQenFfAe+xQ+oAc85Nmtvq0ROM83Q==", "dev": true, "engines": { "node": ">=0.10.0" } }, + "node_modules/@ensdomains/ens/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, "node_modules/@ensdomains/ens/node_modules/semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", @@ -380,7 +392,7 @@ "node_modules/@ensdomains/ens/node_modules/string-width": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", "dev": true, "dependencies": { "code-point-at": "^1.0.0", @@ -394,7 +406,7 @@ "node_modules/@ensdomains/ens/node_modules/strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", "dev": true, "dependencies": { "ansi-regex": "^2.0.0" @@ -406,7 +418,7 @@ "node_modules/@ensdomains/ens/node_modules/strip-bom": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "integrity": "sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==", "dev": true, "dependencies": { "is-utf8": "^0.2.0" @@ -418,7 +430,7 @@ "node_modules/@ensdomains/ens/node_modules/wrap-ansi": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "integrity": "sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==", "dev": true, "dependencies": { "string-width": "^1.0.1", @@ -437,7 +449,7 @@ "node_modules/@ensdomains/ens/node_modules/yargs": { "version": "4.8.1", "resolved": "https://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz", - "integrity": "sha1-wMQpJMpKqmsObaFznfshZDn53cA=", + "integrity": "sha512-LqodLrnIDM3IFT+Hf/5sxBnEGECrfdC1uIbgZeJmESCSo4HoCAaKEus8MylXHAkdacGc0ye+Qa+dpkuom8uVYA==", "dev": true, "dependencies": { "cliui": "^3.2.0", @@ -459,7 +471,7 @@ "node_modules/@ensdomains/ens/node_modules/yargs-parser": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz", - "integrity": "sha1-hVaN488VD/SfpRgl8DqMiA3cxcQ=", + "integrity": "sha512-9pIKIJhnI5tonzG6OnCFlz/yln8xHYcGl+pn3xR0Vzff0vzN1PbNRaelgfgRUwZ3s4i3jvxT9WhmUGL4whnasA==", "dev": true, "dependencies": { "camelcase": "^3.0.0", @@ -474,9 +486,9 @@ "dev": true }, "node_modules/@eslint/eslintrc": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.1.tgz", - "integrity": "sha512-OhSY22oQQdw3zgPOOwdoj01l/Dzl1Z+xyUP33tkSN+aqyEhymJCcPHyXt+ylW8FSe0TfRC2VG+ROQOapD0aZSQ==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", + "integrity": "sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==", "dev": true, "dependencies": { "ajv": "^6.12.4", @@ -496,73 +508,6 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/@eslint/eslintrc/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/@eslint/eslintrc/node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@eslint/eslintrc/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/@eslint/eslintrc/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/@eslint/eslintrc/node_modules/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, - "engines": { - "node": ">=4" - } - }, - "node_modules/@eslint/eslintrc/node_modules/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, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@ethereum-waffle/chai": { "version": "3.4.4", "resolved": "https://registry.npmjs.org/@ethereum-waffle/chai/-/chai-3.4.4.tgz", @@ -641,100 +586,10 @@ "node": ">=10.0" } }, - "node_modules/@ethereumjs/block": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/@ethereumjs/block/-/block-3.6.2.tgz", - "integrity": "sha512-mOqYWwMlAZpYUEOEqt7EfMFuVL2eyLqWWIzcf4odn6QgXY8jBI2NhVuJncrMCKeMZrsJAe7/auaRRB6YcdH+Qw==", - "dev": true, - "dependencies": { - "@ethereumjs/common": "^2.6.3", - "@ethereumjs/tx": "^3.5.1", - "ethereumjs-util": "^7.1.4", - "merkle-patricia-tree": "^4.2.4" - } - }, - "node_modules/@ethereumjs/blockchain": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/@ethereumjs/blockchain/-/blockchain-5.5.2.tgz", - "integrity": "sha512-Jz26iJmmsQtngerW6r5BDFaew/f2mObLrRZo3rskLOx1lmtMZ8+TX/vJexmivrnWgmAsTdNWhlKUYY4thPhPig==", - "dev": true, - "dependencies": { - "@ethereumjs/block": "^3.6.2", - "@ethereumjs/common": "^2.6.3", - "@ethereumjs/ethash": "^1.1.0", - "debug": "^4.3.3", - "ethereumjs-util": "^7.1.4", - "level-mem": "^5.0.1", - "lru-cache": "^5.1.1", - "semaphore-async-await": "^1.5.1" - } - }, - "node_modules/@ethereumjs/common": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-2.6.3.tgz", - "integrity": "sha512-mQwPucDL7FDYIg9XQ8DL31CnIYZwGhU5hyOO5E+BMmT71G0+RHvIT5rIkLBirJEKxV6+Rcf9aEIY0kXInxUWpQ==", - "dev": true, - "dependencies": { - "crc-32": "^1.2.0", - "ethereumjs-util": "^7.1.4" - } - }, - "node_modules/@ethereumjs/ethash": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@ethereumjs/ethash/-/ethash-1.1.0.tgz", - "integrity": "sha512-/U7UOKW6BzpA+Vt+kISAoeDie1vAvY4Zy2KF5JJb+So7+1yKmJeJEHOGSnQIj330e9Zyl3L5Nae6VZyh2TJnAA==", - "dev": true, - "dependencies": { - "@ethereumjs/block": "^3.5.0", - "@types/levelup": "^4.3.0", - "buffer-xor": "^2.0.1", - "ethereumjs-util": "^7.1.1", - "miller-rabin": "^4.0.0" - } - }, - "node_modules/@ethereumjs/ethash/node_modules/buffer-xor": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-2.0.2.tgz", - "integrity": "sha512-eHslX0bin3GB+Lx2p7lEYRShRewuNZL3fUl4qlVJGGiwoPGftmt8JQgk2Y9Ji5/01TnVDo33E5b5O3vUB1HdqQ==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.1.1" - } - }, - "node_modules/@ethereumjs/tx": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-3.5.1.tgz", - "integrity": "sha512-xzDrTiu4sqZXUcaBxJ4n4W5FrppwxLxZB4ZDGVLtxSQR4lVuOnFR6RcUHdg1mpUhAPVrmnzLJpxaeXnPxIyhWA==", - "dev": true, - "dependencies": { - "@ethereumjs/common": "^2.6.3", - "ethereumjs-util": "^7.1.4" - } - }, - "node_modules/@ethereumjs/vm": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethereumjs/vm/-/vm-5.8.0.tgz", - "integrity": "sha512-mn2G2SX79QY4ckVvZUfxlNUpzwT2AEIkvgJI8aHoQaNYEHhH8rmdVDIaVVgz6//PjK52BZsK23afz+WvSR0Qqw==", - "dev": true, - "dependencies": { - "@ethereumjs/block": "^3.6.2", - "@ethereumjs/blockchain": "^5.5.2", - "@ethereumjs/common": "^2.6.3", - "@ethereumjs/tx": "^3.5.1", - "async-eventemitter": "^0.2.4", - "core-js-pure": "^3.0.1", - "debug": "^4.3.3", - "ethereumjs-util": "^7.1.4", - "functional-red-black-tree": "^1.0.1", - "mcl-wasm": "^0.7.1", - "merkle-patricia-tree": "^4.2.4", - "rustbn.js": "~0.2.0" - } - }, "node_modules/@ethersproject/abi": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.6.0.tgz", - "integrity": "sha512-AhVByTwdXCc2YQ20v300w6KVHle9g2OFc28ZAFCPnJyEpkv1xKXjZcSTgWOlv1i+0dqlgF8RCF2Rn2KC1t+1Vg==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz", + "integrity": "sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==", "dev": true, "funding": [ { @@ -747,21 +602,21 @@ } ], "dependencies": { - "@ethersproject/address": "^5.6.0", - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/constants": "^5.6.0", - "@ethersproject/hash": "^5.6.0", - "@ethersproject/keccak256": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/strings": "^5.6.0" + "@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" } }, "node_modules/@ethersproject/abstract-provider": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.6.0.tgz", - "integrity": "sha512-oPMFlKLN+g+y7a79cLK3WiLcjWFnZQtXWgnLAbHZcN3s7L4v90UHpTOrLk+m3yr0gt+/h9STTM6zrr7PM8uoRw==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz", + "integrity": "sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==", "dev": true, "funding": [ { @@ -774,19 +629,19 @@ } ], "dependencies": { - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/networks": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/transactions": "^5.6.0", - "@ethersproject/web": "^5.6.0" + "@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" } }, "node_modules/@ethersproject/abstract-signer": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.6.0.tgz", - "integrity": "sha512-WOqnG0NJKtI8n0wWZPReHtaLkDByPL67tn4nBaDAhmVq8sjHTPbCdz4DRhVu/cfTOvfy9w3iq5QZ7BX7zw56BQ==", + "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, "funding": [ { @@ -799,17 +654,17 @@ } ], "dependencies": { - "@ethersproject/abstract-provider": "^5.6.0", - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0" + "@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" } }, "node_modules/@ethersproject/address": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.6.0.tgz", - "integrity": "sha512-6nvhYXjbXsHPS+30sHZ+U4VMagFC/9zAk6Gd/h3S21YW4+yfb0WfRtaAIZ4kfM4rrVwqiy284LP0GtL5HXGLxQ==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz", + "integrity": "sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==", "dev": true, "funding": [ { @@ -822,17 +677,17 @@ } ], "dependencies": { - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/keccak256": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/rlp": "^5.6.0" + "@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" } }, "node_modules/@ethersproject/base64": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.6.0.tgz", - "integrity": "sha512-2Neq8wxJ9xHxCF9TUgmKeSh9BXJ6OAxWfeGWvbauPh8FuHEjamgHilllx8KkSd5ErxyHIX7Xv3Fkcud2kY9ezw==", + "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, "funding": [ { @@ -845,13 +700,13 @@ } ], "dependencies": { - "@ethersproject/bytes": "^5.6.0" + "@ethersproject/bytes": "^5.7.0" } }, "node_modules/@ethersproject/basex": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.6.0.tgz", - "integrity": "sha512-qN4T+hQd/Md32MoJpc69rOwLYRUXwjTlhHDIeUkUmiN/JyWkkLLMoG0TqvSQKNqZOMgN5stbUYN6ILC+eD7MEQ==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.7.0.tgz", + "integrity": "sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw==", "dev": true, "funding": [ { @@ -864,14 +719,14 @@ } ], "dependencies": { - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/properties": "^5.6.0" + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/properties": "^5.7.0" } }, "node_modules/@ethersproject/bignumber": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.6.0.tgz", - "integrity": "sha512-VziMaXIUHQlHJmkv1dlcd6GY2PmT0khtAqaMctCIDogxkrarMzA9L94KN1NeXqqOfFD6r0sJT3vCTOFSmZ07DA==", + "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, "funding": [ { @@ -884,15 +739,15 @@ } ], "dependencies": { - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "bn.js": "^4.11.9" + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "bn.js": "^5.2.1" } }, "node_modules/@ethersproject/bytes": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.6.1.tgz", - "integrity": "sha512-NwQt7cKn5+ZE4uDn+X5RAXLp46E1chXoaMmrxAyA0rblpxz8t58lVkrHXoRIn0lz1joQElQ8410GqhTqMOwc6g==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz", + "integrity": "sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==", "dev": true, "funding": [ { @@ -905,13 +760,13 @@ } ], "dependencies": { - "@ethersproject/logger": "^5.6.0" + "@ethersproject/logger": "^5.7.0" } }, "node_modules/@ethersproject/constants": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.6.0.tgz", - "integrity": "sha512-SrdaJx2bK0WQl23nSpV/b1aq293Lh0sUaZT/yYKPDKn4tlAbkH96SPJwIhwSwTsoQQZxuh1jnqsKwyymoiBdWA==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.7.0.tgz", + "integrity": "sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==", "dev": true, "funding": [ { @@ -924,13 +779,13 @@ } ], "dependencies": { - "@ethersproject/bignumber": "^5.6.0" + "@ethersproject/bignumber": "^5.7.0" } }, "node_modules/@ethersproject/contracts": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.6.0.tgz", - "integrity": "sha512-74Ge7iqTDom0NX+mux8KbRUeJgu1eHZ3iv6utv++sLJG80FVuU9HnHeKVPfjd9s3woFhaFoQGf3B3iH/FrQmgw==", + "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, "funding": [ { @@ -943,22 +798,22 @@ } ], "dependencies": { - "@ethersproject/abi": "^5.6.0", - "@ethersproject/abstract-provider": "^5.6.0", - "@ethersproject/abstract-signer": "^5.6.0", - "@ethersproject/address": "^5.6.0", - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/constants": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/transactions": "^5.6.0" + "@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/@ethersproject/hash": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.6.0.tgz", - "integrity": "sha512-fFd+k9gtczqlr0/BruWLAu7UAOas1uRRJvOR84uDf4lNZ+bTkGl366qvniUZHKtlqxBRU65MkOobkmvmpHU+jA==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz", + "integrity": "sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==", "dev": true, "funding": [ { @@ -971,20 +826,21 @@ } ], "dependencies": { - "@ethersproject/abstract-signer": "^5.6.0", - "@ethersproject/address": "^5.6.0", - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/keccak256": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/strings": "^5.6.0" + "@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" } }, "node_modules/@ethersproject/hdnode": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.6.0.tgz", - "integrity": "sha512-61g3Jp3nwDqJcL/p4nugSyLrpl/+ChXIOtCEM8UDmWeB3JCAt5FoLdOMXQc3WWkc0oM2C0aAn6GFqqMcS/mHTw==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.7.0.tgz", + "integrity": "sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==", "dev": true, "funding": [ { @@ -997,24 +853,24 @@ } ], "dependencies": { - "@ethersproject/abstract-signer": "^5.6.0", - "@ethersproject/basex": "^5.6.0", - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/pbkdf2": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/sha2": "^5.6.0", - "@ethersproject/signing-key": "^5.6.0", - "@ethersproject/strings": "^5.6.0", - "@ethersproject/transactions": "^5.6.0", - "@ethersproject/wordlists": "^5.6.0" + "@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" } }, "node_modules/@ethersproject/json-wallets": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.6.0.tgz", - "integrity": "sha512-fmh86jViB9r0ibWXTQipxpAGMiuxoqUf78oqJDlCAJXgnJF024hOOX7qVgqsjtbeoxmcLwpPsXNU0WEe/16qPQ==", + "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, "funding": [ { @@ -1027,25 +883,25 @@ } ], "dependencies": { - "@ethersproject/abstract-signer": "^5.6.0", - "@ethersproject/address": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/hdnode": "^5.6.0", - "@ethersproject/keccak256": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/pbkdf2": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/random": "^5.6.0", - "@ethersproject/strings": "^5.6.0", - "@ethersproject/transactions": "^5.6.0", + "@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" } }, "node_modules/@ethersproject/keccak256": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.6.0.tgz", - "integrity": "sha512-tk56BJ96mdj/ksi7HWZVWGjCq0WVl/QvfhFQNeL8fxhBlGoP+L80uDCiQcpJPd+2XxkivS3lwRm3E0CXTfol0w==", + "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, "funding": [ { @@ -1058,20 +914,14 @@ } ], "dependencies": { - "@ethersproject/bytes": "^5.6.0", + "@ethersproject/bytes": "^5.7.0", "js-sha3": "0.8.0" } }, - "node_modules/@ethersproject/keccak256/node_modules/js-sha3": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", - "dev": true - }, "node_modules/@ethersproject/logger": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.6.0.tgz", - "integrity": "sha512-BiBWllUROH9w+P21RzoxJKzqoqpkyM1pRnEKG69bulE9TSQD8SAIvTQqIMZmmCO8pUNkgLP1wndX1gKghSpBmg==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.7.0.tgz", + "integrity": "sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==", "dev": true, "funding": [ { @@ -1085,9 +935,9 @@ ] }, "node_modules/@ethersproject/networks": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.6.1.tgz", - "integrity": "sha512-b2rrupf3kCTcc3jr9xOWBuHylSFtbpJf79Ga7QR98ienU2UqGimPGEsYMgbI29KHJfA5Us89XwGVmxrlxmSrMg==", + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.1.tgz", + "integrity": "sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==", "dev": true, "funding": [ { @@ -1100,13 +950,13 @@ } ], "dependencies": { - "@ethersproject/logger": "^5.6.0" + "@ethersproject/logger": "^5.7.0" } }, "node_modules/@ethersproject/pbkdf2": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.6.0.tgz", - "integrity": "sha512-Wu1AxTgJo3T3H6MIu/eejLFok9TYoSdgwRr5oGY1LTLfmGesDoSx05pemsbrPT2gG4cQME+baTSCp5sEo2erZQ==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz", + "integrity": "sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw==", "dev": true, "funding": [ { @@ -1119,14 +969,14 @@ } ], "dependencies": { - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/sha2": "^5.6.0" + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/sha2": "^5.7.0" } }, "node_modules/@ethersproject/properties": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.6.0.tgz", - "integrity": "sha512-szoOkHskajKePTJSZ46uHUWWkbv7TzP2ypdEK6jGMqJaEt2sb0jCgfBo0gH0m2HBpRixMuJ6TBRaQCF7a9DoCg==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.7.0.tgz", + "integrity": "sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==", "dev": true, "funding": [ { @@ -1139,13 +989,13 @@ } ], "dependencies": { - "@ethersproject/logger": "^5.6.0" + "@ethersproject/logger": "^5.7.0" } }, "node_modules/@ethersproject/providers": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.6.2.tgz", - "integrity": "sha512-6/EaFW/hNWz+224FXwl8+HdMRzVHt8DpPmu5MZaIQqx/K/ELnC9eY236SMV7mleCM3NnEArFwcAAxH5kUUgaRg==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.2.tgz", + "integrity": "sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg==", "dev": true, "funding": [ { @@ -1158,31 +1008,32 @@ } ], "dependencies": { - "@ethersproject/abstract-provider": "^5.6.0", - "@ethersproject/abstract-signer": "^5.6.0", - "@ethersproject/address": "^5.6.0", - "@ethersproject/basex": "^5.6.0", - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/constants": "^5.6.0", - "@ethersproject/hash": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/networks": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/random": "^5.6.0", - "@ethersproject/rlp": "^5.6.0", - "@ethersproject/sha2": "^5.6.0", - "@ethersproject/strings": "^5.6.0", - "@ethersproject/transactions": "^5.6.0", - "@ethersproject/web": "^5.6.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/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" } }, "node_modules/@ethersproject/random": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.6.0.tgz", - "integrity": "sha512-si0PLcLjq+NG/XHSZz90asNf+YfKEqJGVdxoEkSukzbnBgC8rydbgbUgBbBGLeHN4kAJwUFEKsu3sCXT93YMsw==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.7.0.tgz", + "integrity": "sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ==", "dev": true, "funding": [ { @@ -1195,14 +1046,14 @@ } ], "dependencies": { - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/logger": "^5.6.0" + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0" } }, "node_modules/@ethersproject/rlp": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.6.0.tgz", - "integrity": "sha512-dz9WR1xpcTL+9DtOT/aDO+YyxSSdO8YIS0jyZwHHSlAmnxA6cKU3TrTd4Xc/bHayctxTgGLYNuVVoiXE4tTq1g==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.7.0.tgz", + "integrity": "sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==", "dev": true, "funding": [ { @@ -1215,14 +1066,14 @@ } ], "dependencies": { - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/logger": "^5.6.0" + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0" } }, "node_modules/@ethersproject/sha2": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.6.0.tgz", - "integrity": "sha512-1tNWCPFLu1n3JM9t4/kytz35DkuF9MxqkGGEHNauEbaARdm2fafnOyw1s0tIQDPKF/7bkP1u3dbrmjpn5CelyA==", + "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, "funding": [ { @@ -1235,15 +1086,15 @@ } ], "dependencies": { - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/logger": "^5.6.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", "hash.js": "1.1.7" } }, "node_modules/@ethersproject/signing-key": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.6.0.tgz", - "integrity": "sha512-S+njkhowmLeUu/r7ir8n78OUKx63kBdMCPssePS89So1TH4hZqnWFsThEd/GiXYp9qMxVrydf7KdM9MTGPFukA==", + "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, "funding": [ { @@ -1256,18 +1107,18 @@ } ], "dependencies": { - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "bn.js": "^4.11.9", + "@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" } }, "node_modules/@ethersproject/solidity": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.6.0.tgz", - "integrity": "sha512-YwF52vTNd50kjDzqKaoNNbC/r9kMDPq3YzDWmsjFTRBcIF1y4JCQJ8gB30wsTfHbaxgxelI5BfxQSxD/PbJOww==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.7.0.tgz", + "integrity": "sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA==", "dev": true, "funding": [ { @@ -1280,18 +1131,18 @@ } ], "dependencies": { - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/keccak256": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/sha2": "^5.6.0", - "@ethersproject/strings": "^5.6.0" + "@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/@ethersproject/strings": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.6.0.tgz", - "integrity": "sha512-uv10vTtLTZqrJuqBZR862ZQjTIa724wGPWQqZrofaPI/kUsf53TBG0I0D+hQ1qyNtllbNzaW+PDPHHUI6/65Mg==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.7.0.tgz", + "integrity": "sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==", "dev": true, "funding": [ { @@ -1304,15 +1155,15 @@ } ], "dependencies": { - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/constants": "^5.6.0", - "@ethersproject/logger": "^5.6.0" + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0" } }, "node_modules/@ethersproject/transactions": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.6.0.tgz", - "integrity": "sha512-4HX+VOhNjXHZyGzER6E/LVI2i6lf9ejYeWD6l4g50AdmimyuStKc39kvKf1bXWQMg7QNVh+uC7dYwtaZ02IXeg==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.7.0.tgz", + "integrity": "sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==", "dev": true, "funding": [ { @@ -1325,21 +1176,21 @@ } ], "dependencies": { - "@ethersproject/address": "^5.6.0", - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/constants": "^5.6.0", - "@ethersproject/keccak256": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/rlp": "^5.6.0", - "@ethersproject/signing-key": "^5.6.0" + "@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" } }, "node_modules/@ethersproject/units": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.6.0.tgz", - "integrity": "sha512-tig9x0Qmh8qbo1w8/6tmtyrm/QQRviBh389EQ+d8fP4wDsBrJBf08oZfoiz1/uenKK9M78yAP4PoR7SsVoTjsw==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.7.0.tgz", + "integrity": "sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg==", "dev": true, "funding": [ { @@ -1352,15 +1203,15 @@ } ], "dependencies": { - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/constants": "^5.6.0", - "@ethersproject/logger": "^5.6.0" + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0" } }, "node_modules/@ethersproject/wallet": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.6.0.tgz", - "integrity": "sha512-qMlSdOSTyp0MBeE+r7SUhr1jjDlC1zAXB8VD84hCnpijPQiSNbxr6GdiLXxpUs8UKzkDiNYYC5DRI3MZr+n+tg==", + "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, "funding": [ { @@ -1373,27 +1224,27 @@ } ], "dependencies": { - "@ethersproject/abstract-provider": "^5.6.0", - "@ethersproject/abstract-signer": "^5.6.0", - "@ethersproject/address": "^5.6.0", - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/hash": "^5.6.0", - "@ethersproject/hdnode": "^5.6.0", - "@ethersproject/json-wallets": "^5.6.0", - "@ethersproject/keccak256": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/random": "^5.6.0", - "@ethersproject/signing-key": "^5.6.0", - "@ethersproject/transactions": "^5.6.0", - "@ethersproject/wordlists": "^5.6.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/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" } }, "node_modules/@ethersproject/web": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.6.0.tgz", - "integrity": "sha512-G/XHj0hV1FxI2teHRfCGvfBUHFmU+YOSbCxlAMqJklxSa7QMiHFQfAxvwY2PFqgvdkxEKwRNr/eCjfAPEm2Ctg==", + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.1.tgz", + "integrity": "sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==", "dev": true, "funding": [ { @@ -1406,17 +1257,17 @@ } ], "dependencies": { - "@ethersproject/base64": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/strings": "^5.6.0" + "@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" } }, "node_modules/@ethersproject/wordlists": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.6.0.tgz", - "integrity": "sha512-q0bxNBfIX3fUuAo9OmjlEYxP40IB8ABgb7HjEZCL5IKubzV3j30CWi2rqQbjTS2HfoyQbfINoKcTVWP4ejwR7Q==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.7.0.tgz", + "integrity": "sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA==", "dev": true, "funding": [ { @@ -1429,37 +1280,27 @@ } ], "dependencies": { - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/hash": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/strings": "^5.6.0" + "@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" } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.4.tgz", - "integrity": "sha512-mXAIHxZT3Vcpg83opl1wGlVZ9xydbfZO3r5YfRSH6Gpp2J/PfdBP0wbDa2sO6/qRbcalpoevVyW6A/fI6LfeMw==", + "version": "0.11.7", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.7.tgz", + "integrity": "sha512-kBbPWzN8oVMLb0hOUYXhmxggL/1cJE6ydvjDIGi9EnAGUyA7cLVKQg+d/Dsm+KZwx2czGHrCmMVLiyg8s5JPKw==", "dev": true, "dependencies": { "@humanwhocodes/object-schema": "^1.2.1", "debug": "^4.1.1", - "minimatch": "^3.0.4" + "minimatch": "^3.0.5" }, "engines": { "node": ">=10.10.0" } }, - "node_modules/@humanwhocodes/gitignore-to-minimatch": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz", - "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==", - "dev": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", @@ -1479,6 +1320,31 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true + }, + "node_modules/@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, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, "node_modules/@kwsites/file-exists": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz", @@ -1495,9 +1361,9 @@ "dev": true }, "node_modules/@metamask/eth-sig-util": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@metamask/eth-sig-util/-/eth-sig-util-4.0.0.tgz", - "integrity": "sha512-LczOjjxY4A7XYloxzyxJIHONELmUxVZncpOLoClpEcTiebiVdM46KRPYXGuULro9oNNR2xdVx3yoKiQjdfWmoA==", + "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, "dependencies": { "ethereumjs-abi": "^0.6.8", @@ -1519,6 +1385,12 @@ "@types/node": "*" } }, + "node_modules/@metamask/eth-sig-util/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/@metamask/eth-sig-util/node_modules/ethereumjs-util": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", @@ -1534,19 +1406,37 @@ "rlp": "^2.2.3" } }, - "node_modules/@metamask/eth-sig-util/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/@noble/hashes": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.1.2.tgz", + "integrity": "sha512-KYRCASVTv6aeUi1tsF8/vpyR7zpfs3FUzy2Jqm+MU+LmUKhQ0y2FpfwqkCcxSg2ua4GALJd8k2R76WxwZGbQpA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/@noble/secp256k1": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-1.6.3.tgz", + "integrity": "sha512-T04e4iTurVy7I8Sw4+c5OSN9/RkPlo1uKxAomtxQNLq8j1uPAqnsqG1bqvY3Jv7c13gyr6dui0zmh/I3+f/JaQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] }, "node_modules/@nodelib/fs.scandir": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz", - "integrity": "sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==", + "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, "dependencies": { - "@nodelib/fs.stat": "2.0.4", + "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" }, "engines": { @@ -1554,31 +1444,395 @@ } }, "node_modules/@nodelib/fs.stat": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz", - "integrity": "sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q==", + "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, "engines": { "node": ">= 8" } }, "node_modules/@nodelib/fs.walk": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz", - "integrity": "sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==", + "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, "dependencies": { - "@nodelib/fs.scandir": "2.1.4", + "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" }, "engines": { "node": ">= 8" } }, + "node_modules/@nomicfoundation/ethereumjs-block": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-block/-/ethereumjs-block-4.0.0.tgz", + "integrity": "sha512-bk8uP8VuexLgyIZAHExH1QEovqx0Lzhc9Ntm63nCRKLHXIZkobaFaeCVwTESV7YkPKUk7NiK11s8ryed4CS9yA==", + "dev": true, + "dependencies": { + "@nomicfoundation/ethereumjs-common": "^3.0.0", + "@nomicfoundation/ethereumjs-rlp": "^4.0.0", + "@nomicfoundation/ethereumjs-trie": "^5.0.0", + "@nomicfoundation/ethereumjs-tx": "^4.0.0", + "@nomicfoundation/ethereumjs-util": "^8.0.0", + "ethereum-cryptography": "0.1.3" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@nomicfoundation/ethereumjs-blockchain": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-blockchain/-/ethereumjs-blockchain-6.0.0.tgz", + "integrity": "sha512-pLFEoea6MWd81QQYSReLlLfH7N9v7lH66JC/NMPN848ySPPQA5renWnE7wPByfQFzNrPBuDDRFFULMDmj1C0xw==", + "dev": true, + "dependencies": { + "@nomicfoundation/ethereumjs-block": "^4.0.0", + "@nomicfoundation/ethereumjs-common": "^3.0.0", + "@nomicfoundation/ethereumjs-ethash": "^2.0.0", + "@nomicfoundation/ethereumjs-rlp": "^4.0.0", + "@nomicfoundation/ethereumjs-trie": "^5.0.0", + "@nomicfoundation/ethereumjs-util": "^8.0.0", + "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" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@nomicfoundation/ethereumjs-common": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-3.0.0.tgz", + "integrity": "sha512-WS7qSshQfxoZOpHG/XqlHEGRG1zmyjYrvmATvc4c62+gZXgre1ymYP8ZNgx/3FyZY0TWe9OjFlKOfLqmgOeYwA==", + "dev": true, + "dependencies": { + "@nomicfoundation/ethereumjs-util": "^8.0.0", + "crc-32": "^1.2.0" + } + }, + "node_modules/@nomicfoundation/ethereumjs-ethash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-ethash/-/ethereumjs-ethash-2.0.0.tgz", + "integrity": "sha512-WpDvnRncfDUuXdsAXlI4lXbqUDOA+adYRQaEezIkxqDkc+LDyYDbd/xairmY98GnQzo1zIqsIL6GB5MoMSJDew==", + "dev": true, + "dependencies": { + "@nomicfoundation/ethereumjs-block": "^4.0.0", + "@nomicfoundation/ethereumjs-rlp": "^4.0.0", + "@nomicfoundation/ethereumjs-util": "^8.0.0", + "abstract-level": "^1.0.3", + "bigint-crypto-utils": "^3.0.23", + "ethereum-cryptography": "0.1.3" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@nomicfoundation/ethereumjs-evm": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-evm/-/ethereumjs-evm-1.0.0.tgz", + "integrity": "sha512-hVS6qRo3V1PLKCO210UfcEQHvlG7GqR8iFzp0yyjTg2TmJQizcChKgWo8KFsdMw6AyoLgLhHGHw4HdlP8a4i+Q==", + "dev": true, + "dependencies": { + "@nomicfoundation/ethereumjs-common": "^3.0.0", + "@nomicfoundation/ethereumjs-util": "^8.0.0", + "@types/async-eventemitter": "^0.2.1", + "async-eventemitter": "^0.2.4", + "debug": "^4.3.3", + "ethereum-cryptography": "0.1.3", + "mcl-wasm": "^0.7.1", + "rustbn.js": "~0.2.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@nomicfoundation/ethereumjs-rlp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-4.0.0.tgz", + "integrity": "sha512-GaSOGk5QbUk4eBP5qFbpXoZoZUj/NrW7MRa0tKY4Ew4c2HAS0GXArEMAamtFrkazp0BO4K5p2ZCG3b2FmbShmw==", + "dev": true, + "bin": { + "rlp": "bin/rlp" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@nomicfoundation/ethereumjs-statemanager": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-statemanager/-/ethereumjs-statemanager-1.0.0.tgz", + "integrity": "sha512-jCtqFjcd2QejtuAMjQzbil/4NHf5aAWxUc+CvS0JclQpl+7M0bxMofR2AJdtz+P3u0ke2euhYREDiE7iSO31vQ==", + "dev": true, + "dependencies": { + "@nomicfoundation/ethereumjs-common": "^3.0.0", + "@nomicfoundation/ethereumjs-rlp": "^4.0.0", + "@nomicfoundation/ethereumjs-trie": "^5.0.0", + "@nomicfoundation/ethereumjs-util": "^8.0.0", + "debug": "^4.3.3", + "ethereum-cryptography": "0.1.3", + "functional-red-black-tree": "^1.0.1" + } + }, + "node_modules/@nomicfoundation/ethereumjs-trie": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-trie/-/ethereumjs-trie-5.0.0.tgz", + "integrity": "sha512-LIj5XdE+s+t6WSuq/ttegJzZ1vliwg6wlb+Y9f4RlBpuK35B9K02bO7xU+E6Rgg9RGptkWd6TVLdedTI4eNc2A==", + "dev": true, + "dependencies": { + "@nomicfoundation/ethereumjs-rlp": "^4.0.0", + "@nomicfoundation/ethereumjs-util": "^8.0.0", + "ethereum-cryptography": "0.1.3", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@nomicfoundation/ethereumjs-tx": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-4.0.0.tgz", + "integrity": "sha512-Gg3Lir2lNUck43Kp/3x6TfBNwcWC9Z1wYue9Nz3v4xjdcv6oDW9QSMJxqsKw9QEGoBBZ+gqwpW7+F05/rs/g1w==", + "dev": true, + "dependencies": { + "@nomicfoundation/ethereumjs-common": "^3.0.0", + "@nomicfoundation/ethereumjs-rlp": "^4.0.0", + "@nomicfoundation/ethereumjs-util": "^8.0.0", + "ethereum-cryptography": "0.1.3" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@nomicfoundation/ethereumjs-util": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-8.0.0.tgz", + "integrity": "sha512-2emi0NJ/HmTG+CGY58fa+DQuAoroFeSH9gKu9O6JnwTtlzJtgfTixuoOqLEgyyzZVvwfIpRueuePb8TonL1y+A==", + "dev": true, + "dependencies": { + "@nomicfoundation/ethereumjs-rlp": "^4.0.0-beta.2", + "ethereum-cryptography": "0.1.3" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@nomicfoundation/ethereumjs-vm": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-vm/-/ethereumjs-vm-6.0.0.tgz", + "integrity": "sha512-JMPxvPQ3fzD063Sg3Tp+UdwUkVxMoo1uML6KSzFhMH3hoQi/LMuXBoEHAoW83/vyNS9BxEe6jm6LmT5xdeEJ6w==", + "dev": true, + "dependencies": { + "@nomicfoundation/ethereumjs-block": "^4.0.0", + "@nomicfoundation/ethereumjs-blockchain": "^6.0.0", + "@nomicfoundation/ethereumjs-common": "^3.0.0", + "@nomicfoundation/ethereumjs-evm": "^1.0.0", + "@nomicfoundation/ethereumjs-rlp": "^4.0.0", + "@nomicfoundation/ethereumjs-statemanager": "^1.0.0", + "@nomicfoundation/ethereumjs-trie": "^5.0.0", + "@nomicfoundation/ethereumjs-tx": "^4.0.0", + "@nomicfoundation/ethereumjs-util": "^8.0.0", + "@types/async-eventemitter": "^0.2.1", + "async-eventemitter": "^0.2.4", + "debug": "^4.3.3", + "ethereum-cryptography": "0.1.3", + "functional-red-black-tree": "^1.0.1", + "mcl-wasm": "^0.7.1", + "rustbn.js": "~0.2.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.0.tgz", + "integrity": "sha512-xGWAiVCGOycvGiP/qrlf9f9eOn7fpNbyJygcB0P21a1MDuVPlKt0Srp7rvtBEutYQ48ouYnRXm33zlRnlTOPHg==", + "dev": true, + "engines": { + "node": ">= 12" + }, + "optionalDependencies": { + "@nomicfoundation/solidity-analyzer-darwin-arm64": "0.1.0", + "@nomicfoundation/solidity-analyzer-darwin-x64": "0.1.0", + "@nomicfoundation/solidity-analyzer-freebsd-x64": "0.1.0", + "@nomicfoundation/solidity-analyzer-linux-arm64-gnu": "0.1.0", + "@nomicfoundation/solidity-analyzer-linux-arm64-musl": "0.1.0", + "@nomicfoundation/solidity-analyzer-linux-x64-gnu": "0.1.0", + "@nomicfoundation/solidity-analyzer-linux-x64-musl": "0.1.0", + "@nomicfoundation/solidity-analyzer-win32-arm64-msvc": "0.1.0", + "@nomicfoundation/solidity-analyzer-win32-ia32-msvc": "0.1.0", + "@nomicfoundation/solidity-analyzer-win32-x64-msvc": "0.1.0" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-darwin-arm64": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.0.tgz", + "integrity": "sha512-vEF3yKuuzfMHsZecHQcnkUrqm8mnTWfJeEVFHpg+cO+le96xQA4lAJYdUan8pXZohQxv1fSReQsn4QGNuBNuCw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-darwin-x64": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-x64/-/solidity-analyzer-darwin-x64-0.1.0.tgz", + "integrity": "sha512-dlHeIg0pTL4dB1l9JDwbi/JG6dHQaU1xpDK+ugYO8eJ1kxx9Dh2isEUtA4d02cQAl22cjOHTvifAk96A+ItEHA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-freebsd-x64": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-freebsd-x64/-/solidity-analyzer-freebsd-x64-0.1.0.tgz", + "integrity": "sha512-WFCZYMv86WowDA4GiJKnebMQRt3kCcFqHeIomW6NMyqiKqhK1kIZCxSLDYsxqlx396kKLPN1713Q1S8tu68GKg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-linux-arm64-gnu": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-gnu/-/solidity-analyzer-linux-arm64-gnu-0.1.0.tgz", + "integrity": "sha512-DTw6MNQWWlCgc71Pq7CEhEqkb7fZnS7oly13pujs4cMH1sR0JzNk90Mp1zpSCsCs4oKan2ClhMlLKtNat/XRKQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-linux-arm64-musl": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-musl/-/solidity-analyzer-linux-arm64-musl-0.1.0.tgz", + "integrity": "sha512-wUpUnR/3GV5Da88MhrxXh/lhb9kxh9V3Jya2NpBEhKDIRCDmtXMSqPMXHZmOR9DfCwCvG6vLFPr/+YrPCnUN0w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-linux-x64-gnu": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-gnu/-/solidity-analyzer-linux-x64-gnu-0.1.0.tgz", + "integrity": "sha512-lR0AxK1x/MeKQ/3Pt923kPvwigmGX3OxeU5qNtQ9pj9iucgk4PzhbS3ruUeSpYhUxG50jN4RkIGwUMoev5lguw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-linux-x64-musl": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-musl/-/solidity-analyzer-linux-x64-musl-0.1.0.tgz", + "integrity": "sha512-A1he/8gy/JeBD3FKvmI6WUJrGrI5uWJNr5Xb9WdV+DK0F8msuOqpEByLlnTdLkXMwW7nSl3awvLezOs9xBHJEg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-win32-arm64-msvc": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-arm64-msvc/-/solidity-analyzer-win32-arm64-msvc-0.1.0.tgz", + "integrity": "sha512-7x5SXZ9R9H4SluJZZP8XPN+ju7Mx+XeUMWZw7ZAqkdhP5mK19I4vz3x0zIWygmfE8RT7uQ5xMap0/9NPsO+ykw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-win32-ia32-msvc": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-ia32-msvc/-/solidity-analyzer-win32-ia32-msvc-0.1.0.tgz", + "integrity": "sha512-m7w3xf+hnE774YRXu+2mGV7RiF3QJtUoiYU61FascCkQhX3QMQavh7saH/vzb2jN5D24nT/jwvaHYX/MAM9zUw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-win32-x64-msvc": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-x64-msvc/-/solidity-analyzer-win32-x64-msvc-0.1.0.tgz", + "integrity": "sha512-xCuybjY0sLJQnJhupiFAXaek2EqF0AP0eBjgzaalPXSNvCEN6ZYHvUzdA50ENDVeSYFXcUsYf3+FsD3XKaeptA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, "node_modules/@nomiclabs/hardhat-ethers": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.0.5.tgz", - "integrity": "sha512-A2gZAGB6kUvLx+kzM92HKuUF33F1FSe90L0TmkXkT2Hh0OKRpvWZURUSU2nghD2yC4DzfEZ3DftfeHGvZ2JTUw==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.2.1.tgz", + "integrity": "sha512-RHWYwnxryWR8hzRmU4Jm/q4gzvXpetUOJ4OPlwH2YARcDB+j79+yAYCwO0lN1SUOb4++oOTJEe6AWLEc42LIvg==", "dev": true, "peerDependencies": { "ethers": "^5.0.0", @@ -1586,27 +1840,101 @@ } }, "node_modules/@nomiclabs/hardhat-etherscan": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-3.0.3.tgz", - "integrity": "sha512-OfNtUKc/ZwzivmZnnpwWREfaYncXteKHskn3yDnz+fPBZ6wfM4GR+d5RwjREzYFWE+o5iR9ruXhWw/8fejWM9g==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-3.1.2.tgz", + "integrity": "sha512-IEikeOVq0C/7CY6aD74d8L4BpGoc/FNiN6ldiPVg0QIFIUSu4FSGA1dmtJZJKk1tjpwgrfTLQNWnigtEaN9REg==", "dev": true, "dependencies": { "@ethersproject/abi": "^5.1.2", "@ethersproject/address": "^5.0.2", "cbor": "^5.0.2", + "chalk": "^2.4.2", "debug": "^4.1.1", "fs-extra": "^7.0.1", + "lodash": "^4.17.11", "semver": "^6.3.0", - "undici": "^4.14.1" + "table": "^6.8.0", + "undici": "^5.4.0" }, "peerDependencies": { "hardhat": "^2.0.4" } }, + "node_modules/@nomiclabs/hardhat-etherscan/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/@nomiclabs/hardhat-etherscan/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/@nomiclabs/hardhat-etherscan/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/@nomiclabs/hardhat-etherscan/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/@nomiclabs/hardhat-etherscan/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/@nomiclabs/hardhat-etherscan/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/@nomiclabs/hardhat-etherscan/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/@nomiclabs/hardhat-solhint": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-solhint/-/hardhat-solhint-2.0.0.tgz", - "integrity": "sha512-fn+izC923/oCnfbGyp7YwOXZYtwcrDIrTLlFVeEgeSAHe2ZnipRRtNCxEClZuzCptHmTzIIayBmAaijsTmEAoA==", + "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, "dependencies": { "solhint": "^2.0.0" @@ -1644,13 +1972,14 @@ "dev": true }, "node_modules/@openzeppelin/hardhat-upgrades": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/@openzeppelin/hardhat-upgrades/-/hardhat-upgrades-1.17.0.tgz", - "integrity": "sha512-GNxR3/3fCKQsFpBi/r+5ib6U81UM9KCypmcOQxuCkVp9JKJ80/3hQdg1R+AQku/dlnhutPsfkCokH2LZFc5mNA==", + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@openzeppelin/hardhat-upgrades/-/hardhat-upgrades-1.21.0.tgz", + "integrity": "sha512-Kwl7IN0Hlhj4HluMTTl0DrtU90OI/Q6rG3sAyd2pv3fababe9EuZqs9DydOlkWM45JwTzC+eBzX3TgHsqI13eA==", "dev": true, "dependencies": { - "@openzeppelin/upgrades-core": "^1.14.1", + "@openzeppelin/upgrades-core": "^1.20.0", "chalk": "^4.1.0", + "debug": "^4.1.1", "proper-lockfile": "^4.1.1" }, "bin": { @@ -1658,31 +1987,31 @@ }, "peerDependencies": { "@nomiclabs/hardhat-ethers": "^2.0.0", + "@nomiclabs/hardhat-etherscan": "^3.1.0", + "ethers": "^5.0.5", "hardhat": "^2.0.2" + }, + "peerDependenciesMeta": { + "@nomiclabs/harhdat-etherscan": { + "optional": true + } } }, "node_modules/@openzeppelin/upgrades-core": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@openzeppelin/upgrades-core/-/upgrades-core-1.14.1.tgz", - "integrity": "sha512-iKlh1mbUxyfdjdEiUFyhMkqirfas+DMUu7ED53nZbHEyhcYsm+5Fl/g0Bv6bZA+a7k8kO8+22DNEKsqaDUBc2Q==", + "version": "1.20.4", + "resolved": "https://registry.npmjs.org/@openzeppelin/upgrades-core/-/upgrades-core-1.20.4.tgz", + "integrity": "sha512-Y4/+BPIbnopfE6ZhPOE2CD0V5fnvDxKKm7+kryx5+WrcRCTW3B5DjbXL9xyyoviG8Rn5EXUh5Fk1GLbiYDfu0g==", "dev": true, "dependencies": { - "bn.js": "^5.1.2", "cbor": "^8.0.0", "chalk": "^4.1.0", - "compare-versions": "^4.0.0", + "compare-versions": "^5.0.0", "debug": "^4.1.1", "ethereumjs-util": "^7.0.3", "proper-lockfile": "^4.1.1", "solidity-ast": "^0.4.15" } }, - "node_modules/@openzeppelin/upgrades-core/node_modules/bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", - "dev": true - }, "node_modules/@openzeppelin/upgrades-core/node_modules/cbor": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/cbor/-/cbor-8.1.0.tgz", @@ -1785,6 +2114,51 @@ "ms": "^2.1.1" } }, + "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==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/@scure/bip32": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.0.tgz", + "integrity": "sha512-ftTW3kKX54YXLCxH6BB7oEEoJfoE2pIgw7MINKAs5PsS6nqKPuKk1haTF/EuHmYqG330t5GSrdmtRuHaY1a62Q==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "@noble/hashes": "~1.1.1", + "@noble/secp256k1": "~1.6.0", + "@scure/base": "~1.1.0" + } + }, + "node_modules/@scure/bip39": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.0.tgz", + "integrity": "sha512-pwrPOS16VeTKg98dYXQyIjJEcWfz7/1YJIwxUEPFfQPtc86Ym/1sVgQ2RLoD43AazMk2l/unK4ITySSpW2+82w==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "@noble/hashes": "~1.1.1", + "@scure/base": "~1.1.0" + } + }, "node_modules/@sentry/core": { "version": "5.30.0", "resolved": "https://registry.npmjs.org/@sentry/core/-/core-5.30.0.tgz", @@ -1887,183 +2261,37 @@ "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/@sinonjs/commons": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", - "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", - "dev": true, - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/@sinonjs/fake-timers": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-7.0.5.tgz", - "integrity": "sha512-fUt6b15bjV/VW93UP5opNXJxdwZSbK1EdiwnhN7XrQrcpaOhMJpZ/CjwFpM3THpxwA+YviBUJKSuEqKlCK5alw==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^1.7.0" - } - }, "node_modules/@solidity-parser/parser": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.14.1.tgz", - "integrity": "sha512-eLjj2L6AuQjBB6s/ibwCAc0DwrR5Ge+ys+wgWo+bviU7fV2nTMQhU63CGaDKXg9iTmMxwhkyoggdIR7ZGRfMgw==", + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.14.5.tgz", + "integrity": "sha512-6dKnHZn7fg/iQATVEzqyUOyEidbn05q7YA2mQ9hC0MMXhhV3/JrsxmFSYZAcr7j1yUP700LLhTruvJ3MiQmjJg==", "dev": true, "dependencies": { "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/@truffle/error": { - "version": "0.0.14", - "resolved": "https://registry.npmjs.org/@truffle/error/-/error-0.0.14.tgz", - "integrity": "sha512-utJx+SZYoMqk8wldQG4gCVKhV8GwMJbWY7sLXFT/D8wWZTnE2peX7URFJh/cxkjTRCO328z1s2qewkhyVsu2HA==", - "dev": true - }, - "node_modules/@truffle/interface-adapter": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/@truffle/interface-adapter/-/interface-adapter-0.4.23.tgz", - "integrity": "sha512-mfpwY25Apx36WHHNJMNHWyDQVFZoZYNQ43rOwr/n+5gAMxke7+D7+IR9UW4kuO/Jp0+2848UxMdRV+oqm017kQ==", - "dev": true, - "dependencies": { - "bn.js": "^5.1.3", - "ethers": "^4.0.32", - "web3": "1.3.5" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", - "dev": true - }, - "node_modules/@truffle/interface-adapter/node_modules/elliptic": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", - "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", - "dev": true, - "dependencies": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.0" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/elliptic/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/@truffle/interface-adapter/node_modules/ethers": { - "version": "4.0.48", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.48.tgz", - "integrity": "sha512-sZD5K8H28dOrcidzx9f8KYh8083n5BexIO3+SbE4jK83L85FxtpXZBCQdXb8gkg+7sBqomcLhhkU7UHL+F7I2g==", - "dev": true, - "dependencies": { - "aes-js": "3.0.0", - "bn.js": "^4.4.0", - "elliptic": "6.5.3", - "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" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/ethers/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/@truffle/interface-adapter/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==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.0" - } - }, - "node_modules/@truffle/interface-adapter/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 - }, - "node_modules/@truffle/interface-adapter/node_modules/setimmediate": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz", - "integrity": "sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48=", - "dev": true - }, - "node_modules/@truffle/interface-adapter/node_modules/uuid": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz", - "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=", - "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 - }, - "node_modules/@truffle/provider": { - "version": "0.2.30", - "resolved": "https://registry.npmjs.org/@truffle/provider/-/provider-0.2.30.tgz", - "integrity": "sha512-5ScTbWsrm7zmQjw020T41U30/kYA1LppXAtaeucUGN2jvPrSwlh0aTL18makbqftTx1NRuYKw7C8wO4jCKQSUQ==", - "dev": true, - "dependencies": { - "@truffle/error": "^0.0.14", - "@truffle/interface-adapter": "^0.4.23", - "web3": "1.3.5" - } - }, "node_modules/@tsconfig/node10": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", - "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", "dev": true }, "node_modules/@tsconfig/node12": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", - "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", "dev": true }, "node_modules/@tsconfig/node14": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", - "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", "dev": true }, "node_modules/@tsconfig/node16": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", - "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", "dev": true }, "node_modules/@typechain/ethers-v5": { @@ -2079,25 +2307,25 @@ "typechain": "^3.0.0" } }, - "node_modules/@types/abstract-leveldown": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@types/abstract-leveldown/-/abstract-leveldown-7.2.0.tgz", - "integrity": "sha512-q5veSX6zjUy/DlDhR4Y4cU0k2Ar+DT2LUraP00T19WLmTO6Se1djepCCaqU6nQrwcJ5Hyo/CWqxTzrrFg8eqbQ==", + "node_modules/@types/async-eventemitter": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@types/async-eventemitter/-/async-eventemitter-0.2.1.tgz", + "integrity": "sha512-M2P4Ng26QbAeITiH7w1d7OxtldgfAe0wobpyJzVK/XOb0cUGKU2R4pfAhqcJBXAe2ife5ZOhSv4wk7p+ffURtg==", "dev": true }, "node_modules/@types/bn.js": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", - "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.1.tgz", + "integrity": "sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g==", "dev": true, "dependencies": { "@types/node": "*" } }, "node_modules/@types/chai": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.0.tgz", - "integrity": "sha512-/ceqdqeRraGolFTcfoXNiqjyQhZzbINDngeoAq9GoHa8PPK1yNzTaxWjA6BFWp5Ua9JpXEMSS4s5i9tS0hOJtw==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.4.tgz", + "integrity": "sha512-KnRanxnpfpjUTqTCXslZSEdLfXExwgNxYPdiO2WGUj8+HDjFi8R3k5RVKPeSCzLjCcshCAtVO2QBbVuAV4kTnw==", "dev": true }, "node_modules/@types/chai-as-promised": { @@ -2110,9 +2338,9 @@ } }, "node_modules/@types/cli-table": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@types/cli-table/-/cli-table-0.3.0.tgz", - "integrity": "sha512-QnZUISJJXyhyD6L1e5QwXDV/A5i2W1/gl6D6YMc8u0ncPepbv/B4w3S+izVvtAg60m6h+JP09+Y/0zF2mojlFQ==", + "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==", "dev": true }, "node_modules/@types/concat-stream": { @@ -2127,16 +2355,16 @@ "node_modules/@types/form-data": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz", - "integrity": "sha1-yayFsqX9GENbjIXZ7LUObWyJP/g=", + "integrity": "sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==", "dev": true, "dependencies": { "@types/node": "*" } }, "node_modules/@types/glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", "dev": true, "dependencies": { "@types/minimatch": "*", @@ -2149,33 +2377,16 @@ "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", "dev": true }, - "node_modules/@types/level-errors": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/level-errors/-/level-errors-3.0.0.tgz", - "integrity": "sha512-/lMtoq/Cf/2DVOm6zE6ORyOM+3ZVm/BvzEZVxUhf6bgh8ZHglXlBqxbxSlJeVp8FCbD3IVvk/VbsaNmDjrQvqQ==", - "dev": true - }, - "node_modules/@types/levelup": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@types/levelup/-/levelup-4.3.3.tgz", - "integrity": "sha512-K+OTIjJcZHVlZQN1HmU64VtrC0jC3dXWQozuEIR9zVvltIk90zaGPM2AgT+fIkChpzHhFE3YnvFLCbLtzAmexA==", - "dev": true, - "dependencies": { - "@types/abstract-leveldown": "*", - "@types/level-errors": "*", - "@types/node": "*" - } - }, "node_modules/@types/lru-cache": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.0.tgz", - "integrity": "sha512-RaE0B+14ToE4l6UqdarKPnXwVDuigfFv+5j9Dze/Nqr23yyuqdNvzcZi3xB+3Agvi5R4EOgAksfv3lXX4vBt9w==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==", "dev": true }, "node_modules/@types/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", + "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", "dev": true }, "node_modules/@types/mkdirp": { @@ -2188,41 +2399,27 @@ } }, "node_modules/@types/mocha": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.0.tgz", - "integrity": "sha512-QCWHkbMv4Y5U9oW10Uxbr45qMMSzl4OzijsozynUAgx3kEHUdXB00udx2dWDQ7f2TU2a2uuiFaRZjCe3unPpeg==", + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.1.tgz", + "integrity": "sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw==", "dev": true }, "node_modules/@types/node": { - "version": "17.0.23", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", - "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==", + "version": "17.0.45", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", + "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==", "dev": true }, "node_modules/@types/node-fetch": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.1.tgz", - "integrity": "sha512-oMqjURCaxoSIsHSr1E47QHzbmzNR5rK8McHuNb11BOM9cHcIK3Avy0s/b2JlXHoQGTYS3NsvWzV1M0iK7l0wbA==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.2.tgz", + "integrity": "sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A==", "dev": true, "dependencies": { "@types/node": "*", "form-data": "^3.0.0" } }, - "node_modules/@types/node-fetch/node_modules/form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", - "dev": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/@types/pbkdf2": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz", @@ -2233,9 +2430,9 @@ } }, "node_modules/@types/prettier": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.4.tgz", - "integrity": "sha512-ReVR2rLTV1kvtlWFyuot+d1pkpG2Fw/XKE3PDAdj57rbM97ttSp9JZ2UsP+2EHTylra9cUf6JA7tGwW1INzUrA==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.1.tgz", + "integrity": "sha512-ri0UmynRRvZiiUJdiz38MmIblKK+oH30MztdBVR95dv/Ubw6neWSb8u1XpRb72L4qsZOhz+L+z9JD40SJmfWow==", "dev": true }, "node_modules/@types/qs": { @@ -2254,37 +2451,49 @@ } }, "node_modules/@types/secp256k1": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.2.tgz", - "integrity": "sha512-QMg+9v0bbNJ2peLuHRWxzmy0HRJIG6gFZNhaRSp7S3ggSbCCxiqQB2/ybvhXyhHOCequpNkrx7OavNhrWOsW0A==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.3.tgz", + "integrity": "sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==", "dev": true, "dependencies": { "@types/node": "*" } }, + "node_modules/@types/semver": { + "version": "7.3.13", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", + "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==", + "dev": true + }, "node_modules/@types/sinon": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.0.tgz", - "integrity": "sha512-jDZ55oCKxqlDmoTBBbBBEx+N8ZraUVhggMZ9T5t+6/Dh8/4NiOjSUfpLrPiEwxQDlAe3wpAkoXhWvE6LibtsMQ==", + "version": "10.0.13", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.13.tgz", + "integrity": "sha512-UVjDqJblVNQYvVNUsj0PuYYw0ELRmgt1Nt5Vk0pT5f16ROGfcKJY8o1HVuMOJOpD727RrGB9EGvoaTQE5tgxZQ==", "dev": true, "dependencies": { - "@sinonjs/fake-timers": "^7.0.4" + "@types/sinonjs__fake-timers": "*" } }, "node_modules/@types/sinon-chai": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/@types/sinon-chai/-/sinon-chai-3.2.5.tgz", - "integrity": "sha512-bKQqIpew7mmIGNRlxW6Zli/QVyc3zikpGzCa797B/tRnD9OtHvZ/ts8sYXV+Ilj9u3QRaUEM8xrjgd1gwm1BpQ==", + "version": "3.2.9", + "resolved": "https://registry.npmjs.org/@types/sinon-chai/-/sinon-chai-3.2.9.tgz", + "integrity": "sha512-/19t63pFYU0ikrdbXKBWj9PCdnKyTd0Qkz0X91Ta081cYsq90OxYdcWwK/dwEoDa6dtXgj2HJfmzgq+QZTHdmQ==", "dev": true, "dependencies": { "@types/chai": "*", "@types/sinon": "*" } }, + "node_modules/@types/sinonjs__fake-timers": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.2.tgz", + "integrity": "sha512-9GcLXF0/v3t80caGs5p2rRfkB+a8VBGLJZVih6CNFkx8IZ994wiKKLSRs9nuFwk1HevWs/1mnUmkApGrSGsShA==", + "dev": true + }, "node_modules/@types/underscore": { - "version": "1.11.2", - "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.11.2.tgz", - "integrity": "sha512-Ls2ylbo7++ITrWk2Yc3G/jijwSq5V3GT0tlgVXEl2kKYXY3ImrtmTCoE2uyTWFRI5owMBriloZFWbE1SXOsE7w==", + "version": "1.11.4", + "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.11.4.tgz", + "integrity": "sha512-uO4CD2ELOjw8tasUrAhvnn2W4A0ZECOvMjCivJr4gA9pGgjv+qxKWY9GLTMVEK8ej85BxQOocUyE7hImmSQYcg==", "dev": true }, "node_modules/@types/web3": { @@ -2298,17 +2507,17 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.36.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.36.0.tgz", - "integrity": "sha512-X3In41twSDnYRES7hO2xna4ZC02SY05UN9sGW//eL1P5k4CKfvddsdC2hOq0O3+WU1wkCPQkiTY9mzSnXKkA0w==", + "version": "5.42.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.42.1.tgz", + "integrity": "sha512-LyR6x784JCiJ1j6sH5Y0K6cdExqCCm8DJUTcwG5ThNXJj/G8o5E56u5EdG4SLy+bZAwZBswC+GYn3eGdttBVCg==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.36.0", - "@typescript-eslint/type-utils": "5.36.0", - "@typescript-eslint/utils": "5.36.0", + "@typescript-eslint/scope-manager": "5.42.1", + "@typescript-eslint/type-utils": "5.42.1", + "@typescript-eslint/utils": "5.42.1", "debug": "^4.3.4", - "functional-red-black-tree": "^1.0.1", "ignore": "^5.2.0", + "natural-compare-lite": "^1.4.0", "regexpp": "^3.2.0", "semver": "^7.3.7", "tsutils": "^3.21.0" @@ -2343,9 +2552,9 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -2364,15 +2573,15 @@ "dev": true }, "node_modules/@typescript-eslint/parser": { - "version": "5.36.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.36.0.tgz", - "integrity": "sha512-dlBZj7EGB44XML8KTng4QM0tvjI8swDh8MdpE5NX5iHWgWEfIuqSfSE+GPeCrCdj7m4tQLuevytd57jNDXJ2ZA==", + "version": "5.42.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.42.1.tgz", + "integrity": "sha512-kAV+NiNBWVQDY9gDJDToTE/NO8BHi4f6b7zTsVAJoTkmB/zlfOpiEVBzHOKtlgTndCKe8vj9F/PuolemZSh50Q==", "dev": true, "peer": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.36.0", - "@typescript-eslint/types": "5.36.0", - "@typescript-eslint/typescript-estree": "5.36.0", + "@typescript-eslint/scope-manager": "5.42.1", + "@typescript-eslint/types": "5.42.1", + "@typescript-eslint/typescript-estree": "5.42.1", "debug": "^4.3.4" }, "engines": { @@ -2392,13 +2601,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.36.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.36.0.tgz", - "integrity": "sha512-PZUC9sz0uCzRiuzbkh6BTec7FqgwXW03isumFVkuPw/Ug/6nbAqPUZaRy4w99WCOUuJTjhn3tMjsM94NtEj64g==", + "version": "5.42.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.42.1.tgz", + "integrity": "sha512-QAZY/CBP1Emx4rzxurgqj3rUinfsh/6mvuKbLNMfJMMKYLRBfweus8brgXF8f64ABkIZ3zdj2/rYYtF8eiuksQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.36.0", - "@typescript-eslint/visitor-keys": "5.36.0" + "@typescript-eslint/types": "5.42.1", + "@typescript-eslint/visitor-keys": "5.42.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -2409,13 +2618,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.36.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.36.0.tgz", - "integrity": "sha512-W/E3yJFqRYsjPljJ2gy0YkoqLJyViWs2DC6xHkXcWyhkIbCDdaVnl7mPLeQphVI+dXtY05EcXFzWLXhq8Mm/lQ==", + "version": "5.42.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.42.1.tgz", + "integrity": "sha512-WWiMChneex5w4xPIX56SSnQQo0tEOy5ZV2dqmj8Z371LJ0E+aymWD25JQ/l4FOuuX+Q49A7pzh/CGIQflxMVXg==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "5.36.0", - "@typescript-eslint/utils": "5.36.0", + "@typescript-eslint/typescript-estree": "5.42.1", + "@typescript-eslint/utils": "5.42.1", "debug": "^4.3.4", "tsutils": "^3.21.0" }, @@ -2436,9 +2645,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.36.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.36.0.tgz", - "integrity": "sha512-3JJuLL1r3ljRpFdRPeOtgi14Vmpx+2JcR6gryeORmW3gPBY7R1jNYoq4yBN1L//ONZjMlbJ7SCIwugOStucYiQ==", + "version": "5.42.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.42.1.tgz", + "integrity": "sha512-Qrco9dsFF5lhalz+lLFtxs3ui1/YfC6NdXu+RAGBa8uSfn01cjO7ssCsjIsUs484vny9Xm699FSKwpkCcqwWwA==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -2449,13 +2658,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.36.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.36.0.tgz", - "integrity": "sha512-EW9wxi76delg/FS9+WV+fkPdwygYzRrzEucdqFVWXMQWPOjFy39mmNNEmxuO2jZHXzSQTXzhxiU1oH60AbIw9A==", + "version": "5.42.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.42.1.tgz", + "integrity": "sha512-qElc0bDOuO0B8wDhhW4mYVgi/LZL+igPwXtV87n69/kYC/7NG3MES0jHxJNCr4EP7kY1XVsRy8C/u3DYeTKQmw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.36.0", - "@typescript-eslint/visitor-keys": "5.36.0", + "@typescript-eslint/types": "5.42.1", + "@typescript-eslint/visitor-keys": "5.42.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -2475,26 +2684,6 @@ } } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@typescript-eslint/typescript-estree/node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -2508,9 +2697,9 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -2522,15 +2711,6 @@ "node": ">=10" } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/@typescript-eslint/typescript-estree/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", @@ -2538,17 +2718,19 @@ "dev": true }, "node_modules/@typescript-eslint/utils": { - "version": "5.36.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.36.0.tgz", - "integrity": "sha512-wAlNhXXYvAAUBbRmoJDywF/j2fhGLBP4gnreFvYvFbtlsmhMJ4qCKVh/Z8OP4SgGR3xbciX2nmG639JX0uw1OQ==", + "version": "5.42.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.42.1.tgz", + "integrity": "sha512-Gxvf12xSp3iYZd/fLqiQRD4uKZjDNR01bQ+j8zvhPjpsZ4HmvEFL/tC4amGNyxN9Rq+iqvpHLhlqx6KTxz9ZyQ==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.36.0", - "@typescript-eslint/types": "5.36.0", - "@typescript-eslint/typescript-estree": "5.36.0", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.42.1", + "@typescript-eslint/types": "5.42.1", + "@typescript-eslint/typescript-estree": "5.42.1", "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" + "eslint-utils": "^3.0.0", + "semver": "^7.3.7" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -2561,35 +2743,46 @@ "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/@typescript-eslint/utils/node_modules/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==", + "node_modules/@typescript-eslint/utils/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, "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" + "yallist": "^4.0.0" }, "engines": { - "node": ">=8.0.0" + "node": ">=10" } }, - "node_modules/@typescript-eslint/utils/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "node_modules/@typescript-eslint/utils/node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, "engines": { - "node": ">=4.0" + "node": ">=10" } }, + "node_modules/@typescript-eslint/utils/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 + }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.36.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.36.0.tgz", - "integrity": "sha512-pdqSJwGKueOrpjYIex0T39xarDt1dn4p7XJ+6FqBWugNQwXlNGC5h62qayAIYZ/RPPtD+ButDWmpXT1eGtiaYg==", + "version": "5.42.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.42.1.tgz", + "integrity": "sha512-LOQtSF4z+hejmpUvitPlc4hA7ERGoj2BVkesOcG91HCn8edLGUXbTrErmutmPbl8Bo9HjAvOO/zBKQHExXNA2A==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.36.0", + "@typescript-eslint/types": "5.42.1", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -2600,12 +2793,6 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@ungap/promise-all-settled": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", - "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", - "dev": true - }, "node_modules/@yarnpkg/lockfile": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", @@ -2615,7 +2802,7 @@ "node_modules/abbrev": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", - "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=", + "integrity": "sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q==", "dev": true }, "node_modules/abort-controller": { @@ -2630,39 +2817,28 @@ "node": ">=6.5" } }, - "node_modules/abstract-leveldown": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.3.0.tgz", - "integrity": "sha512-TU5nlYgta8YrBMNpc9FwQzRbiXsj49gsALsXadbGHt9CROPzX5fB0rWDR5mtdpOOKa5XqRFpbj1QroPAoPzVjQ==", - "dev": true, - "dependencies": { - "buffer": "^5.5.0", - "immediate": "^3.2.3", - "level-concat-iterator": "~2.0.0", - "level-supports": "~1.0.0", - "xtend": "~4.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "node_modules/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, "dependencies": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" + "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" }, "engines": { - "node": ">= 0.6" + "node": ">=12" } }, "node_modules/acorn": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", - "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", + "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -2690,12 +2866,12 @@ } }, "node_modules/address": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/address/-/address-1.1.2.tgz", - "integrity": "sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/address/-/address-1.2.1.tgz", + "integrity": "sha512-B+6bi5D34+fDYENiH5qOlA0cV2rAGKuWZ9LeyUUehbXy8e0VS9e498yO0Jeeh+iM+6KbfudHTFjXw2MmJD4QRA==", "dev": true, "engines": { - "node": ">= 0.12.0" + "node": ">= 10.0.0" } }, "node_modules/adm-zip": { @@ -2710,7 +2886,7 @@ "node_modules/aes-js": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", - "integrity": "sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0=", + "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==", "dev": true }, "node_modules/agent-base": { @@ -2738,15 +2914,6 @@ "node": ">=8" } }, - "node_modules/aggregate-error/node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -2766,7 +2933,7 @@ "node_modules/amdefine": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", + "integrity": "sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==", "dev": true, "optional": true, "engines": { @@ -2774,9 +2941,9 @@ } }, "node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "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, "engines": { "node": ">=6" @@ -2797,13 +2964,25 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/ansi-escapes/node_modules/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, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "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==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/ansi-styles": { @@ -2853,13 +3032,10 @@ "dev": true }, "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, - "dependencies": { - "sprintf-js": "~1.0.2" - } + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true }, "node_modules/array-back": { "version": "2.0.0", @@ -2873,27 +3049,15 @@ "node": ">=4" } }, - "node_modules/array-filter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-1.0.0.tgz", - "integrity": "sha1-uveeYubvTCpMC4MSMtr/7CUfnYM=", - "dev": true - }, "node_modules/array-find-index": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", - "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "integrity": "sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==", "dev": true, "engines": { "node": ">=0.10.0" } }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", - "dev": true - }, "node_modules/array-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", @@ -2906,16 +3070,35 @@ "node_modules/array-uniq": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", "dev": true, "engines": { "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==", + "dev": true, + "dependencies": { + "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" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", "dev": true, "engines": { "node": ">=0.10.0" @@ -2924,34 +3107,22 @@ "node_modules/asap": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", "dev": true }, "node_modules/asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "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, "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/assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", "dev": true, "engines": { "node": ">=0.8" @@ -2967,18 +3138,18 @@ } }, "node_modules/astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", "dev": true, "dependencies": { "lodash": "^4.17.14" @@ -2993,37 +3164,16 @@ "async": "^2.4.0" } }, - "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/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "dev": true }, - "node_modules/available-typed-arrays": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz", - "integrity": "sha512-XWX3OX8Onv97LMk/ftVyBibpGwY5a8SmuxZPzeOxqmuEqUCOM9ZE+uIaD1VNJ5QnvU2UQusvmKbuM1FR8QWGfQ==", - "dev": true, - "dependencies": { - "array-filter": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", "dev": true, "engines": { "node": "*" @@ -3042,9 +3192,9 @@ "dev": true }, "node_modules/base-x": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.8.tgz", - "integrity": "sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA==", + "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, "dependencies": { "safe-buffer": "^5.0.1" @@ -3073,22 +3223,49 @@ "node_modules/bcrypt-pbkdf": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", "dev": true, "dependencies": { "tweetnacl": "^0.14.3" } }, + "node_modules/bcrypt-pbkdf/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/bech32": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==", "dev": true }, + "node_modules/bigint-crypto-utils": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/bigint-crypto-utils/-/bigint-crypto-utils-3.1.7.tgz", + "integrity": "sha512-zpCQpIE2Oy5WIQpjC9iYZf8Uh9QqoS51ZCooAcNvzv1AQ3VWdT52D0ksr1+/faeK8HVIej1bxXcP75YcqH3KPA==", + "dev": true, + "dependencies": { + "bigint-mod-arith": "^3.1.0" + }, + "engines": { + "node": ">=10.4.0" + } + }, + "node_modules/bigint-mod-arith": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bigint-mod-arith/-/bigint-mod-arith-3.1.2.tgz", + "integrity": "sha512-nx8J8bBeiRR+NlsROFH9jHswW5HO8mgfOSqW0AmjicMMvaONDa8AO+5ViKDUUNytBPWiwfvZP4/Bj4Y3lUfvgQ==", + "dev": true, + "engines": { + "node": ">=10.4.0" + } + }, "node_modules/bignumber.js": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", - "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.0.tgz", + "integrity": "sha512-4LwHK4nfDOraBCtst+wOWIHbu1vhvAPJK8g8nROd4iuc3PSEjWif/qwbkh8jwCJz6yDBvtU4KPynETgrfh7y3A==", "dev": true, "engines": { "node": "*" @@ -3103,28 +3280,10 @@ "node": ">=8" } }, - "node_modules/bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "dependencies": { - "file-uri-to-path": "1.0.0" - } - }, - "node_modules/bip66": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", - "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=", - "dev": true, - "dependencies": { - "safe-buffer": "^5.0.1" - } - }, "node_modules/blakejs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz", - "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", + "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==", "dev": true }, "node_modules/bluebird": { @@ -3134,93 +3293,11 @@ "dev": true }, "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/body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", - "dev": true, - "dependencies": { - "bytes": "3.1.0", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" - }, - "engines": { - "node": ">= 0.8" - } - }, - "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/http-errors": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", - "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", - "dev": true, - "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/body-parser/node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "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/node_modules/qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", - "dev": true, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/body-parser/node_modules/raw-body": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", - "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", - "dev": true, - "dependencies": { - "bytes": "3.1.0", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -3246,9 +3323,21 @@ "node_modules/brorand": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", "dev": true }, + "node_modules/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, + "dependencies": { + "abstract-level": "^1.0.2", + "catering": "^2.1.1", + "module-error": "^1.0.2", + "run-parallel-limit": "^1.1.0" + } + }, "node_modules/browser-stdout": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", @@ -3269,72 +3358,10 @@ "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-rsa/node_modules/bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", - "dev": true - }, - "node_modules/browserify-sign": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", - "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", - "dev": true, - "dependencies": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.3", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - } - }, - "node_modules/browserify-sign/node_modules/bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", - "dev": true - }, "node_modules/bs58": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", - "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", + "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", "dev": true, "dependencies": { "base-x": "^3.0.2" @@ -3352,9 +3379,9 @@ } }, "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", "dev": true, "funding": [ { @@ -3372,86 +3399,40 @@ ], "dependencies": { "base64-js": "^1.3.1", - "ieee754": "^1.1.13" + "ieee754": "^1.2.1" } }, "node_modules/buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "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": "sha1-YGSkD6dutDxyOrqe+PbhIW0QURo=", + "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 }, "node_modules/buffer-xor": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", "dev": true }, - "node_modules/bufferutil": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.3.tgz", - "integrity": "sha512-yEYTwGndELGvfXsImMBLop58eaGW+YdONi1fNjTINSY98tmMmFijBG6WXgdkfuLNt4imzQNtIE+eBp1PVpMCSw==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "node-gyp-build": "^4.2.0" - } - }, - "node_modules/bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "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==", + "node_modules/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", "dev": true, "dependencies": { - "pump": "^3.0.0" + "streamsearch": "^1.1.0" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=10.16.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==", + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "dev": true, "engines": { - "node": ">=8" + "node": ">= 0.8" } }, "node_modules/call-bind": { @@ -3470,7 +3451,7 @@ "node_modules/caller-callsite": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", - "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", + "integrity": "sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ==", "dev": true, "dependencies": { "callsites": "^2.0.0" @@ -3479,10 +3460,19 @@ "node": ">=4" } }, + "node_modules/caller-callsite/node_modules/callsites": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/caller-path": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", - "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", + "integrity": "sha512-MCL3sf6nCSXOwCTzvPKhN18TU7AHTvdtam8DAogxcrJ8Rjfbbg7Lgng64H9Iy+vUV6VGFClN/TyxBkAebLRR4A==", "dev": true, "dependencies": { "caller-callsite": "^2.0.0" @@ -3492,18 +3482,18 @@ } }, "node_modules/callsites": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", - "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, "engines": { - "node": ">=4" + "node": ">=6" } }, "node_modules/camelcase": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "integrity": "sha512-FxAv7HpHrXbh3aPo4o2qxHay2lkLY3x5Mw3KeE4KQE8ysVfziWeRZDwcjauvwBSGEC/nXUPzZy8zeh4HokqOnw==", "dev": true, "engines": { "node": ">=4" @@ -3512,7 +3502,7 @@ "node_modules/camelcase-keys": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz", - "integrity": "sha1-oqpfsa9oh1glnDLBQUJteJI7m3c=", + "integrity": "sha512-Ej37YKYbFUI8QiYlvj9YHb6/Z60dZyPJW0Cs8sFilMbd2lP0bw3ylAq9yJkK4lcTA2dID5fG8LjmJYbO7kWb7Q==", "dev": true, "dependencies": { "camelcase": "^4.1.0", @@ -3526,9 +3516,18 @@ "node_modules/caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", "dev": true }, + "node_modules/catering": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/catering/-/catering-2.1.1.tgz", + "integrity": "sha512-K7Qy8O9p76sL3/3m7/zLKbRkyOlSZAgzEaLhyj2mXS8PsCud2Eo4hAb8aLtZqHh0QGqLcb9dlJSu6lHRVENm1w==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/cbor": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/cbor/-/cbor-5.2.0.tgz", @@ -3543,14 +3542,14 @@ } }, "node_modules/chai": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz", - "integrity": "sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.7.tgz", + "integrity": "sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==", "dev": true, "dependencies": { "assertion-error": "^1.1.0", "check-error": "^1.0.2", - "deep-eql": "^3.0.1", + "deep-eql": "^4.1.2", "get-func-name": "^2.0.0", "loupe": "^2.3.1", "pathval": "^1.1.1", @@ -3573,9 +3572,9 @@ } }, "node_modules/chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -3597,7 +3596,7 @@ "node_modules/charenc": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", - "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=", + "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", "dev": true, "engines": { "node": "*" @@ -3606,73 +3605,56 @@ "node_modules/check-error": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", "dev": true, "engines": { "node": "*" } }, "node_modules/chokidar": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", - "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], "dependencies": { - "anymatch": "~3.1.1", + "anymatch": "~3.1.2", "braces": "~3.0.2", - "glob-parent": "~5.1.0", + "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", - "readdirp": "~3.5.0" + "readdirp": "~3.6.0" }, "engines": { "node": ">= 8.10.0" }, "optionalDependencies": { - "fsevents": "~2.3.1" + "fsevents": "~2.3.2" } }, - "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", + "node_modules/chokidar/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": { - "buffer": "^5.5.0", - "class-is": "^1.1.0", - "multibase": "~0.6.0", - "multicodec": "^1.0.0", - "multihashes": "~0.4.15" + "is-glob": "^4.0.1" }, "engines": { - "node": ">=4.0.0", - "npm": ">=3.0.0" + "node": ">= 6" } }, - "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/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/cipher-base": { "version": "1.0.4", @@ -3684,11 +3666,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/classic-level": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/classic-level/-/classic-level-1.2.0.tgz", + "integrity": "sha512-qw5B31ANxSluWz9xBzklRWTUAJ1SXIdaVKTVS7HcTGKOAmExx65Wo5BUICW+YGORe2FOUaDghoI9ZDxj82QcFg==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "abstract-level": "^1.0.2", + "catering": "^2.1.0", + "module-error": "^1.0.1", + "napi-macros": "~2.0.0", + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=12" + } }, "node_modules/clean-stack": { "version": "2.2.0", @@ -3723,15 +3716,6 @@ "node": ">= 0.2.0" } }, - "node_modules/cli-table/node_modules/colors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", - "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=", - "dev": true, - "engines": { - "node": ">=0.1.90" - } - }, "node_modules/cli-table3": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.5.1.tgz", @@ -3748,6 +3732,16 @@ "colors": "^1.1.2" } }, + "node_modules/cli-table3/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, + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, "node_modules/cli-width": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", @@ -3765,21 +3759,6 @@ "wrap-ansi": "^7.0.0" } }, - "node_modules/cliui/node_modules/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, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/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/cliui/node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -3803,31 +3782,10 @@ "node": ">=8" } }, - "node_modules/cliui/node_modules/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, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/clone-response": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", - "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", - "dev": true, - "dependencies": { - "mimic-response": "^1.0.0" - } - }, "node_modules/code-point-at": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", "dev": true, "engines": { "node": ">=0.10.0" @@ -3852,9 +3810,9 @@ "dev": true }, "node_modules/colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", + "integrity": "sha512-pFGrxThWcWQ2MsAz6RtgeWe4NK2kUE1WfsrvvlctdII745EW9I0yflqhe7++M5LEc7bV2c/9/5zc8sFcpL0Drw==", "dev": true, "engines": { "node": ">=0.1.90" @@ -3893,27 +3851,27 @@ } }, "node_modules/commander": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz", - "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==", + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, "node_modules/commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", "dev": true }, "node_modules/compare-versions": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-4.1.3.tgz", - "integrity": "sha512-WQfnbDcrYnGr55UwbxKiQKASnTtNnaAWVi8jZyy8NTpVAXWACSne8lMD1iaIo9AiU6mnuLvSVshCzewVuWxHUg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-5.0.1.tgz", + "integrity": "sha512-v8Au3l0b+Nwkp4G142JcgJFh1/TUhdxut7wzD1Nq1dyp5oa3tXaqb03EXOAB6jS4gMlalkjAUPZBMiAfKUixHQ==", "dev": true }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, "node_modules/concat-stream": { @@ -3961,120 +3919,98 @@ "safe-buffer": "~5.1.0" } }, - "node_modules/content-disposition": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", - "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "node_modules/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, - "dependencies": { - "safe-buffer": "5.1.2" - }, "engines": { "node": ">= 0.6" } }, - "node_modules/content-disposition/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==", + "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/content-hash": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/content-hash/-/content-hash-2.5.2.tgz", - "integrity": "sha512-FvIQKy0S1JaWV10sMsA7TRx8bpU+pqPkhbsfvOJAdjRXvYxEckAwQWGwtRjiaJfh+E0DvcWUGqcdjwMGFjsSdw==", + "node_modules/cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", "dev": true, "dependencies": { - "cids": "^0.7.1", - "multicodec": "^0.5.5", - "multihashes": "^0.4.15" - } - }, - "node_modules/content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", - "dev": true, + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + }, "engines": { - "node": ">= 0.6" + "node": ">=4" } }, - "node_modules/cookie": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", - "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==", + "node_modules/cosmiconfig/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, - "engines": { - "node": ">= 0.6" + "dependencies": { + "sprintf-js": "~1.0.2" } }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", - "dev": true - }, - "node_modules/cookiejar": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz", - "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==", - "dev": true - }, - "node_modules/core-js-pure": { - "version": "3.21.1", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.21.1.tgz", - "integrity": "sha512-12VZfFIu+wyVbBebyHmRTuEE/tZrB4tJToWcwAMcsp3h4+sHR+fMJWbKpYiCRWlhFBq+KNyO8rIV9rTkeVmznQ==", - "deprecated": "core-js-pure@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js-pure.", + "node_modules/cosmiconfig/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, - "hasInstallScript": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" } }, - "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": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "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==", + "node_modules/cosmiconfig/node_modules/import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==", "dev": true, "dependencies": { - "object-assign": "^4", - "vary": "^1" + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" }, "engines": { - "node": ">= 0.10" + "node": ">=4" } }, - "node_modules/cosmiconfig": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", - "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "node_modules/cosmiconfig/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": { - "import-fresh": "^2.0.0", - "is-directory": "^0.3.1", - "js-yaml": "^3.13.1", - "parse-json": "^4.0.0" + "argparse": "^1.0.7", + "esprima": "^4.0.0" }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/cosmiconfig/node_modules/resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", + "dev": true, "engines": { "node": ">=4" } }, "node_modules/crc-32": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.1.tgz", - "integrity": "sha512-Dn/xm/1vFFgs3nfrpEVScHoIslO9NZRITWGz/1E/St6u4xw99vfZzVkW0OSnzx2h9egej9xwMCEut6sqwokM/w==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", "dev": true, - "dependencies": { - "exit-on-epipe": "~1.0.1", - "printj": "~1.3.1" - }, "bin": { "crc32": "bin/crc32.njs" }, @@ -4082,16 +4018,6 @@ "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-hash": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", @@ -4126,57 +4052,24 @@ "dev": true }, "node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" }, "engines": { - "node": ">=4.8" - } - }, - "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==", - "dev": true, - "bin": { - "semver": "bin/semver" + "node": ">= 8" } }, "node_modules/crypt": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", - "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=", - "dev": true, - "engines": { - "node": "*" - } - }, - "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==", + "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", "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": "*" } @@ -4184,7 +4077,7 @@ "node_modules/currently-unhandled": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", - "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "integrity": "sha512-/fITjgjGU50vjQ4FH6eUoYu+iUoUKIXws2hL15JJpIR+BbTxaXQsMuuyjtNh2WqsSBS5nsaZHFsFecyw5CCAng==", "dev": true, "dependencies": { "array-find-index": "^1.0.1" @@ -4193,20 +4086,10 @@ "node": ">=0.10.0" } }, - "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": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", "dev": true, "dependencies": { "assert-plus": "^1.0.0" @@ -4218,7 +4101,7 @@ "node_modules/death": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/death/-/death-1.1.0.tgz", - "integrity": "sha1-AaqcQB7dknUFFEcLgmY5DGbGcxg=", + "integrity": "sha512-vsV6S4KVHvTGxbEcij7hkWRv0It+sGGWVOM67dQde/o5Xjnr+KmLjxWJii2uEObIrt1CcM9w0Yaovx+iOlIL+w==", "dev": true }, "node_modules/debug": { @@ -4241,16 +4124,16 @@ "node_modules/decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/decamelize-keys": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", - "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", + "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", "dev": true, "dependencies": { "decamelize": "^1.1.0", @@ -4258,169 +4141,86 @@ }, "engines": { "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/decamelize-keys/node_modules/map-obj": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", "dev": true, "engines": { "node": ">=0.10.0" } }, - "node_modules/decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "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": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", - "dev": true, - "dependencies": { - "mimic-response": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.2.tgz", + "integrity": "sha512-gT18+YW4CcW/DBNTwAmqTtkJh7f9qqScu2qFVlx7kCoeY9tlBu9cUcr7+I+Z/noG8INehS3xQgLpTtd/QUTn4w==", "dev": true, "dependencies": { "type-detect": "^4.0.0" }, "engines": { - "node": ">=0.12" + "node": ">=6" } }, "node_modules/deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "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==", + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, - "node_modules/deferred-leveldown": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-5.3.0.tgz", - "integrity": "sha512-a59VOT+oDy7vtAbLRCZwWgxu2BaCfd5Hk7wxJd48ei7I+nsg8Orlb9CLG0PMZienk9BSUKgeAqkO2+Lw+1+Ukw==", - "dev": true, - "dependencies": { - "abstract-leveldown": "~6.2.1", - "inherits": "^2.0.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/deferred-leveldown/node_modules/abstract-leveldown": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.2.3.tgz", - "integrity": "sha512-BsLm5vFMRUrrLeCcRc+G0t2qOaTzpoJQLOubq2XM72eNpjF5UdU5o/5NvlNhx95XHcAvcl8OMXr4mlg/fRgUXQ==", - "dev": true, - "dependencies": { - "buffer": "^5.5.0", - "immediate": "^3.2.3", - "level-concat-iterator": "~2.0.0", - "level-supports": "~1.0.0", - "xtend": "~4.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", + "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", "dev": true, "dependencies": { - "object-keys": "^1.0.12" + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "dev": true, "engines": { "node": ">=0.4.0" } }, "node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", "dev": true, "engines": { - "node": ">= 0.6" - } - }, - "node_modules/des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" + "node": ">= 0.8" } }, - "node_modules/destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", - "dev": true - }, "node_modules/detect-port": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.3.0.tgz", - "integrity": "sha512-E+B1gzkl2gqxt1IhUzwjrxBKRqx1UzC3WLONHinn8S3T6lwV/agVCyitiFOsGJ/eYuEUBvD71MZHy3Pv1G9doQ==", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.5.1.tgz", + "integrity": "sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ==", "dev": true, "dependencies": { "address": "^1.0.1", - "debug": "^2.6.0" + "debug": "4" }, "bin": { - "detect": "bin/detect-port", - "detect-port": "bin/detect-port" - }, - "engines": { - "node": ">= 4.2.1" - } - }, - "node_modules/detect-port/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" + "detect": "bin/detect-port.js", + "detect-port": "bin/detect-port.js" } }, - "node_modules/detect-port/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, "node_modules/diff": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", @@ -4430,15 +4230,16 @@ "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==", + "node_modules/difflib": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/difflib/-/difflib-0.2.4.tgz", + "integrity": "sha512-9YVwmMb0wQHQNr5J9m6BSj6fk4pfGITGQOOs+D9Fl+INODWFOfvhIU1hNv6GgR1RBoC/9NJcwu77zShxV0kT7w==", "dev": true, "dependencies": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" + "heap": ">= 0.2.0" + }, + "engines": { + "node": "*" } }, "node_modules/dir-glob": { @@ -4453,15 +4254,6 @@ "node": ">=8" } }, - "node_modules/dir-glob/node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -4474,57 +4266,25 @@ "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.0.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.0.tgz", - "integrity": "sha512-qD9WU0MPM4SWLPJy/r2Be+2WgQj8plChsyrCNQzW/0WjvcJQiKQJ9mH3ZgB3fxbUUxgc/11ZJ0Fi5KiimWGz2Q==", + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", + "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==", "dev": true, "engines": { "node": ">=12" } }, - "node_modules/drbg.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz", - "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=", - "dev": true, - "dependencies": { - "browserify-aes": "^1.0.6", - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/duplexer3": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", - "dev": true - }, "node_modules/ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", "dev": 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": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", - "dev": true - }, "node_modules/elliptic": { "version": "6.5.4", "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", @@ -4540,6 +4300,12 @@ "minimalistic-crypto-utils": "^1.0.1" } }, + "node_modules/elliptic/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/email-addresses": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/email-addresses/-/email-addresses-3.1.0.tgz", @@ -4547,44 +4313,11 @@ "dev": true }, "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==", + "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": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/encoding-down": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/encoding-down/-/encoding-down-6.3.0.tgz", - "integrity": "sha512-QKrV0iKR6MZVJV08QY0wp1e7vF6QbhnbQhb07bwpEyuz4uZiZgPlEGdkCROuFkUwdxlFaiPIhjyarH1ee/3vhw==", - "dev": true, - "dependencies": { - "abstract-leveldown": "^6.2.1", - "inherits": "^2.0.3", - "level-codec": "^9.0.0", - "level-errors": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "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", @@ -4606,18 +4339,6 @@ "node": ">=6" } }, - "node_modules/errno": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", - "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", - "dev": true, - "dependencies": { - "prr": "~1.0.1" - }, - "bin": { - "errno": "cli.js" - } - }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -4628,31 +4349,53 @@ } }, "node_modules/es-abstract": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.2.tgz", - "integrity": "sha512-gfSBJoZdlL2xRiOCy0g8gLMryhoe1TlimjzU99L/31Z8QEGIhVQI+EWwt5lT+AuU9SnorVupXFqqOGqGfsyO6w==", + "version": "1.20.4", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.4.tgz", + "integrity": "sha512-0UtvRN79eMe2L+UNEF1BwRe364sj/DXhQ/k5FmivgoSdpM90b8Jc0mDzKMGo7QS0BVbOP/bTwBKNnDc9rNzaPA==", "dev": true, "dependencies": { "call-bind": "^1.0.2", "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", + "function.prototype.name": "^1.1.5", + "get-intrinsic": "^1.1.3", "get-symbol-description": "^1.0.0", "has": "^1.0.3", + "has-property-descriptors": "^1.0.0", "has-symbols": "^1.0.3", "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", + "is-callable": "^1.2.7", "is-negative-zero": "^2.0.2", "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.1", + "is-shared-array-buffer": "^1.0.2", "is-string": "^1.0.7", "is-weakref": "^1.0.2", - "object-inspect": "^1.12.0", + "object-inspect": "^1.12.2", "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.1" + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.4.3", + "safe-regex-test": "^1.0.0", + "string.prototype.trimend": "^1.0.5", + "string.prototype.trimstart": "^1.0.5", + "unbox-primitive": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "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==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" }, "engines": { "node": ">= 0.4" @@ -4661,6 +4404,12 @@ "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 + }, "node_modules/es-to-primitive": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", @@ -4678,38 +4427,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/es5-ext": { - "version": "0.10.53", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", - "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", - "dev": true, - "dependencies": { - "es6-iterator": "~2.0.3", - "es6-symbol": "~3.1.3", - "next-tick": "~1.0.0" - } - }, - "node_modules/es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", - "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", @@ -4719,25 +4436,22 @@ "node": ">=6" } }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", - "dev": true - }, "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": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, "engines": { - "node": ">=0.8.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/escodegen": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", - "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=", + "integrity": "sha512-yhi5S+mNTOuRvyW4gWlg5W1byMaQGWWSYHXsuFZ7GBo7tpyOwi2EdzMP/QWxh9hwkD2m+wDVHJsxhRIj+v/b/A==", "dev": true, "dependencies": { "esprima": "^2.7.1", @@ -4756,66 +4470,100 @@ "source-map": "~0.2.0" } }, - "node_modules/escodegen/node_modules/esprima": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", + "node_modules/escodegen/node_modules/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, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, "engines": { "node": ">=0.10.0" } }, - "node_modules/escodegen/node_modules/source-map": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", - "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=", + "node_modules/escodegen/node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", "dev": true, - "optional": true, "dependencies": { - "amdefine": ">=0.0.4" + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" }, "engines": { - "node": ">=0.8.0" + "node": ">= 0.8.0" } }, - "node_modules/eslint": { - "version": "8.23.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.23.0.tgz", - "integrity": "sha512-pBG/XOn0MsJcKcTRLr27S5HpzQo4kLr+HjLQIyK4EiCsijDl/TB+h5uEuJU6bQ8Edvwz1XWOjpaP2qgnXGpTcA==", + "node_modules/escodegen/node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", "dev": true, "dependencies": { - "@eslint/eslintrc": "^1.3.1", - "@humanwhocodes/config-array": "^0.10.4", - "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", - "@humanwhocodes/module-importer": "^1.0.1", - "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.1.1", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.3.0", + "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" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/escodegen/node_modules/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, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/escodegen/node_modules/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, + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/eslint": { + "version": "8.27.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.27.0.tgz", + "integrity": "sha512-0y1bfG2ho7mty+SiILVf9PfuRA49ek4Nc60Wmmu62QlobNR+CeXa4xXIJgcuwSQgZiWaPH+5BDsctpIW0PR/wQ==", + "dev": true, + "dependencies": { + "@eslint/eslintrc": "^1.3.3", + "@humanwhocodes/config-array": "^0.11.6", + "@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.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", "espree": "^9.4.0", "esquery": "^1.4.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", "find-up": "^5.0.0", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^6.0.1", + "glob-parent": "^6.0.2", "globals": "^13.15.0", - "globby": "^11.1.0", "grapheme-splitter": "^1.0.4", "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-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", @@ -4839,25 +4587,16 @@ } }, "node_modules/eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "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, "dependencies": { "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" + "estraverse": "^4.1.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/eslint-scope/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" + "node": ">=8.0.0" } }, "node_modules/eslint-utils": { @@ -4896,331 +4635,32 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/eslint/node_modules/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, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/eslint/node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/eslint/node_modules/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, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/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, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/eslint/node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/eslint/node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/eslint/node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/eslint/node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "dependencies": { - "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" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/eslint/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/eslint/node_modules/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, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint/node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/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, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/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, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/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/eslint/node_modules/eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", "dev": true, "dependencies": { - "prelude-ls": "^1.2.1" + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" }, "engines": { - "node": ">= 0.8.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/eslint/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/eslint/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, "engines": { - "node": ">= 8" + "node": ">=4.0" } }, "node_modules/espree": { - "version": "9.4.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", - "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", + "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", "dev": true, "dependencies": { "acorn": "^8.8.0", @@ -5235,16 +4675,16 @@ } }, "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==", + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha512-OarPfz0lFCiW4/AV2Oy1Rp9qu0iusTKqykwTspGCZtPxmF81JR4MmIebvF1F9+UOKth2ZubLQ4XGGaU+hSn99A==", "dev": true, "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" }, "engines": { - "node": ">=4" + "node": ">=0.10.0" } }, "node_modules/esquery": { @@ -5260,9 +4700,9 @@ } }, "node_modules/esquery/node_modules/estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, "engines": { "node": ">=4.0" @@ -5290,12 +4730,12 @@ } }, "node_modules/estraverse": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", - "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=4.0" } }, "node_modules/esutils": { @@ -5307,36 +4747,33 @@ "node": ">=0.10.0" } }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", - "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": "sha1-IprEbsqG1S4MmR58sq74P/D2i88=", + "integrity": "sha512-VWEI1+KJfz4Km//dadyvBBoBeSQ0MHTXPvr8UIXiLW6IanxvAV+DmlZAijZwAyggqGUfwQBeHf7tc9wzc1piSw==", "dev": true, "dependencies": { "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.24", - "resolved": "https://registry.npmjs.org/eth-gas-reporter/-/eth-gas-reporter-0.2.24.tgz", - "integrity": "sha512-RbXLC2bnuPHzIMU/rnLXXlb6oiHEEKu7rq2UrAX/0mfo0Lzrr/kb9QTjWjfz8eNvc+uu6J8AuBwI++b+MLNI2w==", + "version": "0.2.25", + "resolved": "https://registry.npmjs.org/eth-gas-reporter/-/eth-gas-reporter-0.2.25.tgz", + "integrity": "sha512-1fRgyE4xUB8SoqLgN3eDfpDfwEfRxh2Sz1b7wzFbyQA+9TekMmvSjjoRu9SKcSVyK+vLkLIsVbJDsTWjw195OQ==", "dev": true, "dependencies": { "@ethersproject/abi": "^5.0.0-beta.146", "@solidity-parser/parser": "^0.14.0", "cli-table3": "^0.5.0", "colors": "1.4.0", - "ethereumjs-util": "6.2.0", + "ethereum-cryptography": "^1.0.3", "ethers": "^4.0.40", "fs-readdir-recursive": "^1.1.0", "lodash": "^4.17.14", @@ -5357,15 +4794,6 @@ } } }, - "node_modules/eth-gas-reporter/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/eth-gas-reporter/node_modules/ansi-colors": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", @@ -5396,6 +4824,21 @@ "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, + "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==", + "dev": true + }, "node_modules/eth-gas-reporter/node_modules/camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", @@ -5475,9 +4918,18 @@ "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": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "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==", + "dev": true, + "engines": { + "node": ">=0.1.90" + } + }, "node_modules/eth-gas-reporter/node_modules/debug": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", @@ -5497,19 +4949,44 @@ "node": ">=0.3.1" } }, - "node_modules/eth-gas-reporter/node_modules/ethereumjs-util": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.0.tgz", - "integrity": "sha512-vb0XN9J2QGdZGIEKG2vXM+kUdEivUfU6Wmi5y0cg+LRhDYKnXIZ/Lz7XjFbHRR9VIKq2lVGLzGBkA++y2nOdOQ==", + "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==", + "dev": true + }, + "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, + "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, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eth-gas-reporter/node_modules/ethereum-cryptography": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.1.2.tgz", + "integrity": "sha512-XDSJlg4BD+hq9N2FjvotwUET9Tfxpxc3kWGE2AqUG5vcbeunnbImVk3cj6e/xT3phdW21mE8R5IugU4fspQDcQ==", "dev": true, "dependencies": { - "@types/bn.js": "^4.11.3", - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "ethjs-util": "0.1.6", - "keccak": "^2.0.0", - "rlp": "^2.2.3", - "secp256k1": "^3.0.1" + "@noble/hashes": "1.1.2", + "@noble/secp256k1": "1.6.3", + "@scure/bip32": "1.1.0", + "@scure/bip39": "1.1.0" } }, "node_modules/eth-gas-reporter/node_modules/ethers": { @@ -5585,10 +5062,22 @@ "node": "*" } }, + "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==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "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": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, "engines": { "node": ">=4" @@ -5604,20 +5093,23 @@ "minimalistic-assert": "^1.0.0" } }, - "node_modules/eth-gas-reporter/node_modules/keccak": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/keccak/-/keccak-2.1.0.tgz", - "integrity": "sha512-m1wbJRTo+gWbctZWay9i26v5fFnYkOn7D5PCxJ3fZUGUEb49dE1Pm4BREUYCt/aoO6di7jeoGmhvqN9Nzylm3Q==", + "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 + }, + "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==", "dev": true, - "hasInstallScript": true, "dependencies": { - "bindings": "^1.5.0", - "inherits": "^2.0.4", - "nan": "^2.14.0", - "safe-buffer": "^5.2.0" + "argparse": "^1.0.7", + "esprima": "^4.0.0" }, - "engines": { - "node": ">=5.12.0" + "bin": { + "js-yaml": "bin/js-yaml.js" } }, "node_modules/eth-gas-reporter/node_modules/locate-path": { @@ -5645,6 +5137,30 @@ "node": ">=8" } }, + "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==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "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==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, "node_modules/eth-gas-reporter/node_modules/mocha": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", @@ -5694,21 +5210,6 @@ "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", "dev": true }, - "node_modules/eth-gas-reporter/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==", - "dev": true, - "dependencies": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - }, - "engines": { - "node": ">= 0.4" - } - }, "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", @@ -5736,13 +5237,13 @@ "node": ">=6" } }, - "node_modules/eth-gas-reporter/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==", + "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==", "dev": true, "engines": { - "node": ">=6" + "node": ">=4" } }, "node_modules/eth-gas-reporter/node_modules/readdirp": { @@ -5769,30 +5270,10 @@ "integrity": "sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw==", "dev": true }, - "node_modules/eth-gas-reporter/node_modules/secp256k1": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.8.0.tgz", - "integrity": "sha512-k5ke5avRZbtl9Tqx/SA7CbY3NF6Ro+Sj9cZxezFzuBlLDmyqPiL8hJJ+EmzD8Ig4LUDByHJ3/iPOVoRixs/hmw==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "bindings": "^1.5.0", - "bip66": "^1.1.5", - "bn.js": "^4.11.8", - "create-hash": "^1.2.0", - "drbg.js": "^1.0.1", - "elliptic": "^6.5.2", - "nan": "^2.14.0", - "safe-buffer": "^5.1.2" - }, - "engines": { - "node": ">=4.0.0" - } - }, "node_modules/eth-gas-reporter/node_modules/setimmediate": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz", - "integrity": "sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48=", + "integrity": "sha512-/TjEmXQVEzdod/FFskf3o7oOAsGhHf2j1dZqRFbDzq4F3mvvxflIIi4Hd3bLQE9y/CpwqfSQam5JakI/mi3Pog==", "dev": true }, "node_modules/eth-gas-reporter/node_modules/string-width": { @@ -5821,6 +5302,15 @@ "node": ">=6" } }, + "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==", + "dev": true, + "engines": { + "node": ">=0.10.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", @@ -5836,14 +5326,26 @@ "node_modules/eth-gas-reporter/node_modules/uuid": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz", - "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=", + "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 }, + "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==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, "node_modules/eth-gas-reporter/node_modules/which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", "dev": true }, "node_modules/eth-gas-reporter/node_modules/wrap-ansi": { @@ -5908,32 +5410,15 @@ "node": ">=6" } }, - "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": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - } - }, "node_modules/ethereum-bloom-filters": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.9.tgz", - "integrity": "sha512-GiK/RQkAkcVaEdxKVkPcG07PQ5vD7v2MFSHgZmBJSfMzNRHimntdBithsHAT89tAXnIpzVDWt8iaCD1DvkaxGg==", + "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, "dependencies": { "js-sha3": "^0.8.0" } }, - "node_modules/ethereum-bloom-filters/node_modules/js-sha3": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", - "dev": true - }, "node_modules/ethereum-checksum-address": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/ethereum-checksum-address/-/ethereum-checksum-address-0.0.2.tgz", @@ -6024,49 +5509,13 @@ "@types/node": "*" } }, - "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, - "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" - } - }, - "node_modules/ethereumjs-common": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/ethereumjs-common/-/ethereumjs-common-1.5.2.tgz", - "integrity": "sha512-hTfZjwGX52GS2jcVO6E2sx4YuFnf0Fhp5ylo4pEPhEffNln7vS59Hr5sLnp3/QCazFLluuBZ+FZ6J5HTp0EqCA==", - "deprecated": "New package name format for new versions: @ethereumjs/common. Please update.", + "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-tx": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-2.1.2.tgz", - "integrity": "sha512-zZEK1onCeiORb0wyCXUvg94Ve5It/K6GD1K+26KfFKodiBiS6d9lfCXlUKGBBdQ+bv7Day+JK0tj1K+BeNFRAw==", - "deprecated": "New package name format for new versions: @ethereumjs/tx. Please update.", - "dev": true, - "dependencies": { - "ethereumjs-common": "^1.5.0", - "ethereumjs-util": "^6.0.0" - } - }, - "node_modules/ethereumjs-tx/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/ethereumjs-tx/node_modules/ethereumjs-util": { + "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==", @@ -6082,9 +5531,9 @@ } }, "node_modules/ethereumjs-util": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.4.tgz", - "integrity": "sha512-p6KmuPCX4mZIqsQzXfmSx9Y0l2hqf+VkAiwSisW3UKUFdk8ZkAt+AYaor83z2nSi6CU2zSsXMlD80hAbNEGM0A==", + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", + "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", "dev": true, "dependencies": { "@types/bn.js": "^5.1.0", @@ -6097,16 +5546,10 @@ "node": ">=10.0.0" } }, - "node_modules/ethereumjs-util/node_modules/bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", - "dev": true - }, "node_modules/ethers": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.6.2.tgz", - "integrity": "sha512-EzGCbns24/Yluu7+ToWnMca3SXJ1Jk1BvWB7CCmVNxyOeM4LLvw2OLuIHhlkhQk1dtOcj9UMsdkxUh8RiG1dxQ==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", + "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", "dev": true, "funding": [ { @@ -6119,42 +5562,42 @@ } ], "dependencies": { - "@ethersproject/abi": "5.6.0", - "@ethersproject/abstract-provider": "5.6.0", - "@ethersproject/abstract-signer": "5.6.0", - "@ethersproject/address": "5.6.0", - "@ethersproject/base64": "5.6.0", - "@ethersproject/basex": "5.6.0", - "@ethersproject/bignumber": "5.6.0", - "@ethersproject/bytes": "5.6.1", - "@ethersproject/constants": "5.6.0", - "@ethersproject/contracts": "5.6.0", - "@ethersproject/hash": "5.6.0", - "@ethersproject/hdnode": "5.6.0", - "@ethersproject/json-wallets": "5.6.0", - "@ethersproject/keccak256": "5.6.0", - "@ethersproject/logger": "5.6.0", - "@ethersproject/networks": "5.6.1", - "@ethersproject/pbkdf2": "5.6.0", - "@ethersproject/properties": "5.6.0", - "@ethersproject/providers": "5.6.2", - "@ethersproject/random": "5.6.0", - "@ethersproject/rlp": "5.6.0", - "@ethersproject/sha2": "5.6.0", - "@ethersproject/signing-key": "5.6.0", - "@ethersproject/solidity": "5.6.0", - "@ethersproject/strings": "5.6.0", - "@ethersproject/transactions": "5.6.0", - "@ethersproject/units": "5.6.0", - "@ethersproject/wallet": "5.6.0", - "@ethersproject/web": "5.6.0", - "@ethersproject/wordlists": "5.6.0" + "@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/ethjs-unit": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", - "integrity": "sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk=", + "integrity": "sha512-/Sn9Y0oKl0uqQuvgFk/zQgR7aw1g36qX/jzSQ5lSwlO0GigPymk4eGQfeNTD03w1dPOqfz8V77Cy43jH56pagw==", "dev": true, "dependencies": { "bn.js": "4.11.6", @@ -6168,7 +5611,7 @@ "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": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=", + "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", "dev": true }, "node_modules/ethjs-util": { @@ -6194,12 +5637,6 @@ "node": ">=6" } }, - "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/evp_bytestokey": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", @@ -6210,110 +5647,6 @@ "safe-buffer": "^5.1.1" } }, - "node_modules/exit-on-epipe": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz", - "integrity": "sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw==", - "dev": true, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/express": { - "version": "4.17.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", - "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", - "dev": true, - "dependencies": { - "accepts": "~1.3.7", - "array-flatten": "1.1.1", - "body-parser": "1.19.0", - "content-disposition": "0.5.3", - "content-type": "~1.0.4", - "cookie": "0.4.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~1.1.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "~1.1.2", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.5", - "qs": "6.7.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.1.2", - "send": "0.17.1", - "serve-static": "1.14.1", - "setprototypeof": "1.1.1", - "statuses": "~1.5.0", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/express/node_modules/cookie": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", - "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "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, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/express/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/express/node_modules/qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", - "dev": true, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/express/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/ext": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz", - "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==", - "dev": true, - "dependencies": { - "type": "^2.0.0" - } - }, - "node_modules/ext/node_modules/type": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/type/-/type-2.5.0.tgz", - "integrity": "sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw==", - "dev": true - }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -6337,7 +5670,7 @@ "node_modules/extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", "dev": true, "engines": [ "node >=0.6.0" @@ -6356,9 +5689,9 @@ "dev": true }, "node_modules/fast-glob": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", - "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", @@ -6371,6 +5704,18 @@ "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" + }, + "engines": { + "node": ">= 6" + } + }, "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", @@ -6380,13 +5725,13 @@ "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, "node_modules/fastq": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz", - "integrity": "sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g==", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", "dev": true, "dependencies": { "reusify": "^1.0.4" @@ -6404,6 +5749,15 @@ "node": ">=4" } }, + "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, + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -6416,16 +5770,10 @@ "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true - }, "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": "sha1-q/c9+rc10EVECr/qLZHzieu/oik=", + "integrity": "sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==", "dev": true, "engines": { "node": ">=4" @@ -6460,39 +5808,6 @@ "node": ">=8" } }, - "node_modules/finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "dev": true, - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "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, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, "node_modules/find-cache-dir": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", @@ -6513,7 +5828,7 @@ "node_modules/find-replace": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-1.0.3.tgz", - "integrity": "sha1-uI5zZNLZyVlVnziMZmcNYTBEH6A=", + "integrity": "sha512-KrUnjzDCD9426YnCP56zGYy/eieTnhtK6Vn++j+JJzmlsWWwEkDnsyVF575spT6HJ6Ow9tlbT3TQTDsa+O4UWA==", "dev": true, "dependencies": { "array-back": "^1.0.4", @@ -6526,7 +5841,7 @@ "node_modules/find-replace/node_modules/array-back": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", - "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=", + "integrity": "sha512-1WxbZvrmyhkNoeYcizokbmh5oiOCIfyvGtcqbK3Ls1v1fKcquzxnQSceOx6tzq7jmai2kFLWIpGND2cLhH6TPw==", "dev": true, "dependencies": { "typical": "^2.6.0" @@ -6536,15 +5851,19 @@ } }, "node_modules/find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "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, "dependencies": { - "locate-path": "^2.0.0" + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/find-yarn-workspace-root": { @@ -6578,21 +5897,6 @@ "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/flat-cache/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/flatted": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", @@ -6600,9 +5904,9 @@ "dev": true }, "node_modules/follow-redirects": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.0.tgz", - "integrity": "sha512-0vRwd7RKQBTt+mgu87mtYeofLFZpTas2S9zY+jIeuLJMNvudIgF52nr19q40HOwH5RrhWIPuj9puybzSJiRrVg==", + "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": [ { @@ -6619,52 +5923,34 @@ } } }, - "node_modules/foreach": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", - "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", - "dev": true - }, "node_modules/forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", "dev": 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==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", "dev": true, "dependencies": { "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", + "combined-stream": "^1.0.8", "mime-types": "^2.1.12" }, "engines": { - "node": ">= 0.12" - } - }, - "node_modules/forwarded": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", - "dev": true, - "engines": { - "node": ">= 0.6" + "node": ">= 6" } }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", - "dev": true, - "engines": { - "node": ">= 0.6" - } + "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", @@ -6680,15 +5966,6 @@ "node": ">=6 <7 || >=8" } }, - "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, - "dependencies": { - "minipass": "^2.6.0" - } - }, "node_modules/fs-readdir-recursive": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", @@ -6698,7 +5975,7 @@ "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true }, "node_modules/fsevents": { @@ -6721,12 +5998,39 @@ "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, + "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": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "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, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/ganache-core": { "version": "2.13.2", "resolved": "https://registry.npmjs.org/ganache-core/-/ganache-core-2.13.2.tgz", @@ -15917,21 +15221,21 @@ "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": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", "dev": true, "engines": { "node": "*" } }, "node_modules/get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", + "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", "dev": true, "dependencies": { "function-bind": "^1.1.1", "has": "^1.0.3", - "has-symbols": "^1.0.1" + "has-symbols": "^1.0.3" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -15940,24 +15244,12 @@ "node_modules/get-port": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", - "integrity": "sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw=", + "integrity": "sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==", "dev": true, "engines": { "node": ">=4" } }, - "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": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/get-symbol-description": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", @@ -15977,7 +15269,7 @@ "node_modules/getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", "dev": true, "dependencies": { "assert-plus": "^1.0.0" @@ -16008,7 +15300,7 @@ "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": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", "dev": true, "dependencies": { "array-uniq": "^1.0.1" @@ -16017,12 +15309,6 @@ "node": ">=0.10.0" } }, - "node_modules/gh-pages/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, "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", @@ -16040,7 +15326,7 @@ "node_modules/gh-pages/node_modules/globby": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "integrity": "sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw==", "dev": true, "dependencies": { "array-union": "^1.0.1", @@ -16056,7 +15342,7 @@ "node_modules/gh-pages/node_modules/pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", "dev": true, "engines": { "node": ">=0.10.0" @@ -16113,13 +15399,22 @@ "node_modules/ghost-testrpc/node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, + "node_modules/ghost-testrpc/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/ghost-testrpc/node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, "engines": { "node": ">=4" @@ -16138,9 +15433,9 @@ } }, "node_modules/glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", "dev": true, "dependencies": { "fs.realpath": "^1.0.0", @@ -16158,25 +15453,15 @@ } }, "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==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, "dependencies": { - "is-glob": "^4.0.1" + "is-glob": "^4.0.3" }, "engines": { - "node": ">= 6" - } - }, - "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": ">=10.13.0" } }, "node_modules/global-modules": { @@ -16205,6 +15490,18 @@ "node": ">=6" } }, + "node_modules/global-prefix/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, "node_modules/globals": { "version": "13.17.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", @@ -16220,72 +15517,30 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/globals/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, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/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==", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, "dependencies": { - "@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", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", "slash": "^3.0.0" }, "engines": { - "node": ">=8" - } - }, - "node_modules/globby/node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "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" + "node": ">=10" }, - "engines": { - "node": ">=8.6" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/graceful-fs": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", - "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", "dev": true }, "node_modules/grapheme-splitter": { @@ -16324,10 +15579,19 @@ "uglify-js": "^3.1.4" } }, + "node_modules/handlebars/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_modules/har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", "dev": true, "engines": { "node": ">=4" @@ -16348,20 +15612,25 @@ } }, "node_modules/hardhat": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.9.2.tgz", - "integrity": "sha512-elTcUK1EdFverWinybQ+DoJzsM6sgiHUYs0ZYNNXMfESty6ESHiFSwkfJsC88/q09vmIz6YVaMh73BYnYd+feQ==", + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.12.2.tgz", + "integrity": "sha512-f3ZhzXy1uyQv0UXnAQ8GCBOWjzv++WJNb7bnm10SsyC3dB7vlPpsMWBNhq7aoRxKrNhX9tCev81KFV3i5BTeMQ==", "dev": true, "dependencies": { - "@ethereumjs/block": "^3.6.0", - "@ethereumjs/blockchain": "^5.5.0", - "@ethereumjs/common": "^2.6.0", - "@ethereumjs/tx": "^3.4.0", - "@ethereumjs/vm": "^5.6.0", "@ethersproject/abi": "^5.1.2", "@metamask/eth-sig-util": "^4.0.0", + "@nomicfoundation/ethereumjs-block": "^4.0.0", + "@nomicfoundation/ethereumjs-blockchain": "^6.0.0", + "@nomicfoundation/ethereumjs-common": "^3.0.0", + "@nomicfoundation/ethereumjs-evm": "^1.0.0", + "@nomicfoundation/ethereumjs-rlp": "^4.0.0", + "@nomicfoundation/ethereumjs-statemanager": "^1.0.0", + "@nomicfoundation/ethereumjs-trie": "^5.0.0", + "@nomicfoundation/ethereumjs-tx": "^4.0.0", + "@nomicfoundation/ethereumjs-util": "^8.0.0", + "@nomicfoundation/ethereumjs-vm": "^6.0.0", + "@nomicfoundation/solidity-analyzer": "^0.1.0", "@sentry/node": "^5.18.1", - "@solidity-parser/parser": "^0.14.1", "@types/bn.js": "^5.1.0", "@types/lru-cache": "^5.1.0", "abort-controller": "^3.0.0", @@ -16374,31 +15643,28 @@ "debug": "^4.1.1", "enquirer": "^2.3.0", "env-paths": "^2.2.0", - "ethereum-cryptography": "^0.1.2", + "ethereum-cryptography": "^1.0.3", "ethereumjs-abi": "^0.6.8", - "ethereumjs-util": "^7.1.3", "find-up": "^2.1.0", "fp-ts": "1.19.3", "fs-extra": "^7.0.1", - "glob": "^7.1.3", + "glob": "7.2.0", "immutable": "^4.0.0-rc.12", "io-ts": "1.10.4", + "keccak": "^3.0.2", "lodash": "^4.17.11", - "merkle-patricia-tree": "^4.2.2", "mnemonist": "^0.38.0", - "mocha": "^9.2.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", - "slash": "^3.0.0", "solc": "0.7.3", "source-map-support": "^0.5.13", "stacktrace-parser": "^0.1.10", - "true-case-path": "^2.2.1", "tsort": "0.0.1", - "undici": "^4.14.1", + "undici": "^5.4.0", "uuid": "^8.3.2", "ws": "^7.4.6" }, @@ -16406,17 +15672,29 @@ "hardhat": "internal/cli/cli.js" }, "engines": { - "node": "^12.0.0 || ^14.0.0 || ^16.0.0" + "node": "^14.0.0 || ^16.0.0 || ^18.0.0" + }, + "peerDependencies": { + "ts-node": "*", + "typescript": "*" + }, + "peerDependenciesMeta": { + "ts-node": { + "optional": true + }, + "typescript": { + "optional": true + } } }, "node_modules/hardhat-gas-reporter": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.8.tgz", - "integrity": "sha512-1G5thPnnhcwLHsFnl759f2tgElvuwdkzxlI65fC9PwxYMEe9cmjkVAAWTf3/3y8uP6ZSPiUiOW8PgZnykmZe0g==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.9.tgz", + "integrity": "sha512-INN26G3EW43adGKBNzYWOlI3+rlLnasXTwW79YNnUhXPDa+yHESgt639dJEs37gCjhkbNKcRRJnomXEuMFBXJg==", "dev": true, "dependencies": { "array-uniq": "1.0.3", - "eth-gas-reporter": "^0.2.24", + "eth-gas-reporter": "^0.2.25", "sha1": "^1.1.1" }, "peerDependencies": { @@ -16424,9 +15702,9 @@ } }, "node_modules/hardhat-tracer": { - "version": "1.1.0-rc.3", - "resolved": "https://registry.npmjs.org/hardhat-tracer/-/hardhat-tracer-1.1.0-rc.3.tgz", - "integrity": "sha512-UGOfwRXkdxWM66JqcyGDJfIjiDXNkqgiaomLPvILg3nppVTjxtBmddYtnvGhDrV9FE1NgWyBnP1B35NaRIKM8A==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/hardhat-tracer/-/hardhat-tracer-1.1.1.tgz", + "integrity": "sha512-NgOnnNAvARBtYC5x5c7Qcbw+lr+Jb+0OV1NC2tTpUUQj0ym+/0y42F0CYT/zKnHw3uf046NKg0CNTzYg1j0JWg==", "dev": true, "dependencies": { "ethers": "^5.6.1" @@ -16475,82 +15753,131 @@ "node_modules/hardhat/node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, - "node_modules/hardhat/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==", + "node_modules/hardhat/node_modules/commander": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz", + "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==", "dev": true }, - "node_modules/hardhat/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "node_modules/hardhat/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": ">=4" + "node": ">=0.8.0" } }, - "node_modules/hardhat/node_modules/io-ts": { - "version": "1.10.4", - "resolved": "https://registry.npmjs.org/io-ts/-/io-ts-1.10.4.tgz", - "integrity": "sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g==", + "node_modules/hardhat/node_modules/ethereum-cryptography": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.1.2.tgz", + "integrity": "sha512-XDSJlg4BD+hq9N2FjvotwUET9Tfxpxc3kWGE2AqUG5vcbeunnbImVk3cj6e/xT3phdW21mE8R5IugU4fspQDcQ==", "dev": true, "dependencies": { - "fp-ts": "^1.0.0" + "@noble/hashes": "1.1.2", + "@noble/secp256k1": "1.6.3", + "@scure/bip32": "1.1.0", + "@scure/bip39": "1.1.0" } }, - "node_modules/hardhat/node_modules/js-sha3": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", - "dev": true + "node_modules/hardhat/node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", + "dev": true, + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/hardhat/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/hardhat/node_modules/jsonfile": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "integrity": "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==", "dev": true, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, - "node_modules/hardhat/node_modules/qs": { - "version": "6.10.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz", - "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==", + "node_modules/hardhat/node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", "dev": true, "dependencies": { - "side-channel": "^1.0.4" + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" }, "engines": { - "node": ">=0.6" + "node": ">=4" + } + }, + "node_modules/hardhat/node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "dependencies": { + "p-try": "^1.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=4" } }, - "node_modules/hardhat/node_modules/resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "node_modules/hardhat/node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", "dev": true, "dependencies": { - "path-parse": "^1.0.6" + "p-limit": "^1.1.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=4" } }, - "node_modules/hardhat/node_modules/slash": { + "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/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", "dev": true, "engines": { - "node": ">=8" + "node": ">=4" + } + }, + "node_modules/hardhat/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" } }, "node_modules/hardhat/node_modules/solc": { @@ -16579,7 +15906,7 @@ "node_modules/hardhat/node_modules/solc/node_modules/fs-extra": { "version": "0.30.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", - "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", + "integrity": "sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==", "dev": true, "dependencies": { "graceful-fs": "^4.1.2", @@ -16610,15 +15937,6 @@ "node": ">=4" } }, - "node_modules/hardhat/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==", - "dev": true, - "bin": { - "uuid": "dist/bin/uuid" - } - }, "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -16632,9 +15950,9 @@ } }, "node_modules/has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", + "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, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -16649,13 +15967,16 @@ "node": ">=8" } }, - "node_modules/has-symbol-support-x": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz", - "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==", + "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==", "dev": true, - "engines": { - "node": "*" + "dependencies": { + "get-intrinsic": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-symbols": { @@ -16670,18 +15991,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-to-string-tag-x": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz", - "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==", - "dev": true, - "dependencies": { - "has-symbol-support-x": "^1.4.1" - }, - "engines": { - "node": "*" - } - }, "node_modules/has-tostringtag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", @@ -16730,10 +16039,16 @@ "he": "bin/he" } }, + "node_modules/heap": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.7.tgz", + "integrity": "sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==", + "dev": true + }, "node_modules/hmac-drbg": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", "dev": true, "dependencies": { "hash.js": "^1.0.3", @@ -16762,34 +16077,22 @@ "node": ">=6.0.0" } }, - "node_modules/http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", - "dev": true - }, "node_modules/http-errors": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", - "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", "dev": true, "dependencies": { - "depd": "~1.1.2", + "depd": "2.0.0", "inherits": "2.0.4", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" }, "engines": { - "node": ">= 0.6" + "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": "sha1-L5CN1fHbQGjAWM1ubUzjkskTOJs=", - "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", @@ -16808,7 +16111,7 @@ "node_modules/http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", "dev": true, "dependencies": { "assert-plus": "^1.0.0", @@ -16821,9 +16124,9 @@ } }, "node_modules/https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", "dev": true, "dependencies": { "agent-base": "6", @@ -16886,53 +16189,50 @@ "node": ">= 4" } }, - "node_modules/immediate": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz", - "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==", - "dev": true - }, "node_modules/immutable": { - "version": "4.0.0-rc.12", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.0.0-rc.12.tgz", - "integrity": "sha512-0M2XxkZLx/mi3t8NVwIm1g8nHoEmM9p9UBl/G9k4+hm0kBgOVdMV/B3CY5dQ8qG8qc80NN4gDV4HQv6FTJ5q7A==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz", + "integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==", "dev": true }, "node_modules/import-fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", - "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, "dependencies": { - "caller-path": "^2.0.0", - "resolve-from": "^3.0.0" + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" }, "engines": { - "node": ">=4" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, "engines": { "node": ">=0.8.19" } }, "node_modules/indent-string": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", - "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "dev": true, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dev": true, "dependencies": { "once": "^1.3.0", @@ -17034,6 +16334,15 @@ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, + "node_modules/inquirer/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/inquirer/node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -17093,47 +16402,35 @@ "node_modules/invert-kv": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", + "integrity": "sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ==", "dev": true, "engines": { "node": ">=0.10.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.0", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.0.tgz", - "integrity": "sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg==", + "node_modules/io-ts": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/io-ts/-/io-ts-1.10.4.tgz", + "integrity": "sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g==", "dev": true, "dependencies": { - "call-bind": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "fp-ts": "^1.0.0" } }, "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "dev": true }, "node_modules/is-bigint": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.2.tgz", - "integrity": "sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", "dev": true, + "dependencies": { + "has-bigints": "^1.0.1" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -17151,12 +16448,13 @@ } }, "node_modules/is-boolean-object": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.1.tgz", - "integrity": "sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", "dev": true, "dependencies": { - "call-bind": "^1.0.2" + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -17189,9 +16487,9 @@ } }, "node_modules/is-callable": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "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, "engines": { "node": ">= 0.4" @@ -17212,23 +16510,14 @@ "is-ci": "bin.js" } }, - "node_modules/is-core-module": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.3.0.tgz", - "integrity": "sha512-xSphU2KG9867tsYdLD4RWQ1VqdFl4HTO9Thf3I/3dLEfr0dbPTWKsuCKrgqMljg4nPE+Gq0VCnzT3gr0CyBmsw==", + "node_modules/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, "dependencies": { - "has": "^1.0.3" + "has-tostringtag": "^1.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-date-object": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.4.tgz", - "integrity": "sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A==", - "dev": true, "engines": { "node": ">= 0.4" }, @@ -17239,7 +16528,7 @@ "node_modules/is-directory": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", - "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", + "integrity": "sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw==", "dev": true, "engines": { "node": ">=0.10.0" @@ -17263,7 +16552,7 @@ "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, "engines": { "node": ">=0.10.0" @@ -17272,30 +16561,12 @@ "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": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", "dev": true, "engines": { "node": ">=4" } }, - "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.9", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.9.tgz", - "integrity": "sha512-ZJ34p1uvIfptHCN7sFTjGibB9/oBg17sHqzDLfuwhvmN/qLVvIQXRQ8licZQ35WJ8KuEQt/etnnzQFI9C9Ue/A==", - "dev": true, - "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", @@ -17311,7 +16582,7 @@ "node_modules/is-hex-prefixed": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", - "integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ=", + "integrity": "sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==", "dev": true, "engines": { "node": ">=6.5.0", @@ -17340,10 +16611,13 @@ } }, "node_modules/is-number-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.5.tgz", - "integrity": "sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, "engines": { "node": ">= 0.4" }, @@ -17351,19 +16625,19 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.2.tgz", - "integrity": "sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==", + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=8" } }, "node_modules/is-plain-obj": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", "dev": true, "engines": { "node": ">=0.10.0" @@ -17385,33 +16659,18 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-retry-allowed": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", - "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-shared-array-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", - "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==", + "version": "1.0.2", + "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, + "dependencies": { + "call-bind": "^1.0.2" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-string": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", @@ -17442,29 +16701,10 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-typed-array": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.5.tgz", - "integrity": "sha512-S+GRDgJlR3PyEbsX/Fobd9cqpZBuvUS+8asRqYDMLCb2qMzt1oz5m5oxQCxOgUDxiWsOVNi4yaF+/uvdlHlYug==", - "dev": true, - "dependencies": { - "available-typed-arrays": "^1.0.2", - "call-bind": "^1.0.2", - "es-abstract": "^1.18.0-next.2", - "foreach": "^2.0.5", - "has-symbols": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", "dev": true }, "node_modules/is-unicode-supported": { @@ -17488,7 +16728,7 @@ "node_modules/is-utf8": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==", "dev": true }, "node_modules/is-weakref": { @@ -17518,38 +16758,31 @@ "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", "dev": true }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, "node_modules/isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", "dev": true }, - "node_modules/isurl": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz", - "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==", - "dev": true, - "dependencies": { - "has-to-string-tag-x": "^1.2.0", - "is-object": "^1.0.1" - }, - "engines": { - "node": ">= 4" - } + "node_modules/js-sdsl": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.5.tgz", + "integrity": "sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q==", + "dev": true }, "node_modules/js-sha3": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", - "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=", + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", "dev": true }, "node_modules/js-tokens": { @@ -17559,13 +16792,12 @@ "dev": true }, "node_modules/js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" @@ -17574,13 +16806,7 @@ "node_modules/jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true - }, - "node_modules/json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", "dev": true }, "node_modules/json-parse-better-errors": { @@ -17590,9 +16816,9 @@ "dev": true }, "node_modules/json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", "dev": true }, "node_modules/json-schema-traverse": { @@ -17604,79 +16830,72 @@ "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, "node_modules/json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", "dev": true }, "node_modules/jsonfile": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", "dev": true, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "node_modules/jsonschema": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.0.tgz", - "integrity": "sha512-/YgW6pRMr6M7C+4o8kS+B/2myEpHCrxO4PEWnqJNBFMjn7EWXqlQ4tGwL6xTHeRplwuZmcAncdvfOad1nT2yMw==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.1.tgz", + "integrity": "sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ==", "dev": true, "engines": { "node": "*" } }, "node_modules/jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", "dev": true, - "engines": [ - "node >=0.6.0" - ], "dependencies": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", - "json-schema": "0.2.3", + "json-schema": "0.4.0", "verror": "1.10.0" + }, + "engines": { + "node": ">=0.6.0" } }, "node_modules/keccak": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.1.tgz", - "integrity": "sha512-epq90L9jlFWCW7+pQa6JOnKn2Xgl2mtI664seYR6MHskvI9agt7AnDqmAlp9TqU4/caMYbA08Hi5DMZAl5zdkA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.2.tgz", + "integrity": "sha512-PyKKjkH53wDMLGrvmRGSNWgmSxZOUqbnXwKL9tmgbFYA1iAYqW21kfR7mZXV0MlESiefxQQE9X9fTa3X+2MPDQ==", "dev": true, "hasInstallScript": true, "dependencies": { "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" + "node-gyp-build": "^4.2.0", + "readable-stream": "^3.6.0" }, "engines": { "node": ">=10.0.0" } }, "node_modules/keccak256": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/keccak256/-/keccak256-1.0.2.tgz", - "integrity": "sha512-f2EncSgmHmmQOkgxZ+/f2VaWTNkFL6f39VIrpoX+p8cEXJVyyCs/3h9GNz/ViHgwchxvv7oG5mjT2Tk4ZqInag==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.8", - "keccak": "^3.0.1" - } - }, - "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==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/keccak256/-/keccak256-1.0.6.tgz", + "integrity": "sha512-8GLiM01PkdJVGUhR1e6M/AvWnSqYS0HaERI+K/QtStGDGlSTx2B1zTqZk4Zlqu5TxHJNTxWAdP9Y+WI50OApUw==", "dev": true, "dependencies": { - "json-buffer": "3.0.0" + "bn.js": "^5.2.0", + "buffer": "^6.0.3", + "keccak": "^3.0.2" } }, "node_modules/kind-of": { @@ -17691,7 +16910,7 @@ "node_modules/klaw": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", - "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", + "integrity": "sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw==", "dev": true, "optionalDependencies": { "graceful-fs": "^4.1.9" @@ -17718,7 +16937,7 @@ "node_modules/lcid": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "integrity": "sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw==", "dev": true, "dependencies": { "invert-kv": "^1.0.0" @@ -17727,129 +16946,53 @@ "node": ">=0.10.0" } }, - "node_modules/level-codec": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-9.0.2.tgz", - "integrity": "sha512-UyIwNb1lJBChJnGfjmO0OR+ezh2iVu1Kas3nvBS/BzGnx79dv6g7unpKIDNPMhfdTEGoc7mC8uAu51XEtX+FHQ==", - "dev": true, - "dependencies": { - "buffer": "^5.6.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/level-concat-iterator": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/level-concat-iterator/-/level-concat-iterator-2.0.1.tgz", - "integrity": "sha512-OTKKOqeav2QWcERMJR7IS9CUo1sHnke2C0gkSmcR7QuEtFNLLzHQAvnMw8ykvEcv0Qtkg0p7FOwP1v9e5Smdcw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/level-errors": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-2.0.1.tgz", - "integrity": "sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw==", - "dev": true, - "dependencies": { - "errno": "~0.1.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/level-iterator-stream": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-4.0.2.tgz", - "integrity": "sha512-ZSthfEqzGSOMWoUGhTXdX9jv26d32XJuHz/5YnuHZzH6wldfWMOVwI9TBtKcya4BKTyTt3XVA0A3cF3q5CY30Q==", - "dev": true, - "dependencies": { - "inherits": "^2.0.4", - "readable-stream": "^3.4.0", - "xtend": "^4.0.2" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/level-mem": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/level-mem/-/level-mem-5.0.1.tgz", - "integrity": "sha512-qd+qUJHXsGSFoHTziptAKXoLX87QjR7v2KMbqncDXPxQuCdsQlzmyX+gwrEHhlzn08vkf8TyipYyMmiC6Gobzg==", + "node_modules/level": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/level/-/level-8.0.0.tgz", + "integrity": "sha512-ypf0jjAk2BWI33yzEaaotpq7fkOPALKAgDBxggO6Q9HGX2MRXn0wbP1Jn/tJv1gtL867+YOjOB49WaUF3UoJNQ==", "dev": true, "dependencies": { - "level-packager": "^5.0.3", - "memdown": "^5.0.0" + "browser-level": "^1.0.1", + "classic-level": "^1.2.0" }, "engines": { - "node": ">=6" - } - }, - "node_modules/level-packager": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/level-packager/-/level-packager-5.1.1.tgz", - "integrity": "sha512-HMwMaQPlTC1IlcwT3+swhqf/NUO+ZhXVz6TY1zZIIZlIR0YSn8GtAAWmIvKjNY16ZkEg/JcpAuQskxsXqC0yOQ==", - "dev": true, - "dependencies": { - "encoding-down": "^6.3.0", - "levelup": "^4.3.2" + "node": ">=12" }, - "engines": { - "node": ">=6" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/level" } }, "node_modules/level-supports": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/level-supports/-/level-supports-1.0.1.tgz", - "integrity": "sha512-rXM7GYnW8gsl1vedTJIbzOrRv85c/2uCMpiiCzO2fndd06U/kUXEEU9evYn4zFggBOg36IsBW8LzqIpETwwQzg==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/level-supports/-/level-supports-4.0.1.tgz", + "integrity": "sha512-PbXpve8rKeNcZ9C1mUicC9auIYFyGpkV9/i6g76tLgANwWhtG2v7I4xNBUlkn3lE2/dZF3Pi0ygYGtLc4RXXdA==", "dev": true, - "dependencies": { - "xtend": "^4.0.2" - }, "engines": { - "node": ">=6" - } - }, - "node_modules/level-ws": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-2.0.0.tgz", - "integrity": "sha512-1iv7VXx0G9ec1isqQZ7y5LmoZo/ewAsyDHNA8EFDW5hqH2Kqovm33nSFkSdnLLAK+I5FlT+lo5Cw9itGe+CpQA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "readable-stream": "^3.1.0", - "xtend": "^4.0.1" - }, - "engines": { - "node": ">=6" + "node": ">=12" } }, - "node_modules/levelup": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/levelup/-/levelup-4.4.0.tgz", - "integrity": "sha512-94++VFO3qN95cM/d6eBXvd894oJE0w3cInq9USsyQzzoJxmiYzPAocNcuGCPGGjoXqDVJcr3C1jzt1TSjyaiLQ==", + "node_modules/level-transcoder": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/level-transcoder/-/level-transcoder-1.0.1.tgz", + "integrity": "sha512-t7bFwFtsQeD8cl8NIoQ2iwxA0CL/9IFw7/9gAjOonH0PWTTiRfY7Hq+Ejbsxh86tXobDQ6IOiddjNYIfOBs06w==", "dev": true, "dependencies": { - "deferred-leveldown": "~5.3.0", - "level-errors": "~2.0.0", - "level-iterator-stream": "~4.0.0", - "level-supports": "~1.0.0", - "xtend": "~4.0.0" + "buffer": "^6.0.3", + "module-error": "^1.0.1" }, "engines": { - "node": ">=6" + "node": ">=12" } }, "node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" }, "engines": { "node": ">= 0.8.0" @@ -17858,7 +17001,7 @@ "node_modules/load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", "dev": true, "dependencies": { "graceful-fs": "^4.1.2", @@ -17871,16 +17014,18 @@ } }, "node_modules/locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "dependencies": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" + "p-locate": "^5.0.0" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/lodash": { @@ -17892,7 +17037,7 @@ "node_modules/lodash.assign": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", - "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=", + "integrity": "sha512-hFuH8TY+Yji7Eja3mGiuAxBqLagejScbG8GbG0j6o9vzn0YL14My+ktnqtZgFTosKymC9/44wP6s7xyuLfnClw==", "dev": true }, "node_modules/lodash.merge": { @@ -17901,10 +17046,10 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, - "node_modules/lodash.toarray": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.toarray/-/lodash.toarray-4.4.0.tgz", - "integrity": "sha1-JMS/zWsvuji/0FlNsRedjptlZWE=", + "node_modules/lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", "dev": true }, "node_modules/log-symbols": { @@ -17926,7 +17071,7 @@ "node_modules/loud-rejection": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", - "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "integrity": "sha512-RPNliZOFkqFumDhvYqOaNY4Uz9oJM2K9tC6JWsJJsNdhuONW4LQHRBpb0qf4pJApVffI5N39SwzWZJuEhfd7eQ==", "dev": true, "dependencies": { "currently-unhandled": "^0.4.1", @@ -17937,27 +17082,18 @@ } }, "node_modules/loupe": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz", - "integrity": "sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==", + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz", + "integrity": "sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==", "dev": true, "dependencies": { "get-func-name": "^2.0.0" } }, - "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": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz", - "integrity": "sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0=", + "integrity": "sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==", "dev": true }, "node_modules/lru-cache": { @@ -17969,12 +17105,6 @@ "yallist": "^3.0.2" } }, - "node_modules/ltgt": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz", - "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=", - "dev": true - }, "node_modules/make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -17999,7 +17129,7 @@ "node_modules/map-obj": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz", - "integrity": "sha1-plzSkIepJZi4eRJXpSPgISIqwfk=", + "integrity": "sha512-TzQSV2DiMYgoF5RycneKVUzIa9bQsj/B3tTgsE3dOGqlzHnGIDaC7XBE7grnA+8kZPnfqSGFe95VHc2oc0VFUQ==", "dev": true, "engines": { "node": ">=4" @@ -18031,58 +17161,24 @@ "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": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/memdown": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/memdown/-/memdown-5.1.0.tgz", - "integrity": "sha512-B3J+UizMRAlEArDjWHTMmadet+UKwHd3UjMgGBkZcKAxAYVPS9o0Yeiha4qvz7iGiL2Sb3igUft6p7nbFWctpw==", - "dev": true, - "dependencies": { - "abstract-leveldown": "~6.2.1", - "functional-red-black-tree": "~1.0.1", - "immediate": "~3.2.3", - "inherits": "~2.0.1", - "ltgt": "~2.2.0", - "safe-buffer": "~5.2.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/memdown/node_modules/abstract-leveldown": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.2.3.tgz", - "integrity": "sha512-BsLm5vFMRUrrLeCcRc+G0t2qOaTzpoJQLOubq2XM72eNpjF5UdU5o/5NvlNhx95XHcAvcl8OMXr4mlg/fRgUXQ==", + "node_modules/memory-level": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/memory-level/-/memory-level-1.0.0.tgz", + "integrity": "sha512-UXzwewuWeHBz5krr7EvehKcmLFNoXxGcvuYhC41tRnkrTbJohtS7kVn9akmgirtRygg+f7Yjsfi8Uu5SGSQ4Og==", "dev": true, "dependencies": { - "buffer": "^5.5.0", - "immediate": "^3.2.3", - "level-concat-iterator": "~2.0.0", - "level-supports": "~1.0.0", - "xtend": "~4.0.0" + "abstract-level": "^1.0.0", + "functional-red-black-tree": "^1.0.1", + "module-error": "^1.0.1" }, "engines": { - "node": ">=6" + "node": ">=12" } }, - "node_modules/memdown/node_modules/immediate": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.2.3.tgz", - "integrity": "sha1-0UD6j2FGWb1lQSMwl92qwlzdmRw=", - "dev": true - }, "node_modules/memorystream": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", - "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=", + "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", "dev": true, "engines": { "node": ">= 0.10.0" @@ -18108,12 +17204,6 @@ "node": ">=6" } }, - "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", - "dev": true - }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -18123,83 +17213,35 @@ "node": ">= 8" } }, - "node_modules/merkle-patricia-tree": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-4.2.4.tgz", - "integrity": "sha512-eHbf/BG6eGNsqqfbLED9rIqbsF4+sykEaBn6OLNs71tjclbMcMOk1tEPmJKcNcNCLkvbpY/lwyOlizWsqPNo8w==", - "dev": true, - "dependencies": { - "@types/levelup": "^4.3.0", - "ethereumjs-util": "^7.1.4", - "level-mem": "^5.0.1", - "level-ws": "^2.0.0", - "readable-stream": "^3.6.0", - "semaphore-async-await": "^1.5.1" - } - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "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.1", - "picomatch": "^2.2.3" + "braces": "^3.0.2", + "picomatch": "^2.3.1" }, "engines": { "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/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.47.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz", - "integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==", + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "dev": true, "engines": { "node": ">= 0.6" } }, "node_modules/mime-types": { - "version": "2.1.30", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz", - "integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==", + "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, "dependencies": { - "mime-db": "1.47.0" + "mime-db": "1.52.0" }, "engines": { "node": ">= 0.6" @@ -18214,24 +17256,6 @@ "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": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", - "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", @@ -18241,13 +17265,13 @@ "node_modules/minimalistic-crypto-utils": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", "dev": true }, "node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "dependencies": { "brace-expansion": "^1.1.7" @@ -18257,10 +17281,13 @@ } }, "node_modules/minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", + "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/minimist-options": { "version": "3.0.2", @@ -18275,252 +17302,92 @@ "node": ">= 4" } }, - "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.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", "dev": true, "dependencies": { - "minimist": "^1.2.5" + "minimist": "^1.2.6" }, "bin": { "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": "sha1-6bj2jlUsaKnBcTuEiD96HdA5uKE=", - "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.3", - "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.38.3.tgz", - "integrity": "sha512-2K9QYubXx/NAjv4VLq1d1Ly8pWNC5L3BrixtdkyTegXWJIqY+zLNDhhX/A+ZwWt70tB1S8H4BE8FLYEFyNoOBw==", + "version": "0.38.5", + "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.38.5.tgz", + "integrity": "sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg==", "dev": true, "dependencies": { - "obliterator": "^1.6.1" + "obliterator": "^2.0.0" } }, "node_modules/mocha": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz", - "integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.1.0.tgz", + "integrity": "sha512-vUF7IYxEoN7XhQpFLxQAEMtE4W91acW4B6En9l97MwE9stL1A9gusXfoHZCLVHDUJ/7V5+lbCM6yMqzo5vNymg==", "dev": true, "dependencies": { - "@ungap/promise-all-settled": "1.1.2", "ansi-colors": "4.1.1", "browser-stdout": "1.3.1", "chokidar": "3.5.3", - "debug": "4.3.3", + "debug": "4.3.4", "diff": "5.0.0", "escape-string-regexp": "4.0.0", "find-up": "5.0.0", "glob": "7.2.0", - "growl": "1.10.5", "he": "1.2.0", "js-yaml": "4.1.0", "log-symbols": "4.1.0", - "minimatch": "4.2.1", + "minimatch": "5.0.1", "ms": "2.1.3", - "nanoid": "3.3.1", + "nanoid": "3.3.3", "serialize-javascript": "6.0.0", "strip-json-comments": "3.1.1", "supports-color": "8.1.1", - "which": "2.0.2", - "workerpool": "6.2.0", + "workerpool": "6.2.1", "yargs": "16.2.0", "yargs-parser": "20.2.4", "yargs-unparser": "2.0.0" }, "bin": { "_mocha": "bin/_mocha", - "mocha": "bin/mocha" + "mocha": "bin/mocha.js" }, "engines": { - "node": ">= 12.0.0" + "node": ">= 14.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/mochajs" } }, - "node_modules/mocha/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/mocha/node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.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" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/mocha/node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/mocha/node_modules/debug/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/mocha/node_modules/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, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mocha/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, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mocha/node_modules/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dev": 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": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/mocha/node_modules/glob/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/mocha/node_modules/ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, "engines": { - "node": "*" - } - }, - "node_modules/mocha/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "node": ">=6" } }, - "node_modules/mocha/node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "node_modules/mocha/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "balanced-match": "^1.0.0" } }, "node_modules/mocha/node_modules/minimatch": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz", - "integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", + "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", "dev": true, "dependencies": { - "brace-expansion": "^1.1.7" + "brace-expansion": "^2.0.1" }, "engines": { "node": ">=10" @@ -18532,69 +17399,6 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, - "node_modules/mocha/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mocha/node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mocha/node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/mocha/node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/mocha/node_modules/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, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/mocha/node_modules/supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -18610,21 +17414,6 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/mocha/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, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/mocha/node_modules/yargs-parser": { "version": "20.2.4", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", @@ -18634,11 +17423,14 @@ "node": ">=10" } }, - "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", + "integrity": "sha512-0yuvsqSCv8LbaOKhnsQ/T5JhyFlCYLPXK3U2sgV10zoKQwzs/MyfuQUOZQ1V/6OCOJsK/TRgNVrPuPDqtdMFtA==", + "dev": true, + "engines": { + "node": ">=10" + } }, "node_modules/ms": { "version": "2.1.2", @@ -18646,71 +17438,16 @@ "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/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/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/nan": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", - "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==", - "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": "sha1-DMj20OK2IrR5xA1JnEbWS3Vcb18=", - "dev": true - }, "node_modules/nanoid": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", - "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", + "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", "dev": true, "bin": { "nanoid": "bin/nanoid.cjs" @@ -18719,20 +17456,23 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/napi-macros": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/napi-macros/-/napi-macros-2.0.0.tgz", + "integrity": "sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg==", + "dev": true + }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, - "node_modules/negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", - "dev": true, - "engines": { - "node": ">= 0.6" - } + "node_modules/natural-compare-lite": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", + "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", + "dev": true }, "node_modules/neo-async": { "version": "2.6.2", @@ -18740,12 +17480,6 @@ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "dev": true }, - "node_modules/next-tick": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", - "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", - "dev": true - }, "node_modules/nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", @@ -18759,12 +17493,12 @@ "dev": true }, "node_modules/node-emoji": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.10.0.tgz", - "integrity": "sha512-Yt3384If5H6BYGVHiHwTL+99OzJKHhgp82S8/dktEK73T26BazdgZ4JZh92xSVtGNJvz9UbXdNAc5hcrXV42vw==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", + "integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==", "dev": true, "dependencies": { - "lodash.toarray": "^4.4.0" + "lodash": "^4.17.21" } }, "node_modules/node-environment-flags": { @@ -18807,9 +17541,9 @@ } }, "node_modules/node-gyp-build": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz", - "integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.5.0.tgz", + "integrity": "sha512-2iGbaQBV+ITgCz76ZEjmhUKAKVf7xfY1sRl4UiKQspfZMH2h06SyhNsnSVy50cwkFQDGLyif6m/6uFXHkOZ6rg==", "dev": true, "bin": { "node-gyp-build": "bin.js", @@ -18829,7 +17563,7 @@ "node_modules/nopt": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", - "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "integrity": "sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg==", "dev": true, "dependencies": { "abbrev": "1" @@ -18868,19 +17602,10 @@ "node": ">=0.10.0" } }, - "node_modules/normalize-url": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", - "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", "dev": true, "engines": { "node": ">=0.10.0" @@ -18889,7 +17614,7 @@ "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": "sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA=", + "integrity": "sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig==", "dev": true, "dependencies": { "bn.js": "4.11.6", @@ -18903,7 +17628,7 @@ "node_modules/number-to-bn/node_modules/bn.js": { "version": "4.11.6", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=", + "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", "dev": true }, "node_modules/oauth-sign": { @@ -18918,16 +17643,16 @@ "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/object-inspect": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", - "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", + "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -18943,32 +17668,30 @@ } }, "node_modules/object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", "dev": true, "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/object.getownpropertydescriptors": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.3.tgz", - "integrity": "sha512-VdDoCwvJI4QdC6ndjpqFmoL3/+HxffFBbcJzKi5hwLLqqx3mdbedRpfZDdK0SrOSauj8X4GzBvnDZl4vTN7dOw==", + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.5.tgz", + "integrity": "sha512-yDNzckpM6ntyQiGTik1fKV1DcVDRS+w8bvpWNCBanvH5LfRX9O8WTHqQzG4RZwRAM4I0oU7TV11Lj5v0g20ibw==", "dev": true, "dependencies": { + "array.prototype.reduce": "^1.0.5", "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" }, "engines": { "node": ">= 0.8" @@ -18978,36 +17701,15 @@ } }, "node_modules/obliterator": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-1.6.1.tgz", - "integrity": "sha512-9WXswnqINnnhOG/5SLimUlzuU1hFJUc8zkwyD59Sd+dPOMf05PmnYG/d6Q7HZ+KmgkZJa1PxRso6QdM3sTNHig==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.4.tgz", + "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": "sha1-VVQoTFQ6ImbXo48X4HOCH73jk80=", - "dev": true, - "dependencies": { - "http-https": "^1.0.0" - } - }, - "node_modules/on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "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", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, "dependencies": { "wrappy": "1" @@ -19042,17 +17744,17 @@ } }, "node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", "dev": true, "dependencies": { - "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" + "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" }, "engines": { "node": ">= 0.8.0" @@ -19061,7 +17763,7 @@ "node_modules/os-locale": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "integrity": "sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g==", "dev": true, "dependencies": { "lcid": "^1.0.0" @@ -19073,52 +17775,40 @@ "node_modules/os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", "dev": true, "engines": { "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-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "dependencies": { - "p-try": "^1.0.0" + "yocto-queue": "^0.1.0" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, "dependencies": { - "p-limit": "^1.1.0" + "p-limit": "^3.0.2" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-map": { @@ -19136,25 +17826,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/p-timeout": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz", - "integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=", - "dev": true, - "dependencies": { - "p-finally": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "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": ">=4" + "node": ">=6" } }, "node_modules/parent-module": { @@ -19169,44 +17847,16 @@ "node": ">=6" } }, - "node_modules/parent-module/node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "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", - "integrity": "sha1-juqz5U+laSD+Fro493+iGqzC104=", - "dev": true - }, - "node_modules/parse-headers": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.3.tgz", - "integrity": "sha512-QhhZ+DCCit2Coi2vmAKbq5RGTRcQUOE2+REgv8vdyu7MnYx2eZztegqtTx99TZ86GTIwqiy3+4nQTWZ2tgmdCA==", - "dev": true + "node_modules/parse-cache-control": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", + "integrity": "sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==", + "dev": true }, "node_modules/parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", "dev": true, "dependencies": { "error-ex": "^1.3.1", @@ -19216,90 +17866,70 @@ "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/patch-package": { - "version": "6.4.7", - "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-6.4.7.tgz", - "integrity": "sha512-S0vh/ZEafZ17hbhgqdnpunKDfzHQibQizx9g8yEf5dcVk3KOflOfdufRXQX8CSEkyOQwuM/bNz1GwKvFj54kaQ==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-6.5.0.tgz", + "integrity": "sha512-tC3EqJmo74yKqfsMzELaFwxOAu6FH6t+FzFOsnWAuARm7/n2xB5AOeOueE221eM9gtMuIKMKpF9tBy/X2mNP0Q==", "dev": true, "dependencies": { "@yarnpkg/lockfile": "^1.1.0", - "chalk": "^2.4.2", + "chalk": "^4.1.2", "cross-spawn": "^6.0.5", "find-yarn-workspace-root": "^2.0.0", "fs-extra": "^7.0.1", "is-ci": "^2.0.0", "klaw-sync": "^6.0.0", - "minimist": "^1.2.0", + "minimist": "^1.2.6", "open": "^7.4.2", "rimraf": "^2.6.3", "semver": "^5.6.0", "slash": "^2.0.0", - "tmp": "^0.0.33" + "tmp": "^0.0.33", + "yaml": "^1.10.2" }, "bin": { "patch-package": "index.js" }, "engines": { + "node": ">=10", "npm": ">5" } }, - "node_modules/patch-package/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==", + "node_modules/patch-package/node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", "dev": true, "dependencies": { - "color-convert": "^1.9.0" + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" }, "engines": { - "node": ">=4" + "node": ">=4.8" } }, - "node_modules/patch-package/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/patch-package/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, "engines": { "node": ">=4" } }, - "node_modules/patch-package/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/patch-package/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "dev": true, "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/patch-package/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "node_modules/patch-package/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true, - "engines": { - "node": ">=4" + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" } }, "node_modules/patch-package/node_modules/semver": { @@ -19311,16 +17941,46 @@ "semver": "bin/semver" } }, - "node_modules/patch-package/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/patch-package/node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", "dev": true, "dependencies": { - "has-flag": "^3.0.0" + "shebang-regex": "^1.0.0" }, "engines": { - "node": ">=4" + "node": ">=0.10.0" + } + }, + "node_modules/patch-package/node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/patch-package/node_modules/slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/patch-package/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" } }, "node_modules/path-browserify": { @@ -19330,18 +17990,18 @@ "dev": true }, "node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true, "engines": { "node": ">=0.10.0" @@ -19354,36 +18014,27 @@ "dev": true }, "node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "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": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, "node_modules/path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true, - "dependencies": { - "pify": "^3.0.0" - }, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/pathval": { @@ -19414,13 +18065,13 @@ "node_modules/performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", "dev": true }, "node_modules/picomatch": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", - "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, "engines": { "node": ">=8.6" @@ -19432,7 +18083,7 @@ "node_modules/pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", "dev": true, "engines": { "node": ">=4" @@ -19441,7 +18092,7 @@ "node_modules/pinkie": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", "dev": true, "engines": { "node": ">=0.10.0" @@ -19450,7 +18101,7 @@ "node_modules/pinkie-promise": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", "dev": true, "dependencies": { "pinkie": "^2.0.0" @@ -19523,24 +18174,6 @@ "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/pkg-dir/node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/postinstall-postinstall": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/postinstall-postinstall/-/postinstall-postinstall-2.1.0.tgz", @@ -19549,57 +18182,25 @@ "hasInstallScript": true }, "node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, "engines": { "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": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/prettier": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.1.tgz", - "integrity": "sha512-8UVbTBYGwN37Bs9LERmxCPjdvPxlEowx2urIL6urHzdb3SDq4B/Z6xLFCblrSnE4iKWcS6ziJ3aOYrc1kz/E2A==", + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", + "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", "dev": true, + "optional": true, "bin": { "prettier": "bin-prettier.js" }, "engines": { - "node": ">=10.13.0" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/printj": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/printj/-/printj-1.3.1.tgz", - "integrity": "sha512-GA3TdL8szPK4AQ2YnOe/b+Y1jUFwmmGMMK/qbY7VcE3Z7FU8JstbKiKRzO6CIiAKPhTO8m01NoQ0V5f3jc4OGg==", - "dev": true, - "bin": { - "printj": "bin/printj.njs" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true, - "engines": { - "node": ">= 0.6.0" + "node": ">=4" } }, "node_modules/process-nextick-args": { @@ -19618,9 +18219,9 @@ } }, "node_modules/promise": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/promise/-/promise-8.1.0.tgz", - "integrity": "sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", + "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==", "dev": true, "dependencies": { "asap": "~2.0.6" @@ -19650,91 +18251,40 @@ "signal-exit": "^3.0.2" } }, - "node_modules/proxy-addr": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", - "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", - "dev": true, - "dependencies": { - "forwarded": "~0.1.2", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", - "dev": true - }, "node_modules/psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "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, - "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/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.1.0", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz", - "integrity": "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0=", + "integrity": "sha512-Yxz2kRwT90aPiWEMHVYnEf4+rhwF1tBmmZ4KepCP+Wkium9JxtWnUm1nqGwpiAHr/tnTSeHqr3wb++jgSkXjhA==", "dev": true, "engines": { "node": ">=6" } }, "node_modules/qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "dev": true, - "engines": { - "node": ">=0.6" - } - }, - "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==", + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", "dev": true, "dependencies": { - "decode-uri-component": "^0.2.0", - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" + "side-channel": "^1.0.4" }, "engines": { - "node": ">=0.10.0" + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/querystring": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==", "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", "dev": true, "engines": { @@ -19764,7 +18314,7 @@ "node_modules/quick-lru": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-1.1.0.tgz", - "integrity": "sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g=", + "integrity": "sha512-tRS7sTgyxMXtLum8L65daJnHUhfDUgboRdcWW2bR9vBfrj2+O5HSMbQOJfJJjIVSPFqbBCF37FpwWXGitDc5tA==", "dev": true, "engines": { "node": ">=4" @@ -19779,33 +18329,14 @@ "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.4.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.1.tgz", - "integrity": "sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA==", + "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, "dependencies": { - "bytes": "3.1.0", - "http-errors": "1.7.3", + "bytes": "3.1.2", + "http-errors": "2.0.0", "iconv-lite": "0.4.24", "unpipe": "1.0.0" }, @@ -19816,7 +18347,7 @@ "node_modules/read-pkg": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", "dev": true, "dependencies": { "load-json-file": "^4.0.0", @@ -19830,7 +18361,7 @@ "node_modules/read-pkg-up": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", - "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", + "integrity": "sha512-YFzFrVvpC6frF1sz8psoHDBGF7fLPc+llq/8NB43oagqWkx8ar5zYtsTORtOjw9W2RHLpWP+zTWwBvf1bCmcSw==", "dev": true, "dependencies": { "find-up": "^2.0.0", @@ -19840,6 +18371,85 @@ "node": ">=4" } }, + "node_modules/read-pkg-up/node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", + "dev": true, + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", + "dev": true, + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", + "dev": true, + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/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/read-pkg-up/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, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg/node_modules/path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", @@ -19855,9 +18465,9 @@ } }, "node_modules/readdirp": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", - "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, "dependencies": { "picomatch": "^2.2.1" @@ -19869,7 +18479,7 @@ "node_modules/rechoir": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", "dev": true, "dependencies": { "resolve": "^1.1.6" @@ -19879,21 +18489,21 @@ } }, "node_modules/recursive-readdir": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.2.tgz", - "integrity": "sha512-nRCcW9Sj7NuZwa2XvH9co8NPeXUBhZP7CRKJtU+cS6PW9FpCIFoI5ib0NT1ZrbNuPoRy0ylyCaUL8Gih4LSyFg==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", + "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", "dev": true, "dependencies": { - "minimatch": "3.0.4" + "minimatch": "^3.0.5" }, "engines": { - "node": ">=0.10.0" + "node": ">=6.0.0" } }, "node_modules/redent": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz", - "integrity": "sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo=", + "integrity": "sha512-XNwrTx77JQCEMXTeb8movBKuK75MgH0RZkujNuDKCezemx/voapl9i2gCSi8WWm8+ox5ycJi1gxF22fR7c0Ciw==", "dev": true, "dependencies": { "indent-string": "^3.0.0", @@ -19903,6 +18513,32 @@ "node": ">=4" } }, + "node_modules/redent/node_modules/indent-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", + "integrity": "sha512-BYqTHXTGUIvg7t1r4sJNKcbDZkL92nkXA8YtRpbjFHRHGDL/NtUeiBJMeE60kIFN/Mg8ESaWQvftaYMGJzQZCQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", + "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "functions-have-names": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/regexpp": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", @@ -19918,7 +18554,7 @@ "node_modules/req-cwd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/req-cwd/-/req-cwd-2.0.0.tgz", - "integrity": "sha1-1AgrTURZgDZkD7c93qAe1T20nrw=", + "integrity": "sha512-ueoIoLo1OfB6b05COxAA9UpeoscNpYyM+BqYlA7H6LVF4hKGPXQQSSaD2YmvDVJMkk4UDpAHIeU1zG53IqjvlQ==", "dev": true, "dependencies": { "req-from": "^2.0.0" @@ -19930,7 +18566,7 @@ "node_modules/req-from": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/req-from/-/req-from-2.0.0.tgz", - "integrity": "sha1-10GI5H+TeW9Kpx327jWuaJ8+DnA=", + "integrity": "sha512-LzTfEVDVQHBRfjOUMgNBA+V6DWsSnoeKzf42J7l0xa/B4jyPOuuF5MlNSmomLNGemWTnV2TIdjSSLnEn95fOQA==", "dev": true, "dependencies": { "resolve-from": "^3.0.0" @@ -19939,6 +18575,15 @@ "node": ">=4" } }, + "node_modules/req-from/node_modules/resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/request": { "version": "2.88.2", "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", @@ -20004,10 +18649,43 @@ "request": "^2.34" } }, + "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, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/request/node_modules/qs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/request/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "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, + "bin": { + "uuid": "bin/uuid" + } + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true, "engines": { "node": ">=0.10.0" @@ -20025,16 +18703,15 @@ "node_modules/require-main-filename": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "integrity": "sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==", "dev": true }, "node_modules/resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", "dev": true, "dependencies": { - "is-core-module": "^2.2.0", "path-parse": "^1.0.6" }, "funding": { @@ -20042,23 +18719,14 @@ } }, "node_modules/resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "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, "engines": { "node": ">=4" } }, - "node_modules/responselike": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", - "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", @@ -20075,7 +18743,7 @@ "node_modules/retry": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", "dev": true, "engines": { "node": ">= 4" @@ -20092,15 +18760,18 @@ } }, "node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, "dependencies": { "glob": "^7.1.3" }, "bin": { "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/ripemd160": { @@ -20114,12 +18785,12 @@ } }, "node_modules/rlp": { - "version": "2.2.6", - "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.6.tgz", - "integrity": "sha512-HAfAmL6SDYNWPUOJNrM500x4Thn4PZsEy5pijPh40U9WfNk0z15hUYzO9xVIMAdIHdFtD8CBDHd75Td1g36Mjg==", + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz", + "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==", "dev": true, "dependencies": { - "bn.js": "^4.11.1" + "bn.js": "^5.2.0" }, "bin": { "rlp": "bin/rlp" @@ -20157,6 +18828,29 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/run-parallel-limit": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/run-parallel-limit/-/run-parallel-limit-1.1.0.tgz", + "integrity": "sha512-jJA7irRNM91jaKc3Hcl1npHsFLOXOoTkPCUL1JEa1R82O2miplXXRaGdjW/KM/98YQWDhJLiSs793CnXfblJUw==", + "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": { + "queue-microtask": "^1.2.2" + } + }, "node_modules/rustbn.js": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/rustbn.js/-/rustbn.js-0.2.0.tgz", @@ -20195,6 +18889,20 @@ } ] }, + "node_modules/safe-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -20226,29 +18934,25 @@ "istanbul": "lib/cli.js" } }, + "node_modules/sc-istanbul/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, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, "node_modules/sc-istanbul/node_modules/async": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==", "dev": true }, - "node_modules/sc-istanbul/node_modules/esprima": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", - "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/sc-istanbul/node_modules/glob": { "version": "5.0.15", "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", - "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "integrity": "sha512-c9IPMazfRITpmAAKi22dK1VKxGDX9ehhqfABDriL/lzO92xcUKEJPQHrVA/2YHSNFB4iFlykVmWvwo48nr3OxA==", "dev": true, "dependencies": { "inflight": "^1.0.4", @@ -20264,22 +18968,48 @@ "node_modules/sc-istanbul/node_modules/has-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "integrity": "sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA==", "dev": true, "engines": { "node": ">=0.10.0" } }, + "node_modules/sc-istanbul/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/sc-istanbul/node_modules/js-yaml/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/sc-istanbul/node_modules/resolve": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "integrity": "sha512-9znBF0vBcaSN3W2j7wKvdERPwqTxSpCq+if5C0WoTCyV9n24rua28jeuQ2pL/HOf+yUe/Mef+H/5p60K0Id3bg==", "dev": true }, "node_modules/sc-istanbul/node_modules/supports-color": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "integrity": "sha512-Jds2VIYDrlp5ui7t8abHN2bjAu4LV/q4N2KivFPpGH0lrka0BMq/33AmECUXlKPcHigkNaqfXRENFju+rlcy+A==", "dev": true, "dependencies": { "has-flag": "^1.0.0" @@ -20288,6 +19018,18 @@ "node": ">=0.8.0" } }, + "node_modules/sc-istanbul/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, "node_modules/scrypt-js": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", @@ -20295,13 +19037,13 @@ "dev": true }, "node_modules/secp256k1": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.2.tgz", - "integrity": "sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz", + "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==", "dev": true, "hasInstallScript": true, "dependencies": { - "elliptic": "^6.5.2", + "elliptic": "^6.5.4", "node-addon-api": "^2.0.0", "node-gyp-build": "^4.2.0" }, @@ -20309,15 +19051,6 @@ "node": ">=10.0.0" } }, - "node_modules/semaphore-async-await": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/semaphore-async-await/-/semaphore-async-await-1.5.1.tgz", - "integrity": "sha1-hXvvXjZEYBykuVcLh+nfXKEpdPo=", - "dev": true, - "engines": { - "node": ">=4.1" - } - }, "node_modules/semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -20327,51 +19060,6 @@ "semver": "bin/semver.js" } }, - "node_modules/send": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", - "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", - "dev": true, - "dependencies": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "~1.7.2", - "mime": "1.6.0", - "ms": "2.1.1", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.0" - }, - "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": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/send/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 - }, "node_modules/serialize-javascript": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", @@ -20381,53 +19069,22 @@ "randombytes": "^2.1.0" } }, - "node_modules/serve-static": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", - "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", - "dev": true, - "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.17.1" - }, - "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-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", "dev": true }, "node_modules/setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", "dev": true }, "node_modules/setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", "dev": true }, "node_modules/sha.js": { @@ -20446,7 +19103,7 @@ "node_modules/sha1": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/sha1/-/sha1-1.1.1.tgz", - "integrity": "sha1-rdqnqTFo85PxnrKxUJFhjicA+Eg=", + "integrity": "sha512-dZBS6OrMjtgVkopB1Gmo4RQCDKiZsqcpAQpkV/aaj+FCrCg8r4I4qMkDPQjBgLIxlmu9k4nUbWq6ohXahOneYA==", "dev": true, "dependencies": { "charenc": ">= 0.0.1", @@ -20457,24 +19114,24 @@ } }, "node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "dependencies": { - "shebang-regex": "^1.0.0" + "shebang-regex": "^3.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, "node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, "node_modules/shelljs": { @@ -20509,46 +19166,15 @@ } }, "node_modules/signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "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.1", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.1.tgz", - "integrity": "sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw==", - "dev": true, - "dependencies": { - "decompress-response": "^3.3.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, "node_modules/simple-git": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.10.0.tgz", - "integrity": "sha512-2w35xrS5rVtAW0g67LqtxCZN5cdddz/woQRfS0OJXaljXEoTychZ4jnE+CQgra/wX4ZvHeiChTUMenCwfIYEYw==", + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.14.1.tgz", + "integrity": "sha512-1ThF4PamK9wBORVGMK9HK5si4zoGS2GpRO7tkAFObA4FZv6dKaCVHLQT+8zlgiBm6K2h+wEU9yOaFCu/SR3OyA==", "dev": true, "dependencies": { "@kwsites/file-exists": "^1.1.1", @@ -20567,55 +19193,40 @@ "dev": true }, "node_modules/slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, "engines": { - "node": ">=6" + "node": ">=8" } }, "node_modules/slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, "dependencies": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" }, "engines": { - "node": ">=6" - } - }, - "node_modules/slice-ansi/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" + "node": ">=10" }, - "engines": { - "node": ">=4" + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, - "node_modules/slice-ansi/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/slice-ansi/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, - "dependencies": { - "color-name": "1.1.3" + "engines": { + "node": ">=8" } }, - "node_modules/slice-ansi/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/solc": { "version": "0.6.12", "resolved": "https://registry.npmjs.org/solc/-/solc-0.6.12.tgz", @@ -20638,10 +19249,16 @@ "node": ">=8.0.0" } }, + "node_modules/solc/node_modules/commander": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz", + "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==", + "dev": true + }, "node_modules/solc/node_modules/fs-extra": { "version": "0.30.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", - "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", + "integrity": "sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==", "dev": true, "dependencies": { "graceful-fs": "^4.1.2", @@ -20651,21 +19268,27 @@ "rimraf": "^2.2.8" } }, - "node_modules/solc/node_modules/js-sha3": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", - "dev": true - }, "node_modules/solc/node_modules/jsonfile": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "integrity": "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==", "dev": true, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, + "node_modules/solc/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, "node_modules/solc/node_modules/semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", @@ -20713,6 +19336,15 @@ "node": ">=0.4.0" } }, + "node_modules/solhint/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, + "engines": { + "node": ">=4" + } + }, "node_modules/solhint/node_modules/ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -20725,6 +19357,24 @@ "node": ">=4" } }, + "node_modules/solhint/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, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/solhint/node_modules/astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/solhint/node_modules/chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -20751,7 +19401,7 @@ "node_modules/solhint/node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, "node_modules/solhint/node_modules/commander": { @@ -20760,6 +19410,46 @@ "integrity": "sha512-6CYPa+JP2ftfRU2qkDK+UTVeQYosOg/2GbcjIcKPHfinyOLPVGXu/ovN86RP49Re5ndJK1N0kuiidFFuepc4ZQ==", "dev": true }, + "node_modules/solhint/node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "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==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/solhint/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 + }, + "node_modules/solhint/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/solhint/node_modules/eslint": { "version": "5.16.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz", @@ -20867,13 +19557,17 @@ "node": ">=6.0.0" } }, - "node_modules/solhint/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "node_modules/solhint/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.0" + "node": ">=4" } }, "node_modules/solhint/node_modules/file-entry-cache": { @@ -20920,7 +19614,7 @@ "node_modules/solhint/node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, "engines": { "node": ">=4" @@ -20935,35 +19629,67 @@ "node": ">= 4" } }, - "node_modules/solhint/node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "node_modules/solhint/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": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" + "argparse": "^1.0.7", + "esprima": "^4.0.0" }, - "engines": { - "node": ">=6" + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/solhint/node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">= 0.8.0" } }, - "node_modules/solhint/node_modules/prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", + "node_modules/solhint/node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", "dev": true, - "optional": true, - "bin": { - "prettier": "bin-prettier.js" + "dependencies": { + "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" }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/solhint/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "dev": true, "engines": { "node": ">=4" } }, + "node_modules/solhint/node_modules/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, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/solhint/node_modules/regexpp": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", @@ -20973,15 +19699,6 @@ "node": ">=6.5.0" } }, - "node_modules/solhint/node_modules/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, - "engines": { - "node": ">=4" - } - }, "node_modules/solhint/node_modules/rimraf": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", @@ -20994,6 +19711,97 @@ "rimraf": "bin.js" } }, + "node_modules/solhint/node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "dev": true, + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/solhint/node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/solhint/node_modules/slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/solhint/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, + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/solhint/node_modules/string-width/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==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/solhint/node_modules/string-width/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, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/solhint/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, + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/solhint/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, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/solhint/node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -21006,39 +19814,101 @@ "node": ">=4" } }, + "node_modules/solhint/node_modules/table": { + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "dev": true, + "dependencies": { + "ajv": "^6.10.2", + "lodash": "^4.17.14", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/solhint/node_modules/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, + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/solhint/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, "node_modules/solidity-ast": { - "version": "0.4.31", - "resolved": "https://registry.npmjs.org/solidity-ast/-/solidity-ast-0.4.31.tgz", - "integrity": "sha512-kX6o4XE4ihaqENuRRTMJfwQNHoqWusPENZUlX4oVb19gQdfi7IswFWnThONHSW/61umgfWdKtCBgW45iuOTryQ==", + "version": "0.4.35", + "resolved": "https://registry.npmjs.org/solidity-ast/-/solidity-ast-0.4.35.tgz", + "integrity": "sha512-F5bTDLh3rmDxRmLSrs3qt3nvxJprWSEkS7h2KmuXDx7XTfJ6ZKVTV1rtPIYCqJAuPsU/qa8YUeFn7jdOAZcTPA==", "dev": true }, "node_modules/solidity-coverage": { - "version": "0.7.20", - "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.7.20.tgz", - "integrity": "sha512-edOXTugUYdqxrtEnIn4vgrGjLPxdexcL0WD8LzAvVA3d1dwgcfRO3k8xQR02ZQnOnWMBi8Cqs0F+kAQQp3JW8g==", + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.8.2.tgz", + "integrity": "sha512-cv2bWb7lOXPE9/SSleDO6czkFiMHgP4NXPj+iW9W7iEKLBk7Cj0AGBiNmGX3V1totl9wjPrT0gHmABZKZt65rQ==", "dev": true, "dependencies": { - "@solidity-parser/parser": "^0.14.0", - "@truffle/provider": "^0.2.24", + "@ethersproject/abi": "^5.0.9", + "@solidity-parser/parser": "^0.14.1", "chalk": "^2.4.2", "death": "^1.1.0", "detect-port": "^1.3.0", + "difflib": "^0.2.4", "fs-extra": "^8.1.0", "ghost-testrpc": "^0.0.2", "global-modules": "^2.0.0", "globby": "^10.0.1", "jsonschema": "^1.2.4", "lodash": "^4.17.15", + "mocha": "7.1.2", "node-emoji": "^1.10.0", "pify": "^4.0.1", "recursive-readdir": "^2.2.2", "sc-istanbul": "^0.4.5", "semver": "^7.3.4", "shelljs": "^0.8.3", - "web3-utils": "^1.3.0" + "web3-utils": "^1.3.6" }, "bin": { "solidity-coverage": "plugins/bin.js" + }, + "peerDependencies": { + "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, + "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==", + "dev": true, + "engines": { + "node": ">=6" } }, "node_modules/solidity-coverage/node_modules/ansi-styles": { @@ -21053,6 +19923,24 @@ "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, + "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, + "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", @@ -21067,6 +19955,38 @@ "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==", + "dev": 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, + "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", @@ -21079,168 +19999,613 @@ "node_modules/solidity-coverage/node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, - "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", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "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, "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, + "ms": "^2.1.1" + } + }, + "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, "engines": { - "node": ">=6 <7 || >=8" + "node": ">=0.3.1" } }, - "node_modules/solidity-coverage/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "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 + }, + "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", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, "engines": { - "node": ">=4" + "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/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, - "dependencies": { - "yallist": "^4.0.0" + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" }, "engines": { - "node": ">=10" + "node": ">=4" } }, - "node_modules/solidity-coverage/node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "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, + "dependencies": { + "locate-path": "^3.0.0" + }, "engines": { "node": ">=6" } }, - "node_modules/solidity-coverage/node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "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, "dependencies": { - "lru-cache": "^6.0.0" + "is-buffer": "~2.0.3" }, "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" + "flat": "cli.js" } }, - "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==", + "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", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", "dev": true, "dependencies": { - "has-flag": "^3.0.0" + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" }, "engines": { - "node": ">=4" + "node": ">=6 <7 || >=8" } }, - "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 - }, - "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==", + "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" + ], "engines": { - "node": ">=0.10.0" + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "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, "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" + "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/spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "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, "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" } }, - "node_modules/spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true - }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "node_modules/solidity-coverage/node_modules/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, "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" + "@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" + }, + "engines": { + "node": ">=8" } }, - "node_modules/spdx-license-ids": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz", - "integrity": "sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==", - "dev": true - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true + "node_modules/solidity-coverage/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/sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "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==", "dev": 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" + "argparse": "^1.0.7", + "esprima": "^4.0.0" }, "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" - }, - "engines": { - "node": ">=0.10.0" + "js-yaml": "bin/js-yaml.js" } }, + "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==", + "dev": true, + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "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==", + "dev": true, + "dependencies": { + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=8" + } + }, + "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, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "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==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "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==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "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==", + "dev": 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" + } + }, + "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==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "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==", + "dev": true + }, + "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==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "dev": 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, + "engines": { + "node": ">=4" + } + }, + "node_modules/solidity-coverage/node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "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, + "dependencies": { + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/solidity-coverage/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 + }, + "node_modules/solidity-coverage/node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "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, + "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, + "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, + "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, + "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, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/solidity-coverage/node_modules/which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", + "dev": true + }, + "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, + "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 + }, + "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 + }, + "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==", + "dev": 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" + } + }, + "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, + "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, + "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, + "dependencies": { + "amdefine": ">=0.0.4" + }, + "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_modules/spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz", + "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==", + "dev": true + }, + "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==", + "dev": 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_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/stacktrace-parser": { "version": "0.1.10", "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz", @@ -21263,30 +20628,30 @@ } }, "node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", "dev": true, "engines": { - "node": ">= 0.6" + "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": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", + "integrity": "sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g==", "dev": true, "engines": { "node": ">=0.10.0" } }, - "node_modules/strict-uri-encode": { + "node_modules/streamsearch": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=10.0.0" } }, "node_modules/string_decoder": { @@ -21311,48 +20676,71 @@ "node": ">=4" } }, + "node_modules/string-width/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, + "engines": { + "node": ">=4" + } + }, + "node_modules/string-width/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, + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "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==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3" + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", + "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3" + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "dependencies": { - "ansi-regex": "^3.0.0" + "ansi-regex": "^5.0.1" }, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "dev": true, "engines": { "node": ">=4" @@ -21361,7 +20749,7 @@ "node_modules/strip-hex-prefix": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", - "integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=", + "integrity": "sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==", "dev": true, "dependencies": { "is-hex-prefixed": "1.0.0" @@ -21374,19 +20762,22 @@ "node_modules/strip-indent": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", - "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=", + "integrity": "sha512-RsSNPLpq6YUL7QYy44RnPVTn/lcVZtb48Uof3X5JLbF4zD/Gs7ZFDv2HWol+leoQN2mT86LAzSshGfkTlSOpsA==", "dev": true, "engines": { "node": ">=4" } }, "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": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "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, "engines": { - "node": ">=0.10.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/strip-outer": { @@ -21401,6 +20792,15 @@ "node": ">=0.10.0" } }, + "node_modules/strip-outer/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/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -21413,131 +20813,6 @@ "node": ">=8" } }, - "node_modules/swarm-js": { - "version": "0.1.40", - "resolved": "https://registry.npmjs.org/swarm-js/-/swarm-js-0.1.40.tgz", - "integrity": "sha512-yqiOCEoA4/IShXkY3WKwP5PvZhmoOOD8clsKA7EEcRILMkTEYHCQ21HDCAcVpmIxZq4LyZvWeRJ6quIyHk1caA==", - "dev": true, - "dependencies": { - "bluebird": "^3.5.0", - "buffer": "^5.0.5", - "eth-lib": "^0.1.26", - "fs-extra": "^4.0.2", - "got": "^7.1.0", - "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/swarm-js/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, - "dependencies": { - "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/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": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/swarm-js/node_modules/got": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz", - "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==", - "dev": true, - "dependencies": { - "decompress-response": "^3.2.0", - "duplexer3": "^0.1.4", - "get-stream": "^3.0.0", - "is-plain-obj": "^1.1.0", - "is-retry-allowed": "^1.0.0", - "is-stream": "^1.0.0", - "isurl": "^1.0.0-alpha5", - "lowercase-keys": "^1.0.0", - "p-cancelable": "^0.3.0", - "p-timeout": "^1.1.1", - "safe-buffer": "^5.0.1", - "timed-out": "^4.0.0", - "url-parse-lax": "^1.0.0", - "url-to-options": "^1.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/swarm-js/node_modules/p-cancelable": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz", - "integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/swarm-js/node_modules/prepend-http": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/swarm-js/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/swarm-js/node_modules/url-parse-lax": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", - "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", - "dev": true, - "dependencies": { - "prepend-http": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/swarm-js/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, - "dependencies": { - "async-limiter": "~1.0.0", - "safe-buffer": "~5.1.0", - "ultron": "~1.1.0" - } - }, "node_modules/sync-request": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz", @@ -21562,77 +20837,70 @@ } }, "node_modules/table": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", + "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", "dev": true, "dependencies": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" + "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": ">=6.0.0" - } - }, - "node_modules/table/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==", - "dev": true, - "engines": { - "node": ">=6" + "node": ">=10.0.0" } }, - "node_modules/table/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/table/node_modules/ajv": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", "dev": true, "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" }, - "engines": { - "node": ">=6" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/table/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/table/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/tar": { - "version": "4.4.13", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", - "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", + "node_modules/table/node_modules/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 + }, + "node_modules/table/node_modules/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, "dependencies": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.8.6", - "minizlib": "^1.2.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.3" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { - "node": ">=4.5" + "node": ">=8" } }, "node_modules/test-value": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/test-value/-/test-value-2.1.0.tgz", - "integrity": "sha1-Edpv9nDzRxpztiXKTz/c97t0gpE=", + "integrity": "sha512-+1epbAxtKeXttkGFMTX9H42oqzOTufR1ceCF+GYA5aOmvaPq9wd4PUS8329fn2RRLGNeUkgRLnVpycjx8DsO2w==", "dev": true, "dependencies": { "array-back": "^1.0.3", @@ -21645,7 +20913,7 @@ "node_modules/test-value/node_modules/array-back": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", - "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=", + "integrity": "sha512-1WxbZvrmyhkNoeYcizokbmh5oiOCIfyvGtcqbK3Ls1v1fKcquzxnQSceOx6tzq7jmai2kFLWIpGND2cLhH6TPw==", "dev": true, "dependencies": { "typical": "^2.6.0" @@ -21664,7 +20932,7 @@ "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, "node_modules/then-request": { @@ -21695,21 +20963,26 @@ "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==", "dev": 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, + "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": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", - "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", @@ -21722,15 +20995,6 @@ "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", @@ -21744,9 +21008,9 @@ } }, "node_modules/toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "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, "engines": { "node": ">=0.6" @@ -21777,13 +21041,13 @@ "node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", "dev": true }, "node_modules/trim-newlines": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz", - "integrity": "sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA=", + "integrity": "sha512-MTBWv3jhVjTU7XR3IQHllbiJs8sc75a80OEhB6or/q7pLTWgQ0bMGQXXYQSrSuXe6WiKWDZ5txXY5P59a/coVA==", "dev": true, "engines": { "node": ">=4" @@ -21792,7 +21056,7 @@ "node_modules/trim-repeated": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", - "integrity": "sha1-42RqLqTokTEr9+rObPsFOAvAHCE=", + "integrity": "sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==", "dev": true, "dependencies": { "escape-string-regexp": "^1.0.2" @@ -21801,11 +21065,14 @@ "node": ">=0.10.0" } }, - "node_modules/true-case-path": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-2.2.1.tgz", - "integrity": "sha512-0z3j8R7MCjy10kc/g+qg7Ln3alJTodw9aDuVWZa3uiWqfuBMKeAeP2ocWcxoyM3D73yz3Jt/Pu4qPr4wHSdB/Q==", - "dev": true + "node_modules/trim-repeated/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/ts-essentials": { "version": "1.0.4", @@ -21871,18 +21138,42 @@ "node_modules/ts-generator/node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, + "node_modules/ts-generator/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/ts-generator/node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, "engines": { "node": ">=4" } }, + "node_modules/ts-generator/node_modules/prettier": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", + "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/ts-generator/node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -21896,12 +21187,12 @@ } }, "node_modules/ts-node": { - "version": "10.7.0", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.7.0.tgz", - "integrity": "sha512-TbIGS4xgJoX2i3do417KSaep1uRAW/Lu+WAL2doDHC0D6ummjirVOXU5/7aiZotbQ5p1Zp9tP7U6cYhA0O7M8A==", + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", "dev": true, "dependencies": { - "@cspotcode/source-map-support": "0.7.0", + "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", "@tsconfig/node12": "^1.0.7", "@tsconfig/node14": "^1.0.0", @@ -21912,7 +21203,7 @@ "create-require": "^1.1.0", "diff": "^4.0.1", "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.0", + "v8-compile-cache-lib": "^3.0.1", "yn": "3.1.1" }, "bin": { @@ -21956,7 +21247,7 @@ "node_modules/tsort": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/tsort/-/tsort-0.0.1.tgz", - "integrity": "sha1-4igPXoF/i/QnVlf9D5rr1E9aJ4Y=", + "integrity": "sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw==", "dev": true }, "node_modules/tsutils": { @@ -21977,7 +21268,7 @@ "node_modules/tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", "dev": true, "dependencies": { "safe-buffer": "^5.0.1" @@ -21987,9 +21278,9 @@ } }, "node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "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": { @@ -21998,19 +21289,13 @@ "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.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "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.1.2" + "prelude-ls": "^1.2.1" }, "engines": { "node": ">= 0.8.0" @@ -22026,9 +21311,9 @@ } }, "node_modules/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==", + "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, "engines": { "node": ">=10" @@ -22037,19 +21322,6 @@ "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": "3.0.0", "resolved": "https://registry.npmjs.org/typechain/-/typechain-3.0.0.tgz", @@ -22068,12 +21340,6 @@ "typechain": "dist/cli/cli.js" } }, - "node_modules/typechain/node_modules/js-sha3": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", - "dev": true - }, "node_modules/typechain/node_modules/ts-essentials": { "version": "6.0.7", "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-6.0.7.tgz", @@ -22086,22 +21352,13 @@ "node_modules/typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", "dev": 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.6.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz", - "integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==", + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", + "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -22114,13 +21371,13 @@ "node_modules/typical": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", - "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=", + "integrity": "sha512-ofhi8kjIje6npGozTip9Fr8iecmYfEbS06i0JnIg+rh51KakryWF4+jX8lLKZVhy6N+ID45WYSFCxPOdTWCzNg==", "dev": true }, "node_modules/uglify-js": { - "version": "3.13.6", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.13.6.tgz", - "integrity": "sha512-rRprLwl8RVaS+Qvx3Wh5hPfPBn9++G6xkGlUupya0s5aDmNjI7z3lnRLB3u7sN4OmbB0pWgzhM9BEJyiWAwtAA==", + "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, "bin": { @@ -22130,38 +21387,29 @@ "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.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", "dev": true, "dependencies": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", "which-boxed-primitive": "^1.0.2" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/underscore": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", - "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==", - "dev": true - }, "node_modules/undici": { - "version": "4.16.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-4.16.0.tgz", - "integrity": "sha512-tkZSECUYi+/T1i4u+4+lwZmQgLXd4BLGlrc7KZPcLIW7Jpq99+Xpc30ONv7nS6F5UNOxp/HBZSSL9MafUrvJbw==", + "version": "5.12.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.12.0.tgz", + "integrity": "sha512-zMLamCG62PGjd9HHMpo05bSLvvwWOZgGeiWlN/vlqu3+lRo3elxktVGEyLMX+IO7c2eflLjcW74AlkhEZm15mg==", "dev": true, + "dependencies": { + "busboy": "^1.6.0" + }, "engines": { "node": ">=12.18" } @@ -22178,7 +21426,7 @@ "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "dev": true, "engines": { "node": ">= 0.8" @@ -22196,105 +21444,44 @@ "node_modules/url": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "integrity": "sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==", "dev": true, "dependencies": { "punycode": "1.3.2", "querystring": "0.2.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": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", - "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": "sha1-AW6M/Xwg7gXK/neV6JK9BwL6ozk=", - "dev": true - }, - "node_modules/url-to-options": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz", - "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=", - "dev": true, - "engines": { - "node": ">= 4" - } - }, "node_modules/url/node_modules/punycode": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==", "dev": true }, - "node_modules/utf-8-validate": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.5.tgz", - "integrity": "sha512-+pnxRYsS/axEpkrrEpzYfNZGXp0IjC/9RIxwM5gntY4Koi8SHmUGSfxfWqxZdRxrtaoVstuOzUp/rbs3JSPELQ==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "node-gyp-build": "^4.2.0" - } - }, "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.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.3.tgz", - "integrity": "sha512-I8XkoQwE+fPQEhy9v012V+TSdH2kp9ts29i20TaaDUXsg7x/onePbhFJUExBfv/2ay1ZOp/Vsm3nDlmnFGSAog==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "safe-buffer": "^5.1.2", - "which-typed-array": "^1.1.2" - } - }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "dev": true }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", - "dev": true, - "engines": { - "node": ">= 0.4.0" - } - }, "node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "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.", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "dev": true, "bin": { - "uuid": "bin/uuid" + "uuid": "dist/bin/uuid" } }, "node_modules/v8-compile-cache-lib": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.0.tgz", - "integrity": "sha512-mpSYqfsFvASnSn5qMiwrr4VKfumbPyONLCOPmsR3A6pTY/r0+tSaVbgPWSAIuzbk3lCTa+FForeTiO+wBQGkjA==", + "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 }, "node_modules/validate-npm-package-license": { @@ -22307,25 +21494,10 @@ "spdx-expression-parse": "^3.0.0" } }, - "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": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", "dev": true, "engines": [ "node >=0.6.0" @@ -22336,411 +21508,18 @@ "extsprintf": "^1.2.0" } }, - "node_modules/web3": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/web3/-/web3-1.3.5.tgz", - "integrity": "sha512-UyQW/MT5EIGBrXPCh/FDIaD7RtJTn5/rJUNw2FOglp0qoXnCQHNKvntiR1ylztk05fYxIF6UgsC76IrazlKJjw==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "web3-bzz": "1.3.5", - "web3-core": "1.3.5", - "web3-eth": "1.3.5", - "web3-eth-personal": "1.3.5", - "web3-net": "1.3.5", - "web3-shh": "1.3.5", - "web3-utils": "1.3.5" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-bzz": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.3.5.tgz", - "integrity": "sha512-XiEUAbB1uKm/agqfwBsCW8fbw+sma85TfwuDpdcy591vinVk0S9TfWgLxro6v1KJ6nSELySIbKGbAJbh2GSyxw==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "@types/node": "^12.12.6", - "got": "9.6.0", - "swarm-js": "^0.1.40", - "underscore": "1.9.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-bzz/node_modules/@types/node": { - "version": "12.20.13", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.13.tgz", - "integrity": "sha512-1x8W5OpxPq+T85OUsHRP6BqXeosKmeXRtjoF39STcdf/UWLqUsoehstZKOi0CunhVqHG17AyZgpj20eRVooK6A==", - "dev": true - }, - "node_modules/web3-core": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.3.5.tgz", - "integrity": "sha512-VQjTvnGTqJwDwjKEHSApea3RmgtFGLDSJ6bqrOyHROYNyTyKYjFQ/drG9zs3rjDkND9mgh8foI1ty37Qua3QCQ==", - "dev": true, - "dependencies": { - "@types/bn.js": "^4.11.5", - "@types/node": "^12.12.6", - "bignumber.js": "^9.0.0", - "web3-core-helpers": "1.3.5", - "web3-core-method": "1.3.5", - "web3-core-requestmanager": "1.3.5", - "web3-utils": "1.3.5" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-core-helpers": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.3.5.tgz", - "integrity": "sha512-HYh3ix5FjysgT0jyzD8s/X5ym0b4BGU7I2QtuBiydMnE0mQEWy7GcT9XKpTySA8FTOHHIAQYvQS07DN/ky3UzA==", - "dev": true, - "dependencies": { - "underscore": "1.9.1", - "web3-eth-iban": "1.3.5", - "web3-utils": "1.3.5" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-core-method": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.3.5.tgz", - "integrity": "sha512-hCbmgQ+At6OTuaNGAdjXMsCr4eUCmp9yGKSuaB5HdkNVDpqFso4HHjVxcjNrTyJp3OZnyjKBzQzK1ZWLpLl84Q==", - "dev": true, - "dependencies": { - "@ethersproject/transactions": "^5.0.0-beta.135", - "underscore": "1.9.1", - "web3-core-helpers": "1.3.5", - "web3-core-promievent": "1.3.5", - "web3-core-subscriptions": "1.3.5", - "web3-utils": "1.3.5" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-core-promievent": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.3.5.tgz", - "integrity": "sha512-K0j8x3ZJr0eAyNvyUCxOUsSTd4hco0/9nxxlyOuijcsa6YV8l9NL6eqhniWbSyxCJT8ka5Mb7yAiUZe69EDLBQ==", - "dev": true, - "dependencies": { - "eventemitter3": "4.0.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-core-requestmanager": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.3.5.tgz", - "integrity": "sha512-9l294U3Ga8qmvv8E37BqjQREfMs+kFnkU3PY28g9DZGYzKvl3V1dgDYqxyrOBdCFhc7rNSpHdgC4PrVHjouspg==", - "dev": true, - "dependencies": { - "underscore": "1.9.1", - "util": "^0.12.0", - "web3-core-helpers": "1.3.5", - "web3-providers-http": "1.3.5", - "web3-providers-ipc": "1.3.5", - "web3-providers-ws": "1.3.5" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-core-subscriptions": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.3.5.tgz", - "integrity": "sha512-6mtXdaEB1V1zKLqYBq7RF2W75AK5ZJNGpW6QYC7Zvbku7zq1ZlgaUkJo88JKMWJ7etfaHaYqQ/7VveHk5sQynA==", - "dev": true, - "dependencies": { - "eventemitter3": "4.0.4", - "underscore": "1.9.1", - "web3-core-helpers": "1.3.5" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "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, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/web3-core/node_modules/@types/node": { - "version": "12.20.13", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.13.tgz", - "integrity": "sha512-1x8W5OpxPq+T85OUsHRP6BqXeosKmeXRtjoF39STcdf/UWLqUsoehstZKOi0CunhVqHG17AyZgpj20eRVooK6A==", - "dev": true - }, - "node_modules/web3-eth": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.3.5.tgz", - "integrity": "sha512-5qqDPMMD+D0xRqOV2ePU2G7/uQmhn0FgCEhFzKDMHrssDQJyQLW/VgfA0NLn64lWnuUrGnQStGvNxrWf7MgsfA==", - "dev": true, - "dependencies": { - "underscore": "1.9.1", - "web3-core": "1.3.5", - "web3-core-helpers": "1.3.5", - "web3-core-method": "1.3.5", - "web3-core-subscriptions": "1.3.5", - "web3-eth-abi": "1.3.5", - "web3-eth-accounts": "1.3.5", - "web3-eth-contract": "1.3.5", - "web3-eth-ens": "1.3.5", - "web3-eth-iban": "1.3.5", - "web3-eth-personal": "1.3.5", - "web3-net": "1.3.5", - "web3-utils": "1.3.5" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-abi": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.3.5.tgz", - "integrity": "sha512-bkbG2v/mOW5DH6rF/SEgqunusjYoEi2IBw+fkmD3rzWDaEY7+/i1xY94AeO257d06QMgld75GtV/N+aEs7A6vQ==", - "dev": true, - "dependencies": { - "@ethersproject/abi": "5.0.7", - "underscore": "1.9.1", - "web3-utils": "1.3.5" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "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-accounts": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.3.5.tgz", - "integrity": "sha512-r3WOR21rgm6Cd6OFnifr3Tizdm5K+g2TsSOPySwX4FrgLrYDL6ck4zr5VXUPz+llpSExb/JztpE8pqEHr3U2NA==", - "dev": true, - "dependencies": { - "crypto-browserify": "3.12.0", - "eth-lib": "0.2.8", - "ethereumjs-common": "^1.3.2", - "ethereumjs-tx": "^2.1.1", - "scrypt-js": "^3.0.1", - "underscore": "1.9.1", - "uuid": "3.3.2", - "web3-core": "1.3.5", - "web3-core-helpers": "1.3.5", - "web3-core-method": "1.3.5", - "web3-utils": "1.3.5" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "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, - "bin": { - "uuid": "bin/uuid" - } - }, - "node_modules/web3-eth-contract": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.3.5.tgz", - "integrity": "sha512-WfGVeQquN3D7Qm+KEIN9EI7yrm/fL2V9Y4+YhDWiKA/ns1pX1LYcEWojTOnBXCnPF3tcvoKKL+KBxXg1iKm38A==", - "dev": true, - "dependencies": { - "@types/bn.js": "^4.11.5", - "underscore": "1.9.1", - "web3-core": "1.3.5", - "web3-core-helpers": "1.3.5", - "web3-core-method": "1.3.5", - "web3-core-promievent": "1.3.5", - "web3-core-subscriptions": "1.3.5", - "web3-eth-abi": "1.3.5", - "web3-utils": "1.3.5" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "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-ens": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.3.5.tgz", - "integrity": "sha512-5bkpFTXV18CvaVP8kCbLZZm2r1TWUv9AsXH+80yz8bTZulUGvXsBMRfK6e5nfEr2Yv59xlIXCFoalmmySI9EJw==", - "dev": true, - "dependencies": { - "content-hash": "^2.5.2", - "eth-ens-namehash": "2.0.8", - "underscore": "1.9.1", - "web3-core": "1.3.5", - "web3-core-helpers": "1.3.5", - "web3-core-promievent": "1.3.5", - "web3-eth-abi": "1.3.5", - "web3-eth-contract": "1.3.5", - "web3-utils": "1.3.5" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-iban": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.3.5.tgz", - "integrity": "sha512-x+BI/d2Vt0J1cKK8eFd4W0f1TDjgEOYCwiViTb28lLE+tqrgyPqWDA+l6UlKYLF/yMFX3Dym4ofcCOtgcn4q4g==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.9", - "web3-utils": "1.3.5" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-personal": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.3.5.tgz", - "integrity": "sha512-xELQHNZ8p3VoO1582ghCaq+Bx7pSkOOalc6/ACOCGtHDMelqgVejrmSIZGScYl+k0HzngmQAzURZWQocaoGM1g==", - "dev": true, - "dependencies": { - "@types/node": "^12.12.6", - "web3-core": "1.3.5", - "web3-core-helpers": "1.3.5", - "web3-core-method": "1.3.5", - "web3-net": "1.3.5", - "web3-utils": "1.3.5" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-personal/node_modules/@types/node": { - "version": "12.20.13", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.13.tgz", - "integrity": "sha512-1x8W5OpxPq+T85OUsHRP6BqXeosKmeXRtjoF39STcdf/UWLqUsoehstZKOi0CunhVqHG17AyZgpj20eRVooK6A==", - "dev": true - }, - "node_modules/web3-net": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.3.5.tgz", - "integrity": "sha512-usbFbuUpKK8s7jPLGoUzi/WpNnefGFPTj948aJv8BZ04UQA4L/XS5NNkkhk358zNMmhGfEFW8wrWy+0Oy0njtA==", - "dev": true, - "dependencies": { - "web3-core": "1.3.5", - "web3-core-method": "1.3.5", - "web3-utils": "1.3.5" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-providers-http": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.3.5.tgz", - "integrity": "sha512-ZQOmceFjcajEZdiuqciXjijwIYWNmEJ1oxMtbrwB2eGxHRCMXEH2xGRUZuhOFNF88yQC/VXVi14yvYg5ZlFJlA==", - "dev": true, - "dependencies": { - "web3-core-helpers": "1.3.5", - "xhr2-cookies": "1.1.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-providers-ipc": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.3.5.tgz", - "integrity": "sha512-cbZOeb/sALiHjzMolJjIyHla/J5wdL2JKUtRO66Nh/uLALBCpU8JUgzNvpAdJ1ae3+A33+EdFStdzuDYHKtQew==", - "dev": true, - "dependencies": { - "oboe": "2.1.5", - "underscore": "1.9.1", - "web3-core-helpers": "1.3.5" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-providers-ws": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.3.5.tgz", - "integrity": "sha512-zeZ4LMvKhYaJBDCqA//Bzgp4r/T0tNq5U/xvN0axA4YflzF7yqlsbzGwCkcZYDbrUaK3Ltl2uOmvwjbWALOZ1A==", - "dev": true, - "dependencies": { - "eventemitter3": "4.0.4", - "underscore": "1.9.1", - "web3-core-helpers": "1.3.5", - "websocket": "^1.0.32" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-shh": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.3.5.tgz", - "integrity": "sha512-aRwzCduXvuGVslLL/Y15VcOHa70Qr2kxZI7UwOzQVhaaOdxuRRvo3AK/cmyln1Tsd54/n93Yk8I3qg5I2+6alw==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "web3-core": "1.3.5", - "web3-core-method": "1.3.5", - "web3-core-subscriptions": "1.3.5", - "web3-net": "1.3.5" - }, - "engines": { - "node": ">=8.0.0" - } - }, "node_modules/web3-utils": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.3.5.tgz", - "integrity": "sha512-5apMRm8ElYjI/92GHqijmaLC+s+d5lgjpjHft+rJSs/dsnX8I8tQreqev0dmU+wzU+2EEe4Sx9a/OwGWHhQv3A==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.8.0.tgz", + "integrity": "sha512-7nUIl7UWpLVka2f09CMbKOSEvorvHnaugIabU4mj7zfMvm0tSByLcEu3eyV9qgS11qxxLuOkzBIwCstTflhmpQ==", "dev": true, "dependencies": { - "bn.js": "^4.11.9", - "eth-lib": "0.2.8", + "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", - "underscore": "1.9.1", "utf8": "3.0.0" }, "engines": { @@ -22750,45 +21529,13 @@ "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", - "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, - "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" - } - }, - "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, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/websocket/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "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": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", "dev": true, "dependencies": { "tr46": "~0.0.3", @@ -22796,15 +21543,18 @@ } }, "node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "dependencies": { "isexe": "^2.0.0" }, "bin": { - "which": "bin/which" + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" } }, "node_modules/which-boxed-primitive": { @@ -22826,30 +21576,9 @@ "node_modules/which-module": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", - "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", + "integrity": "sha512-F6+WgncZi/mJDrammbTuHe1q0R5hOXv/mBaiNA2TCNT/LTHusX0V+CJnj9XT8ki5ln2UZyyddDgHfCzyrOH7MQ==", "dev": true }, - "node_modules/which-typed-array": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.4.tgz", - "integrity": "sha512-49E0SpUe90cjpoc7BOJwyPHRqSAd12c10Qm2amdEZrJPCY2NDxaW01zHITrem+rnETY3dwrbH3UUrUwagfCYDA==", - "dev": true, - "dependencies": { - "available-typed-arrays": "^1.0.2", - "call-bind": "^1.0.0", - "es-abstract": "^1.18.0-next.1", - "foreach": "^2.0.5", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.1", - "is-typed-array": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/wide-align": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", @@ -22862,7 +21591,7 @@ "node_modules/window-size": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz", - "integrity": "sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU=", + "integrity": "sha512-UD7d8HFA2+PZsbKyaOCEy8gMh1oDtHgJh1LfgjQ4zVXmYjAT/kvz3PueITKuqDiIXQe7yzpPnxX3lNc+AhQMyw==", "dev": true, "bin": { "window-size": "cli.js" @@ -22883,13 +21612,13 @@ "node_modules/wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", "dev": true }, "node_modules/workerpool": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", - "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", + "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", "dev": true }, "node_modules/wrap-ansi": { @@ -22909,21 +21638,6 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/wrap-ansi/node_modules/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, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/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/wrap-ansi/node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -22947,22 +21661,10 @@ "node": ">=8" } }, - "node_modules/wrap-ansi/node_modules/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, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, "node_modules/write": { @@ -22998,69 +21700,15 @@ } } }, - "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, - "dependencies": { - "global": "~4.4.0", - "is-function": "^1.0.1", - "parse-headers": "^2.0.0", - "xtend": "^4.0.0" - } - }, - "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, - "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" - } - }, - "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, - "dependencies": { - "xhr-request": "^1.1.0" - } - }, - "node_modules/xhr2-cookies": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz", - "integrity": "sha1-fXdEnQmZGX8VXLc7I99yUF7YnUg=", - "dev": true, - "dependencies": { - "cookiejar": "^2.1.1" - } - }, "node_modules/xmlhttprequest": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", - "integrity": "sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw=", + "integrity": "sha512-58Im/U0mlVBLM38NdZjHyhuMtCqa61469k2YP/AaPbvCoV9aQGUpbJBj1QRm2ytRiVQBD/fsw7L2bJGDVQswBA==", "dev": true, "engines": { "node": ">=0.4.0" } }, - "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, - "engines": { - "node": ">=0.4" - } - }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -23070,21 +21718,21 @@ "node": ">=10" } }, - "node_modules/yaeti": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz", - "integrity": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc=", - "dev": true, - "engines": { - "node": ">=0.10.32" - } - }, "node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, "node_modules/yargs": { "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", @@ -23160,21 +21808,6 @@ "node": ">=8" } }, - "node_modules/yargs/node_modules/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, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/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/yargs/node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -23198,18 +21831,6 @@ "node": ">=8" } }, - "node_modules/yargs/node_modules/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, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/yargs/node_modules/yargs-parser": { "version": "20.2.9", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", @@ -23252,9 +21873,9 @@ } }, "@babel/helper-validator-identifier": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz", - "integrity": "sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==", + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", "dev": true }, "@babel/highlight": { @@ -23303,6 +21924,12 @@ "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", @@ -23320,19 +21947,13 @@ } } }, - "@cspotcode/source-map-consumer": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", - "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", - "dev": true - }, "@cspotcode/source-map-support": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", - "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", + "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": { - "@cspotcode/source-map-consumer": "0.8.0" + "@jridgewell/trace-mapping": "0.3.9" } }, "@ensdomains/ens": { @@ -23351,19 +21972,19 @@ "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", "dev": true }, "camelcase": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", + "integrity": "sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg==", "dev": true }, "cliui": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "integrity": "sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w==", "dev": true, "requires": { "string-width": "^1.0.1", @@ -23374,7 +21995,7 @@ "find-up": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "integrity": "sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==", "dev": true, "requires": { "path-exists": "^2.0.0", @@ -23384,7 +22005,7 @@ "fs-extra": { "version": "0.30.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", - "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", + "integrity": "sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==", "dev": true, "requires": { "graceful-fs": "^4.1.2", @@ -23403,7 +22024,7 @@ "is-fullwidth-code-point": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", "dev": true, "requires": { "number-is-nan": "^1.0.0" @@ -23412,7 +22033,7 @@ "jsonfile": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "integrity": "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==", "dev": true, "requires": { "graceful-fs": "^4.1.6" @@ -23421,7 +22042,7 @@ "load-json-file": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "integrity": "sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A==", "dev": true, "requires": { "graceful-fs": "^4.1.2", @@ -23434,7 +22055,7 @@ "parse-json": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==", "dev": true, "requires": { "error-ex": "^1.2.0" @@ -23443,7 +22064,7 @@ "path-exists": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "integrity": "sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==", "dev": true, "requires": { "pinkie-promise": "^2.0.0" @@ -23452,7 +22073,7 @@ "path-type": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "integrity": "sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg==", "dev": true, "requires": { "graceful-fs": "^4.1.2", @@ -23463,13 +22084,13 @@ "pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", "dev": true }, "read-pkg": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "integrity": "sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ==", "dev": true, "requires": { "load-json-file": "^1.0.0", @@ -23480,7 +22101,7 @@ "read-pkg-up": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "integrity": "sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A==", "dev": true, "requires": { "find-up": "^1.0.0", @@ -23490,9 +22111,18 @@ "require-from-string": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-1.2.1.tgz", - "integrity": "sha1-UpyczvJzgK3+yaL5ZbZJu+5jZBg=", + "integrity": "sha512-H7AkJWMobeskkttHyhTVtS0fxpFLjxhbfMa6Bk3wimP7sdPRGL3EyCg3sAQenFfAe+xQ+oAc85Nmtvq0ROM83Q==", "dev": true }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", @@ -23515,7 +22145,7 @@ "string-width": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", "dev": true, "requires": { "code-point-at": "^1.0.0", @@ -23526,7 +22156,7 @@ "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", "dev": true, "requires": { "ansi-regex": "^2.0.0" @@ -23535,7 +22165,7 @@ "strip-bom": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "integrity": "sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==", "dev": true, "requires": { "is-utf8": "^0.2.0" @@ -23544,7 +22174,7 @@ "wrap-ansi": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "integrity": "sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==", "dev": true, "requires": { "string-width": "^1.0.1", @@ -23560,7 +22190,7 @@ "yargs": { "version": "4.8.1", "resolved": "https://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz", - "integrity": "sha1-wMQpJMpKqmsObaFznfshZDn53cA=", + "integrity": "sha512-LqodLrnIDM3IFT+Hf/5sxBnEGECrfdC1uIbgZeJmESCSo4HoCAaKEus8MylXHAkdacGc0ye+Qa+dpkuom8uVYA==", "dev": true, "requires": { "cliui": "^3.2.0", @@ -23582,7 +22212,7 @@ "yargs-parser": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz", - "integrity": "sha1-hVaN488VD/SfpRgl8DqMiA3cxcQ=", + "integrity": "sha512-9pIKIJhnI5tonzG6OnCFlz/yln8xHYcGl+pn3xR0Vzff0vzN1PbNRaelgfgRUwZ3s4i3jvxT9WhmUGL4whnasA==", "dev": true, "requires": { "camelcase": "^3.0.0", @@ -23598,9 +22228,9 @@ "dev": true }, "@eslint/eslintrc": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.1.tgz", - "integrity": "sha512-OhSY22oQQdw3zgPOOwdoj01l/Dzl1Z+xyUP33tkSN+aqyEhymJCcPHyXt+ylW8FSe0TfRC2VG+ROQOapD0aZSQ==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", + "integrity": "sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==", "dev": true, "requires": { "ajv": "^6.12.4", @@ -23612,54 +22242,6 @@ "js-yaml": "^4.1.0", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" - }, - "dependencies": { - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "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 - }, - "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 - } } }, "@ethereum-waffle/chai": { @@ -23725,522 +22307,418 @@ "postinstall-postinstall": "^2.1.0" } }, - "@ethereumjs/block": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/@ethereumjs/block/-/block-3.6.2.tgz", - "integrity": "sha512-mOqYWwMlAZpYUEOEqt7EfMFuVL2eyLqWWIzcf4odn6QgXY8jBI2NhVuJncrMCKeMZrsJAe7/auaRRB6YcdH+Qw==", - "dev": true, - "requires": { - "@ethereumjs/common": "^2.6.3", - "@ethereumjs/tx": "^3.5.1", - "ethereumjs-util": "^7.1.4", - "merkle-patricia-tree": "^4.2.4" - } - }, - "@ethereumjs/blockchain": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/@ethereumjs/blockchain/-/blockchain-5.5.2.tgz", - "integrity": "sha512-Jz26iJmmsQtngerW6r5BDFaew/f2mObLrRZo3rskLOx1lmtMZ8+TX/vJexmivrnWgmAsTdNWhlKUYY4thPhPig==", - "dev": true, - "requires": { - "@ethereumjs/block": "^3.6.2", - "@ethereumjs/common": "^2.6.3", - "@ethereumjs/ethash": "^1.1.0", - "debug": "^4.3.3", - "ethereumjs-util": "^7.1.4", - "level-mem": "^5.0.1", - "lru-cache": "^5.1.1", - "semaphore-async-await": "^1.5.1" - } - }, - "@ethereumjs/common": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-2.6.3.tgz", - "integrity": "sha512-mQwPucDL7FDYIg9XQ8DL31CnIYZwGhU5hyOO5E+BMmT71G0+RHvIT5rIkLBirJEKxV6+Rcf9aEIY0kXInxUWpQ==", - "dev": true, - "requires": { - "crc-32": "^1.2.0", - "ethereumjs-util": "^7.1.4" - } - }, - "@ethereumjs/ethash": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@ethereumjs/ethash/-/ethash-1.1.0.tgz", - "integrity": "sha512-/U7UOKW6BzpA+Vt+kISAoeDie1vAvY4Zy2KF5JJb+So7+1yKmJeJEHOGSnQIj330e9Zyl3L5Nae6VZyh2TJnAA==", - "dev": true, - "requires": { - "@ethereumjs/block": "^3.5.0", - "@types/levelup": "^4.3.0", - "buffer-xor": "^2.0.1", - "ethereumjs-util": "^7.1.1", - "miller-rabin": "^4.0.0" - }, - "dependencies": { - "buffer-xor": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-2.0.2.tgz", - "integrity": "sha512-eHslX0bin3GB+Lx2p7lEYRShRewuNZL3fUl4qlVJGGiwoPGftmt8JQgk2Y9Ji5/01TnVDo33E5b5O3vUB1HdqQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.1" - } - } - } - }, - "@ethereumjs/tx": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-3.5.1.tgz", - "integrity": "sha512-xzDrTiu4sqZXUcaBxJ4n4W5FrppwxLxZB4ZDGVLtxSQR4lVuOnFR6RcUHdg1mpUhAPVrmnzLJpxaeXnPxIyhWA==", - "dev": true, - "requires": { - "@ethereumjs/common": "^2.6.3", - "ethereumjs-util": "^7.1.4" - } - }, - "@ethereumjs/vm": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethereumjs/vm/-/vm-5.8.0.tgz", - "integrity": "sha512-mn2G2SX79QY4ckVvZUfxlNUpzwT2AEIkvgJI8aHoQaNYEHhH8rmdVDIaVVgz6//PjK52BZsK23afz+WvSR0Qqw==", - "dev": true, - "requires": { - "@ethereumjs/block": "^3.6.2", - "@ethereumjs/blockchain": "^5.5.2", - "@ethereumjs/common": "^2.6.3", - "@ethereumjs/tx": "^3.5.1", - "async-eventemitter": "^0.2.4", - "core-js-pure": "^3.0.1", - "debug": "^4.3.3", - "ethereumjs-util": "^7.1.4", - "functional-red-black-tree": "^1.0.1", - "mcl-wasm": "^0.7.1", - "merkle-patricia-tree": "^4.2.4", - "rustbn.js": "~0.2.0" - } - }, "@ethersproject/abi": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.6.0.tgz", - "integrity": "sha512-AhVByTwdXCc2YQ20v300w6KVHle9g2OFc28ZAFCPnJyEpkv1xKXjZcSTgWOlv1i+0dqlgF8RCF2Rn2KC1t+1Vg==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz", + "integrity": "sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==", "dev": true, "requires": { - "@ethersproject/address": "^5.6.0", - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/constants": "^5.6.0", - "@ethersproject/hash": "^5.6.0", - "@ethersproject/keccak256": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/strings": "^5.6.0" + "@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" } }, "@ethersproject/abstract-provider": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.6.0.tgz", - "integrity": "sha512-oPMFlKLN+g+y7a79cLK3WiLcjWFnZQtXWgnLAbHZcN3s7L4v90UHpTOrLk+m3yr0gt+/h9STTM6zrr7PM8uoRw==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz", + "integrity": "sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==", "dev": true, "requires": { - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/networks": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/transactions": "^5.6.0", - "@ethersproject/web": "^5.6.0" + "@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" } }, "@ethersproject/abstract-signer": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.6.0.tgz", - "integrity": "sha512-WOqnG0NJKtI8n0wWZPReHtaLkDByPL67tn4nBaDAhmVq8sjHTPbCdz4DRhVu/cfTOvfy9w3iq5QZ7BX7zw56BQ==", + "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": { - "@ethersproject/abstract-provider": "^5.6.0", - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0" + "@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" } }, "@ethersproject/address": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.6.0.tgz", - "integrity": "sha512-6nvhYXjbXsHPS+30sHZ+U4VMagFC/9zAk6Gd/h3S21YW4+yfb0WfRtaAIZ4kfM4rrVwqiy284LP0GtL5HXGLxQ==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz", + "integrity": "sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==", "dev": true, "requires": { - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/keccak256": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/rlp": "^5.6.0" + "@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" } }, "@ethersproject/base64": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.6.0.tgz", - "integrity": "sha512-2Neq8wxJ9xHxCF9TUgmKeSh9BXJ6OAxWfeGWvbauPh8FuHEjamgHilllx8KkSd5ErxyHIX7Xv3Fkcud2kY9ezw==", + "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, "requires": { - "@ethersproject/bytes": "^5.6.0" + "@ethersproject/bytes": "^5.7.0" } }, "@ethersproject/basex": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.6.0.tgz", - "integrity": "sha512-qN4T+hQd/Md32MoJpc69rOwLYRUXwjTlhHDIeUkUmiN/JyWkkLLMoG0TqvSQKNqZOMgN5stbUYN6ILC+eD7MEQ==", + "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.6.0", - "@ethersproject/properties": "^5.6.0" + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/properties": "^5.7.0" } }, "@ethersproject/bignumber": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.6.0.tgz", - "integrity": "sha512-VziMaXIUHQlHJmkv1dlcd6GY2PmT0khtAqaMctCIDogxkrarMzA9L94KN1NeXqqOfFD6r0sJT3vCTOFSmZ07DA==", + "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, "requires": { - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "bn.js": "^4.11.9" + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "bn.js": "^5.2.1" } }, "@ethersproject/bytes": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.6.1.tgz", - "integrity": "sha512-NwQt7cKn5+ZE4uDn+X5RAXLp46E1chXoaMmrxAyA0rblpxz8t58lVkrHXoRIn0lz1joQElQ8410GqhTqMOwc6g==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz", + "integrity": "sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==", "dev": true, "requires": { - "@ethersproject/logger": "^5.6.0" + "@ethersproject/logger": "^5.7.0" } }, "@ethersproject/constants": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.6.0.tgz", - "integrity": "sha512-SrdaJx2bK0WQl23nSpV/b1aq293Lh0sUaZT/yYKPDKn4tlAbkH96SPJwIhwSwTsoQQZxuh1jnqsKwyymoiBdWA==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.7.0.tgz", + "integrity": "sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==", "dev": true, "requires": { - "@ethersproject/bignumber": "^5.6.0" + "@ethersproject/bignumber": "^5.7.0" } }, "@ethersproject/contracts": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.6.0.tgz", - "integrity": "sha512-74Ge7iqTDom0NX+mux8KbRUeJgu1eHZ3iv6utv++sLJG80FVuU9HnHeKVPfjd9s3woFhaFoQGf3B3iH/FrQmgw==", + "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.6.0", - "@ethersproject/abstract-provider": "^5.6.0", - "@ethersproject/abstract-signer": "^5.6.0", - "@ethersproject/address": "^5.6.0", - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/constants": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/transactions": "^5.6.0" + "@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" } }, "@ethersproject/hash": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.6.0.tgz", - "integrity": "sha512-fFd+k9gtczqlr0/BruWLAu7UAOas1uRRJvOR84uDf4lNZ+bTkGl366qvniUZHKtlqxBRU65MkOobkmvmpHU+jA==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz", + "integrity": "sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==", "dev": true, "requires": { - "@ethersproject/abstract-signer": "^5.6.0", - "@ethersproject/address": "^5.6.0", - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/keccak256": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/strings": "^5.6.0" + "@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" } }, "@ethersproject/hdnode": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.6.0.tgz", - "integrity": "sha512-61g3Jp3nwDqJcL/p4nugSyLrpl/+ChXIOtCEM8UDmWeB3JCAt5FoLdOMXQc3WWkc0oM2C0aAn6GFqqMcS/mHTw==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.7.0.tgz", + "integrity": "sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==", "dev": true, "requires": { - "@ethersproject/abstract-signer": "^5.6.0", - "@ethersproject/basex": "^5.6.0", - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/pbkdf2": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/sha2": "^5.6.0", - "@ethersproject/signing-key": "^5.6.0", - "@ethersproject/strings": "^5.6.0", - "@ethersproject/transactions": "^5.6.0", - "@ethersproject/wordlists": "^5.6.0" + "@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" } }, "@ethersproject/json-wallets": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.6.0.tgz", - "integrity": "sha512-fmh86jViB9r0ibWXTQipxpAGMiuxoqUf78oqJDlCAJXgnJF024hOOX7qVgqsjtbeoxmcLwpPsXNU0WEe/16qPQ==", - "dev": true, - "requires": { - "@ethersproject/abstract-signer": "^5.6.0", - "@ethersproject/address": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/hdnode": "^5.6.0", - "@ethersproject/keccak256": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/pbkdf2": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/random": "^5.6.0", - "@ethersproject/strings": "^5.6.0", - "@ethersproject/transactions": "^5.6.0", + "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, + "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" } }, "@ethersproject/keccak256": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.6.0.tgz", - "integrity": "sha512-tk56BJ96mdj/ksi7HWZVWGjCq0WVl/QvfhFQNeL8fxhBlGoP+L80uDCiQcpJPd+2XxkivS3lwRm3E0CXTfol0w==", + "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, "requires": { - "@ethersproject/bytes": "^5.6.0", + "@ethersproject/bytes": "^5.7.0", "js-sha3": "0.8.0" - }, - "dependencies": { - "js-sha3": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", - "dev": true - } } }, "@ethersproject/logger": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.6.0.tgz", - "integrity": "sha512-BiBWllUROH9w+P21RzoxJKzqoqpkyM1pRnEKG69bulE9TSQD8SAIvTQqIMZmmCO8pUNkgLP1wndX1gKghSpBmg==", + "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.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.6.1.tgz", - "integrity": "sha512-b2rrupf3kCTcc3jr9xOWBuHylSFtbpJf79Ga7QR98ienU2UqGimPGEsYMgbI29KHJfA5Us89XwGVmxrlxmSrMg==", + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.1.tgz", + "integrity": "sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==", "dev": true, "requires": { - "@ethersproject/logger": "^5.6.0" + "@ethersproject/logger": "^5.7.0" } }, "@ethersproject/pbkdf2": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.6.0.tgz", - "integrity": "sha512-Wu1AxTgJo3T3H6MIu/eejLFok9TYoSdgwRr5oGY1LTLfmGesDoSx05pemsbrPT2gG4cQME+baTSCp5sEo2erZQ==", + "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": { - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/sha2": "^5.6.0" + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/sha2": "^5.7.0" } }, "@ethersproject/properties": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.6.0.tgz", - "integrity": "sha512-szoOkHskajKePTJSZ46uHUWWkbv7TzP2ypdEK6jGMqJaEt2sb0jCgfBo0gH0m2HBpRixMuJ6TBRaQCF7a9DoCg==", + "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": { - "@ethersproject/logger": "^5.6.0" + "@ethersproject/logger": "^5.7.0" } }, "@ethersproject/providers": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.6.2.tgz", - "integrity": "sha512-6/EaFW/hNWz+224FXwl8+HdMRzVHt8DpPmu5MZaIQqx/K/ELnC9eY236SMV7mleCM3NnEArFwcAAxH5kUUgaRg==", - "dev": true, - "requires": { - "@ethersproject/abstract-provider": "^5.6.0", - "@ethersproject/abstract-signer": "^5.6.0", - "@ethersproject/address": "^5.6.0", - "@ethersproject/basex": "^5.6.0", - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/constants": "^5.6.0", - "@ethersproject/hash": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/networks": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/random": "^5.6.0", - "@ethersproject/rlp": "^5.6.0", - "@ethersproject/sha2": "^5.6.0", - "@ethersproject/strings": "^5.6.0", - "@ethersproject/transactions": "^5.6.0", - "@ethersproject/web": "^5.6.0", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.2.tgz", + "integrity": "sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg==", + "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" } }, "@ethersproject/random": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.6.0.tgz", - "integrity": "sha512-si0PLcLjq+NG/XHSZz90asNf+YfKEqJGVdxoEkSukzbnBgC8rydbgbUgBbBGLeHN4kAJwUFEKsu3sCXT93YMsw==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.7.0.tgz", + "integrity": "sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ==", "dev": true, "requires": { - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/logger": "^5.6.0" + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0" } }, "@ethersproject/rlp": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.6.0.tgz", - "integrity": "sha512-dz9WR1xpcTL+9DtOT/aDO+YyxSSdO8YIS0jyZwHHSlAmnxA6cKU3TrTd4Xc/bHayctxTgGLYNuVVoiXE4tTq1g==", + "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": { - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/logger": "^5.6.0" + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0" } }, "@ethersproject/sha2": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.6.0.tgz", - "integrity": "sha512-1tNWCPFLu1n3JM9t4/kytz35DkuF9MxqkGGEHNauEbaARdm2fafnOyw1s0tIQDPKF/7bkP1u3dbrmjpn5CelyA==", + "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.6.0", - "@ethersproject/logger": "^5.6.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", "hash.js": "1.1.7" } }, "@ethersproject/signing-key": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.6.0.tgz", - "integrity": "sha512-S+njkhowmLeUu/r7ir8n78OUKx63kBdMCPssePS89So1TH4hZqnWFsThEd/GiXYp9qMxVrydf7KdM9MTGPFukA==", + "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.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "bn.js": "^4.11.9", + "@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.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.6.0.tgz", - "integrity": "sha512-YwF52vTNd50kjDzqKaoNNbC/r9kMDPq3YzDWmsjFTRBcIF1y4JCQJ8gB30wsTfHbaxgxelI5BfxQSxD/PbJOww==", + "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.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/keccak256": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/sha2": "^5.6.0", - "@ethersproject/strings": "^5.6.0" + "@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" } }, "@ethersproject/strings": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.6.0.tgz", - "integrity": "sha512-uv10vTtLTZqrJuqBZR862ZQjTIa724wGPWQqZrofaPI/kUsf53TBG0I0D+hQ1qyNtllbNzaW+PDPHHUI6/65Mg==", + "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": { - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/constants": "^5.6.0", - "@ethersproject/logger": "^5.6.0" + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0" } }, "@ethersproject/transactions": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.6.0.tgz", - "integrity": "sha512-4HX+VOhNjXHZyGzER6E/LVI2i6lf9ejYeWD6l4g50AdmimyuStKc39kvKf1bXWQMg7QNVh+uC7dYwtaZ02IXeg==", + "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": { - "@ethersproject/address": "^5.6.0", - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/constants": "^5.6.0", - "@ethersproject/keccak256": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/rlp": "^5.6.0", - "@ethersproject/signing-key": "^5.6.0" + "@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" } }, "@ethersproject/units": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.6.0.tgz", - "integrity": "sha512-tig9x0Qmh8qbo1w8/6tmtyrm/QQRviBh389EQ+d8fP4wDsBrJBf08oZfoiz1/uenKK9M78yAP4PoR7SsVoTjsw==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.7.0.tgz", + "integrity": "sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg==", "dev": true, "requires": { - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/constants": "^5.6.0", - "@ethersproject/logger": "^5.6.0" + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0" } }, "@ethersproject/wallet": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.6.0.tgz", - "integrity": "sha512-qMlSdOSTyp0MBeE+r7SUhr1jjDlC1zAXB8VD84hCnpijPQiSNbxr6GdiLXxpUs8UKzkDiNYYC5DRI3MZr+n+tg==", - "dev": true, - "requires": { - "@ethersproject/abstract-provider": "^5.6.0", - "@ethersproject/abstract-signer": "^5.6.0", - "@ethersproject/address": "^5.6.0", - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/hash": "^5.6.0", - "@ethersproject/hdnode": "^5.6.0", - "@ethersproject/json-wallets": "^5.6.0", - "@ethersproject/keccak256": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/random": "^5.6.0", - "@ethersproject/signing-key": "^5.6.0", - "@ethersproject/transactions": "^5.6.0", - "@ethersproject/wordlists": "^5.6.0" + "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": { + "@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" } }, "@ethersproject/web": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.6.0.tgz", - "integrity": "sha512-G/XHj0hV1FxI2teHRfCGvfBUHFmU+YOSbCxlAMqJklxSa7QMiHFQfAxvwY2PFqgvdkxEKwRNr/eCjfAPEm2Ctg==", + "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.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/strings": "^5.6.0" + "@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" } }, "@ethersproject/wordlists": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.6.0.tgz", - "integrity": "sha512-q0bxNBfIX3fUuAo9OmjlEYxP40IB8ABgb7HjEZCL5IKubzV3j30CWi2rqQbjTS2HfoyQbfINoKcTVWP4ejwR7Q==", + "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": { - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/hash": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/strings": "^5.6.0" + "@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" } }, "@humanwhocodes/config-array": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.4.tgz", - "integrity": "sha512-mXAIHxZT3Vcpg83opl1wGlVZ9xydbfZO3r5YfRSH6Gpp2J/PfdBP0wbDa2sO6/qRbcalpoevVyW6A/fI6LfeMw==", + "version": "0.11.7", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.7.tgz", + "integrity": "sha512-kBbPWzN8oVMLb0hOUYXhmxggL/1cJE6ydvjDIGi9EnAGUyA7cLVKQg+d/Dsm+KZwx2czGHrCmMVLiyg8s5JPKw==", "dev": true, "requires": { "@humanwhocodes/object-schema": "^1.2.1", "debug": "^4.1.1", - "minimatch": "^3.0.4" + "minimatch": "^3.0.5" } }, - "@humanwhocodes/gitignore-to-minimatch": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz", - "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==", - "dev": true - }, "@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", @@ -24253,6 +22731,28 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, + "@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "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==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, "@kwsites/file-exists": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz", @@ -24269,9 +22769,9 @@ "dev": true }, "@metamask/eth-sig-util": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@metamask/eth-sig-util/-/eth-sig-util-4.0.0.tgz", - "integrity": "sha512-LczOjjxY4A7XYloxzyxJIHONELmUxVZncpOLoClpEcTiebiVdM46KRPYXGuULro9oNNR2xdVx3yoKiQjdfWmoA==", + "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", @@ -24290,6 +22790,12 @@ "@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 + }, "ethereumjs-util": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", @@ -24304,67 +22810,375 @@ "ethjs-util": "0.1.6", "rlp": "^2.2.3" } - }, - "tweetnacl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==", - "dev": true } } }, + "@noble/hashes": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.1.2.tgz", + "integrity": "sha512-KYRCASVTv6aeUi1tsF8/vpyR7zpfs3FUzy2Jqm+MU+LmUKhQ0y2FpfwqkCcxSg2ua4GALJd8k2R76WxwZGbQpA==", + "dev": true + }, + "@noble/secp256k1": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-1.6.3.tgz", + "integrity": "sha512-T04e4iTurVy7I8Sw4+c5OSN9/RkPlo1uKxAomtxQNLq8j1uPAqnsqG1bqvY3Jv7c13gyr6dui0zmh/I3+f/JaQ==", + "dev": true + }, "@nodelib/fs.scandir": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz", - "integrity": "sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==", + "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": { - "@nodelib/fs.stat": "2.0.4", + "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "@nodelib/fs.stat": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz", - "integrity": "sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q==", + "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 }, "@nodelib/fs.walk": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz", - "integrity": "sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==", + "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, "requires": { - "@nodelib/fs.scandir": "2.1.4", + "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, + "@nomicfoundation/ethereumjs-block": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-block/-/ethereumjs-block-4.0.0.tgz", + "integrity": "sha512-bk8uP8VuexLgyIZAHExH1QEovqx0Lzhc9Ntm63nCRKLHXIZkobaFaeCVwTESV7YkPKUk7NiK11s8ryed4CS9yA==", + "dev": true, + "requires": { + "@nomicfoundation/ethereumjs-common": "^3.0.0", + "@nomicfoundation/ethereumjs-rlp": "^4.0.0", + "@nomicfoundation/ethereumjs-trie": "^5.0.0", + "@nomicfoundation/ethereumjs-tx": "^4.0.0", + "@nomicfoundation/ethereumjs-util": "^8.0.0", + "ethereum-cryptography": "0.1.3" + } + }, + "@nomicfoundation/ethereumjs-blockchain": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-blockchain/-/ethereumjs-blockchain-6.0.0.tgz", + "integrity": "sha512-pLFEoea6MWd81QQYSReLlLfH7N9v7lH66JC/NMPN848ySPPQA5renWnE7wPByfQFzNrPBuDDRFFULMDmj1C0xw==", + "dev": true, + "requires": { + "@nomicfoundation/ethereumjs-block": "^4.0.0", + "@nomicfoundation/ethereumjs-common": "^3.0.0", + "@nomicfoundation/ethereumjs-ethash": "^2.0.0", + "@nomicfoundation/ethereumjs-rlp": "^4.0.0", + "@nomicfoundation/ethereumjs-trie": "^5.0.0", + "@nomicfoundation/ethereumjs-util": "^8.0.0", + "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": "3.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-3.0.0.tgz", + "integrity": "sha512-WS7qSshQfxoZOpHG/XqlHEGRG1zmyjYrvmATvc4c62+gZXgre1ymYP8ZNgx/3FyZY0TWe9OjFlKOfLqmgOeYwA==", + "dev": true, + "requires": { + "@nomicfoundation/ethereumjs-util": "^8.0.0", + "crc-32": "^1.2.0" + } + }, + "@nomicfoundation/ethereumjs-ethash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-ethash/-/ethereumjs-ethash-2.0.0.tgz", + "integrity": "sha512-WpDvnRncfDUuXdsAXlI4lXbqUDOA+adYRQaEezIkxqDkc+LDyYDbd/xairmY98GnQzo1zIqsIL6GB5MoMSJDew==", + "dev": true, + "requires": { + "@nomicfoundation/ethereumjs-block": "^4.0.0", + "@nomicfoundation/ethereumjs-rlp": "^4.0.0", + "@nomicfoundation/ethereumjs-util": "^8.0.0", + "abstract-level": "^1.0.3", + "bigint-crypto-utils": "^3.0.23", + "ethereum-cryptography": "0.1.3" + } + }, + "@nomicfoundation/ethereumjs-evm": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-evm/-/ethereumjs-evm-1.0.0.tgz", + "integrity": "sha512-hVS6qRo3V1PLKCO210UfcEQHvlG7GqR8iFzp0yyjTg2TmJQizcChKgWo8KFsdMw6AyoLgLhHGHw4HdlP8a4i+Q==", + "dev": true, + "requires": { + "@nomicfoundation/ethereumjs-common": "^3.0.0", + "@nomicfoundation/ethereumjs-util": "^8.0.0", + "@types/async-eventemitter": "^0.2.1", + "async-eventemitter": "^0.2.4", + "debug": "^4.3.3", + "ethereum-cryptography": "0.1.3", + "mcl-wasm": "^0.7.1", + "rustbn.js": "~0.2.0" + } + }, + "@nomicfoundation/ethereumjs-rlp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-4.0.0.tgz", + "integrity": "sha512-GaSOGk5QbUk4eBP5qFbpXoZoZUj/NrW7MRa0tKY4Ew4c2HAS0GXArEMAamtFrkazp0BO4K5p2ZCG3b2FmbShmw==", + "dev": true + }, + "@nomicfoundation/ethereumjs-statemanager": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-statemanager/-/ethereumjs-statemanager-1.0.0.tgz", + "integrity": "sha512-jCtqFjcd2QejtuAMjQzbil/4NHf5aAWxUc+CvS0JclQpl+7M0bxMofR2AJdtz+P3u0ke2euhYREDiE7iSO31vQ==", + "dev": true, + "requires": { + "@nomicfoundation/ethereumjs-common": "^3.0.0", + "@nomicfoundation/ethereumjs-rlp": "^4.0.0", + "@nomicfoundation/ethereumjs-trie": "^5.0.0", + "@nomicfoundation/ethereumjs-util": "^8.0.0", + "debug": "^4.3.3", + "ethereum-cryptography": "0.1.3", + "functional-red-black-tree": "^1.0.1" + } + }, + "@nomicfoundation/ethereumjs-trie": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-trie/-/ethereumjs-trie-5.0.0.tgz", + "integrity": "sha512-LIj5XdE+s+t6WSuq/ttegJzZ1vliwg6wlb+Y9f4RlBpuK35B9K02bO7xU+E6Rgg9RGptkWd6TVLdedTI4eNc2A==", + "dev": true, + "requires": { + "@nomicfoundation/ethereumjs-rlp": "^4.0.0", + "@nomicfoundation/ethereumjs-util": "^8.0.0", + "ethereum-cryptography": "0.1.3", + "readable-stream": "^3.6.0" + } + }, + "@nomicfoundation/ethereumjs-tx": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-4.0.0.tgz", + "integrity": "sha512-Gg3Lir2lNUck43Kp/3x6TfBNwcWC9Z1wYue9Nz3v4xjdcv6oDW9QSMJxqsKw9QEGoBBZ+gqwpW7+F05/rs/g1w==", + "dev": true, + "requires": { + "@nomicfoundation/ethereumjs-common": "^3.0.0", + "@nomicfoundation/ethereumjs-rlp": "^4.0.0", + "@nomicfoundation/ethereumjs-util": "^8.0.0", + "ethereum-cryptography": "0.1.3" + } + }, + "@nomicfoundation/ethereumjs-util": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-8.0.0.tgz", + "integrity": "sha512-2emi0NJ/HmTG+CGY58fa+DQuAoroFeSH9gKu9O6JnwTtlzJtgfTixuoOqLEgyyzZVvwfIpRueuePb8TonL1y+A==", + "dev": true, + "requires": { + "@nomicfoundation/ethereumjs-rlp": "^4.0.0-beta.2", + "ethereum-cryptography": "0.1.3" + } + }, + "@nomicfoundation/ethereumjs-vm": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-vm/-/ethereumjs-vm-6.0.0.tgz", + "integrity": "sha512-JMPxvPQ3fzD063Sg3Tp+UdwUkVxMoo1uML6KSzFhMH3hoQi/LMuXBoEHAoW83/vyNS9BxEe6jm6LmT5xdeEJ6w==", + "dev": true, + "requires": { + "@nomicfoundation/ethereumjs-block": "^4.0.0", + "@nomicfoundation/ethereumjs-blockchain": "^6.0.0", + "@nomicfoundation/ethereumjs-common": "^3.0.0", + "@nomicfoundation/ethereumjs-evm": "^1.0.0", + "@nomicfoundation/ethereumjs-rlp": "^4.0.0", + "@nomicfoundation/ethereumjs-statemanager": "^1.0.0", + "@nomicfoundation/ethereumjs-trie": "^5.0.0", + "@nomicfoundation/ethereumjs-tx": "^4.0.0", + "@nomicfoundation/ethereumjs-util": "^8.0.0", + "@types/async-eventemitter": "^0.2.1", + "async-eventemitter": "^0.2.4", + "debug": "^4.3.3", + "ethereum-cryptography": "0.1.3", + "functional-red-black-tree": "^1.0.1", + "mcl-wasm": "^0.7.1", + "rustbn.js": "~0.2.0" + } + }, + "@nomicfoundation/solidity-analyzer": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.0.tgz", + "integrity": "sha512-xGWAiVCGOycvGiP/qrlf9f9eOn7fpNbyJygcB0P21a1MDuVPlKt0Srp7rvtBEutYQ48ouYnRXm33zlRnlTOPHg==", + "dev": true, + "requires": { + "@nomicfoundation/solidity-analyzer-darwin-arm64": "0.1.0", + "@nomicfoundation/solidity-analyzer-darwin-x64": "0.1.0", + "@nomicfoundation/solidity-analyzer-freebsd-x64": "0.1.0", + "@nomicfoundation/solidity-analyzer-linux-arm64-gnu": "0.1.0", + "@nomicfoundation/solidity-analyzer-linux-arm64-musl": "0.1.0", + "@nomicfoundation/solidity-analyzer-linux-x64-gnu": "0.1.0", + "@nomicfoundation/solidity-analyzer-linux-x64-musl": "0.1.0", + "@nomicfoundation/solidity-analyzer-win32-arm64-msvc": "0.1.0", + "@nomicfoundation/solidity-analyzer-win32-ia32-msvc": "0.1.0", + "@nomicfoundation/solidity-analyzer-win32-x64-msvc": "0.1.0" + } + }, + "@nomicfoundation/solidity-analyzer-darwin-arm64": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.0.tgz", + "integrity": "sha512-vEF3yKuuzfMHsZecHQcnkUrqm8mnTWfJeEVFHpg+cO+le96xQA4lAJYdUan8pXZohQxv1fSReQsn4QGNuBNuCw==", + "dev": true, + "optional": true + }, + "@nomicfoundation/solidity-analyzer-darwin-x64": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-x64/-/solidity-analyzer-darwin-x64-0.1.0.tgz", + "integrity": "sha512-dlHeIg0pTL4dB1l9JDwbi/JG6dHQaU1xpDK+ugYO8eJ1kxx9Dh2isEUtA4d02cQAl22cjOHTvifAk96A+ItEHA==", + "dev": true, + "optional": true + }, + "@nomicfoundation/solidity-analyzer-freebsd-x64": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-freebsd-x64/-/solidity-analyzer-freebsd-x64-0.1.0.tgz", + "integrity": "sha512-WFCZYMv86WowDA4GiJKnebMQRt3kCcFqHeIomW6NMyqiKqhK1kIZCxSLDYsxqlx396kKLPN1713Q1S8tu68GKg==", + "dev": true, + "optional": true + }, + "@nomicfoundation/solidity-analyzer-linux-arm64-gnu": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-gnu/-/solidity-analyzer-linux-arm64-gnu-0.1.0.tgz", + "integrity": "sha512-DTw6MNQWWlCgc71Pq7CEhEqkb7fZnS7oly13pujs4cMH1sR0JzNk90Mp1zpSCsCs4oKan2ClhMlLKtNat/XRKQ==", + "dev": true, + "optional": true + }, + "@nomicfoundation/solidity-analyzer-linux-arm64-musl": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-musl/-/solidity-analyzer-linux-arm64-musl-0.1.0.tgz", + "integrity": "sha512-wUpUnR/3GV5Da88MhrxXh/lhb9kxh9V3Jya2NpBEhKDIRCDmtXMSqPMXHZmOR9DfCwCvG6vLFPr/+YrPCnUN0w==", + "dev": true, + "optional": true + }, + "@nomicfoundation/solidity-analyzer-linux-x64-gnu": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-gnu/-/solidity-analyzer-linux-x64-gnu-0.1.0.tgz", + "integrity": "sha512-lR0AxK1x/MeKQ/3Pt923kPvwigmGX3OxeU5qNtQ9pj9iucgk4PzhbS3ruUeSpYhUxG50jN4RkIGwUMoev5lguw==", + "dev": true, + "optional": true + }, + "@nomicfoundation/solidity-analyzer-linux-x64-musl": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-musl/-/solidity-analyzer-linux-x64-musl-0.1.0.tgz", + "integrity": "sha512-A1he/8gy/JeBD3FKvmI6WUJrGrI5uWJNr5Xb9WdV+DK0F8msuOqpEByLlnTdLkXMwW7nSl3awvLezOs9xBHJEg==", + "dev": true, + "optional": true + }, + "@nomicfoundation/solidity-analyzer-win32-arm64-msvc": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-arm64-msvc/-/solidity-analyzer-win32-arm64-msvc-0.1.0.tgz", + "integrity": "sha512-7x5SXZ9R9H4SluJZZP8XPN+ju7Mx+XeUMWZw7ZAqkdhP5mK19I4vz3x0zIWygmfE8RT7uQ5xMap0/9NPsO+ykw==", + "dev": true, + "optional": true + }, + "@nomicfoundation/solidity-analyzer-win32-ia32-msvc": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-ia32-msvc/-/solidity-analyzer-win32-ia32-msvc-0.1.0.tgz", + "integrity": "sha512-m7w3xf+hnE774YRXu+2mGV7RiF3QJtUoiYU61FascCkQhX3QMQavh7saH/vzb2jN5D24nT/jwvaHYX/MAM9zUw==", + "dev": true, + "optional": true + }, + "@nomicfoundation/solidity-analyzer-win32-x64-msvc": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-x64-msvc/-/solidity-analyzer-win32-x64-msvc-0.1.0.tgz", + "integrity": "sha512-xCuybjY0sLJQnJhupiFAXaek2EqF0AP0eBjgzaalPXSNvCEN6ZYHvUzdA50ENDVeSYFXcUsYf3+FsD3XKaeptA==", + "dev": true, + "optional": true + }, "@nomiclabs/hardhat-ethers": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.0.5.tgz", - "integrity": "sha512-A2gZAGB6kUvLx+kzM92HKuUF33F1FSe90L0TmkXkT2Hh0OKRpvWZURUSU2nghD2yC4DzfEZ3DftfeHGvZ2JTUw==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.2.1.tgz", + "integrity": "sha512-RHWYwnxryWR8hzRmU4Jm/q4gzvXpetUOJ4OPlwH2YARcDB+j79+yAYCwO0lN1SUOb4++oOTJEe6AWLEc42LIvg==", "dev": true, "requires": {} }, "@nomiclabs/hardhat-etherscan": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-3.0.3.tgz", - "integrity": "sha512-OfNtUKc/ZwzivmZnnpwWREfaYncXteKHskn3yDnz+fPBZ6wfM4GR+d5RwjREzYFWE+o5iR9ruXhWw/8fejWM9g==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-3.1.2.tgz", + "integrity": "sha512-IEikeOVq0C/7CY6aD74d8L4BpGoc/FNiN6ldiPVg0QIFIUSu4FSGA1dmtJZJKk1tjpwgrfTLQNWnigtEaN9REg==", "dev": true, "requires": { "@ethersproject/abi": "^5.1.2", "@ethersproject/address": "^5.0.2", "cbor": "^5.0.2", + "chalk": "^2.4.2", "debug": "^4.1.1", "fs-extra": "^7.0.1", + "lodash": "^4.17.11", "semver": "^6.3.0", - "undici": "^4.14.1" + "table": "^6.8.0", + "undici": "^5.4.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" + } + } } }, "@nomiclabs/hardhat-solhint": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-solhint/-/hardhat-solhint-2.0.0.tgz", - "integrity": "sha512-fn+izC923/oCnfbGyp7YwOXZYtwcrDIrTLlFVeEgeSAHe2ZnipRRtNCxEClZuzCptHmTzIIayBmAaijsTmEAoA==", + "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": { "solhint": "^2.0.0" @@ -24393,38 +23207,32 @@ "dev": true }, "@openzeppelin/hardhat-upgrades": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/@openzeppelin/hardhat-upgrades/-/hardhat-upgrades-1.17.0.tgz", - "integrity": "sha512-GNxR3/3fCKQsFpBi/r+5ib6U81UM9KCypmcOQxuCkVp9JKJ80/3hQdg1R+AQku/dlnhutPsfkCokH2LZFc5mNA==", + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@openzeppelin/hardhat-upgrades/-/hardhat-upgrades-1.21.0.tgz", + "integrity": "sha512-Kwl7IN0Hlhj4HluMTTl0DrtU90OI/Q6rG3sAyd2pv3fababe9EuZqs9DydOlkWM45JwTzC+eBzX3TgHsqI13eA==", "dev": true, "requires": { - "@openzeppelin/upgrades-core": "^1.14.1", + "@openzeppelin/upgrades-core": "^1.20.0", "chalk": "^4.1.0", + "debug": "^4.1.1", "proper-lockfile": "^4.1.1" } }, "@openzeppelin/upgrades-core": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@openzeppelin/upgrades-core/-/upgrades-core-1.14.1.tgz", - "integrity": "sha512-iKlh1mbUxyfdjdEiUFyhMkqirfas+DMUu7ED53nZbHEyhcYsm+5Fl/g0Bv6bZA+a7k8kO8+22DNEKsqaDUBc2Q==", + "version": "1.20.4", + "resolved": "https://registry.npmjs.org/@openzeppelin/upgrades-core/-/upgrades-core-1.20.4.tgz", + "integrity": "sha512-Y4/+BPIbnopfE6ZhPOE2CD0V5fnvDxKKm7+kryx5+WrcRCTW3B5DjbXL9xyyoviG8Rn5EXUh5Fk1GLbiYDfu0g==", "dev": true, "requires": { - "bn.js": "^5.1.2", "cbor": "^8.0.0", "chalk": "^4.1.0", - "compare-versions": "^4.0.0", + "compare-versions": "^5.0.0", "debug": "^4.1.1", "ethereumjs-util": "^7.0.3", "proper-lockfile": "^4.1.1", "solidity-ast": "^0.4.15" }, "dependencies": { - "bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", - "dev": true - }, "cbor": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/cbor/-/cbor-8.1.0.tgz", @@ -24531,6 +23339,33 @@ } } }, + "@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.0", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.0.tgz", + "integrity": "sha512-ftTW3kKX54YXLCxH6BB7oEEoJfoE2pIgw7MINKAs5PsS6nqKPuKk1haTF/EuHmYqG330t5GSrdmtRuHaY1a62Q==", + "dev": true, + "requires": { + "@noble/hashes": "~1.1.1", + "@noble/secp256k1": "~1.6.0", + "@scure/base": "~1.1.0" + } + }, + "@scure/bip39": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.0.tgz", + "integrity": "sha512-pwrPOS16VeTKg98dYXQyIjJEcWfz7/1YJIwxUEPFfQPtc86Ym/1sVgQ2RLoD43AazMk2l/unK4ITySSpW2+82w==", + "dev": true, + "requires": { + "@noble/hashes": "~1.1.1", + "@scure/base": "~1.1.0" + } + }, "@sentry/core": { "version": "5.30.0", "resolved": "https://registry.npmjs.org/@sentry/core/-/core-5.30.0.tgz", @@ -24612,182 +23447,37 @@ "tslib": "^1.9.3" } }, - "@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 - }, - "@sinonjs/commons": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", - "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", - "dev": true, - "requires": { - "type-detect": "4.0.8" - } - }, - "@sinonjs/fake-timers": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-7.0.5.tgz", - "integrity": "sha512-fUt6b15bjV/VW93UP5opNXJxdwZSbK1EdiwnhN7XrQrcpaOhMJpZ/CjwFpM3THpxwA+YviBUJKSuEqKlCK5alw==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.7.0" - } - }, "@solidity-parser/parser": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.14.1.tgz", - "integrity": "sha512-eLjj2L6AuQjBB6s/ibwCAc0DwrR5Ge+ys+wgWo+bviU7fV2nTMQhU63CGaDKXg9iTmMxwhkyoggdIR7ZGRfMgw==", + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.14.5.tgz", + "integrity": "sha512-6dKnHZn7fg/iQATVEzqyUOyEidbn05q7YA2mQ9hC0MMXhhV3/JrsxmFSYZAcr7j1yUP700LLhTruvJ3MiQmjJg==", "dev": true, "requires": { "antlr4ts": "^0.5.0-alpha.4" } }, - "@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": { - "defer-to-connect": "^1.0.1" - } - }, - "@truffle/error": { - "version": "0.0.14", - "resolved": "https://registry.npmjs.org/@truffle/error/-/error-0.0.14.tgz", - "integrity": "sha512-utJx+SZYoMqk8wldQG4gCVKhV8GwMJbWY7sLXFT/D8wWZTnE2peX7URFJh/cxkjTRCO328z1s2qewkhyVsu2HA==", - "dev": true - }, - "@truffle/interface-adapter": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/@truffle/interface-adapter/-/interface-adapter-0.4.23.tgz", - "integrity": "sha512-mfpwY25Apx36WHHNJMNHWyDQVFZoZYNQ43rOwr/n+5gAMxke7+D7+IR9UW4kuO/Jp0+2848UxMdRV+oqm017kQ==", - "dev": true, - "requires": { - "bn.js": "^5.1.3", - "ethers": "^4.0.32", - "web3": "1.3.5" - }, - "dependencies": { - "bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", - "dev": true - }, - "elliptic": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", - "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", - "dev": true, - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.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 - } - } - }, - "ethers": { - "version": "4.0.48", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.48.tgz", - "integrity": "sha512-sZD5K8H28dOrcidzx9f8KYh8083n5BexIO3+SbE4jK83L85FxtpXZBCQdXb8gkg+7sBqomcLhhkU7UHL+F7I2g==", - "dev": true, - "requires": { - "aes-js": "3.0.0", - "bn.js": "^4.4.0", - "elliptic": "6.5.3", - "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" - }, - "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 - } - } - }, - "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==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.0" - } - }, - "scrypt-js": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.4.tgz", - "integrity": "sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw==", - "dev": true - }, - "setimmediate": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz", - "integrity": "sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48=", - "dev": true - }, - "uuid": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz", - "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=", - "dev": true - } - } - }, - "@truffle/provider": { - "version": "0.2.30", - "resolved": "https://registry.npmjs.org/@truffle/provider/-/provider-0.2.30.tgz", - "integrity": "sha512-5ScTbWsrm7zmQjw020T41U30/kYA1LppXAtaeucUGN2jvPrSwlh0aTL18makbqftTx1NRuYKw7C8wO4jCKQSUQ==", - "dev": true, - "requires": { - "@truffle/error": "^0.0.14", - "@truffle/interface-adapter": "^0.4.23", - "web3": "1.3.5" - } - }, "@tsconfig/node10": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", - "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", "dev": true }, "@tsconfig/node12": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", - "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", "dev": true }, "@tsconfig/node14": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", - "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", "dev": true }, "@tsconfig/node16": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", - "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", "dev": true }, "@typechain/ethers-v5": { @@ -24799,25 +23489,25 @@ "ethers": "^5.0.2" } }, - "@types/abstract-leveldown": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@types/abstract-leveldown/-/abstract-leveldown-7.2.0.tgz", - "integrity": "sha512-q5veSX6zjUy/DlDhR4Y4cU0k2Ar+DT2LUraP00T19WLmTO6Se1djepCCaqU6nQrwcJ5Hyo/CWqxTzrrFg8eqbQ==", + "@types/async-eventemitter": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@types/async-eventemitter/-/async-eventemitter-0.2.1.tgz", + "integrity": "sha512-M2P4Ng26QbAeITiH7w1d7OxtldgfAe0wobpyJzVK/XOb0cUGKU2R4pfAhqcJBXAe2ife5ZOhSv4wk7p+ffURtg==", "dev": true }, "@types/bn.js": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", - "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.1.tgz", + "integrity": "sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g==", "dev": true, "requires": { "@types/node": "*" } }, "@types/chai": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.0.tgz", - "integrity": "sha512-/ceqdqeRraGolFTcfoXNiqjyQhZzbINDngeoAq9GoHa8PPK1yNzTaxWjA6BFWp5Ua9JpXEMSS4s5i9tS0hOJtw==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.4.tgz", + "integrity": "sha512-KnRanxnpfpjUTqTCXslZSEdLfXExwgNxYPdiO2WGUj8+HDjFi8R3k5RVKPeSCzLjCcshCAtVO2QBbVuAV4kTnw==", "dev": true }, "@types/chai-as-promised": { @@ -24830,9 +23520,9 @@ } }, "@types/cli-table": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@types/cli-table/-/cli-table-0.3.0.tgz", - "integrity": "sha512-QnZUISJJXyhyD6L1e5QwXDV/A5i2W1/gl6D6YMc8u0ncPepbv/B4w3S+izVvtAg60m6h+JP09+Y/0zF2mojlFQ==", + "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==", "dev": true }, "@types/concat-stream": { @@ -24847,16 +23537,16 @@ "@types/form-data": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz", - "integrity": "sha1-yayFsqX9GENbjIXZ7LUObWyJP/g=", + "integrity": "sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==", "dev": true, "requires": { "@types/node": "*" } }, "@types/glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", "dev": true, "requires": { "@types/minimatch": "*", @@ -24869,33 +23559,16 @@ "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", "dev": true }, - "@types/level-errors": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/level-errors/-/level-errors-3.0.0.tgz", - "integrity": "sha512-/lMtoq/Cf/2DVOm6zE6ORyOM+3ZVm/BvzEZVxUhf6bgh8ZHglXlBqxbxSlJeVp8FCbD3IVvk/VbsaNmDjrQvqQ==", - "dev": true - }, - "@types/levelup": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@types/levelup/-/levelup-4.3.3.tgz", - "integrity": "sha512-K+OTIjJcZHVlZQN1HmU64VtrC0jC3dXWQozuEIR9zVvltIk90zaGPM2AgT+fIkChpzHhFE3YnvFLCbLtzAmexA==", - "dev": true, - "requires": { - "@types/abstract-leveldown": "*", - "@types/level-errors": "*", - "@types/node": "*" - } - }, "@types/lru-cache": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.0.tgz", - "integrity": "sha512-RaE0B+14ToE4l6UqdarKPnXwVDuigfFv+5j9Dze/Nqr23yyuqdNvzcZi3xB+3Agvi5R4EOgAksfv3lXX4vBt9w==", + "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": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", + "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", "dev": true }, "@types/mkdirp": { @@ -24908,38 +23581,25 @@ } }, "@types/mocha": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.0.tgz", - "integrity": "sha512-QCWHkbMv4Y5U9oW10Uxbr45qMMSzl4OzijsozynUAgx3kEHUdXB00udx2dWDQ7f2TU2a2uuiFaRZjCe3unPpeg==", + "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.23", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", - "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==", + "version": "17.0.45", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", + "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==", "dev": true }, "@types/node-fetch": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.1.tgz", - "integrity": "sha512-oMqjURCaxoSIsHSr1E47QHzbmzNR5rK8McHuNb11BOM9cHcIK3Avy0s/b2JlXHoQGTYS3NsvWzV1M0iK7l0wbA==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.2.tgz", + "integrity": "sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A==", "dev": true, "requires": { "@types/node": "*", "form-data": "^3.0.0" - }, - "dependencies": { - "form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - } } }, "@types/pbkdf2": { @@ -24952,9 +23612,9 @@ } }, "@types/prettier": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.4.tgz", - "integrity": "sha512-ReVR2rLTV1kvtlWFyuot+d1pkpG2Fw/XKE3PDAdj57rbM97ttSp9JZ2UsP+2EHTylra9cUf6JA7tGwW1INzUrA==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.1.tgz", + "integrity": "sha512-ri0UmynRRvZiiUJdiz38MmIblKK+oH30MztdBVR95dv/Ubw6neWSb8u1XpRb72L4qsZOhz+L+z9JD40SJmfWow==", "dev": true }, "@types/qs": { @@ -24973,37 +23633,49 @@ } }, "@types/secp256k1": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.2.tgz", - "integrity": "sha512-QMg+9v0bbNJ2peLuHRWxzmy0HRJIG6gFZNhaRSp7S3ggSbCCxiqQB2/ybvhXyhHOCequpNkrx7OavNhrWOsW0A==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.3.tgz", + "integrity": "sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==", "dev": true, "requires": { "@types/node": "*" } }, + "@types/semver": { + "version": "7.3.13", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", + "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==", + "dev": true + }, "@types/sinon": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.0.tgz", - "integrity": "sha512-jDZ55oCKxqlDmoTBBbBBEx+N8ZraUVhggMZ9T5t+6/Dh8/4NiOjSUfpLrPiEwxQDlAe3wpAkoXhWvE6LibtsMQ==", + "version": "10.0.13", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.13.tgz", + "integrity": "sha512-UVjDqJblVNQYvVNUsj0PuYYw0ELRmgt1Nt5Vk0pT5f16ROGfcKJY8o1HVuMOJOpD727RrGB9EGvoaTQE5tgxZQ==", "dev": true, "requires": { - "@sinonjs/fake-timers": "^7.0.4" + "@types/sinonjs__fake-timers": "*" } }, "@types/sinon-chai": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/@types/sinon-chai/-/sinon-chai-3.2.5.tgz", - "integrity": "sha512-bKQqIpew7mmIGNRlxW6Zli/QVyc3zikpGzCa797B/tRnD9OtHvZ/ts8sYXV+Ilj9u3QRaUEM8xrjgd1gwm1BpQ==", + "version": "3.2.9", + "resolved": "https://registry.npmjs.org/@types/sinon-chai/-/sinon-chai-3.2.9.tgz", + "integrity": "sha512-/19t63pFYU0ikrdbXKBWj9PCdnKyTd0Qkz0X91Ta081cYsq90OxYdcWwK/dwEoDa6dtXgj2HJfmzgq+QZTHdmQ==", "dev": true, "requires": { "@types/chai": "*", "@types/sinon": "*" } }, + "@types/sinonjs__fake-timers": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.2.tgz", + "integrity": "sha512-9GcLXF0/v3t80caGs5p2rRfkB+a8VBGLJZVih6CNFkx8IZ994wiKKLSRs9nuFwk1HevWs/1mnUmkApGrSGsShA==", + "dev": true + }, "@types/underscore": { - "version": "1.11.2", - "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.11.2.tgz", - "integrity": "sha512-Ls2ylbo7++ITrWk2Yc3G/jijwSq5V3GT0tlgVXEl2kKYXY3ImrtmTCoE2uyTWFRI5owMBriloZFWbE1SXOsE7w==", + "version": "1.11.4", + "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.11.4.tgz", + "integrity": "sha512-uO4CD2ELOjw8tasUrAhvnn2W4A0ZECOvMjCivJr4gA9pGgjv+qxKWY9GLTMVEK8ej85BxQOocUyE7hImmSQYcg==", "dev": true }, "@types/web3": { @@ -25017,17 +23689,17 @@ } }, "@typescript-eslint/eslint-plugin": { - "version": "5.36.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.36.0.tgz", - "integrity": "sha512-X3In41twSDnYRES7hO2xna4ZC02SY05UN9sGW//eL1P5k4CKfvddsdC2hOq0O3+WU1wkCPQkiTY9mzSnXKkA0w==", + "version": "5.42.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.42.1.tgz", + "integrity": "sha512-LyR6x784JCiJ1j6sH5Y0K6cdExqCCm8DJUTcwG5ThNXJj/G8o5E56u5EdG4SLy+bZAwZBswC+GYn3eGdttBVCg==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.36.0", - "@typescript-eslint/type-utils": "5.36.0", - "@typescript-eslint/utils": "5.36.0", + "@typescript-eslint/scope-manager": "5.42.1", + "@typescript-eslint/type-utils": "5.42.1", + "@typescript-eslint/utils": "5.42.1", "debug": "^4.3.4", - "functional-red-black-tree": "^1.0.1", "ignore": "^5.2.0", + "natural-compare-lite": "^1.4.0", "regexpp": "^3.2.0", "semver": "^7.3.7", "tsutils": "^3.21.0" @@ -25043,9 +23715,9 @@ } }, "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -25060,54 +23732,54 @@ } }, "@typescript-eslint/parser": { - "version": "5.36.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.36.0.tgz", - "integrity": "sha512-dlBZj7EGB44XML8KTng4QM0tvjI8swDh8MdpE5NX5iHWgWEfIuqSfSE+GPeCrCdj7m4tQLuevytd57jNDXJ2ZA==", + "version": "5.42.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.42.1.tgz", + "integrity": "sha512-kAV+NiNBWVQDY9gDJDToTE/NO8BHi4f6b7zTsVAJoTkmB/zlfOpiEVBzHOKtlgTndCKe8vj9F/PuolemZSh50Q==", "dev": true, "peer": true, "requires": { - "@typescript-eslint/scope-manager": "5.36.0", - "@typescript-eslint/types": "5.36.0", - "@typescript-eslint/typescript-estree": "5.36.0", + "@typescript-eslint/scope-manager": "5.42.1", + "@typescript-eslint/types": "5.42.1", + "@typescript-eslint/typescript-estree": "5.42.1", "debug": "^4.3.4" } }, "@typescript-eslint/scope-manager": { - "version": "5.36.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.36.0.tgz", - "integrity": "sha512-PZUC9sz0uCzRiuzbkh6BTec7FqgwXW03isumFVkuPw/Ug/6nbAqPUZaRy4w99WCOUuJTjhn3tMjsM94NtEj64g==", + "version": "5.42.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.42.1.tgz", + "integrity": "sha512-QAZY/CBP1Emx4rzxurgqj3rUinfsh/6mvuKbLNMfJMMKYLRBfweus8brgXF8f64ABkIZ3zdj2/rYYtF8eiuksQ==", "dev": true, "requires": { - "@typescript-eslint/types": "5.36.0", - "@typescript-eslint/visitor-keys": "5.36.0" + "@typescript-eslint/types": "5.42.1", + "@typescript-eslint/visitor-keys": "5.42.1" } }, "@typescript-eslint/type-utils": { - "version": "5.36.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.36.0.tgz", - "integrity": "sha512-W/E3yJFqRYsjPljJ2gy0YkoqLJyViWs2DC6xHkXcWyhkIbCDdaVnl7mPLeQphVI+dXtY05EcXFzWLXhq8Mm/lQ==", + "version": "5.42.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.42.1.tgz", + "integrity": "sha512-WWiMChneex5w4xPIX56SSnQQo0tEOy5ZV2dqmj8Z371LJ0E+aymWD25JQ/l4FOuuX+Q49A7pzh/CGIQflxMVXg==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "5.36.0", - "@typescript-eslint/utils": "5.36.0", + "@typescript-eslint/typescript-estree": "5.42.1", + "@typescript-eslint/utils": "5.42.1", "debug": "^4.3.4", "tsutils": "^3.21.0" } }, "@typescript-eslint/types": { - "version": "5.36.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.36.0.tgz", - "integrity": "sha512-3JJuLL1r3ljRpFdRPeOtgi14Vmpx+2JcR6gryeORmW3gPBY7R1jNYoq4yBN1L//ONZjMlbJ7SCIwugOStucYiQ==", + "version": "5.42.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.42.1.tgz", + "integrity": "sha512-Qrco9dsFF5lhalz+lLFtxs3ui1/YfC6NdXu+RAGBa8uSfn01cjO7ssCsjIsUs484vny9Xm699FSKwpkCcqwWwA==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.36.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.36.0.tgz", - "integrity": "sha512-EW9wxi76delg/FS9+WV+fkPdwygYzRrzEucdqFVWXMQWPOjFy39mmNNEmxuO2jZHXzSQTXzhxiU1oH60AbIw9A==", + "version": "5.42.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.42.1.tgz", + "integrity": "sha512-qElc0bDOuO0B8wDhhW4mYVgi/LZL+igPwXtV87n69/kYC/7NG3MES0jHxJNCr4EP7kY1XVsRy8C/u3DYeTKQmw==", "dev": true, "requires": { - "@typescript-eslint/types": "5.36.0", - "@typescript-eslint/visitor-keys": "5.36.0", + "@typescript-eslint/types": "5.42.1", + "@typescript-eslint/visitor-keys": "5.42.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -25115,20 +23787,6 @@ "tsutils": "^3.21.0" }, "dependencies": { - "globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - } - }, "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -25139,20 +23797,14 @@ } }, "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "requires": { "lru-cache": "^6.0.0" } }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", @@ -25162,53 +23814,57 @@ } }, "@typescript-eslint/utils": { - "version": "5.36.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.36.0.tgz", - "integrity": "sha512-wAlNhXXYvAAUBbRmoJDywF/j2fhGLBP4gnreFvYvFbtlsmhMJ4qCKVh/Z8OP4SgGR3xbciX2nmG639JX0uw1OQ==", + "version": "5.42.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.42.1.tgz", + "integrity": "sha512-Gxvf12xSp3iYZd/fLqiQRD4uKZjDNR01bQ+j8zvhPjpsZ4HmvEFL/tC4amGNyxN9Rq+iqvpHLhlqx6KTxz9ZyQ==", "dev": true, "requires": { "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.36.0", - "@typescript-eslint/types": "5.36.0", - "@typescript-eslint/typescript-estree": "5.36.0", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.42.1", + "@typescript-eslint/types": "5.42.1", + "@typescript-eslint/typescript-estree": "5.42.1", "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" + "eslint-utils": "^3.0.0", + "semver": "^7.3.7" }, "dependencies": { - "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==", + "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": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" + "yallist": "^4.0.0" } }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "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 } } }, "@typescript-eslint/visitor-keys": { - "version": "5.36.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.36.0.tgz", - "integrity": "sha512-pdqSJwGKueOrpjYIex0T39xarDt1dn4p7XJ+6FqBWugNQwXlNGC5h62qayAIYZ/RPPtD+ButDWmpXT1eGtiaYg==", + "version": "5.42.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.42.1.tgz", + "integrity": "sha512-LOQtSF4z+hejmpUvitPlc4hA7ERGoj2BVkesOcG91HCn8edLGUXbTrErmutmPbl8Bo9HjAvOO/zBKQHExXNA2A==", "dev": true, "requires": { - "@typescript-eslint/types": "5.36.0", + "@typescript-eslint/types": "5.42.1", "eslint-visitor-keys": "^3.3.0" } }, - "@ungap/promise-all-settled": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", - "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", - "dev": true - }, "@yarnpkg/lockfile": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", @@ -25218,7 +23874,7 @@ "abbrev": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", - "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=", + "integrity": "sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q==", "dev": true }, "abort-controller": { @@ -25230,33 +23886,25 @@ "event-target-shim": "^5.0.0" } }, - "abstract-leveldown": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.3.0.tgz", - "integrity": "sha512-TU5nlYgta8YrBMNpc9FwQzRbiXsj49gsALsXadbGHt9CROPzX5fB0rWDR5mtdpOOKa5XqRFpbj1QroPAoPzVjQ==", - "dev": true, - "requires": { - "buffer": "^5.5.0", - "immediate": "^3.2.3", - "level-concat-iterator": "~2.0.0", - "level-supports": "~1.0.0", - "xtend": "~4.0.0" - } - }, - "accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "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": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" + "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" } }, "acorn": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", - "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", + "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", "dev": true }, "acorn-jsx": { @@ -25273,9 +23921,9 @@ "dev": true }, "address": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/address/-/address-1.1.2.tgz", - "integrity": "sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/address/-/address-1.2.1.tgz", + "integrity": "sha512-B+6bi5D34+fDYENiH5qOlA0cV2rAGKuWZ9LeyUUehbXy8e0VS9e498yO0Jeeh+iM+6KbfudHTFjXw2MmJD4QRA==", "dev": true }, "adm-zip": { @@ -25287,7 +23935,7 @@ "aes-js": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", - "integrity": "sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0=", + "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==", "dev": true }, "agent-base": { @@ -25307,14 +23955,6 @@ "requires": { "clean-stack": "^2.0.0", "indent-string": "^4.0.0" - }, - "dependencies": { - "indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true - } } }, "ajv": { @@ -25332,14 +23972,14 @@ "amdefine": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", + "integrity": "sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==", "dev": true, "optional": true }, "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "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": { @@ -25349,12 +23989,20 @@ "dev": true, "requires": { "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 + } } }, "ansi-regex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", - "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "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": { @@ -25395,13 +24043,10 @@ "dev": true }, "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true }, "array-back": { "version": "2.0.0", @@ -25412,22 +24057,10 @@ "typical": "^2.6.1" } }, - "array-filter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-1.0.0.tgz", - "integrity": "sha1-uveeYubvTCpMC4MSMtr/7CUfnYM=", - "dev": true - }, "array-find-index": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", - "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", - "dev": true - }, - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", + "integrity": "sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==", "dev": true }, "array-union": { @@ -25439,46 +24072,47 @@ "array-uniq": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", "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==", + "dev": 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" + } + }, "arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", "dev": true }, "asap": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", "dev": true }, "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "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" - } - }, "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", "dev": true }, "assertion-error": { @@ -25488,15 +24122,15 @@ "dev": true }, "astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true }, "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "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" @@ -25511,31 +24145,16 @@ "async": "^2.4.0" } }, - "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 - }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "dev": true }, - "available-typed-arrays": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz", - "integrity": "sha512-XWX3OX8Onv97LMk/ftVyBibpGwY5a8SmuxZPzeOxqmuEqUCOM9ZE+uIaD1VNJ5QnvU2UQusvmKbuM1FR8QWGfQ==", - "dev": true, - "requires": { - "array-filter": "^1.0.0" - } - }, "aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", "dev": true }, "aws4": { @@ -25551,9 +24170,9 @@ "dev": true }, "base-x": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.8.tgz", - "integrity": "sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA==", + "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" @@ -25568,10 +24187,18 @@ "bcrypt-pbkdf": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "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": { @@ -25580,10 +24207,25 @@ "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==", "dev": true }, + "bigint-crypto-utils": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/bigint-crypto-utils/-/bigint-crypto-utils-3.1.7.tgz", + "integrity": "sha512-zpCQpIE2Oy5WIQpjC9iYZf8Uh9QqoS51ZCooAcNvzv1AQ3VWdT52D0ksr1+/faeK8HVIej1bxXcP75YcqH3KPA==", + "dev": true, + "requires": { + "bigint-mod-arith": "^3.1.0" + } + }, + "bigint-mod-arith": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bigint-mod-arith/-/bigint-mod-arith-3.1.2.tgz", + "integrity": "sha512-nx8J8bBeiRR+NlsROFH9jHswW5HO8mgfOSqW0AmjicMMvaONDa8AO+5ViKDUUNytBPWiwfvZP4/Bj4Y3lUfvgQ==", + "dev": true + }, "bignumber.js": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", - "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.0.tgz", + "integrity": "sha512-4LwHK4nfDOraBCtst+wOWIHbu1vhvAPJK8g8nROd4iuc3PSEjWif/qwbkh8jwCJz6yDBvtU4KPynETgrfh7y3A==", "dev": true }, "binary-extensions": { @@ -25592,28 +24234,10 @@ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "bip66": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", - "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=", - "dev": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, "blakejs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz", - "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", + "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==", "dev": true }, "bluebird": { @@ -25623,83 +24247,11 @@ "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==", + "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.19.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", - "dev": true, - "requires": { - "bytes": "3.1.0", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" - }, - "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" - } - }, - "http-errors": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", - "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", - "dev": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", - "dev": true - }, - "raw-body": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", - "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", - "dev": true, - "requires": { - "bytes": "3.1.0", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - } - } - } - }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -25722,9 +24274,21 @@ "brorand": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "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", @@ -25745,76 +24309,10 @@ "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" - }, - "dependencies": { - "bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", - "dev": true - } - } - }, - "browserify-sign": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", - "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", - "dev": true, - "requires": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.3", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", - "dev": true - } - } - }, "bs58": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", - "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", + "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", "dev": true, "requires": { "base-x": "^3.0.2" @@ -25832,80 +24330,42 @@ } }, "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "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.1.13" + "ieee754": "^1.2.1" } }, "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "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": "sha1-YGSkD6dutDxyOrqe+PbhIW0QURo=", + "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": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", "dev": true }, - "bufferutil": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.3.tgz", - "integrity": "sha512-yEYTwGndELGvfXsImMBLop58eaGW+YdONi1fNjTINSY98tmMmFijBG6WXgdkfuLNt4imzQNtIE+eBp1PVpMCSw==", + "busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", "dev": true, "requires": { - "node-gyp-build": "^4.2.0" + "streamsearch": "^1.1.0" } }, "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "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" - } - }, - "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.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", @@ -25919,37 +24379,45 @@ "caller-callsite": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", - "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", + "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": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", + "integrity": "sha512-MCL3sf6nCSXOwCTzvPKhN18TU7AHTvdtam8DAogxcrJ8Rjfbbg7Lgng64H9Iy+vUV6VGFClN/TyxBkAebLRR4A==", "dev": true, "requires": { "caller-callsite": "^2.0.0" } }, "callsites": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", - "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true }, "camelcase": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "integrity": "sha512-FxAv7HpHrXbh3aPo4o2qxHay2lkLY3x5Mw3KeE4KQE8ysVfziWeRZDwcjauvwBSGEC/nXUPzZy8zeh4HokqOnw==", "dev": true }, "camelcase-keys": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz", - "integrity": "sha1-oqpfsa9oh1glnDLBQUJteJI7m3c=", + "integrity": "sha512-Ej37YKYbFUI8QiYlvj9YHb6/Z60dZyPJW0Cs8sFilMbd2lP0bw3ylAq9yJkK4lcTA2dID5fG8LjmJYbO7kWb7Q==", "dev": true, "requires": { "camelcase": "^4.1.0", @@ -25960,7 +24428,13 @@ "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "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": { @@ -25974,14 +24448,14 @@ } }, "chai": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz", - "integrity": "sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.7.tgz", + "integrity": "sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==", "dev": true, "requires": { "assertion-error": "^1.1.0", "check-error": "^1.0.2", - "deep-eql": "^3.0.1", + "deep-eql": "^4.1.2", "get-func-name": "^2.0.0", "loupe": "^2.3.1", "pathval": "^1.1.1", @@ -25998,9 +24472,9 @@ } }, "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "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", @@ -26016,68 +24490,48 @@ "charenc": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", - "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=", + "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", "dev": true }, "check-error": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", "dev": true }, "chokidar": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", - "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "dev": true, "requires": { - "anymatch": "~3.1.1", + "anymatch": "~3.1.2", "braces": "~3.0.2", - "fsevents": "~2.3.1", - "glob-parent": "~5.1.0", + "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.5.0" - } - }, - "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" + "readdirp": "~3.6.0" }, "dependencies": { - "multicodec": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-1.0.4.tgz", - "integrity": "sha512-NDd7FeS3QamVtbgfvu5h7fd1IlbaC4EQ0/pgU4zqE2vdHCmBGsUa0TiM8/TdSeG6BMPC92OOCf8F1ocE/Wkrrg==", + "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": { - "buffer": "^5.6.0", - "varint": "^5.0.0" + "is-glob": "^4.0.1" } } } }, + "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", @@ -26088,11 +24542,18 @@ "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 + "classic-level": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/classic-level/-/classic-level-1.2.0.tgz", + "integrity": "sha512-qw5B31ANxSluWz9xBzklRWTUAJ1SXIdaVKTVS7HcTGKOAmExx65Wo5BUICW+YGORe2FOUaDghoI9ZDxj82QcFg==", + "dev": true, + "requires": { + "abstract-level": "^1.0.2", + "catering": "^2.1.0", + "module-error": "^1.0.1", + "napi-macros": "~2.0.0", + "node-gyp-build": "^4.3.0" + } }, "clean-stack": { "version": "2.2.0", @@ -26116,14 +24577,6 @@ "dev": true, "requires": { "colors": "1.0.3" - }, - "dependencies": { - "colors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", - "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=", - "dev": true - } } }, "cli-table3": { @@ -26135,6 +24588,15 @@ "colors": "^1.1.2", "object-assign": "^4.1.0", "string-width": "^2.1.1" + }, + "dependencies": { + "colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true, + "optional": true + } } }, "cli-width": { @@ -26154,18 +24616,6 @@ "wrap-ansi": "^7.0.0" }, "dependencies": { - "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 - }, - "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 - }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -26182,31 +24632,13 @@ "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.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" - } } } }, - "clone-response": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", - "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", - "dev": true, - "requires": { - "mimic-response": "^1.0.0" - } - }, "code-point-at": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", "dev": true }, "color-convert": { @@ -26225,9 +24657,9 @@ "dev": true }, "colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "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": { @@ -26257,27 +24689,27 @@ } }, "commander": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz", - "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==", + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, "commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", "dev": true }, "compare-versions": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-4.1.3.tgz", - "integrity": "sha512-WQfnbDcrYnGr55UwbxKiQKASnTtNnaAWVi8jZyy8NTpVAXWACSne8lMD1iaIo9AiU6mnuLvSVshCzewVuWxHUg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-5.0.1.tgz", + "integrity": "sha512-v8Au3l0b+Nwkp4G142JcgJFh1/TUhdxut7wzD1Nq1dyp5oa3tXaqb03EXOAB6jS4gMlalkjAUPZBMiAfKUixHQ==", "dev": true }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, "concat-stream": { @@ -26324,80 +24756,18 @@ } } }, - "content-disposition": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", - "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", - "dev": true, - "requires": { - "safe-buffer": "5.1.2" - }, - "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 - } - } - }, - "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.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", - "dev": true - }, "cookie": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", - "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==", - "dev": true - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", - "dev": true - }, - "cookiejar": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz", - "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==", - "dev": true - }, - "core-js-pure": { - "version": "3.21.1", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.21.1.tgz", - "integrity": "sha512-12VZfFIu+wyVbBebyHmRTuEE/tZrB4tJToWcwAMcsp3h4+sHR+fMJWbKpYiCRWlhFBq+KNyO8rIV9rTkeVmznQ==", + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", "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": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "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, - "requires": { - "object-assign": "^4", - "vary": "^1" - } - }, "cosmiconfig": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", @@ -26408,27 +24778,56 @@ "is-directory": "^0.3.1", "js-yaml": "^3.13.1", "parse-json": "^4.0.0" + }, + "dependencies": { + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "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 + }, + "import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==", + "dev": true, + "requires": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + } + }, + "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, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", + "dev": true + } } }, "crc-32": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.1.tgz", - "integrity": "sha512-Dn/xm/1vFFgs3nfrpEVScHoIslO9NZRITWGz/1E/St6u4xw99vfZzVkW0OSnzx2h9egej9xwMCEut6sqwokM/w==", - "dev": true, - "requires": { - "exit-on-epipe": "~1.0.1", - "printj": "~1.3.1" - } - }, - "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" - } + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "dev": true }, "create-hash": { "version": "1.2.0", @@ -26464,74 +24863,35 @@ "dev": true }, "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" } }, "crypt": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", - "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=", + "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", "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" - } - }, "currently-unhandled": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", - "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "integrity": "sha512-/fITjgjGU50vjQ4FH6eUoYu+iUoUKIXws2hL15JJpIR+BbTxaXQsMuuyjtNh2WqsSBS5nsaZHFsFecyw5CCAng==", "dev": true, "requires": { "array-find-index": "^1.0.1" } }, - "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": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", "dev": true, "requires": { "assert-plus": "^1.0.0" @@ -26540,7 +24900,7 @@ "death": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/death/-/death-1.1.0.tgz", - "integrity": "sha1-AaqcQB7dknUFFEcLgmY5DGbGcxg=", + "integrity": "sha512-vsV6S4KVHvTGxbEcij7hkWRv0It+sGGWVOM67dQde/o5Xjnr+KmLjxWJii2uEObIrt1CcM9w0Yaovx+iOlIL+w==", "dev": true }, "debug": { @@ -26555,13 +24915,13 @@ "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", "dev": true }, "decamelize-keys": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", - "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", + "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", "dev": true, "requires": { "decamelize": "^1.1.0", @@ -26571,134 +24931,56 @@ "map-obj": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", "dev": true } } }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true - }, - "decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", - "dev": true, - "requires": { - "mimic-response": "^1.0.0" - } - }, "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.2.tgz", + "integrity": "sha512-gT18+YW4CcW/DBNTwAmqTtkJh7f9qqScu2qFVlx7kCoeY9tlBu9cUcr7+I+Z/noG8INehS3xQgLpTtd/QUTn4w==", "dev": true, "requires": { "type-detect": "^4.0.0" } }, "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "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==", + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, - "deferred-leveldown": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-5.3.0.tgz", - "integrity": "sha512-a59VOT+oDy7vtAbLRCZwWgxu2BaCfd5Hk7wxJd48ei7I+nsg8Orlb9CLG0PMZienk9BSUKgeAqkO2+Lw+1+Ukw==", - "dev": true, - "requires": { - "abstract-leveldown": "~6.2.1", - "inherits": "^2.0.3" - }, - "dependencies": { - "abstract-leveldown": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.2.3.tgz", - "integrity": "sha512-BsLm5vFMRUrrLeCcRc+G0t2qOaTzpoJQLOubq2XM72eNpjF5UdU5o/5NvlNhx95XHcAvcl8OMXr4mlg/fRgUXQ==", - "dev": true, - "requires": { - "buffer": "^5.5.0", - "immediate": "^3.2.3", - "level-concat-iterator": "~2.0.0", - "level-supports": "~1.0.0", - "xtend": "~4.0.0" - } - } - } - }, "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", + "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", "dev": true, "requires": { - "object-keys": "^1.0.12" + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" } }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "dev": true }, "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", - "dev": true - }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", "dev": true }, "detect-port": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.3.0.tgz", - "integrity": "sha512-E+B1gzkl2gqxt1IhUzwjrxBKRqx1UzC3WLONHinn8S3T6lwV/agVCyitiFOsGJ/eYuEUBvD71MZHy3Pv1G9doQ==", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.5.1.tgz", + "integrity": "sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ==", "dev": true, "requires": { "address": "^1.0.1", - "debug": "^2.6.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": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } + "debug": "4" } }, "diff": { @@ -26707,15 +24989,13 @@ "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==", + "difflib": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/difflib/-/difflib-0.2.4.tgz", + "integrity": "sha512-9YVwmMb0wQHQNr5J9m6BSj6fk4pfGITGQOOs+D9Fl+INODWFOfvhIU1hNv6GgR1RBoC/9NJcwu77zShxV0kT7w==", "dev": true, "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" + "heap": ">= 0.2.0" } }, "dir-glob": { @@ -26725,14 +25005,6 @@ "dev": true, "requires": { "path-type": "^4.0.0" - }, - "dependencies": { - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true - } } }, "doctrine": { @@ -26744,51 +25016,22 @@ "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.0.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.0.tgz", - "integrity": "sha512-qD9WU0MPM4SWLPJy/r2Be+2WgQj8plChsyrCNQzW/0WjvcJQiKQJ9mH3ZgB3fxbUUxgc/11ZJ0Fi5KiimWGz2Q==", - "dev": true - }, - "drbg.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz", - "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=", - "dev": true, - "requires": { - "browserify-aes": "^1.0.6", - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4" - } - }, - "duplexer3": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", + "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==", "dev": true }, "ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", "dev": 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": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", - "dev": true - }, "elliptic": { "version": "6.5.4", "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", @@ -26802,6 +25045,14 @@ "inherits": "^2.0.4", "minimalistic-assert": "^1.0.1", "minimalistic-crypto-utils": "^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 + } } }, "email-addresses": { @@ -26811,38 +25062,11 @@ "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==", - "dev": true - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "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 }, - "encoding-down": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/encoding-down/-/encoding-down-6.3.0.tgz", - "integrity": "sha512-QKrV0iKR6MZVJV08QY0wp1e7vF6QbhnbQhb07bwpEyuz4uZiZgPlEGdkCROuFkUwdxlFaiPIhjyarH1ee/3vhw==", - "dev": true, - "requires": { - "abstract-leveldown": "^6.2.1", - "inherits": "^2.0.3", - "level-codec": "^9.0.0", - "level-errors": "^2.0.0" - } - }, - "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": { - "once": "^1.4.0" - } - }, "enquirer": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", @@ -26858,15 +25082,6 @@ "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", "dev": true }, - "errno": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", - "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", - "dev": true, - "requires": { - "prr": "~1.0.1" - } - }, "error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -26877,33 +25092,57 @@ } }, "es-abstract": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.2.tgz", - "integrity": "sha512-gfSBJoZdlL2xRiOCy0g8gLMryhoe1TlimjzU99L/31Z8QEGIhVQI+EWwt5lT+AuU9SnorVupXFqqOGqGfsyO6w==", + "version": "1.20.4", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.4.tgz", + "integrity": "sha512-0UtvRN79eMe2L+UNEF1BwRe364sj/DXhQ/k5FmivgoSdpM90b8Jc0mDzKMGo7QS0BVbOP/bTwBKNnDc9rNzaPA==", "dev": true, "requires": { "call-bind": "^1.0.2", "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", + "function.prototype.name": "^1.1.5", + "get-intrinsic": "^1.1.3", "get-symbol-description": "^1.0.0", "has": "^1.0.3", + "has-property-descriptors": "^1.0.0", "has-symbols": "^1.0.3", "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", + "is-callable": "^1.2.7", "is-negative-zero": "^2.0.2", "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.1", + "is-shared-array-buffer": "^1.0.2", "is-string": "^1.0.7", "is-weakref": "^1.0.2", - "object-inspect": "^1.12.0", + "object-inspect": "^1.12.2", "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.1" + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.4.3", + "safe-regex-test": "^1.0.0", + "string.prototype.trimend": "^1.0.5", + "string.prototype.trimstart": "^1.0.5", + "unbox-primitive": "^1.0.2" + }, + "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, + "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 + }, "es-to-primitive": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", @@ -26915,60 +25154,22 @@ "is-symbol": "^1.0.2" } }, - "es5-ext": { - "version": "0.10.53", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", - "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", - "dev": true, - "requires": { - "es6-iterator": "~2.0.3", - "es6-symbol": "~3.1.3", - "next-tick": "~1.0.0" - } - }, - "es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "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, - "requires": { - "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": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", - "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": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "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": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=", + "integrity": "sha512-yhi5S+mNTOuRvyW4gWlg5W1byMaQGWWSYHXsuFZ7GBo7tpyOwi2EdzMP/QWxh9hwkD2m+wDVHJsxhRIj+v/b/A==", "dev": true, "requires": { "esprima": "^2.7.1", @@ -26978,34 +25179,63 @@ "source-map": "~0.2.0" }, "dependencies": { - "esprima": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", + "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 }, - "source-map": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", - "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=", + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "dev": 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, + "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 + }, + "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, - "optional": true, "requires": { - "amdefine": ">=0.0.4" + "prelude-ls": "~1.1.2" } } } }, "eslint": { - "version": "8.23.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.23.0.tgz", - "integrity": "sha512-pBG/XOn0MsJcKcTRLr27S5HpzQo4kLr+HjLQIyK4EiCsijDl/TB+h5uEuJU6bQ8Edvwz1XWOjpaP2qgnXGpTcA==", + "version": "8.27.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.27.0.tgz", + "integrity": "sha512-0y1bfG2ho7mty+SiILVf9PfuRA49ek4Nc60Wmmu62QlobNR+CeXa4xXIJgcuwSQgZiWaPH+5BDsctpIW0PR/wQ==", "dev": true, "requires": { - "@eslint/eslintrc": "^1.3.1", - "@humanwhocodes/config-array": "^0.10.4", - "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", + "@eslint/eslintrc": "^1.3.3", + "@humanwhocodes/config-array": "^0.11.6", "@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", @@ -27021,15 +25251,15 @@ "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", "find-up": "^5.0.0", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^6.0.1", + "glob-parent": "^6.0.2", "globals": "^13.15.0", - "globby": "^11.1.0", "grapheme-splitter": "^1.0.4", "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-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", @@ -27043,243 +25273,32 @@ "text-table": "^0.2.0" }, "dependencies": { - "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 - }, - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "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 - }, - "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, - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "requires": { - "is-glob": "^4.0.3" - } - }, - "globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - } - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "requires": { - "p-locate": "^5.0.0" - } - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "requires": { - "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" - } - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "requires": { - "p-limit": "^3.0.2" - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "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 - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", "dev": true, "requires": { - "ansi-regex": "^5.0.1" + "esrecurse": "^4.3.0", + "estraverse": "^5.2.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==", + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "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" - } - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } } } }, "eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "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": "^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": "^4.1.1" } }, "eslint-utils": { @@ -27306,9 +25325,9 @@ "dev": true }, "espree": { - "version": "9.4.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", - "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", + "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", "dev": true, "requires": { "acorn": "^8.8.0", @@ -27317,9 +25336,9 @@ } }, "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha512-OarPfz0lFCiW4/AV2Oy1Rp9qu0iusTKqykwTspGCZtPxmF81JR4MmIebvF1F9+UOKth2ZubLQ4XGGaU+hSn99A==", "dev": true }, "esquery": { @@ -27332,9 +25351,9 @@ }, "dependencies": { "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true } } @@ -27357,9 +25376,9 @@ } }, "estraverse": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", - "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true }, "esutils": { @@ -27368,33 +25387,35 @@ "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": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", - "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": "sha1-IprEbsqG1S4MmR58sq74P/D2i88=", + "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.24", - "resolved": "https://registry.npmjs.org/eth-gas-reporter/-/eth-gas-reporter-0.2.24.tgz", - "integrity": "sha512-RbXLC2bnuPHzIMU/rnLXXlb6oiHEEKu7rq2UrAX/0mfo0Lzrr/kb9QTjWjfz8eNvc+uu6J8AuBwI++b+MLNI2w==", + "version": "0.2.25", + "resolved": "https://registry.npmjs.org/eth-gas-reporter/-/eth-gas-reporter-0.2.25.tgz", + "integrity": "sha512-1fRgyE4xUB8SoqLgN3eDfpDfwEfRxh2Sz1b7wzFbyQA+9TekMmvSjjoRu9SKcSVyK+vLkLIsVbJDsTWjw195OQ==", "dev": true, "requires": { "@ethersproject/abi": "^5.0.0-beta.146", "@solidity-parser/parser": "^0.14.0", "cli-table3": "^0.5.0", "colors": "1.4.0", - "ethereumjs-util": "6.2.0", + "ethereum-cryptography": "^1.0.3", "ethers": "^4.0.40", "fs-readdir-recursive": "^1.1.0", "lodash": "^4.17.14", @@ -27407,15 +25428,6 @@ "sync-request": "^6.0.0" }, "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": "*" - } - }, "ansi-colors": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", @@ -27437,6 +25449,21 @@ "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, + "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 + }, "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", @@ -27504,7 +25531,13 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": 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": { @@ -27522,19 +25555,34 @@ "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", "dev": true }, - "ethereumjs-util": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.0.tgz", - "integrity": "sha512-vb0XN9J2QGdZGIEKG2vXM+kUdEivUfU6Wmi5y0cg+LRhDYKnXIZ/Lz7XjFbHRR9VIKq2lVGLzGBkA++y2nOdOQ==", + "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 + }, + "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 + }, + "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 + }, + "ethereum-cryptography": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.1.2.tgz", + "integrity": "sha512-XDSJlg4BD+hq9N2FjvotwUET9Tfxpxc3kWGE2AqUG5vcbeunnbImVk3cj6e/xT3phdW21mE8R5IugU4fspQDcQ==", "dev": true, "requires": { - "@types/bn.js": "^4.11.3", - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "ethjs-util": "0.1.6", - "keccak": "^2.0.0", - "rlp": "^2.2.3", - "secp256k1": "^3.0.1" + "@noble/hashes": "1.1.2", + "@noble/secp256k1": "1.6.3", + "@scure/bip32": "1.1.0", + "@scure/bip39": "1.1.0" } }, "ethers": { @@ -27593,10 +25641,19 @@ "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==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true }, "hash.js": { @@ -27609,16 +25666,20 @@ "minimalistic-assert": "^1.0.0" } }, - "keccak": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/keccak/-/keccak-2.1.0.tgz", - "integrity": "sha512-m1wbJRTo+gWbctZWay9i26v5fFnYkOn7D5PCxJ3fZUGUEb49dE1Pm4BREUYCt/aoO6di7jeoGmhvqN9Nzylm3Q==", + "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 + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", "dev": true, "requires": { - "bindings": "^1.5.0", - "inherits": "^2.0.4", - "nan": "^2.14.0", - "safe-buffer": "^5.2.0" + "argparse": "^1.0.7", + "esprima": "^4.0.0" } }, "locate-path": { @@ -27640,6 +25701,24 @@ "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, + "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==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, "mocha": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", @@ -27678,18 +25757,6 @@ "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", "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, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, "p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -27708,10 +25775,10 @@ "p-limit": "^2.0.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==", + "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 }, "readdirp": { @@ -27735,26 +25802,10 @@ "integrity": "sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw==", "dev": true }, - "secp256k1": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.8.0.tgz", - "integrity": "sha512-k5ke5avRZbtl9Tqx/SA7CbY3NF6Ro+Sj9cZxezFzuBlLDmyqPiL8hJJ+EmzD8Ig4LUDByHJ3/iPOVoRixs/hmw==", - "dev": true, - "requires": { - "bindings": "^1.5.0", - "bip66": "^1.1.5", - "bn.js": "^4.11.8", - "create-hash": "^1.2.0", - "drbg.js": "^1.0.1", - "elliptic": "^6.5.2", - "nan": "^2.14.0", - "safe-buffer": "^5.1.2" - } - }, "setimmediate": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz", - "integrity": "sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48=", + "integrity": "sha512-/TjEmXQVEzdod/FFskf3o7oOAsGhHf2j1dZqRFbDzq4F3mvvxflIIi4Hd3bLQE9y/CpwqfSQam5JakI/mi3Pog==", "dev": true }, "string-width": { @@ -27777,6 +25828,12 @@ "ansi-regex": "^4.1.0" } }, + "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 + }, "supports-color": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", @@ -27789,13 +25846,22 @@ "uuid": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz", - "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=", + "integrity": "sha512-nWg9+Oa3qD2CQzHIP4qKUqwNfzKn8P0LtFhotaCTFchsV7ZfDhAybeip/HZVeMIpZi9JgY1E3nUlwaCmZT1sEg==", "dev": true }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, "which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", "dev": true }, "wrap-ansi": { @@ -27856,32 +25922,13 @@ } } }, - "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" - } - }, "ethereum-bloom-filters": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.9.tgz", - "integrity": "sha512-GiK/RQkAkcVaEdxKVkPcG07PQ5vD7v2MFSHgZmBJSfMzNRHimntdBithsHAT89tAXnIpzVDWt8iaCD1DvkaxGg==", + "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, "requires": { "js-sha3": "^0.8.0" - }, - "dependencies": { - "js-sha3": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", - "dev": true - } } }, "ethereum-checksum-address": { @@ -27961,47 +26008,11 @@ "@types/node": "*" } }, - "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, - "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" - } - } - } - }, - "ethereumjs-common": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/ethereumjs-common/-/ethereumjs-common-1.5.2.tgz", - "integrity": "sha512-hTfZjwGX52GS2jcVO6E2sx4YuFnf0Fhp5ylo4pEPhEffNln7vS59Hr5sLnp3/QCazFLluuBZ+FZ6J5HTp0EqCA==", - "dev": true - }, - "ethereumjs-tx": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-2.1.2.tgz", - "integrity": "sha512-zZEK1onCeiORb0wyCXUvg94Ve5It/K6GD1K+26KfFKodiBiS6d9lfCXlUKGBBdQ+bv7Day+JK0tj1K+BeNFRAw==", - "dev": true, - "requires": { - "ethereumjs-common": "^1.5.0", - "ethereumjs-util": "^6.0.0" - }, - "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 }, "ethereumjs-util": { "version": "6.2.1", @@ -28021,9 +26032,9 @@ } }, "ethereumjs-util": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.4.tgz", - "integrity": "sha512-p6KmuPCX4mZIqsQzXfmSx9Y0l2hqf+VkAiwSisW3UKUFdk8ZkAt+AYaor83z2nSi6CU2zSsXMlD80hAbNEGM0A==", + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", + "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", "dev": true, "requires": { "@types/bn.js": "^5.1.0", @@ -28031,58 +26042,50 @@ "create-hash": "^1.1.2", "ethereum-cryptography": "^0.1.3", "rlp": "^2.2.4" - }, - "dependencies": { - "bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", - "dev": true - } } }, "ethers": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.6.2.tgz", - "integrity": "sha512-EzGCbns24/Yluu7+ToWnMca3SXJ1Jk1BvWB7CCmVNxyOeM4LLvw2OLuIHhlkhQk1dtOcj9UMsdkxUh8RiG1dxQ==", - "dev": true, - "requires": { - "@ethersproject/abi": "5.6.0", - "@ethersproject/abstract-provider": "5.6.0", - "@ethersproject/abstract-signer": "5.6.0", - "@ethersproject/address": "5.6.0", - "@ethersproject/base64": "5.6.0", - "@ethersproject/basex": "5.6.0", - "@ethersproject/bignumber": "5.6.0", - "@ethersproject/bytes": "5.6.1", - "@ethersproject/constants": "5.6.0", - "@ethersproject/contracts": "5.6.0", - "@ethersproject/hash": "5.6.0", - "@ethersproject/hdnode": "5.6.0", - "@ethersproject/json-wallets": "5.6.0", - "@ethersproject/keccak256": "5.6.0", - "@ethersproject/logger": "5.6.0", - "@ethersproject/networks": "5.6.1", - "@ethersproject/pbkdf2": "5.6.0", - "@ethersproject/properties": "5.6.0", - "@ethersproject/providers": "5.6.2", - "@ethersproject/random": "5.6.0", - "@ethersproject/rlp": "5.6.0", - "@ethersproject/sha2": "5.6.0", - "@ethersproject/signing-key": "5.6.0", - "@ethersproject/solidity": "5.6.0", - "@ethersproject/strings": "5.6.0", - "@ethersproject/transactions": "5.6.0", - "@ethersproject/units": "5.6.0", - "@ethersproject/wallet": "5.6.0", - "@ethersproject/web": "5.6.0", - "@ethersproject/wordlists": "5.6.0" + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", + "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", + "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/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" } }, "ethjs-unit": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", - "integrity": "sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk=", + "integrity": "sha512-/Sn9Y0oKl0uqQuvgFk/zQgR7aw1g36qX/jzSQ5lSwlO0GigPymk4eGQfeNTD03w1dPOqfz8V77Cy43jH56pagw==", "dev": true, "requires": { "bn.js": "4.11.6", @@ -28092,7 +26095,7 @@ "bn.js": { "version": "4.11.6", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=", + "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", "dev": true } } @@ -28113,12 +26116,6 @@ "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", "dev": true }, - "eventemitter3": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz", - "integrity": "sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==", - "dev": true - }, "evp_bytestokey": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", @@ -28129,102 +26126,6 @@ "safe-buffer": "^5.1.1" } }, - "exit-on-epipe": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz", - "integrity": "sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw==", - "dev": true - }, - "express": { - "version": "4.17.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", - "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", - "dev": true, - "requires": { - "accepts": "~1.3.7", - "array-flatten": "1.1.1", - "body-parser": "1.19.0", - "content-disposition": "0.5.3", - "content-type": "~1.0.4", - "cookie": "0.4.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~1.1.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "~1.1.2", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.5", - "qs": "6.7.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.1.2", - "send": "0.17.1", - "serve-static": "1.14.1", - "setprototypeof": "1.1.1", - "statuses": "~1.5.0", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "dependencies": { - "cookie": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", - "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", - "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": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", - "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 - } - } - }, - "ext": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz", - "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==", - "dev": true, - "requires": { - "type": "^2.0.0" - }, - "dependencies": { - "type": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/type/-/type-2.5.0.tgz", - "integrity": "sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw==", - "dev": true - } - } - }, "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -28245,7 +26146,7 @@ "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", "dev": true }, "fast-deep-equal": { @@ -28261,9 +26162,9 @@ "dev": true }, "fast-glob": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", - "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", @@ -28271,6 +26172,17 @@ "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.4" + }, + "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" + } + } } }, "fast-json-stable-stringify": { @@ -28282,13 +26194,13 @@ "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, "fastq": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz", - "integrity": "sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g==", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", "dev": true, "requires": { "reusify": "^1.0.4" @@ -28301,6 +26213,14 @@ "dev": true, "requires": { "escape-string-regexp": "^1.0.5" + }, + "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 + } } }, "file-entry-cache": { @@ -28312,16 +26232,10 @@ "flat-cache": "^3.0.4" } }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true - }, "filename-reserved-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", - "integrity": "sha1-q/c9+rc10EVECr/qLZHzieu/oik=", + "integrity": "sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==", "dev": true }, "filenamify": { @@ -28344,38 +26258,6 @@ "to-regex-range": "^5.0.1" } }, - "finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "dev": true, - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "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": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, "find-cache-dir": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", @@ -28390,7 +26272,7 @@ "find-replace": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-1.0.3.tgz", - "integrity": "sha1-uI5zZNLZyVlVnziMZmcNYTBEH6A=", + "integrity": "sha512-KrUnjzDCD9426YnCP56zGYy/eieTnhtK6Vn++j+JJzmlsWWwEkDnsyVF575spT6HJ6Ow9tlbT3TQTDsa+O4UWA==", "dev": true, "requires": { "array-back": "^1.0.4", @@ -28400,7 +26282,7 @@ "array-back": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", - "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=", + "integrity": "sha512-1WxbZvrmyhkNoeYcizokbmh5oiOCIfyvGtcqbK3Ls1v1fKcquzxnQSceOx6tzq7jmai2kFLWIpGND2cLhH6TPw==", "dev": true, "requires": { "typical": "^2.6.0" @@ -28409,12 +26291,13 @@ } }, "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "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, "requires": { - "locate-path": "^2.0.0" + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" } }, "find-yarn-workspace-root": { @@ -28440,17 +26323,6 @@ "requires": { "flatted": "^3.1.0", "rimraf": "^3.0.2" - }, - "dependencies": { - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } } }, "flatted": { @@ -28460,44 +26332,32 @@ "dev": true }, "follow-redirects": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.0.tgz", - "integrity": "sha512-0vRwd7RKQBTt+mgu87mtYeofLFZpTas2S9zY+jIeuLJMNvudIgF52nr19q40HOwH5RrhWIPuj9puybzSJiRrVg==", - "dev": true - }, - "foreach": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", - "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", "dev": true }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", "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": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", "dev": true, "requires": { "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", + "combined-stream": "^1.0.8", "mime-types": "^2.1.12" } }, - "forwarded": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", - "dev": true - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "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 }, "fs-extra": { @@ -28511,15 +26371,6 @@ "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", @@ -28529,7 +26380,7 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true }, "fsevents": { @@ -28545,10 +26396,28 @@ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "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==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "functions-have-names": "^1.2.2" + } + }, "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": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", + "dev": true + }, + "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 }, "ganache-core": { @@ -35611,35 +33480,26 @@ "get-func-name": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", "dev": true }, "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", + "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", "dev": true, "requires": { "function-bind": "^1.1.1", "has": "^1.0.3", - "has-symbols": "^1.0.1" + "has-symbols": "^1.0.3" } }, "get-port": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", - "integrity": "sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw=", + "integrity": "sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==", "dev": true }, - "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", @@ -35653,7 +33513,7 @@ "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", "dev": true, "requires": { "assert-plus": "^1.0.0" @@ -35677,18 +33537,12 @@ "array-union": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", "dev": true, "requires": { "array-uniq": "^1.0.1" } }, - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, "fs-extra": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", @@ -35703,7 +33557,7 @@ "globby": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "integrity": "sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw==", "dev": true, "requires": { "array-union": "^1.0.1", @@ -35716,7 +33570,7 @@ "pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", "dev": true } } @@ -35763,13 +33617,19 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "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": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true }, "supports-color": { @@ -35784,9 +33644,9 @@ } }, "glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -35798,22 +33658,12 @@ } }, "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" - } - }, - "global": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", - "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, "requires": { - "min-document": "^2.19.0", - "process": "^0.11.10" + "is-glob": "^4.0.3" } }, "global-modules": { @@ -35834,6 +33684,17 @@ "ini": "^1.3.5", "kind-of": "^6.0.2", "which": "^1.3.1" + }, + "dependencies": { + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } } }, "globals": { @@ -35843,63 +33704,26 @@ "dev": true, "requires": { "type-fest": "^0.20.2" - }, - "dependencies": { - "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 - } } }, "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==", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": 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", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", "slash": "^3.0.0" - }, - "dependencies": { - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - } - } - }, - "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.6", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", - "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", "dev": true }, "grapheme-splitter": { @@ -35925,12 +33749,20 @@ "source-map": "^0.6.1", "uglify-js": "^3.1.4", "wordwrap": "^1.0.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 + } } }, "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", "dev": true }, "har-validator": { @@ -35944,20 +33776,25 @@ } }, "hardhat": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.9.2.tgz", - "integrity": "sha512-elTcUK1EdFverWinybQ+DoJzsM6sgiHUYs0ZYNNXMfESty6ESHiFSwkfJsC88/q09vmIz6YVaMh73BYnYd+feQ==", + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.12.2.tgz", + "integrity": "sha512-f3ZhzXy1uyQv0UXnAQ8GCBOWjzv++WJNb7bnm10SsyC3dB7vlPpsMWBNhq7aoRxKrNhX9tCev81KFV3i5BTeMQ==", "dev": true, "requires": { - "@ethereumjs/block": "^3.6.0", - "@ethereumjs/blockchain": "^5.5.0", - "@ethereumjs/common": "^2.6.0", - "@ethereumjs/tx": "^3.4.0", - "@ethereumjs/vm": "^5.6.0", "@ethersproject/abi": "^5.1.2", "@metamask/eth-sig-util": "^4.0.0", + "@nomicfoundation/ethereumjs-block": "^4.0.0", + "@nomicfoundation/ethereumjs-blockchain": "^6.0.0", + "@nomicfoundation/ethereumjs-common": "^3.0.0", + "@nomicfoundation/ethereumjs-evm": "^1.0.0", + "@nomicfoundation/ethereumjs-rlp": "^4.0.0", + "@nomicfoundation/ethereumjs-statemanager": "^1.0.0", + "@nomicfoundation/ethereumjs-trie": "^5.0.0", + "@nomicfoundation/ethereumjs-tx": "^4.0.0", + "@nomicfoundation/ethereumjs-util": "^8.0.0", + "@nomicfoundation/ethereumjs-vm": "^6.0.0", + "@nomicfoundation/solidity-analyzer": "^0.1.0", "@sentry/node": "^5.18.1", - "@solidity-parser/parser": "^0.14.1", "@types/bn.js": "^5.1.0", "@types/lru-cache": "^5.1.0", "abort-controller": "^3.0.0", @@ -35970,31 +33807,28 @@ "debug": "^4.1.1", "enquirer": "^2.3.0", "env-paths": "^2.2.0", - "ethereum-cryptography": "^0.1.2", + "ethereum-cryptography": "^1.0.3", "ethereumjs-abi": "^0.6.8", - "ethereumjs-util": "^7.1.3", "find-up": "^2.1.0", "fp-ts": "1.19.3", "fs-extra": "^7.0.1", - "glob": "^7.1.3", + "glob": "7.2.0", "immutable": "^4.0.0-rc.12", "io-ts": "1.10.4", + "keccak": "^3.0.2", "lodash": "^4.17.11", - "merkle-patricia-tree": "^4.2.2", "mnemonist": "^0.38.0", - "mocha": "^9.2.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", - "slash": "^3.0.0", "solc": "0.7.3", "source-map-support": "^0.5.13", "stacktrace-parser": "^0.1.10", - "true-case-path": "^2.2.1", "tsort": "0.0.1", - "undici": "^4.14.1", + "undici": "^5.4.0", "uuid": "^8.3.2", "ws": "^7.4.6" }, @@ -36031,69 +33865,106 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "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==", + "commander": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz", + "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==", "dev": true }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "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 }, - "io-ts": { - "version": "1.10.4", - "resolved": "https://registry.npmjs.org/io-ts/-/io-ts-1.10.4.tgz", - "integrity": "sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g==", + "ethereum-cryptography": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.1.2.tgz", + "integrity": "sha512-XDSJlg4BD+hq9N2FjvotwUET9Tfxpxc3kWGE2AqUG5vcbeunnbImVk3cj6e/xT3phdW21mE8R5IugU4fspQDcQ==", "dev": true, "requires": { - "fp-ts": "^1.0.0" + "@noble/hashes": "1.1.2", + "@noble/secp256k1": "1.6.3", + "@scure/bip32": "1.1.0", + "@scure/bip39": "1.1.0" } }, - "js-sha3": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", + "dev": true, + "requires": { + "locate-path": "^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 }, "jsonfile": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "integrity": "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==", "dev": true, "requires": { "graceful-fs": "^4.1.6" } }, - "qs": { - "version": "6.10.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz", - "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==", + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", "dev": true, "requires": { - "side-channel": "^1.0.4" + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" } }, - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", "dev": true, "requires": { - "path-parse": "^1.0.6" + "p-try": "^1.0.0" } }, - "slash": { + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", + "dev": true, + "requires": { + "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/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", "dev": true }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, "solc": { "version": "0.7.3", "resolved": "https://registry.npmjs.org/solc/-/solc-0.7.3.tgz", @@ -36114,7 +33985,7 @@ "fs-extra": { "version": "0.30.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", - "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", + "integrity": "sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==", "dev": true, "requires": { "graceful-fs": "^4.1.2", @@ -36140,30 +34011,24 @@ "requires": { "has-flag": "^3.0.0" } - }, - "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 } } }, "hardhat-gas-reporter": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.8.tgz", - "integrity": "sha512-1G5thPnnhcwLHsFnl759f2tgElvuwdkzxlI65fC9PwxYMEe9cmjkVAAWTf3/3y8uP6ZSPiUiOW8PgZnykmZe0g==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.9.tgz", + "integrity": "sha512-INN26G3EW43adGKBNzYWOlI3+rlLnasXTwW79YNnUhXPDa+yHESgt639dJEs37gCjhkbNKcRRJnomXEuMFBXJg==", "dev": true, "requires": { "array-uniq": "1.0.3", - "eth-gas-reporter": "^0.2.24", + "eth-gas-reporter": "^0.2.25", "sha1": "^1.1.1" } }, "hardhat-tracer": { - "version": "1.1.0-rc.3", - "resolved": "https://registry.npmjs.org/hardhat-tracer/-/hardhat-tracer-1.1.0-rc.3.tgz", - "integrity": "sha512-UGOfwRXkdxWM66JqcyGDJfIjiDXNkqgiaomLPvILg3nppVTjxtBmddYtnvGhDrV9FE1NgWyBnP1B35NaRIKM8A==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/hardhat-tracer/-/hardhat-tracer-1.1.1.tgz", + "integrity": "sha512-NgOnnNAvARBtYC5x5c7Qcbw+lr+Jb+0OV1NC2tTpUUQj0ym+/0y42F0CYT/zKnHw3uf046NKg0CNTzYg1j0JWg==", "dev": true, "requires": { "ethers": "^5.6.1" @@ -36179,9 +34044,9 @@ } }, "has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", + "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 }, "has-flag": { @@ -36190,11 +34055,14 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "has-symbol-support-x": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz", - "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==", - "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==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.1" + } }, "has-symbols": { "version": "1.0.3", @@ -36202,15 +34070,6 @@ "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", "dev": true }, - "has-to-string-tag-x": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz", - "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==", - "dev": true, - "requires": { - "has-symbol-support-x": "^1.4.1" - } - }, "has-tostringtag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", @@ -36247,10 +34106,16 @@ "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true }, + "heap": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.7.tgz", + "integrity": "sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==", + "dev": true + }, "hmac-drbg": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", "dev": true, "requires": { "hash.js": "^1.0.3", @@ -36276,31 +34141,19 @@ "parse-cache-control": "^1.0.1" } }, - "http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", - "dev": true - }, "http-errors": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", - "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", "dev": true, "requires": { - "depd": "~1.1.2", + "depd": "2.0.0", "inherits": "2.0.4", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" } }, - "http-https": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/http-https/-/http-https-1.0.0.tgz", - "integrity": "sha1-L5CN1fHbQGjAWM1ubUzjkskTOJs=", - "dev": true - }, "http-response-object": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz", @@ -36321,7 +34174,7 @@ "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", "dev": true, "requires": { "assert-plus": "^1.0.0", @@ -36330,9 +34183,9 @@ } }, "https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", "dev": true, "requires": { "agent-base": "6", @@ -36369,44 +34222,38 @@ "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", "dev": true }, - "immediate": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz", - "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==", - "dev": true - }, "immutable": { - "version": "4.0.0-rc.12", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.0.0-rc.12.tgz", - "integrity": "sha512-0M2XxkZLx/mi3t8NVwIm1g8nHoEmM9p9UBl/G9k4+hm0kBgOVdMV/B3CY5dQ8qG8qc80NN4gDV4HQv6FTJ5q7A==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz", + "integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==", "dev": true }, "import-fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", - "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, "requires": { - "caller-path": "^2.0.0", - "resolve-from": "^3.0.0" + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" } }, "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true }, "indent-string": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", - "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "dev": true }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dev": true, "requires": { "once": "^1.3.0", @@ -36493,6 +34340,12 @@ "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", @@ -36539,35 +34392,32 @@ "invert-kv": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", - "dev": true - }, - "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==", + "integrity": "sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ==", "dev": true }, - "is-arguments": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.0.tgz", - "integrity": "sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg==", + "io-ts": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/io-ts/-/io-ts-1.10.4.tgz", + "integrity": "sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g==", "dev": true, "requires": { - "call-bind": "^1.0.0" + "fp-ts": "^1.0.0" } }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "dev": true }, "is-bigint": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.2.tgz", - "integrity": "sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA==", - "dev": true + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "requires": { + "has-bigints": "^1.0.1" + } }, "is-binary-path": { "version": "2.1.0", @@ -36579,12 +34429,13 @@ } }, "is-boolean-object": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.1.tgz", - "integrity": "sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", "dev": true, "requires": { - "call-bind": "^1.0.2" + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" } }, "is-buffer": { @@ -36594,9 +34445,9 @@ "dev": true }, "is-callable": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "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 }, "is-ci": { @@ -36608,25 +34459,19 @@ "ci-info": "^2.0.0" } }, - "is-core-module": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.3.0.tgz", - "integrity": "sha512-xSphU2KG9867tsYdLD4RWQ1VqdFl4HTO9Thf3I/3dLEfr0dbPTWKsuCKrgqMljg4nPE+Gq0VCnzT3gr0CyBmsw==", + "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, "requires": { - "has": "^1.0.3" + "has-tostringtag": "^1.0.0" } }, - "is-date-object": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.4.tgz", - "integrity": "sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A==", - "dev": true - }, "is-directory": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", - "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", + "integrity": "sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw==", "dev": true }, "is-docker": { @@ -36638,25 +34483,13 @@ "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": 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": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "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.9", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.9.tgz", - "integrity": "sha512-ZJ34p1uvIfptHCN7sFTjGibB9/oBg17sHqzDLfuwhvmN/qLVvIQXRQ8licZQ35WJ8KuEQt/etnnzQFI9C9Ue/A==", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", "dev": true }, "is-glob": { @@ -36671,7 +34504,7 @@ "is-hex-prefixed": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", - "integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ=", + "integrity": "sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==", "dev": true }, "is-negative-zero": { @@ -36687,21 +34520,24 @@ "dev": true }, "is-number-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.5.tgz", - "integrity": "sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw==", - "dev": true + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } }, - "is-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.2.tgz", - "integrity": "sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==", + "is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true }, "is-plain-obj": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", "dev": true }, "is-regex": { @@ -36714,23 +34550,14 @@ "has-tostringtag": "^1.0.0" } }, - "is-retry-allowed": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", - "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==", - "dev": true - }, "is-shared-array-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", - "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==", - "dev": true - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true + "version": "1.0.2", + "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, + "requires": { + "call-bind": "^1.0.2" + } }, "is-string": { "version": "1.0.7", @@ -36750,23 +34577,10 @@ "has-symbols": "^1.0.2" } }, - "is-typed-array": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.5.tgz", - "integrity": "sha512-S+GRDgJlR3PyEbsX/Fobd9cqpZBuvUS+8asRqYDMLCb2qMzt1oz5m5oxQCxOgUDxiWsOVNi4yaF+/uvdlHlYug==", - "dev": true, - "requires": { - "available-typed-arrays": "^1.0.2", - "call-bind": "^1.0.2", - "es-abstract": "^1.18.0-next.2", - "foreach": "^2.0.5", - "has-symbols": "^1.0.1" - } - }, "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", "dev": true }, "is-unicode-supported": { @@ -36784,7 +34598,7 @@ "is-utf8": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==", "dev": true }, "is-weakref": { @@ -36808,35 +34622,31 @@ "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", "dev": true }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", "dev": true }, - "isurl": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz", - "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==", - "dev": true, - "requires": { - "has-to-string-tag-x": "^1.2.0", - "is-object": "^1.0.1" - } + "js-sdsl": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.5.tgz", + "integrity": "sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q==", + "dev": true }, "js-sha3": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", - "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=", + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", "dev": true }, "js-tokens": { @@ -36846,25 +34656,18 @@ "dev": true }, "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "argparse": "^2.0.1" } }, "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true - }, - "json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", "dev": true }, "json-parse-better-errors": { @@ -36874,9 +34677,9 @@ "dev": true }, "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", "dev": true }, "json-schema-traverse": { @@ -36888,69 +34691,62 @@ "json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", "dev": true }, "jsonfile": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", "dev": true, "requires": { "graceful-fs": "^4.1.6" } }, "jsonschema": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.0.tgz", - "integrity": "sha512-/YgW6pRMr6M7C+4o8kS+B/2myEpHCrxO4PEWnqJNBFMjn7EWXqlQ4tGwL6xTHeRplwuZmcAncdvfOad1nT2yMw==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.1.tgz", + "integrity": "sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ==", "dev": true }, "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", "dev": true, "requires": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", - "json-schema": "0.2.3", + "json-schema": "0.4.0", "verror": "1.10.0" } }, "keccak": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.1.tgz", - "integrity": "sha512-epq90L9jlFWCW7+pQa6JOnKn2Xgl2mtI664seYR6MHskvI9agt7AnDqmAlp9TqU4/caMYbA08Hi5DMZAl5zdkA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.2.tgz", + "integrity": "sha512-PyKKjkH53wDMLGrvmRGSNWgmSxZOUqbnXwKL9tmgbFYA1iAYqW21kfR7mZXV0MlESiefxQQE9X9fTa3X+2MPDQ==", "dev": true, "requires": { "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" + "node-gyp-build": "^4.2.0", + "readable-stream": "^3.6.0" } }, "keccak256": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/keccak256/-/keccak256-1.0.2.tgz", - "integrity": "sha512-f2EncSgmHmmQOkgxZ+/f2VaWTNkFL6f39VIrpoX+p8cEXJVyyCs/3h9GNz/ViHgwchxvv7oG5mjT2Tk4ZqInag==", - "dev": true, - "requires": { - "bn.js": "^4.11.8", - "keccak": "^3.0.1" - } - }, - "keyv": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", - "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/keccak256/-/keccak256-1.0.6.tgz", + "integrity": "sha512-8GLiM01PkdJVGUhR1e6M/AvWnSqYS0HaERI+K/QtStGDGlSTx2B1zTqZk4Zlqu5TxHJNTxWAdP9Y+WI50OApUw==", "dev": true, "requires": { - "json-buffer": "3.0.0" + "bn.js": "^5.2.0", + "buffer": "^6.0.3", + "keccak": "^3.0.2" } }, "kind-of": { @@ -36962,7 +34758,7 @@ "klaw": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", - "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", + "integrity": "sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw==", "dev": true, "requires": { "graceful-fs": "^4.1.9" @@ -36986,114 +34782,52 @@ "lcid": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "integrity": "sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw==", "dev": true, "requires": { "invert-kv": "^1.0.0" } }, - "level-codec": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-9.0.2.tgz", - "integrity": "sha512-UyIwNb1lJBChJnGfjmO0OR+ezh2iVu1Kas3nvBS/BzGnx79dv6g7unpKIDNPMhfdTEGoc7mC8uAu51XEtX+FHQ==", + "level": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/level/-/level-8.0.0.tgz", + "integrity": "sha512-ypf0jjAk2BWI33yzEaaotpq7fkOPALKAgDBxggO6Q9HGX2MRXn0wbP1Jn/tJv1gtL867+YOjOB49WaUF3UoJNQ==", "dev": true, "requires": { - "buffer": "^5.6.0" + "browser-level": "^1.0.1", + "classic-level": "^1.2.0" } }, - "level-concat-iterator": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/level-concat-iterator/-/level-concat-iterator-2.0.1.tgz", - "integrity": "sha512-OTKKOqeav2QWcERMJR7IS9CUo1sHnke2C0gkSmcR7QuEtFNLLzHQAvnMw8ykvEcv0Qtkg0p7FOwP1v9e5Smdcw==", + "level-supports": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/level-supports/-/level-supports-4.0.1.tgz", + "integrity": "sha512-PbXpve8rKeNcZ9C1mUicC9auIYFyGpkV9/i6g76tLgANwWhtG2v7I4xNBUlkn3lE2/dZF3Pi0ygYGtLc4RXXdA==", "dev": true }, - "level-errors": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-2.0.1.tgz", - "integrity": "sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw==", - "dev": true, - "requires": { - "errno": "~0.1.1" - } - }, - "level-iterator-stream": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-4.0.2.tgz", - "integrity": "sha512-ZSthfEqzGSOMWoUGhTXdX9jv26d32XJuHz/5YnuHZzH6wldfWMOVwI9TBtKcya4BKTyTt3XVA0A3cF3q5CY30Q==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.4.0", - "xtend": "^4.0.2" - } - }, - "level-mem": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/level-mem/-/level-mem-5.0.1.tgz", - "integrity": "sha512-qd+qUJHXsGSFoHTziptAKXoLX87QjR7v2KMbqncDXPxQuCdsQlzmyX+gwrEHhlzn08vkf8TyipYyMmiC6Gobzg==", - "dev": true, - "requires": { - "level-packager": "^5.0.3", - "memdown": "^5.0.0" - } - }, - "level-packager": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/level-packager/-/level-packager-5.1.1.tgz", - "integrity": "sha512-HMwMaQPlTC1IlcwT3+swhqf/NUO+ZhXVz6TY1zZIIZlIR0YSn8GtAAWmIvKjNY16ZkEg/JcpAuQskxsXqC0yOQ==", - "dev": true, - "requires": { - "encoding-down": "^6.3.0", - "levelup": "^4.3.2" - } - }, - "level-supports": { + "level-transcoder": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/level-supports/-/level-supports-1.0.1.tgz", - "integrity": "sha512-rXM7GYnW8gsl1vedTJIbzOrRv85c/2uCMpiiCzO2fndd06U/kUXEEU9evYn4zFggBOg36IsBW8LzqIpETwwQzg==", - "dev": true, - "requires": { - "xtend": "^4.0.2" - } - }, - "level-ws": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-2.0.0.tgz", - "integrity": "sha512-1iv7VXx0G9ec1isqQZ7y5LmoZo/ewAsyDHNA8EFDW5hqH2Kqovm33nSFkSdnLLAK+I5FlT+lo5Cw9itGe+CpQA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^3.1.0", - "xtend": "^4.0.1" - } - }, - "levelup": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/levelup/-/levelup-4.4.0.tgz", - "integrity": "sha512-94++VFO3qN95cM/d6eBXvd894oJE0w3cInq9USsyQzzoJxmiYzPAocNcuGCPGGjoXqDVJcr3C1jzt1TSjyaiLQ==", + "resolved": "https://registry.npmjs.org/level-transcoder/-/level-transcoder-1.0.1.tgz", + "integrity": "sha512-t7bFwFtsQeD8cl8NIoQ2iwxA0CL/9IFw7/9gAjOonH0PWTTiRfY7Hq+Ejbsxh86tXobDQ6IOiddjNYIfOBs06w==", "dev": true, "requires": { - "deferred-leveldown": "~5.3.0", - "level-errors": "~2.0.0", - "level-iterator-stream": "~4.0.0", - "level-supports": "~1.0.0", - "xtend": "~4.0.0" + "buffer": "^6.0.3", + "module-error": "^1.0.1" } }, "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" } }, "load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", "dev": true, "requires": { "graceful-fs": "^4.1.2", @@ -37103,13 +34837,12 @@ } }, "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" + "p-locate": "^5.0.0" } }, "lodash": { @@ -37121,7 +34854,7 @@ "lodash.assign": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", - "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=", + "integrity": "sha512-hFuH8TY+Yji7Eja3mGiuAxBqLagejScbG8GbG0j6o9vzn0YL14My+ktnqtZgFTosKymC9/44wP6s7xyuLfnClw==", "dev": true }, "lodash.merge": { @@ -37130,10 +34863,10 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, - "lodash.toarray": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.toarray/-/lodash.toarray-4.4.0.tgz", - "integrity": "sha1-JMS/zWsvuji/0FlNsRedjptlZWE=", + "lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", "dev": true }, "log-symbols": { @@ -37149,7 +34882,7 @@ "loud-rejection": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", - "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "integrity": "sha512-RPNliZOFkqFumDhvYqOaNY4Uz9oJM2K9tC6JWsJJsNdhuONW4LQHRBpb0qf4pJApVffI5N39SwzWZJuEhfd7eQ==", "dev": true, "requires": { "currently-unhandled": "^0.4.1", @@ -37157,24 +34890,18 @@ } }, "loupe": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz", - "integrity": "sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==", + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz", + "integrity": "sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==", "dev": true, "requires": { "get-func-name": "^2.0.0" } }, - "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", - "integrity": "sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0=", + "integrity": "sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==", "dev": true }, "lru-cache": { @@ -37186,12 +34913,6 @@ "yallist": "^3.0.2" } }, - "ltgt": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz", - "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=", - "dev": true - }, "make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -37210,7 +34931,7 @@ "map-obj": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz", - "integrity": "sha1-plzSkIepJZi4eRJXpSPgISIqwfk=", + "integrity": "sha512-TzQSV2DiMYgoF5RycneKVUzIa9bQsj/B3tTgsE3dOGqlzHnGIDaC7XBE7grnA+8kZPnfqSGFe95VHc2oc0VFUQ==", "dev": true }, "markdown-table": { @@ -37236,51 +34957,21 @@ "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": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", - "dev": true - }, - "memdown": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/memdown/-/memdown-5.1.0.tgz", - "integrity": "sha512-B3J+UizMRAlEArDjWHTMmadet+UKwHd3UjMgGBkZcKAxAYVPS9o0Yeiha4qvz7iGiL2Sb3igUft6p7nbFWctpw==", + "memory-level": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/memory-level/-/memory-level-1.0.0.tgz", + "integrity": "sha512-UXzwewuWeHBz5krr7EvehKcmLFNoXxGcvuYhC41tRnkrTbJohtS7kVn9akmgirtRygg+f7Yjsfi8Uu5SGSQ4Og==", "dev": true, "requires": { - "abstract-leveldown": "~6.2.1", - "functional-red-black-tree": "~1.0.1", - "immediate": "~3.2.3", - "inherits": "~2.0.1", - "ltgt": "~2.2.0", - "safe-buffer": "~5.2.0" - }, - "dependencies": { - "abstract-leveldown": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.2.3.tgz", - "integrity": "sha512-BsLm5vFMRUrrLeCcRc+G0t2qOaTzpoJQLOubq2XM72eNpjF5UdU5o/5NvlNhx95XHcAvcl8OMXr4mlg/fRgUXQ==", - "dev": true, - "requires": { - "buffer": "^5.5.0", - "immediate": "^3.2.3", - "level-concat-iterator": "~2.0.0", - "level-supports": "~1.0.0", - "xtend": "~4.0.0" - } - }, - "immediate": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.2.3.tgz", - "integrity": "sha1-0UD6j2FGWb1lQSMwl92qwlzdmRw=", - "dev": true - } + "abstract-level": "^1.0.0", + "functional-red-black-tree": "^1.0.1", + "module-error": "^1.0.1" } }, "memorystream": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", - "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=", + "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", "dev": true }, "meow": { @@ -37300,77 +34991,35 @@ "yargs-parser": "^10.0.0" } }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", - "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 }, - "merkle-patricia-tree": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-4.2.4.tgz", - "integrity": "sha512-eHbf/BG6eGNsqqfbLED9rIqbsF4+sykEaBn6OLNs71tjclbMcMOk1tEPmJKcNcNCLkvbpY/lwyOlizWsqPNo8w==", - "dev": true, - "requires": { - "@types/levelup": "^4.3.0", - "ethereumjs-util": "^7.1.4", - "level-mem": "^5.0.1", - "level-ws": "^2.0.0", - "readable-stream": "^3.6.0", - "semaphore-async-await": "^1.5.1" - } - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", - "dev": true - }, "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dev": true, "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" + "braces": "^3.0.2", + "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" - } - }, - "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.47.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz", - "integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==", + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "dev": true }, "mime-types": { - "version": "2.1.30", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz", - "integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==", + "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, "requires": { - "mime-db": "1.47.0" + "mime-db": "1.52.0" } }, "mimic-fn": { @@ -37379,21 +35028,6 @@ "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": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", - "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", @@ -37403,22 +35037,22 @@ "minimalistic-crypto-utils": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", "dev": true }, "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "requires": { "brace-expansion": "^1.1.7" } }, "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", + "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", "dev": true }, "minimist-options": { @@ -37431,189 +35065,75 @@ "is-plain-obj": "^1.1.0" } }, - "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.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "mkdirp-promise": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz", - "integrity": "sha1-6bj2jlUsaKnBcTuEiD96HdA5uKE=", + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", "dev": true, "requires": { - "mkdirp": "*" + "minimist": "^1.2.6" } }, "mnemonist": { - "version": "0.38.3", - "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.38.3.tgz", - "integrity": "sha512-2K9QYubXx/NAjv4VLq1d1Ly8pWNC5L3BrixtdkyTegXWJIqY+zLNDhhX/A+ZwWt70tB1S8H4BE8FLYEFyNoOBw==", + "version": "0.38.5", + "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.38.5.tgz", + "integrity": "sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg==", "dev": true, "requires": { - "obliterator": "^1.6.1" + "obliterator": "^2.0.0" } }, "mocha": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz", - "integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.1.0.tgz", + "integrity": "sha512-vUF7IYxEoN7XhQpFLxQAEMtE4W91acW4B6En9l97MwE9stL1A9gusXfoHZCLVHDUJ/7V5+lbCM6yMqzo5vNymg==", "dev": true, "requires": { - "@ungap/promise-all-settled": "1.1.2", "ansi-colors": "4.1.1", "browser-stdout": "1.3.1", "chokidar": "3.5.3", - "debug": "4.3.3", + "debug": "4.3.4", "diff": "5.0.0", "escape-string-regexp": "4.0.0", "find-up": "5.0.0", "glob": "7.2.0", - "growl": "1.10.5", "he": "1.2.0", "js-yaml": "4.1.0", "log-symbols": "4.1.0", - "minimatch": "4.2.1", + "minimatch": "5.0.1", "ms": "2.1.3", - "nanoid": "3.3.1", + "nanoid": "3.3.3", "serialize-javascript": "6.0.0", "strip-json-comments": "3.1.1", "supports-color": "8.1.1", - "which": "2.0.2", - "workerpool": "6.2.0", + "workerpool": "6.2.1", "yargs": "16.2.0", "yargs-parser": "20.2.4", "yargs-unparser": "2.0.0" }, "dependencies": { - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "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" - } - }, - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dev": true, - "requires": { - "ms": "2.1.2" - }, - "dependencies": { - "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 - } - } - }, - "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==", + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", "dev": true }, - "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, - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dev": 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" - }, - "dependencies": { - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - } - } - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - }, - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, "requires": { - "p-locate": "^5.0.0" + "balanced-match": "^1.0.0" } }, "minimatch": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz", - "integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", + "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", "dev": true, "requires": { - "brace-expansion": "^1.1.7" + "brace-expansion": "^2.0.1" } }, "ms": { @@ -37622,45 +35142,6 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "requires": { - "p-limit": "^3.0.2" - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "requires": { - "picomatch": "^2.2.1" - } - }, - "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 - }, "supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -37670,15 +35151,6 @@ "has-flag": "^4.0.0" } }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, "yargs-parser": { "version": "20.2.4", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", @@ -37687,10 +35159,10 @@ } } }, - "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==", + "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 }, "ms": { @@ -37699,82 +35171,34 @@ "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" - } - }, - "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": { - "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 }, - "nan": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", - "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==", - "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": "sha1-DMj20OK2IrR5xA1JnEbWS3Vcb18=", + "nanoid": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", + "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", "dev": true }, - "nanoid": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", - "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", + "napi-macros": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/napi-macros/-/napi-macros-2.0.0.tgz", + "integrity": "sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg==", "dev": true }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, - "negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", + "natural-compare-lite": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", + "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", "dev": true }, "neo-async": { @@ -37783,12 +35207,6 @@ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "dev": true }, - "next-tick": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", - "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", - "dev": true - }, "nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", @@ -37802,12 +35220,12 @@ "dev": true }, "node-emoji": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.10.0.tgz", - "integrity": "sha512-Yt3384If5H6BYGVHiHwTL+99OzJKHhgp82S8/dktEK73T26BazdgZ4JZh92xSVtGNJvz9UbXdNAc5hcrXV42vw==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", + "integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==", "dev": true, "requires": { - "lodash.toarray": "^4.4.0" + "lodash": "^4.17.21" } }, "node-environment-flags": { @@ -37838,9 +35256,9 @@ } }, "node-gyp-build": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz", - "integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.5.0.tgz", + "integrity": "sha512-2iGbaQBV+ITgCz76ZEjmhUKAKVf7xfY1sRl4UiKQspfZMH2h06SyhNsnSVy50cwkFQDGLyif6m/6uFXHkOZ6rg==", "dev": true }, "nofilter": { @@ -37852,7 +35270,7 @@ "nopt": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", - "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "integrity": "sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg==", "dev": true, "requires": { "abbrev": "1" @@ -37884,22 +35302,16 @@ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true }, - "normalize-url": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", - "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==", - "dev": true - }, "number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", "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": "sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA=", + "integrity": "sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig==", "dev": true, "requires": { "bn.js": "4.11.6", @@ -37909,7 +35321,7 @@ "bn.js": { "version": "4.11.6", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=", + "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", "dev": true } } @@ -37923,13 +35335,13 @@ "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "dev": true }, "object-inspect": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", - "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", + "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", "dev": true }, "object-keys": { @@ -37939,56 +35351,39 @@ "dev": true }, "object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", "dev": true, "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" + "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.3", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.3.tgz", - "integrity": "sha512-VdDoCwvJI4QdC6ndjpqFmoL3/+HxffFBbcJzKi5hwLLqqx3mdbedRpfZDdK0SrOSauj8X4GzBvnDZl4vTN7dOw==", + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.5.tgz", + "integrity": "sha512-yDNzckpM6ntyQiGTik1fKV1DcVDRS+w8bvpWNCBanvH5LfRX9O8WTHqQzG4RZwRAM4I0oU7TV11Lj5v0g20ibw==", "dev": true, "requires": { + "array.prototype.reduce": "^1.0.5", "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" } }, "obliterator": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-1.6.1.tgz", - "integrity": "sha512-9WXswnqINnnhOG/5SLimUlzuU1hFJUc8zkwyD59Sd+dPOMf05PmnYG/d6Q7HZ+KmgkZJa1PxRso6QdM3sTNHig==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.4.tgz", + "integrity": "sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==", "dev": true }, - "oboe": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/oboe/-/oboe-2.1.5.tgz", - "integrity": "sha1-VVQoTFQ6ImbXo48X4HOCH73jk80=", - "dev": true, - "requires": { - "http-https": "^1.0.0" - } - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "dev": true, - "requires": { - "ee-first": "1.1.1" - } - }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, "requires": { "wrappy": "1" @@ -38014,23 +35409,23 @@ } }, "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", "dev": 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" + "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" } }, "os-locale": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "integrity": "sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g==", "dev": true, "requires": { "lcid": "^1.0.0" @@ -38039,37 +35434,25 @@ "os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "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-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", "dev": true }, "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "requires": { - "p-try": "^1.0.0" + "yocto-queue": "^0.1.0" } }, "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, "requires": { - "p-limit": "^1.1.0" + "p-limit": "^3.0.2" } }, "p-map": { @@ -38081,19 +35464,10 @@ "aggregate-error": "^3.0.0" } }, - "p-timeout": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz", - "integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=", - "dev": true, - "requires": { - "p-finally": "^1.0.0" - } - }, "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "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 }, "parent-module": { @@ -38103,132 +35477,108 @@ "dev": true, "requires": { "callsites": "^3.0.0" - }, - "dependencies": { - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - } - } - }, - "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": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", - "integrity": "sha1-juqz5U+laSD+Fro493+iGqzC104=", - "dev": true - }, - "parse-headers": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.3.tgz", - "integrity": "sha512-QhhZ+DCCit2Coi2vmAKbq5RGTRcQUOE2+REgv8vdyu7MnYx2eZztegqtTx99TZ86GTIwqiy3+4nQTWZ2tgmdCA==", + "integrity": "sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==", "dev": true }, "parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", "dev": true, "requires": { "error-ex": "^1.3.1", "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 - }, "patch-package": { - "version": "6.4.7", - "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-6.4.7.tgz", - "integrity": "sha512-S0vh/ZEafZ17hbhgqdnpunKDfzHQibQizx9g8yEf5dcVk3KOflOfdufRXQX8CSEkyOQwuM/bNz1GwKvFj54kaQ==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-6.5.0.tgz", + "integrity": "sha512-tC3EqJmo74yKqfsMzELaFwxOAu6FH6t+FzFOsnWAuARm7/n2xB5AOeOueE221eM9gtMuIKMKpF9tBy/X2mNP0Q==", "dev": true, "requires": { "@yarnpkg/lockfile": "^1.1.0", - "chalk": "^2.4.2", + "chalk": "^4.1.2", "cross-spawn": "^6.0.5", "find-yarn-workspace-root": "^2.0.0", "fs-extra": "^7.0.1", "is-ci": "^2.0.0", "klaw-sync": "^6.0.0", - "minimist": "^1.2.0", + "minimist": "^1.2.6", "open": "^7.4.2", "rimraf": "^2.6.3", "semver": "^5.6.0", "slash": "^2.0.0", - "tmp": "^0.0.33" + "tmp": "^0.0.33", + "yaml": "^1.10.2" }, "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==", + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", "dev": true, "requires": { - "color-convert": "^1.9.0" + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" } }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "dev": true + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "dev": true, "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "glob": "^7.1.3" } }, - "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==", + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", "dev": true, "requires": { - "color-name": "1.1.3" + "shebang-regex": "^1.0.0" } }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", "dev": true }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", "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==", + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "isexe": "^2.0.0" } } } @@ -38240,15 +35590,15 @@ "dev": true }, "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true }, "path-is-inside": { @@ -38258,31 +35608,22 @@ "dev": true }, "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true }, "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "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": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "requires": { - "pify": "^3.0.0" - } + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true }, "pathval": { "version": "1.1.1", @@ -38306,31 +35647,31 @@ "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", "dev": true }, "picomatch": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", - "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true }, "pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", "dev": true }, "pinkie": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", "dev": true }, "pinkie-promise": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", "dev": true, "requires": { "pinkie": "^2.0.0" @@ -38381,18 +35722,6 @@ "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 - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true } } }, @@ -38403,34 +35732,17 @@ "dev": true }, "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true - }, - "prepend-http": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", - "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true }, "prettier": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.1.tgz", - "integrity": "sha512-8UVbTBYGwN37Bs9LERmxCPjdvPxlEowx2urIL6urHzdb3SDq4B/Z6xLFCblrSnE4iKWcS6ziJ3aOYrc1kz/E2A==", - "dev": true - }, - "printj": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/printj/-/printj-1.3.1.tgz", - "integrity": "sha512-GA3TdL8szPK4AQ2YnOe/b+Y1jUFwmmGMMK/qbY7VcE3Z7FU8JstbKiKRzO6CIiAKPhTO8m01NoQ0V5f3jc4OGg==", - "dev": true - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", + "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", + "dev": true, + "optional": true }, "process-nextick-args": { "version": "2.0.1", @@ -38445,9 +35757,9 @@ "dev": true }, "promise": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/promise/-/promise-8.1.0.tgz", - "integrity": "sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", + "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==", "dev": true, "requires": { "asap": "~2.0.6" @@ -38474,79 +35786,31 @@ "signal-exit": "^3.0.2" } }, - "proxy-addr": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", - "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", - "dev": true, - "requires": { - "forwarded": "~0.1.2", - "ipaddr.js": "1.9.1" - } - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", - "dev": true - }, "psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "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, - "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" - } - }, - "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.1.0", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz", - "integrity": "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0=", + "integrity": "sha512-Yxz2kRwT90aPiWEMHVYnEf4+rhwF1tBmmZ4KepCP+Wkium9JxtWnUm1nqGwpiAHr/tnTSeHqr3wb++jgSkXjhA==", "dev": true }, "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "dev": true - }, - "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==", + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", "dev": true, "requires": { - "decode-uri-component": "^0.2.0", - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" + "side-channel": "^1.0.4" } }, "querystring": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==", "dev": true }, "queue-microtask": { @@ -38558,7 +35822,7 @@ "quick-lru": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-1.1.0.tgz", - "integrity": "sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g=", + "integrity": "sha512-tRS7sTgyxMXtLum8L65daJnHUhfDUgboRdcWW2bR9vBfrj2+O5HSMbQOJfJJjIVSPFqbBCF37FpwWXGitDc5tA==", "dev": true }, "randombytes": { @@ -38570,30 +35834,14 @@ "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.4.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.1.tgz", - "integrity": "sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA==", + "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.0", - "http-errors": "1.7.3", + "bytes": "3.1.2", + "http-errors": "2.0.0", "iconv-lite": "0.4.24", "unpipe": "1.0.0" } @@ -38601,22 +35849,84 @@ "read-pkg": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", "dev": true, "requires": { "load-json-file": "^4.0.0", "normalize-package-data": "^2.3.2", "path-type": "^3.0.0" + }, + "dependencies": { + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "^3.0.0" + } + } } }, "read-pkg-up": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", - "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", + "integrity": "sha512-YFzFrVvpC6frF1sz8psoHDBGF7fLPc+llq/8NB43oagqWkx8ar5zYtsTORtOjw9W2RHLpWP+zTWwBvf1bCmcSw==", "dev": true, "requires": { "find-up": "^2.0.0", "read-pkg": "^3.0.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", + "dev": true, + "requires": { + "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", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true + } } }, "readable-stream": { @@ -38631,9 +35941,9 @@ } }, "readdirp": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", - "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, "requires": { "picomatch": "^2.2.1" @@ -38642,29 +35952,48 @@ "rechoir": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", "dev": true, "requires": { "resolve": "^1.1.6" } }, "recursive-readdir": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.2.tgz", - "integrity": "sha512-nRCcW9Sj7NuZwa2XvH9co8NPeXUBhZP7CRKJtU+cS6PW9FpCIFoI5ib0NT1ZrbNuPoRy0ylyCaUL8Gih4LSyFg==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", + "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", "dev": true, "requires": { - "minimatch": "3.0.4" + "minimatch": "^3.0.5" } }, "redent": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz", - "integrity": "sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo=", + "integrity": "sha512-XNwrTx77JQCEMXTeb8movBKuK75MgH0RZkujNuDKCezemx/voapl9i2gCSi8WWm8+ox5ycJi1gxF22fR7c0Ciw==", "dev": true, "requires": { "indent-string": "^3.0.0", "strip-indent": "^2.0.0" + }, + "dependencies": { + "indent-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", + "integrity": "sha512-BYqTHXTGUIvg7t1r4sJNKcbDZkL92nkXA8YtRpbjFHRHGDL/NtUeiBJMeE60kIFN/Mg8ESaWQvftaYMGJzQZCQ==", + "dev": true + } + } + }, + "regexp.prototype.flags": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", + "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "functions-have-names": "^1.2.2" } }, "regexpp": { @@ -38676,7 +36005,7 @@ "req-cwd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/req-cwd/-/req-cwd-2.0.0.tgz", - "integrity": "sha1-1AgrTURZgDZkD7c93qAe1T20nrw=", + "integrity": "sha512-ueoIoLo1OfB6b05COxAA9UpeoscNpYyM+BqYlA7H6LVF4hKGPXQQSSaD2YmvDVJMkk4UDpAHIeU1zG53IqjvlQ==", "dev": true, "requires": { "req-from": "^2.0.0" @@ -38685,10 +36014,18 @@ "req-from": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/req-from/-/req-from-2.0.0.tgz", - "integrity": "sha1-10GI5H+TeW9Kpx327jWuaJ8+DnA=", + "integrity": "sha512-LzTfEVDVQHBRfjOUMgNBA+V6DWsSnoeKzf42J7l0xa/B4jyPOuuF5MlNSmomLNGemWTnV2TIdjSSLnEn95fOQA==", "dev": true, "requires": { "resolve-from": "^3.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", + "dev": true + } } }, "request": { @@ -38717,6 +36054,31 @@ "tough-cookie": "~2.5.0", "tunnel-agent": "^0.6.0", "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 + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + } } }, "request-promise-core": { @@ -38742,7 +36104,7 @@ "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true }, "require-from-string": { @@ -38754,34 +36116,24 @@ "require-main-filename": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "integrity": "sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==", "dev": true }, "resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", "dev": true, "requires": { - "is-core-module": "^2.2.0", "path-parse": "^1.0.6" } }, "resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "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": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", - "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", @@ -38795,7 +36147,7 @@ "retry": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", "dev": true }, "reusify": { @@ -38805,9 +36157,9 @@ "dev": true }, "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, "requires": { "glob": "^7.1.3" @@ -38824,12 +36176,12 @@ } }, "rlp": { - "version": "2.2.6", - "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.6.tgz", - "integrity": "sha512-HAfAmL6SDYNWPUOJNrM500x4Thn4PZsEy5pijPh40U9WfNk0z15hUYzO9xVIMAdIHdFtD8CBDHd75Td1g36Mjg==", + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz", + "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==", "dev": true, "requires": { - "bn.js": "^4.11.1" + "bn.js": "^5.2.0" } }, "run-async": { @@ -38847,6 +36199,15 @@ "queue-microtask": "^1.2.2" } }, + "run-parallel-limit": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/run-parallel-limit/-/run-parallel-limit-1.1.0.tgz", + "integrity": "sha512-jJA7irRNM91jaKc3Hcl1npHsFLOXOoTkPCUL1JEa1R82O2miplXXRaGdjW/KM/98YQWDhJLiSs793CnXfblJUw==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } + }, "rustbn.js": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/rustbn.js/-/rustbn.js-0.2.0.tgz", @@ -38868,6 +36229,17 @@ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true }, + "safe-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" + } + }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -38896,22 +36268,25 @@ "wordwrap": "^1.0.0" }, "dependencies": { + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, "async": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", - "dev": true - }, - "esprima": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", + "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==", "dev": true }, "glob": { "version": "5.0.15", "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", - "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "integrity": "sha512-c9IPMazfRITpmAAKi22dK1VKxGDX9ehhqfABDriL/lzO92xcUKEJPQHrVA/2YHSNFB4iFlykVmWvwo48nr3OxA==", "dev": true, "requires": { "inflight": "^1.0.4", @@ -38924,23 +36299,50 @@ "has-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "integrity": "sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA==", "dev": true }, + "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, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "dependencies": { + "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 + } + } + }, "resolve": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "integrity": "sha512-9znBF0vBcaSN3W2j7wKvdERPwqTxSpCq+if5C0WoTCyV9n24rua28jeuQ2pL/HOf+yUe/Mef+H/5p60K0Id3bg==", "dev": true }, "supports-color": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "integrity": "sha512-Jds2VIYDrlp5ui7t8abHN2bjAu4LV/q4N2KivFPpGH0lrka0BMq/33AmECUXlKPcHigkNaqfXRENFju+rlcy+A==", "dev": true, "requires": { "has-flag": "^1.0.0" } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } } } }, @@ -38951,74 +36353,22 @@ "dev": true }, "secp256k1": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.2.tgz", - "integrity": "sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz", + "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==", "dev": true, "requires": { - "elliptic": "^6.5.2", + "elliptic": "^6.5.4", "node-addon-api": "^2.0.0", "node-gyp-build": "^4.2.0" } }, - "semaphore-async-await": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/semaphore-async-await/-/semaphore-async-await-1.5.1.tgz", - "integrity": "sha1-hXvvXjZEYBykuVcLh+nfXKEpdPo=", - "dev": true - }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true }, - "send": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", - "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", - "dev": true, - "requires": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "~1.7.2", - "mime": "1.6.0", - "ms": "2.1.1", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.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" - }, - "dependencies": { - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": 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==", - "dev": true - } - } - }, "serialize-javascript": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", @@ -39028,47 +36378,22 @@ "randombytes": "^2.1.0" } }, - "serve-static": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", - "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", - "dev": true, - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.17.1" - } - }, - "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-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", "dev": true }, "setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", "dev": true }, "setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", "dev": true }, "sha.js": { @@ -39084,7 +36409,7 @@ "sha1": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/sha1/-/sha1-1.1.1.tgz", - "integrity": "sha1-rdqnqTFo85PxnrKxUJFhjicA+Eg=", + "integrity": "sha512-dZBS6OrMjtgVkopB1Gmo4RQCDKiZsqcpAQpkV/aaj+FCrCg8r4I4qMkDPQjBgLIxlmu9k4nUbWq6ohXahOneYA==", "dev": true, "requires": { "charenc": ">= 0.0.1", @@ -39092,18 +36417,18 @@ } }, "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "requires": { - "shebang-regex": "^1.0.0" + "shebang-regex": "^3.0.0" } }, "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, "shelljs": { @@ -39129,32 +36454,15 @@ } }, "signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", - "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==", + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, - "simple-get": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.1.tgz", - "integrity": "sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw==", - "dev": true, - "requires": { - "decompress-response": "^3.3.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, "simple-git": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.10.0.tgz", - "integrity": "sha512-2w35xrS5rVtAW0g67LqtxCZN5cdddz/woQRfS0OJXaljXEoTychZ4jnE+CQgra/wX4ZvHeiChTUMenCwfIYEYw==", + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.14.1.tgz", + "integrity": "sha512-1ThF4PamK9wBORVGMK9HK5si4zoGS2GpRO7tkAFObA4FZv6dKaCVHLQT+8zlgiBm6K2h+wEU9yOaFCu/SR3OyA==", "dev": true, "requires": { "@kwsites/file-exists": "^1.1.1", @@ -39169,44 +36477,26 @@ "dev": true }, "slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true }, "slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, "requires": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.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" - } - }, - "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==", + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true } } @@ -39227,10 +36517,16 @@ "tmp": "0.0.33" }, "dependencies": { + "commander": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz", + "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==", + "dev": true + }, "fs-extra": { "version": "0.30.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", - "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", + "integrity": "sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==", "dev": true, "requires": { "graceful-fs": "^4.1.2", @@ -39240,21 +36536,24 @@ "rimraf": "^2.2.8" } }, - "js-sha3": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", - "dev": true - }, "jsonfile": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "integrity": "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==", "dev": true, "requires": { "graceful-fs": "^4.1.6" } }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", @@ -39290,6 +36589,12 @@ "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", "dev": 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 + }, "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -39299,6 +36604,21 @@ "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, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true + }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -39322,7 +36642,7 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, "commander": { @@ -39331,6 +36651,39 @@ "integrity": "sha512-6CYPa+JP2ftfRU2qkDK+UTVeQYosOg/2GbcjIcKPHfinyOLPVGXu/ovN86RP49Re5ndJK1N0kuiidFFuepc4ZQ==", "dev": true }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "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==", + "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 + }, "eslint": { "version": "5.16.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz", @@ -39419,10 +36772,10 @@ "eslint-visitor-keys": "^1.0.0" } }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "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 }, "file-entry-cache": { @@ -39460,7 +36813,7 @@ "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true }, "ignore": { @@ -39469,22 +36822,51 @@ "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "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, "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" + "argparse": "^1.0.7", + "esprima": "^4.0.0" } }, - "prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", "dev": true, - "optional": 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, + "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" + } + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "dev": true + }, + "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 }, "regexpp": { "version": "2.0.1", @@ -39492,21 +36874,84 @@ "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", "dev": true }, - "resolve-from": { + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "dev": true + }, + "slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + } + }, + "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, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-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 + }, + "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, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "strip-ansi": { "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 - }, - "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", "dev": true, "requires": { - "glob": "^7.1.3" + "ansi-regex": "^3.0.0" } }, + "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 + }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -39515,41 +36960,85 @@ "requires": { "has-flag": "^3.0.0" } + }, + "table": { + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "dev": true, + "requires": { + "ajv": "^6.10.2", + "lodash": "^4.17.14", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + } + }, + "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, + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } } } }, "solidity-ast": { - "version": "0.4.31", - "resolved": "https://registry.npmjs.org/solidity-ast/-/solidity-ast-0.4.31.tgz", - "integrity": "sha512-kX6o4XE4ihaqENuRRTMJfwQNHoqWusPENZUlX4oVb19gQdfi7IswFWnThONHSW/61umgfWdKtCBgW45iuOTryQ==", + "version": "0.4.35", + "resolved": "https://registry.npmjs.org/solidity-ast/-/solidity-ast-0.4.35.tgz", + "integrity": "sha512-F5bTDLh3rmDxRmLSrs3qt3nvxJprWSEkS7h2KmuXDx7XTfJ6ZKVTV1rtPIYCqJAuPsU/qa8YUeFn7jdOAZcTPA==", "dev": true }, "solidity-coverage": { - "version": "0.7.20", - "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.7.20.tgz", - "integrity": "sha512-edOXTugUYdqxrtEnIn4vgrGjLPxdexcL0WD8LzAvVA3d1dwgcfRO3k8xQR02ZQnOnWMBi8Cqs0F+kAQQp3JW8g==", + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.8.2.tgz", + "integrity": "sha512-cv2bWb7lOXPE9/SSleDO6czkFiMHgP4NXPj+iW9W7iEKLBk7Cj0AGBiNmGX3V1totl9wjPrT0gHmABZKZt65rQ==", "dev": true, "requires": { - "@solidity-parser/parser": "^0.14.0", - "@truffle/provider": "^0.2.24", + "@ethersproject/abi": "^5.0.9", + "@solidity-parser/parser": "^0.14.1", "chalk": "^2.4.2", "death": "^1.1.0", "detect-port": "^1.3.0", + "difflib": "^0.2.4", "fs-extra": "^8.1.0", "ghost-testrpc": "^0.0.2", "global-modules": "^2.0.0", "globby": "^10.0.1", "jsonschema": "^1.2.4", "lodash": "^4.17.15", + "mocha": "7.1.2", "node-emoji": "^1.10.0", "pify": "^4.0.1", "recursive-readdir": "^2.2.2", "sc-istanbul": "^0.4.5", "semver": "^7.3.4", "shelljs": "^0.8.3", - "web3-utils": "^1.3.0" + "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 + }, + "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 + }, "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -39559,6 +37048,21 @@ "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, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -39570,6 +37074,33 @@ "supports-color": "^5.3.0" } }, + "chokidar": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", + "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", + "dev": 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" + } + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -39582,9 +37113,60 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "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==", + "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 + }, + "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 }, + "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, + "requires": { + "locate-path": "^3.0.0" + } + }, + "flat": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz", + "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==", + "dev": true, + "requires": { + "is-buffer": "~2.0.3" + } + }, "fs-extra": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", @@ -39596,12 +37178,87 @@ "universalify": "^0.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 + }, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "dev": 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==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "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, + "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" + } + }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "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, + "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, + "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, + "requires": { + "chalk": "^2.4.2" + } + }, "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -39611,21 +37268,153 @@ "yallist": "^4.0.0" } }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": 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==", + "dev": 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==", + "dev": 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, + "requires": { + "has-flag": "^3.0.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==", + "dev": 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, + "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==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "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 + }, "pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", "dev": true }, + "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, + "requires": { + "picomatch": "^2.0.4" + } + }, + "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 + }, "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "requires": { "lru-cache": "^6.0.0" } }, + "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, + "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, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "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 + }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -39635,28 +37424,111 @@ "has-flag": "^3.0.0" } }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", + "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, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.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 + }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true + }, + "yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": 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" + } + }, + "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, + "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==", + "dev": true, + "requires": { + "flat": "^4.1.0", + "lodash": "^4.17.15", + "yargs": "^13.3.0" + } } } }, "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 + "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, + "requires": { + "amdefine": ">=0.0.4" + } }, "source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "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 + } } }, "spdx-correct": { @@ -39686,21 +37558,21 @@ } }, "spdx-license-ids": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz", - "integrity": "sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==", + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz", + "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==", "dev": true }, "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", + "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", "dev": true, "requires": { "asn1": "~0.2.3", @@ -39712,6 +37584,14 @@ "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 + } } }, "stacktrace-parser": { @@ -39732,21 +37612,21 @@ } }, "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "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": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", + "integrity": "sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g==", "dev": true }, - "strict-uri-encode": { + "streamsearch": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", "dev": true }, "string_decoder": { @@ -39766,47 +37646,66 @@ "requires": { "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^4.0.0" + }, + "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 + }, + "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, + "requires": { + "ansi-regex": "^3.0.0" + } + } } }, "string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "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==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3" + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" } }, "string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", + "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3" + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" } }, "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "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": "^3.0.0" + "ansi-regex": "^5.0.1" } }, "strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "dev": true }, "strip-hex-prefix": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", - "integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=", + "integrity": "sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==", "dev": true, "requires": { "is-hex-prefixed": "1.0.0" @@ -39815,145 +37714,41 @@ "strip-indent": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", - "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=", + "integrity": "sha512-RsSNPLpq6YUL7QYy44RnPVTn/lcVZtb48Uof3X5JLbF4zD/Gs7ZFDv2HWol+leoQN2mT86LAzSshGfkTlSOpsA==", "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": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "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" - } - }, - "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.40", - "resolved": "https://registry.npmjs.org/swarm-js/-/swarm-js-0.1.40.tgz", - "integrity": "sha512-yqiOCEoA4/IShXkY3WKwP5PvZhmoOOD8clsKA7EEcRILMkTEYHCQ21HDCAcVpmIxZq4LyZvWeRJ6quIyHk1caA==", - "dev": true, - "requires": { - "bluebird": "^3.5.0", - "buffer": "^5.0.5", - "eth-lib": "^0.1.26", - "fs-extra": "^4.0.2", - "got": "^7.1.0", - "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": { - "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" - } - }, - "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, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", - "dev": true - }, - "got": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz", - "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==", - "dev": true, - "requires": { - "decompress-response": "^3.2.0", - "duplexer3": "^0.1.4", - "get-stream": "^3.0.0", - "is-plain-obj": "^1.1.0", - "is-retry-allowed": "^1.0.0", - "is-stream": "^1.0.0", - "isurl": "^1.0.0-alpha5", - "lowercase-keys": "^1.0.0", - "p-cancelable": "^0.3.0", - "p-timeout": "^1.1.1", - "safe-buffer": "^5.0.1", - "timed-out": "^4.0.0", - "url-parse-lax": "^1.0.0", - "url-to-options": "^1.0.1" - } - }, - "p-cancelable": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz", - "integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==", - "dev": true - }, - "prepend-http": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", - "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==", + "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 - }, - "url-parse-lax": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", - "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", - "dev": true, - "requires": { - "prepend-http": "^1.0.1" - } - }, - "ws": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", - "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", - "dev": true, - "requires": { - "async-limiter": "~1.0.0", - "safe-buffer": "~5.1.0", - "ultron": "~1.1.0" - } } } }, + "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" + } + }, "sync-request": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz", @@ -39975,64 +37770,59 @@ } }, "table": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", + "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", "dev": true, "requires": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" + "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": { - "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 - }, - "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==", + "ajv": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", "dev": true, "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" } }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "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 + }, + "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": { - "ansi-regex": "^4.1.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" } } } }, - "tar": { - "version": "4.4.13", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", - "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", - "dev": true, - "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.8.6", - "minizlib": "^1.2.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.3" - } - }, "test-value": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/test-value/-/test-value-2.1.0.tgz", - "integrity": "sha1-Edpv9nDzRxpztiXKTz/c97t0gpE=", + "integrity": "sha512-+1epbAxtKeXttkGFMTX9H42oqzOTufR1ceCF+GYA5aOmvaPq9wd4PUS8329fn2RRLGNeUkgRLnVpycjx8DsO2w==", "dev": true, "requires": { "array-back": "^1.0.3", @@ -40042,7 +37832,7 @@ "array-back": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", - "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=", + "integrity": "sha512-1WxbZvrmyhkNoeYcizokbmh5oiOCIfyvGtcqbK3Ls1v1fKcquzxnQSceOx6tzq7jmai2kFLWIpGND2cLhH6TPw==", "dev": true, "requires": { "typical": "^2.6.0" @@ -40059,7 +37849,7 @@ "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, "then-request": { @@ -40086,6 +37876,17 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz", "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==", "dev": true + }, + "form-data": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", + "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } } } }, @@ -40095,12 +37896,6 @@ "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": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", - "dev": true - }, "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -40110,12 +37905,6 @@ "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", @@ -40126,9 +37915,9 @@ } }, "toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "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": { @@ -40152,30 +37941,32 @@ "tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", "dev": true }, "trim-newlines": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz", - "integrity": "sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA=", + "integrity": "sha512-MTBWv3jhVjTU7XR3IQHllbiJs8sc75a80OEhB6or/q7pLTWgQ0bMGQXXYQSrSuXe6WiKWDZ5txXY5P59a/coVA==", "dev": true }, "trim-repeated": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", - "integrity": "sha1-42RqLqTokTEr9+rObPsFOAvAHCE=", + "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 + } } }, - "true-case-path": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-2.2.1.tgz", - "integrity": "sha512-0z3j8R7MCjy10kc/g+qg7Ln3alJTodw9aDuVWZa3uiWqfuBMKeAeP2ocWcxoyM3D73yz3Jt/Pu4qPr4wHSdB/Q==", - "dev": true - }, "ts-essentials": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-1.0.4.tgz", @@ -40231,13 +38022,25 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "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": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "prettier": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", + "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", "dev": true }, "supports-color": { @@ -40252,12 +38055,12 @@ } }, "ts-node": { - "version": "10.7.0", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.7.0.tgz", - "integrity": "sha512-TbIGS4xgJoX2i3do417KSaep1uRAW/Lu+WAL2doDHC0D6ummjirVOXU5/7aiZotbQ5p1Zp9tP7U6cYhA0O7M8A==", + "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.7.0", + "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", "@tsconfig/node12": "^1.0.7", "@tsconfig/node14": "^1.0.0", @@ -40268,7 +38071,7 @@ "create-require": "^1.1.0", "diff": "^4.0.1", "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.0", + "v8-compile-cache-lib": "^3.0.1", "yn": "3.1.1" }, "dependencies": { @@ -40289,7 +38092,7 @@ "tsort": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/tsort/-/tsort-0.0.1.tgz", - "integrity": "sha1-4igPXoF/i/QnVlf9D5rr1E9aJ4Y=", + "integrity": "sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw==", "dev": true }, "tsutils": { @@ -40304,16 +38107,16 @@ "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", "dev": true, "requires": { "safe-buffer": "^5.0.1" } }, "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==", "dev": true }, "tweetnacl-util": { @@ -40322,19 +38125,13 @@ "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.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "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.1.2" + "prelude-ls": "^1.2.1" } }, "type-detect": { @@ -40344,21 +38141,11 @@ "dev": true }, "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==", + "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": "3.0.0", "resolved": "https://registry.npmjs.org/typechain/-/typechain-3.0.0.tgz", @@ -40374,12 +38161,6 @@ "ts-generator": "^0.1.1" }, "dependencies": { - "js-sha3": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", - "dev": true - }, "ts-essentials": { "version": "6.0.7", "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-6.0.7.tgz", @@ -40392,66 +38173,48 @@ "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", "dev": true }, - "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": { - "is-typedarray": "^1.0.0" - } - }, "typescript": { - "version": "4.6.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz", - "integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==", + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", + "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", "dev": true }, "typical": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", - "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=", + "integrity": "sha512-ofhi8kjIje6npGozTip9Fr8iecmYfEbS06i0JnIg+rh51KakryWF4+jX8lLKZVhy6N+ID45WYSFCxPOdTWCzNg==", "dev": true }, "uglify-js": { - "version": "3.13.6", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.13.6.tgz", - "integrity": "sha512-rRprLwl8RVaS+Qvx3Wh5hPfPBn9++G6xkGlUupya0s5aDmNjI7z3lnRLB3u7sN4OmbB0pWgzhM9BEJyiWAwtAA==", + "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 }, - "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.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", "dev": true, "requires": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", "which-boxed-primitive": "^1.0.2" } }, - "underscore": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", - "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==", - "dev": true - }, "undici": { - "version": "4.16.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-4.16.0.tgz", - "integrity": "sha512-tkZSECUYi+/T1i4u+4+lwZmQgLXd4BLGlrc7KZPcLIW7Jpq99+Xpc30ONv7nS6F5UNOxp/HBZSSL9MafUrvJbw==", - "dev": true + "version": "5.12.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.12.0.tgz", + "integrity": "sha512-zMLamCG62PGjd9HHMpo05bSLvvwWOZgGeiWlN/vlqu3+lRo3elxktVGEyLMX+IO7c2eflLjcW74AlkhEZm15mg==", + "dev": true, + "requires": { + "busboy": "^1.6.0" + } }, "universalify": { "version": "0.1.2", @@ -40462,7 +38225,7 @@ "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "dev": true }, "uri-js": { @@ -40477,7 +38240,7 @@ "url": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "integrity": "sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==", "dev": true, "requires": { "punycode": "1.3.2", @@ -40487,83 +38250,33 @@ "punycode": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==", "dev": true } } }, - "url-parse-lax": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", - "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", - "dev": true, - "requires": { - "prepend-http": "^2.0.0" - } - }, - "url-set-query": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/url-set-query/-/url-set-query-1.0.0.tgz", - "integrity": "sha1-AW6M/Xwg7gXK/neV6JK9BwL6ozk=", - "dev": true - }, - "url-to-options": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz", - "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=", - "dev": true - }, - "utf-8-validate": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.5.tgz", - "integrity": "sha512-+pnxRYsS/axEpkrrEpzYfNZGXp0IjC/9RIxwM5gntY4Koi8SHmUGSfxfWqxZdRxrtaoVstuOzUp/rbs3JSPELQ==", - "dev": true, - "requires": { - "node-gyp-build": "^4.2.0" - } - }, "utf8": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==", "dev": true }, - "util": { - "version": "0.12.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.3.tgz", - "integrity": "sha512-I8XkoQwE+fPQEhy9v012V+TSdH2kp9ts29i20TaaDUXsg7x/onePbhFJUExBfv/2ay1ZOp/Vsm3nDlmnFGSAog==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "safe-buffer": "^5.1.2", - "which-typed-array": "^1.1.2" - } - }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "dev": true }, "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "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.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.0.tgz", - "integrity": "sha512-mpSYqfsFvASnSn5qMiwrr4VKfumbPyONLCOPmsR3A6pTY/r0+tSaVbgPWSAIuzbk3lCTa+FForeTiO+wBQGkjA==", + "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 }, "validate-npm-package-license": { @@ -40576,22 +38289,10 @@ "spdx-expression-parse": "^3.0.0" } }, - "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": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", - "dev": true - }, "verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", "dev": true, "requires": { "assert-plus": "^1.0.0", @@ -40599,400 +38300,31 @@ "extsprintf": "^1.2.0" } }, - "web3": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/web3/-/web3-1.3.5.tgz", - "integrity": "sha512-UyQW/MT5EIGBrXPCh/FDIaD7RtJTn5/rJUNw2FOglp0qoXnCQHNKvntiR1ylztk05fYxIF6UgsC76IrazlKJjw==", - "dev": true, - "requires": { - "web3-bzz": "1.3.5", - "web3-core": "1.3.5", - "web3-eth": "1.3.5", - "web3-eth-personal": "1.3.5", - "web3-net": "1.3.5", - "web3-shh": "1.3.5", - "web3-utils": "1.3.5" - } - }, - "web3-bzz": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.3.5.tgz", - "integrity": "sha512-XiEUAbB1uKm/agqfwBsCW8fbw+sma85TfwuDpdcy591vinVk0S9TfWgLxro6v1KJ6nSELySIbKGbAJbh2GSyxw==", - "dev": true, - "requires": { - "@types/node": "^12.12.6", - "got": "9.6.0", - "swarm-js": "^0.1.40", - "underscore": "1.9.1" - }, - "dependencies": { - "@types/node": { - "version": "12.20.13", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.13.tgz", - "integrity": "sha512-1x8W5OpxPq+T85OUsHRP6BqXeosKmeXRtjoF39STcdf/UWLqUsoehstZKOi0CunhVqHG17AyZgpj20eRVooK6A==", - "dev": true - } - } - }, - "web3-core": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.3.5.tgz", - "integrity": "sha512-VQjTvnGTqJwDwjKEHSApea3RmgtFGLDSJ6bqrOyHROYNyTyKYjFQ/drG9zs3rjDkND9mgh8foI1ty37Qua3QCQ==", - "dev": true, - "requires": { - "@types/bn.js": "^4.11.5", - "@types/node": "^12.12.6", - "bignumber.js": "^9.0.0", - "web3-core-helpers": "1.3.5", - "web3-core-method": "1.3.5", - "web3-core-requestmanager": "1.3.5", - "web3-utils": "1.3.5" - }, - "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": "*" - } - }, - "@types/node": { - "version": "12.20.13", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.13.tgz", - "integrity": "sha512-1x8W5OpxPq+T85OUsHRP6BqXeosKmeXRtjoF39STcdf/UWLqUsoehstZKOi0CunhVqHG17AyZgpj20eRVooK6A==", - "dev": true - } - } - }, - "web3-core-helpers": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.3.5.tgz", - "integrity": "sha512-HYh3ix5FjysgT0jyzD8s/X5ym0b4BGU7I2QtuBiydMnE0mQEWy7GcT9XKpTySA8FTOHHIAQYvQS07DN/ky3UzA==", - "dev": true, - "requires": { - "underscore": "1.9.1", - "web3-eth-iban": "1.3.5", - "web3-utils": "1.3.5" - } - }, - "web3-core-method": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.3.5.tgz", - "integrity": "sha512-hCbmgQ+At6OTuaNGAdjXMsCr4eUCmp9yGKSuaB5HdkNVDpqFso4HHjVxcjNrTyJp3OZnyjKBzQzK1ZWLpLl84Q==", - "dev": true, - "requires": { - "@ethersproject/transactions": "^5.0.0-beta.135", - "underscore": "1.9.1", - "web3-core-helpers": "1.3.5", - "web3-core-promievent": "1.3.5", - "web3-core-subscriptions": "1.3.5", - "web3-utils": "1.3.5" - } - }, - "web3-core-promievent": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.3.5.tgz", - "integrity": "sha512-K0j8x3ZJr0eAyNvyUCxOUsSTd4hco0/9nxxlyOuijcsa6YV8l9NL6eqhniWbSyxCJT8ka5Mb7yAiUZe69EDLBQ==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4" - } - }, - "web3-core-requestmanager": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.3.5.tgz", - "integrity": "sha512-9l294U3Ga8qmvv8E37BqjQREfMs+kFnkU3PY28g9DZGYzKvl3V1dgDYqxyrOBdCFhc7rNSpHdgC4PrVHjouspg==", - "dev": true, - "requires": { - "underscore": "1.9.1", - "util": "^0.12.0", - "web3-core-helpers": "1.3.5", - "web3-providers-http": "1.3.5", - "web3-providers-ipc": "1.3.5", - "web3-providers-ws": "1.3.5" - } - }, - "web3-core-subscriptions": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.3.5.tgz", - "integrity": "sha512-6mtXdaEB1V1zKLqYBq7RF2W75AK5ZJNGpW6QYC7Zvbku7zq1ZlgaUkJo88JKMWJ7etfaHaYqQ/7VveHk5sQynA==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4", - "underscore": "1.9.1", - "web3-core-helpers": "1.3.5" - } - }, - "web3-eth": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.3.5.tgz", - "integrity": "sha512-5qqDPMMD+D0xRqOV2ePU2G7/uQmhn0FgCEhFzKDMHrssDQJyQLW/VgfA0NLn64lWnuUrGnQStGvNxrWf7MgsfA==", - "dev": true, - "requires": { - "underscore": "1.9.1", - "web3-core": "1.3.5", - "web3-core-helpers": "1.3.5", - "web3-core-method": "1.3.5", - "web3-core-subscriptions": "1.3.5", - "web3-eth-abi": "1.3.5", - "web3-eth-accounts": "1.3.5", - "web3-eth-contract": "1.3.5", - "web3-eth-ens": "1.3.5", - "web3-eth-iban": "1.3.5", - "web3-eth-personal": "1.3.5", - "web3-net": "1.3.5", - "web3-utils": "1.3.5" - } - }, - "web3-eth-abi": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.3.5.tgz", - "integrity": "sha512-bkbG2v/mOW5DH6rF/SEgqunusjYoEi2IBw+fkmD3rzWDaEY7+/i1xY94AeO257d06QMgld75GtV/N+aEs7A6vQ==", - "dev": true, - "requires": { - "@ethersproject/abi": "5.0.7", - "underscore": "1.9.1", - "web3-utils": "1.3.5" - }, - "dependencies": { - "@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" - } - } - } - }, - "web3-eth-accounts": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.3.5.tgz", - "integrity": "sha512-r3WOR21rgm6Cd6OFnifr3Tizdm5K+g2TsSOPySwX4FrgLrYDL6ck4zr5VXUPz+llpSExb/JztpE8pqEHr3U2NA==", - "dev": true, - "requires": { - "crypto-browserify": "3.12.0", - "eth-lib": "0.2.8", - "ethereumjs-common": "^1.3.2", - "ethereumjs-tx": "^2.1.1", - "scrypt-js": "^3.0.1", - "underscore": "1.9.1", - "uuid": "3.3.2", - "web3-core": "1.3.5", - "web3-core-helpers": "1.3.5", - "web3-core-method": "1.3.5", - "web3-utils": "1.3.5" - }, - "dependencies": { - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", - "dev": true - } - } - }, - "web3-eth-contract": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.3.5.tgz", - "integrity": "sha512-WfGVeQquN3D7Qm+KEIN9EI7yrm/fL2V9Y4+YhDWiKA/ns1pX1LYcEWojTOnBXCnPF3tcvoKKL+KBxXg1iKm38A==", - "dev": true, - "requires": { - "@types/bn.js": "^4.11.5", - "underscore": "1.9.1", - "web3-core": "1.3.5", - "web3-core-helpers": "1.3.5", - "web3-core-method": "1.3.5", - "web3-core-promievent": "1.3.5", - "web3-core-subscriptions": "1.3.5", - "web3-eth-abi": "1.3.5", - "web3-utils": "1.3.5" - }, - "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": "*" - } - } - } - }, - "web3-eth-ens": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.3.5.tgz", - "integrity": "sha512-5bkpFTXV18CvaVP8kCbLZZm2r1TWUv9AsXH+80yz8bTZulUGvXsBMRfK6e5nfEr2Yv59xlIXCFoalmmySI9EJw==", - "dev": true, - "requires": { - "content-hash": "^2.5.2", - "eth-ens-namehash": "2.0.8", - "underscore": "1.9.1", - "web3-core": "1.3.5", - "web3-core-helpers": "1.3.5", - "web3-core-promievent": "1.3.5", - "web3-eth-abi": "1.3.5", - "web3-eth-contract": "1.3.5", - "web3-utils": "1.3.5" - } - }, - "web3-eth-iban": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.3.5.tgz", - "integrity": "sha512-x+BI/d2Vt0J1cKK8eFd4W0f1TDjgEOYCwiViTb28lLE+tqrgyPqWDA+l6UlKYLF/yMFX3Dym4ofcCOtgcn4q4g==", - "dev": true, - "requires": { - "bn.js": "^4.11.9", - "web3-utils": "1.3.5" - } - }, - "web3-eth-personal": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.3.5.tgz", - "integrity": "sha512-xELQHNZ8p3VoO1582ghCaq+Bx7pSkOOalc6/ACOCGtHDMelqgVejrmSIZGScYl+k0HzngmQAzURZWQocaoGM1g==", - "dev": true, - "requires": { - "@types/node": "^12.12.6", - "web3-core": "1.3.5", - "web3-core-helpers": "1.3.5", - "web3-core-method": "1.3.5", - "web3-net": "1.3.5", - "web3-utils": "1.3.5" - }, - "dependencies": { - "@types/node": { - "version": "12.20.13", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.13.tgz", - "integrity": "sha512-1x8W5OpxPq+T85OUsHRP6BqXeosKmeXRtjoF39STcdf/UWLqUsoehstZKOi0CunhVqHG17AyZgpj20eRVooK6A==", - "dev": true - } - } - }, - "web3-net": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.3.5.tgz", - "integrity": "sha512-usbFbuUpKK8s7jPLGoUzi/WpNnefGFPTj948aJv8BZ04UQA4L/XS5NNkkhk358zNMmhGfEFW8wrWy+0Oy0njtA==", - "dev": true, - "requires": { - "web3-core": "1.3.5", - "web3-core-method": "1.3.5", - "web3-utils": "1.3.5" - } - }, - "web3-providers-http": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.3.5.tgz", - "integrity": "sha512-ZQOmceFjcajEZdiuqciXjijwIYWNmEJ1oxMtbrwB2eGxHRCMXEH2xGRUZuhOFNF88yQC/VXVi14yvYg5ZlFJlA==", - "dev": true, - "requires": { - "web3-core-helpers": "1.3.5", - "xhr2-cookies": "1.1.0" - } - }, - "web3-providers-ipc": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.3.5.tgz", - "integrity": "sha512-cbZOeb/sALiHjzMolJjIyHla/J5wdL2JKUtRO66Nh/uLALBCpU8JUgzNvpAdJ1ae3+A33+EdFStdzuDYHKtQew==", - "dev": true, - "requires": { - "oboe": "2.1.5", - "underscore": "1.9.1", - "web3-core-helpers": "1.3.5" - } - }, - "web3-providers-ws": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.3.5.tgz", - "integrity": "sha512-zeZ4LMvKhYaJBDCqA//Bzgp4r/T0tNq5U/xvN0axA4YflzF7yqlsbzGwCkcZYDbrUaK3Ltl2uOmvwjbWALOZ1A==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4", - "underscore": "1.9.1", - "web3-core-helpers": "1.3.5", - "websocket": "^1.0.32" - } - }, - "web3-shh": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.3.5.tgz", - "integrity": "sha512-aRwzCduXvuGVslLL/Y15VcOHa70Qr2kxZI7UwOzQVhaaOdxuRRvo3AK/cmyln1Tsd54/n93Yk8I3qg5I2+6alw==", - "dev": true, - "requires": { - "web3-core": "1.3.5", - "web3-core-method": "1.3.5", - "web3-core-subscriptions": "1.3.5", - "web3-net": "1.3.5" - } - }, "web3-utils": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.3.5.tgz", - "integrity": "sha512-5apMRm8ElYjI/92GHqijmaLC+s+d5lgjpjHft+rJSs/dsnX8I8tQreqev0dmU+wzU+2EEe4Sx9a/OwGWHhQv3A==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.8.0.tgz", + "integrity": "sha512-7nUIl7UWpLVka2f09CMbKOSEvorvHnaugIabU4mj7zfMvm0tSByLcEu3eyV9qgS11qxxLuOkzBIwCstTflhmpQ==", "dev": true, "requires": { - "bn.js": "^4.11.9", - "eth-lib": "0.2.8", + "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", - "underscore": "1.9.1", "utf8": "3.0.0" } }, "webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", + "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": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, "whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", "dev": true, "requires": { "tr46": "~0.0.3", @@ -41000,9 +38332,9 @@ } }, "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "requires": { "isexe": "^2.0.0" @@ -41024,24 +38356,9 @@ "which-module": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", - "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", + "integrity": "sha512-F6+WgncZi/mJDrammbTuHe1q0R5hOXv/mBaiNA2TCNT/LTHusX0V+CJnj9XT8ki5ln2UZyyddDgHfCzyrOH7MQ==", "dev": true }, - "which-typed-array": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.4.tgz", - "integrity": "sha512-49E0SpUe90cjpoc7BOJwyPHRqSAd12c10Qm2amdEZrJPCY2NDxaW01zHITrem+rnETY3dwrbH3UUrUwagfCYDA==", - "dev": true, - "requires": { - "available-typed-arrays": "^1.0.2", - "call-bind": "^1.0.0", - "es-abstract": "^1.18.0-next.1", - "foreach": "^2.0.5", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.1", - "is-typed-array": "^1.1.3" - } - }, "wide-align": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", @@ -41054,7 +38371,7 @@ "window-size": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz", - "integrity": "sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU=", + "integrity": "sha512-UD7d8HFA2+PZsbKyaOCEy8gMh1oDtHgJh1LfgjQ4zVXmYjAT/kvz3PueITKuqDiIXQe7yzpPnxX3lNc+AhQMyw==", "dev": true }, "word-wrap": { @@ -41066,13 +38383,13 @@ "wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", "dev": true }, "workerpool": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", - "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", + "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", "dev": true }, "wrap-ansi": { @@ -41086,18 +38403,6 @@ "strip-ansi": "^6.0.0" }, "dependencies": { - "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 - }, - "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 - }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -41114,22 +38419,13 @@ "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.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" - } } } }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, "write": { @@ -41148,61 +38444,10 @@ "dev": true, "requires": {} }, - "xhr": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.6.0.tgz", - "integrity": "sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==", - "dev": 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": "sha1-fXdEnQmZGX8VXLc7I99yUF7YnUg=", - "dev": true, - "requires": { - "cookiejar": "^2.1.1" - } - }, "xmlhttprequest": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", - "integrity": "sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw=", - "dev": true - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "integrity": "sha512-58Im/U0mlVBLM38NdZjHyhuMtCqa61469k2YP/AaPbvCoV9aQGUpbJBj1QRm2ytRiVQBD/fsw7L2bJGDVQswBA==", "dev": true }, "y18n": { @@ -41211,18 +38456,18 @@ "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": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc=", - "dev": true - }, "yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true }, + "yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true + }, "yargs": { "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", @@ -41238,18 +38483,6 @@ "yargs-parser": "^20.2.2" }, "dependencies": { - "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 - }, - "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 - }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -41267,15 +38500,6 @@ "strip-ansi": "^6.0.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" - } - }, "yargs-parser": { "version": "20.2.9", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", diff --git a/package.json b/package.json index 71ab663c..afe36864 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,8 @@ "name": "ssv-network", "scripts": { "lint": "eslint . --ext .ts", - "lint:fix": "eslint --fix . --ext .ts" + "lint:fix": "eslint --fix . --ext .ts", + "solidity-coverage": "NO_GAS_ENFORCE=1 npx hardhat coverage" }, "devDependencies": { "@nomiclabs/hardhat-ethers": "^2.0.5", @@ -27,12 +28,12 @@ "ethereum-waffle": "^3.4.4", "ethers": "^5.6.2", "gh-pages": "^3.2.3", - "hardhat": "^2.9.2", - "hardhat-gas-reporter": "^1.0.8", - "hardhat-tracer": "^1.1.0-rc.3", + "hardhat": "^2.12.2", + "hardhat-gas-reporter": "^1.0.9", + "hardhat-tracer": "^1.1.1", "prompts": "^2.4.2", "simple-git": "^3.10.0", - "solidity-coverage": "^0.7.20", + "solidity-coverage": "^0.8.2", "ts-node": "^10.7.0", "typechain": "^3.0.0", "typescript": "^4.6.3" diff --git a/test/account/deposit.ts b/test/account/deposit.ts index 2c8ed88e..1857e962 100644 --- a/test/account/deposit.ts +++ b/test/account/deposit.ts @@ -1,23 +1,49 @@ import * as helpers from '../helpers/contract-helpers'; -let ssvNetworkContract: any; +import { expect } from 'chai'; +import { trackGas, GasGroup } from '../helpers/gas-usage'; + +let ssvNetworkContract: any, clusterResult1: any, minDepositAmount: any; describe('Deposit Tests', () => { beforeEach(async () => { - const contractData = await helpers.initializeContract(); - ssvNetworkContract = contractData.contract; - }); + // Initialize contract + ssvNetworkContract = (await helpers.initializeContract()).contract; + + // Register operators + await helpers.registerOperators(0, 12, helpers.CONFIG.minimalOperatorFee); + + minDepositAmount = (helpers.CONFIG.minimalBlocksBeforeLiquidation + 10) * helpers.CONFIG.minimalOperatorFee * 4; - it('Deposit', async () => { + // Register validators + clusterResult1 = await helpers.registerValidators(4, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + }); + it('Deposit as owner emits FundsDeposit event', async () => { + await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); + await expect(ssvNetworkContract.connect(helpers.DB.owners[1])['deposit(bytes32,uint256)'](clusterResult1.clusterId, minDepositAmount)).to.emit(ssvNetworkContract, 'FundsDeposit'); }); - it('Deposit errors', async () => { + it('Deposit as non-owner emits FundsDeposit event', async () => { + await helpers.DB.ssvToken.connect(helpers.DB.owners[0]).approve(ssvNetworkContract.address, minDepositAmount); + await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['deposit(address,bytes32,uint256)'](helpers.DB.owners[1].address, clusterResult1.clusterId, minDepositAmount)).to.emit(ssvNetworkContract, 'FundsDeposit'); + }); + it('Deposit as owner returns error - ClusterNotExists', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[1])['deposit(bytes32,uint256)']('0x392791df626408017a264f53fde61065d5a93a32b60171df9d8a46afdf82992c', minDepositAmount)).to.be.revertedWith('ClusterNotExists'); }); - it('Deposit gas limits', async () => { + it('Deposit as non-owner returns error - ClusterNotExists', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['deposit(address,bytes32,uint256)'](helpers.DB.owners[1].address, '0x392791df626408017a264f53fde61065d5a93a32b60171df9d8a46afdf82992c', minDepositAmount)).to.be.revertedWith('ClusterNotExists'); + }); + it('Deposit as owner gas limits', async () => { + await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1])['deposit(bytes32,uint256)'](clusterResult1.clusterId, minDepositAmount), [GasGroup.DEPOSIT]); }); + it('Deposit as non-owner 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(address,bytes32,uint256)'](helpers.DB.owners[1].address, clusterResult1.clusterId, minDepositAmount), [GasGroup.DEPOSIT]); + }); }); diff --git a/test/account/withdraw.ts b/test/account/withdraw.ts index 11e5b67c..8e1e96a5 100644 --- a/test/account/withdraw.ts +++ b/test/account/withdraw.ts @@ -1,23 +1,75 @@ import * as helpers from '../helpers/contract-helpers'; +import * as utils from '../helpers/utils'; -let ssvNetworkContract: any; +import { expect } from 'chai'; +import { trackGas, GasGroup } from '../helpers/gas-usage'; + +let ssvNetworkContract: any, clusterResult1: any, minDepositAmount: any; describe('Withdraw Tests', () => { beforeEach(async () => { - const contractData = await helpers.initializeContract(); - ssvNetworkContract = contractData.contract; + // Initialize contract + ssvNetworkContract = (await helpers.initializeContract()).contract; + + // Register operators + await helpers.registerOperators(0, 12, helpers.CONFIG.minimalOperatorFee); + + minDepositAmount = (helpers.CONFIG.minimalBlocksBeforeLiquidation + 10) * helpers.CONFIG.minimalOperatorFee * 4; + + // Register validators + clusterResult1 = await helpers.registerValidators(4, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + }); + + it('Withdraw pod balance emits PodFundsWithdrawal event', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).withdrawPodBalance(clusterResult1.clusterId, helpers.CONFIG.minimalOperatorFee)).to.emit(ssvNetworkContract, 'PodFundsWithdrawal'); + }); + + it('Withdraw pod balance returns error - NotEnoughBalance', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).withdrawPodBalance(clusterResult1.clusterId, minDepositAmount)).to.be.revertedWith('NotEnoughBalance'); + }); + + it('Withdraw balance of liquidatable pod returns error - NotEnoughBalance', async () => { + await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).withdrawPodBalance(clusterResult1.clusterId, helpers.CONFIG.minimalOperatorFee)).to.be.revertedWith('NotEnoughBalance'); }); - it('Withdraw', async () => { + it('Withdraw pod balance gas limits', async () => { + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).withdrawPodBalance(clusterResult1.clusterId, helpers.CONFIG.minimalOperatorFee), [GasGroup.WITHDRAW]); + }); + + it('Withdraw total operator balance emits OperatorFundsWithdrawal event', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorBalance(uint64)'](1)).to.emit(ssvNetworkContract, 'OperatorFundsWithdrawal'); + }); + + it('Withdraw total operator balance gas limits', async () => { + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorBalance(uint64)'](1), [GasGroup.WITHDRAW]); + }); + it('Withdraw operator balance emits OperatorFundsWithdrawal event', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorBalance(uint64,uint256)'](1, helpers.CONFIG.minimalOperatorFee)).to.emit(ssvNetworkContract, 'OperatorFundsWithdrawal'); }); - it('Withdraw errors', async () => { + it('Withdraw operator balance returns error - CallerNotOwner', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[2])['withdrawOperatorBalance(uint64,uint256)'](1, minDepositAmount)).to.be.revertedWith('CallerNotOwner'); + }); + it('Withdraw operator balance returns error - NotEnoughBalance', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorBalance(uint64,uint256)'](1, minDepositAmount)).to.be.revertedWith('NotEnoughBalance'); }); - it('Withdraw gas limits', async () => { + it('Withdraw total operator balance returns error - CallerNotOwner', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[2])['withdrawOperatorBalance(uint64)'](12)).to.be.revertedWith('CallerNotOwner'); + }); + it('Withdraw total operator balance returns error - NotEnoughBalance', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorBalance(uint64)'](12)).to.be.revertedWith('NotEnoughBalance'); }); + it('Withdraw operator balance gas limits', async () => { + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorBalance(uint64,uint256)'](1, helpers.CONFIG.minimalOperatorFee), [GasGroup.WITHDRAW]); + }); + + it('Withdraw total operator balance gas limits', async () => { + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorBalance(uint64)'](1), [GasGroup.WITHDRAW]); + }); }); diff --git a/test/helpers/contract-helpers.ts b/test/helpers/contract-helpers.ts index be986e3d..79964775 100644 --- a/test/helpers/contract-helpers.ts +++ b/test/helpers/contract-helpers.ts @@ -33,7 +33,6 @@ export const DataGenerator = { if (result.length < size) { throw new Error('No new clusters. Try to register more operators.'); } - return result; }, byId: (id: any) => DB.clusters[id].operatorIds @@ -79,7 +78,13 @@ export const initializeContract = async () => { DB.ssvNetwork.owner = DB.owners[0]; - return { contract: DB.ssvNetwork.contract, owner: DB.ssvNetwork.owner }; + await DB.ssvToken.mint(DB.owners[1].address, '1000000000000000'); + await DB.ssvToken.mint(DB.owners[2].address, '1000000000000000'); + await DB.ssvToken.mint(DB.owners[3].address, '1000000000000000'); + await DB.ssvToken.mint(DB.owners[4].address, '1000000000000000'); + await DB.ssvToken.mint(DB.owners[5].address, '1000000000000000'); + + return { contract: DB.ssvNetwork.contract, owner: DB.ssvNetwork.owner, ssvToken: DB.ssvToken }; }; export const registerOperators = async (ownerId: number, numberOfOperators: number, fee: string, gasGroups: GasGroup[] = [GasGroup.REGISTER_OPERATOR]) => { @@ -95,22 +100,20 @@ export const registerOperators = async (ownerId: number, numberOfOperators: numb } }; -/* -export const deposit = async (ownerIds: number[], amounts: string[]) => { - // for (let i = 0; i < ownerIds.length; ++i) { - // await DB.ssvNetwork.contract.connect(DB.owners[ownerIds[i]]).deposit(amounts[i]); - // } +export const deposit = async (ownerId: number, clusterId: string, amount: string) => { + await DB.ssvToken.connect(DB.owners[ownerId]).approve(DB.ssvNetwork.contract.address, amount); + await DB.ssvNetwork.contract.connect(DB.owners[ownerId])['deposit(bytes32,uint256)'](clusterId, amount); }; -*/ export const registerPodAndDeposit = async(ownerId: number, operatorIds: number[], amount: string): Promise => { let clusterId; try { clusterId = await DB.ssvNetwork.contract.getClusterId(operatorIds); if (+amount > 0) { - await DB.ssvNetwork.contract.connect(DB.owners[ownerId])['deposit(bytes32,uint256)'](clusterId, amount); + await deposit(ownerId, clusterId, amount); } } catch (e) { + await DB.ssvToken.connect(DB.owners[ownerId]).approve(DB.ssvNetwork.contract.address, amount); const clusterTx = await (await DB.ssvNetwork.contract.connect(DB.owners[ownerId]).registerPod(operatorIds, amount)).wait(); clusterId = clusterTx.events[0].args.clusterId; } diff --git a/test/helpers/gas-usage.ts b/test/helpers/gas-usage.ts index 322e4c30..07c03520 100644 --- a/test/helpers/gas-usage.ts +++ b/test/helpers/gas-usage.ts @@ -12,22 +12,31 @@ export enum GasGroup { TRANSFER_VALIDATOR_NON_EXISTING_POD, BULK_TRANSFER_VALIDATOR, BULK_TRANSFER_VALIDATOR_NON_EXISTING_POD, - LIQUIDATE_VALIDATOR, + DEPOSIT, + WITHDRAW, + REGISTER_POD, + LIQUIDATE_POD, + REACTIVATE_POD, } const MAX_GAS_PER_GROUP: any = { + /* REAL GAS LIMITS */ [GasGroup.REGISTER_OPERATOR]: 105000, [GasGroup.REMOVE_OPERATOR]: 45000, - [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]: 202000, - [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]: 220000, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE]: 333000, // 313000 + [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]: 199000, + [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]: 216000, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE]: 313000, [GasGroup.REMOVE_VALIDATOR]: 120000, [GasGroup.TRANSFER_VALIDATOR_NEW_CLUSTER]: 400000, [GasGroup.TRANSFER_VALIDATOR]: 260000, [GasGroup.TRANSFER_VALIDATOR_NON_EXISTING_POD]: 290000, - [GasGroup.BULK_TRANSFER_VALIDATOR]: 362000, - [GasGroup.BULK_TRANSFER_VALIDATOR_NON_EXISTING_POD]: 379000, - [GasGroup.LIQUIDATE_VALIDATOR]: 101000, + [GasGroup.BULK_TRANSFER_VALIDATOR]: 366000, + [GasGroup.BULK_TRANSFER_VALIDATOR_NON_EXISTING_POD]: 383000, + [GasGroup.DEPOSIT]: 77500, + [GasGroup.WITHDRAW]: 102000, + [GasGroup.REGISTER_POD]: 137000, + [GasGroup.LIQUIDATE_POD]: 156000, + [GasGroup.REACTIVATE_POD]: 163000, }; class GasStats { @@ -49,7 +58,6 @@ class GasStats { } } - const gasUsageStats = new Map(); for (const group in MAX_GAS_PER_GROUP) { diff --git a/test/liquidate/liquidate.ts b/test/liquidate/liquidate.ts index df304ebc..30bd720a 100644 --- a/test/liquidate/liquidate.ts +++ b/test/liquidate/liquidate.ts @@ -6,7 +6,7 @@ import { trackGas, GasGroup } from '../helpers/gas-usage'; let ssvNetworkContract: any, clusterResult1: any, minDepositAmount: any; -describe('Transfer Validator Tests', () => { +describe('Liquidate Validator Tests', () => { beforeEach(async () => { // Initialize contract ssvNetworkContract = (await helpers.initializeContract()).contract; @@ -30,6 +30,30 @@ describe('Transfer Validator Tests', () => { await expect(ssvNetworkContract.liquidate(helpers.DB.owners[4].address, clusterResult1.clusterId)).to.emit(ssvNetworkContract, 'PodLiquidated'); }); + it('Liquidate validator with removed operator in a cluster', async () => { + await ssvNetworkContract.removeOperator(1); + await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); // TMP IT FAILS WITH PROGRESS BLOCK, CRITICAL ERROR IN INDEX MATH LOGIC + await trackGas(ssvNetworkContract.liquidate(helpers.DB.owners[4].address, clusterResult1.clusterId), [GasGroup.LIQUIDATE_POD]); + }); + + it('Liquidate and register in disabled pod', async () => { + await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); + await trackGas(ssvNetworkContract.liquidate(helpers.DB.owners[4].address, clusterResult1.clusterId), [GasGroup.LIQUIDATE_POD]); + await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); + await helpers.DB.ssvToken.connect(helpers.DB.owners[4]).approve(ssvNetworkContract.address, minDepositAmount); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4])['deposit(bytes32,uint256)'](clusterResult1.clusterId, minDepositAmount), [GasGroup.DEPOSIT]); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).registerValidator(helpers.DataGenerator.publicKey(9), clusterResult1.clusterId, helpers.DataGenerator.shares(0)), [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]); + }); + + it('Liquidate and register validator in disabled pod', async () => { + await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); + await trackGas(ssvNetworkContract.liquidate(helpers.DB.owners[4].address, clusterResult1.clusterId), [GasGroup.LIQUIDATE_POD]); + await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); + await helpers.DB.ssvToken.connect(helpers.DB.owners[4]).approve(ssvNetworkContract.address, minDepositAmount); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4])['deposit(bytes32,uint256)'](clusterResult1.clusterId, minDepositAmount), [GasGroup.DEPOSIT]); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).registerValidator(helpers.DataGenerator.publicKey(9), clusterResult1.clusterId, helpers.DataGenerator.shares(0)), [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]); + }); + it('Liquidate errors', async () => { await expect(ssvNetworkContract.liquidate(helpers.DB.owners[4].address, clusterResult1.clusterId)).to.be.revertedWith('PodNotLiquidatable'); }); @@ -43,6 +67,6 @@ describe('Transfer Validator Tests', () => { it('Liquidate gas limits', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).liquidate(helpers.DB.owners[4].address, clusterResult1.clusterId), [GasGroup.LIQUIDATE_VALIDATOR]); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).liquidate(helpers.DB.owners[4].address, clusterResult1.clusterId), [GasGroup.LIQUIDATE_POD]); }); }); diff --git a/test/liquidate/reactivate.ts b/test/liquidate/reactivate.ts new file mode 100644 index 00000000..492a3c35 --- /dev/null +++ b/test/liquidate/reactivate.ts @@ -0,0 +1,58 @@ +import * as helpers from '../helpers/contract-helpers'; +import * as utils from '../helpers/utils'; + +import { expect } from 'chai'; +import { trackGas, GasGroup } from '../helpers/gas-usage'; + +let ssvNetworkContract: any, clusterResult1: any, minDepositAmount: any; + +describe('Reactivate Validator Tests', () => { + beforeEach(async () => { + // Initialize contract + ssvNetworkContract = (await helpers.initializeContract()).contract; + + // Register operators + await helpers.registerOperators(0, 12, helpers.CONFIG.minimalOperatorFee); + + minDepositAmount = (helpers.CONFIG.minimalBlocksBeforeLiquidation + 10) * helpers.CONFIG.minimalOperatorFee * 4; + + // Register validators + clusterResult1 = await helpers.registerValidators(4, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + }); + + it('Reactivate emits PodEnabled', async () => { + await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); + await ssvNetworkContract.liquidate(helpers.DB.owners[4].address, clusterResult1.clusterId); + await helpers.DB.ssvToken.connect(helpers.DB.owners[4]).approve(ssvNetworkContract.address, minDepositAmount); + + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).reactivatePod(clusterResult1.clusterId, minDepositAmount)).to.emit(ssvNetworkContract, 'PodEnabled'); + }); + + it('Reactivate returns error - PodAlreadyEnabled', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).reactivatePod(clusterResult1.clusterId, minDepositAmount)).to.be.revertedWith('PodAlreadyEnabled'); + }); + + it('Reactivate returns error - NegativeBalance', async () => { + await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); + await ssvNetworkContract.liquidate(helpers.DB.owners[4].address, clusterResult1.clusterId); + await helpers.DB.ssvToken.connect(helpers.DB.owners[4]).approve(ssvNetworkContract.address, helpers.CONFIG.minimalOperatorFee * 4); + + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).reactivatePod(clusterResult1.clusterId, helpers.CONFIG.minimalOperatorFee * 4)).to.be.revertedWith('NegativeBalance'); + }); + + it('Reactivate with removed operator in a cluster', async () => { + await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); + await ssvNetworkContract.liquidate(helpers.DB.owners[4].address, clusterResult1.clusterId); + await ssvNetworkContract.removeOperator(1); + await helpers.DB.ssvToken.connect(helpers.DB.owners[4]).approve(ssvNetworkContract.address, minDepositAmount); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).reactivatePod(clusterResult1.clusterId, minDepositAmount), [GasGroup.REACTIVATE_POD]); + }); + + it('Reactivate gas limits', async () => { + await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); + await ssvNetworkContract.liquidate(helpers.DB.owners[4].address, clusterResult1.clusterId); + await helpers.DB.ssvToken.connect(helpers.DB.owners[4]).approve(ssvNetworkContract.address, minDepositAmount); + + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).reactivatePod(clusterResult1.clusterId, minDepositAmount), [GasGroup.REACTIVATE_POD]); + }); +}); diff --git a/test/operators/fee.ts b/test/operators/fee.ts index 761363f5..c4024cac 100644 --- a/test/operators/fee.ts +++ b/test/operators/fee.ts @@ -31,6 +31,16 @@ describe('Operator Fee Tests', () => { .to.be.revertedWith('CallerNotOwner'); }); + it('Declare fee fails no owner', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).declareOperatorFee(1, initialFee + initialFee / 10 )) + .to.be.revertedWith('CallerNotOwner'); + }); + + it('Declare fee fails no operator with public key', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).declareOperatorFee(12, initialFee + initialFee / 10 )) + .to.be.revertedWith('OperatorWithPublicKeyNotExist'); + }); + it('Declare fee fails fee too low', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[2]).declareOperatorFee(1, helpers.CONFIG.minimalOperatorFee - 1)) .to.be.revertedWith('FeeTooLow'); @@ -163,4 +173,8 @@ describe('Operator Fee Tests', () => { expect(await ssvNetworkContract.getOperatorFee(1)).to.equal(initialFee); }); + it('Get fee returns error - OperatorNotFound', async () => { + await expect(ssvNetworkContract.getOperatorFee(12)).to.be.revertedWith('OperatorNotFound'); + }); + }); diff --git a/test/validators/register.ts b/test/validators/register.ts index 83d3065c..d7f2b3ef 100644 --- a/test/validators/register.ts +++ b/test/validators/register.ts @@ -1,7 +1,8 @@ import * as helpers from '../helpers/contract-helpers'; +import * as utils from '../helpers/utils'; import { expect } from 'chai'; -import { GasGroup } from '../helpers/gas-usage'; +import { trackGas, GasGroup } from '../helpers/gas-usage'; let ssvNetworkContract: any, clusterResult: any, minDepositAmount: any; @@ -19,6 +20,26 @@ describe('Register Validator Tests', () => { clusterResult = await helpers.registerValidators(0, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); }); + it('Register new pod emits PodCreated event', async () => { + await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); + await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).registerPod(helpers.DataGenerator.cluster.new(), minDepositAmount)).to.emit(ssvNetworkContract, 'PodCreated'); + }); + + it('Register new pod with new cluster gas limit', async () => { + await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerPod(helpers.DataGenerator.cluster.new(), minDepositAmount), [GasGroup.REGISTER_POD]); + }); + + it('Register new pod in existed cluster gas limit', async () => { + await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerPod(helpers.DataGenerator.cluster.byId(clusterResult.clusterId), minDepositAmount), [GasGroup.REGISTER_POD]); + }); + + it('Register pod does not happen (existed already), just deposit', async () => { + await helpers.DB.ssvToken.approve(ssvNetworkContract.address, minDepositAmount); + await trackGas(ssvNetworkContract.registerPod(helpers.DataGenerator.cluster.byId(clusterResult.clusterId), minDepositAmount), [GasGroup.REGISTER_POD]); + }); + it('Register validator emits ValidatorAdded event', async () => { // register validator using cluster Id await expect(ssvNetworkContract.registerValidator( @@ -28,6 +49,14 @@ describe('Register Validator Tests', () => { )).to.emit(ssvNetworkContract, 'ValidatorAdded'); }); + it('Register validator with removed operator in a cluster', async () => { + await ssvNetworkContract.removeOperator(1); + await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); // TMP IT FAILS WITH PROGRESS BLOCK, CRITICAL ERROR IN INDEX MATH LOGIC + await helpers.DB.ssvToken.connect(helpers.DB.owners[4]).approve(ssvNetworkContract.address, minDepositAmount); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4])['deposit(bytes32,uint256)'](clusterResult.clusterId, minDepositAmount), [GasGroup.DEPOSIT]); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).registerValidator(helpers.DataGenerator.publicKey(9), clusterResult.clusterId, helpers.DataGenerator.shares(0)), [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]); + }); + it('Register one validator into an empty cluster', async () => { await helpers.registerValidators(0, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); }); @@ -40,12 +69,19 @@ describe('Register Validator Tests', () => { await helpers.registerValidators(1, 1, `${minDepositAmount * 2}`, helpers.DataGenerator.cluster.byId(clusterResult.clusterId), [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]); }); + it('Register pod returns error - The operators list should be in ascending order', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).registerPod([3,2,1,4], minDepositAmount)).to.be.revertedWith('The operators list should be in ascending order'); + }); + it('Invalid operator amount', async () => { // 2 Operators await expect(helpers.registerPodAndDeposit(0, [1, 2], minDepositAmount)).to.be.revertedWith('OperatorIdsStructureInvalid'); // 6 Operators await expect(helpers.registerPodAndDeposit(0, [1, 2, 3, 4, 5, 6], minDepositAmount)).to.be.revertedWith('OperatorIdsStructureInvalid'); + + // 14 Operators + await expect(helpers.registerPodAndDeposit(0, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], minDepositAmount)).to.be.revertedWith('OperatorIdsStructureInvalid'); }); it('Invalid public key length', async () => { diff --git a/test/validators/remove.ts b/test/validators/remove.ts index 24d60b7b..025e11fe 100644 --- a/test/validators/remove.ts +++ b/test/validators/remove.ts @@ -1,4 +1,5 @@ import * as helpers from '../helpers/contract-helpers'; +import * as utils from '../helpers/utils'; import { expect } from 'chai'; import { trackGas, GasGroup } from '../helpers/gas-usage'; @@ -25,7 +26,12 @@ describe('Remove Validator Tests', () => { )).to.emit(ssvNetworkContract, 'ValidatorRemoved'); }); - it('Remove validator', async () => { + it('Remove validator track gas', async () => { + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator(clusterResult.validators[0].publicKey), [GasGroup.REMOVE_VALIDATOR]); + }); + + it('Remove validator with removed operator in a cluster', async () => { + await trackGas(ssvNetworkContract.removeOperator(1), [GasGroup.REMOVE_OPERATOR]); await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator(clusterResult.validators[0].publicKey), [GasGroup.REMOVE_VALIDATOR]); }); diff --git a/test/validators/transfer-bulk.ts b/test/validators/transfer-bulk.ts index 5a5827ba..8b86cc4e 100644 --- a/test/validators/transfer-bulk.ts +++ b/test/validators/transfer-bulk.ts @@ -11,8 +11,7 @@ describe('Bulk Transfer Validator Tests', () => { ssvNetworkContract = (await helpers.initializeContract()).contract; // Register operators - await helpers.registerOperators(0, 12, helpers.CONFIG.minimalOperatorFee); - await helpers.registerOperators(0, 1, helpers.CONFIG.minimalOperatorFee); + await helpers.registerOperators(0, 15, helpers.CONFIG.minimalOperatorFee); minDepositAmount = (helpers.CONFIG.minimalBlocksBeforeLiquidation + 2) * helpers.CONFIG.minimalOperatorFee * 4; diff --git a/test/validators/transfer.ts b/test/validators/transfer.ts index 666e43d4..b6f04623 100644 --- a/test/validators/transfer.ts +++ b/test/validators/transfer.ts @@ -1,9 +1,10 @@ import * as helpers from '../helpers/contract-helpers'; +import * as utils from '../helpers/utils'; import { expect } from 'chai'; import { GasGroup } from '../helpers/gas-usage'; -let ssvNetworkContract: any, clusterResult1: any, clusterResult2: any, minDepositAmount: any; +let ssvNetworkContract: any, clusterResult1: any, clusterResult2: any, minDepositAmount: any, clusters: any; describe('Transfer Validator Tests', () => { beforeEach(async () => { @@ -11,13 +12,18 @@ describe('Transfer Validator Tests', () => { ssvNetworkContract = (await helpers.initializeContract()).contract; // Register operators - await helpers.registerOperators(0, 12, helpers.CONFIG.minimalOperatorFee); + await helpers.registerOperators(0, 15, helpers.CONFIG.minimalOperatorFee); - minDepositAmount = helpers.CONFIG.minimalBlocksBeforeLiquidation * helpers.CONFIG.minimalOperatorFee * 4; + minDepositAmount = helpers.CONFIG.minimalBlocksBeforeLiquidation * helpers.CONFIG.minimalOperatorFee * 5; + + clusters = {}; // Register validators - clusterResult1 = await helpers.registerValidators(4, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); - clusterResult2 = await helpers.registerValidators(4, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + clusters.one = helpers.DataGenerator.cluster.new(); + clusterResult1 = await helpers.registerValidators(4, 1, minDepositAmount, clusters.one, [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + clusters.two = helpers.DataGenerator.cluster.new(); + clusterResult2 = await helpers.registerValidators(4, 1, minDepositAmount, clusters.two, [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + clusters.three = helpers.DataGenerator.cluster.new(); }); it('Transfer validator emits ValidatorTransferred event', async () => { @@ -28,8 +34,13 @@ describe('Transfer Validator Tests', () => { )).to.emit(ssvNetworkContract, 'ValidatorTransferred'); }); - it('Transfer validator into a new cluster', async () => { - await helpers.transferValidator(4, clusterResult1.validators[0].publicKey, helpers.DataGenerator.cluster.new(), minDepositAmount, [GasGroup.TRANSFER_VALIDATOR_NEW_CLUSTER]); + it('Transfer validator into a new cluster A-Z', async () => { + await helpers.transferValidator(4, clusterResult2.validators[0].publicKey, clusters.three, minDepositAmount, [GasGroup.TRANSFER_VALIDATOR_NEW_CLUSTER]); + }); + + it('Transfer validator into a new cluster Z-A', async () => { + const cluster = await helpers.registerValidators(4, 1, minDepositAmount, clusters.three, [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + await helpers.transferValidator(4, cluster.validators[0].publicKey, clusters.one, minDepositAmount, [GasGroup.TRANSFER_VALIDATOR_NEW_CLUSTER]); }); it('Transfer validator with an invalid owner', async () => { @@ -76,7 +87,7 @@ describe('Transfer Validator Tests', () => { // GOING ABOVE GAS LIMIT it('Transfer validator to an existing cluster', async () => { // Register validator with different user - const clusterResult3 = await helpers.registerValidators(5, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + const clusterResult3 = await helpers.registerValidators(5, 1, minDepositAmount, clusters.one, [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); // Transfer validator await helpers.transferValidator(4, clusterResult1.validators[0].publicKey, helpers.DataGenerator.cluster.byId(clusterResult3.clusterId), `${minDepositAmount * 2}`, [GasGroup.TRANSFER_VALIDATOR_NON_EXISTING_POD]); @@ -84,6 +95,32 @@ describe('Transfer Validator Tests', () => { // expect(clusterResult3.clusterId).equals(transfredValidator1.eventsByName.ValidatorTransferred[0].args.podId); }); + it('Transfer validator with removed operator in old cluster A-Z', async () => { + await ssvNetworkContract.removeOperator(helpers.DataGenerator.cluster.byId(clusterResult1.clusterId)[0]); + await helpers.transferValidator(4, clusterResult1.validators[0].publicKey, helpers.DataGenerator.cluster.byId(clusterResult2.clusterId), `${minDepositAmount * 2}`, [GasGroup.TRANSFER_VALIDATOR]); + }); + + it('Transfer validator with removed operator in new cluster A-Z', async () => { + await ssvNetworkContract.removeOperator(helpers.DataGenerator.cluster.byId(clusterResult2.clusterId)[0]); + await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); // TMP IT FAILS WITH PROGRESS BLOCK, CRITICAL ERROR IN INDEX MATH LOGIC + await helpers.transferValidator(4, clusterResult1.validators[0].publicKey, helpers.DataGenerator.cluster.byId(clusterResult2.clusterId), `${minDepositAmount * 2}`, [GasGroup.TRANSFER_VALIDATOR]); + }); + + it('Transfer validator with removed operator in old cluster Z-A', async () => { + const cluster = await helpers.registerValidators(4, 1, minDepositAmount, clusters.three, [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + await ssvNetworkContract.removeOperator(clusters.three[0]); + await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); // TMP IT FAILS WITH PROGRESS BLOCK, CRITICAL ERROR IN INDEX MATH LOGIC + await helpers.transferValidator(4, cluster.validators[0].publicKey, clusters.one, `${minDepositAmount * 2}`, [GasGroup.TRANSFER_VALIDATOR_NEW_CLUSTER]); + }); + + it('Transfer validator with removed operator in new cluster Z-A', async () => { + const cluster = await helpers.registerValidators(4, 1, minDepositAmount, clusters.three, [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + await ssvNetworkContract.removeOperator(clusters.one[0]); + await helpers.transferValidator(4, cluster.validators[0].publicKey, clusters.one, minDepositAmount, [GasGroup.TRANSFER_VALIDATOR_NEW_CLUSTER]); + }); + + + // TODO: fix after connecting the token it('Transfer validator with not enough balance', async () => { // await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( From eb682fe4cdc137bef584d0fe55cd205b834dddcb Mon Sep 17 00:00:00 2001 From: Wadym Date: Mon, 14 Nov 2022 16:19:35 +0100 Subject: [PATCH 095/149] core and tests changes for register validator (#112) * core and tests changes for register validator * add getPod func * fix tests * remove ClusterNotExists error from getPod * minor changes Co-authored-by: Vadim --- contracts/ISSVNetwork.sol | 4 +++ contracts/SSVNetwork.sol | 21 +++++++++++++--- test/account/deposit.ts | 4 +-- test/account/withdraw.ts | 12 ++++----- test/helpers/contract-helpers.ts | 10 ++++---- test/liquidate/reactivate.ts | 4 +-- test/operators/fee.ts | 2 +- test/validators/register.ts | 43 +++++++++++++++++++++++--------- 8 files changed, 69 insertions(+), 31 deletions(-) diff --git a/contracts/ISSVNetwork.sol b/contracts/ISSVNetwork.sol index f01701c0..27cf7d4c 100644 --- a/contracts/ISSVNetwork.sol +++ b/contracts/ISSVNetwork.sol @@ -157,6 +157,8 @@ interface ISSVNetwork { error ClusterAlreadyExists(); error ClusterNotExists(); error PodAlreadyEnabled(); + error PodAlreadyExists(); + error PodNotExists(); error BurnRatePositive(); /****************/ @@ -297,6 +299,8 @@ interface ISSVNetwork { function getClusterId(uint64[] memory operatorIds) external view returns(bytes32); + function getPod(uint64[] memory operatorIds) external view returns(bytes32); + function isLiquidatable(address ownerAddress, bytes32 clusterId) external view returns(bool); function isLiquidated(address ownerAddress, bytes32 clusterId) external view returns(bool); diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index 39820677..1b38c04b 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -459,11 +459,14 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { bytes32 hashedPod = keccak256(abi.encodePacked(msg.sender, clusterId)); - if (_pods[hashedPod].usage.block == 0) { - _pods[hashedPod].usage.block = uint64(block.number); - emit PodCreated(msg.sender, clusterId); + if (_pods[hashedPod].usage.block != 0) { + revert PodAlreadyExists(); } + _pods[hashedPod].usage.block = uint64(block.number); + + emit PodCreated(msg.sender, clusterId); + _deposit(msg.sender, clusterId, amount.shrink()); } @@ -724,6 +727,18 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { return clusterId; } + function getPod(uint64[] memory operatorIds) external view override returns(bytes32) { + _validateOperatorIds(operatorIds); + + bytes32 clusterId = keccak256(abi.encodePacked(operatorIds)); + + if (_pods[keccak256(abi.encodePacked(msg.sender, clusterId))].usage.block == 0) { + revert PodNotExists(); + } + + return clusterId; + } + function isLiquidatable(address ownerAddress, bytes32 clusterId) external view override returns (bool) { _validateClusterId(clusterId); diff --git a/test/account/deposit.ts b/test/account/deposit.ts index 1857e962..215487ae 100644 --- a/test/account/deposit.ts +++ b/test/account/deposit.ts @@ -29,11 +29,11 @@ describe('Deposit Tests', () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['deposit(address,bytes32,uint256)'](helpers.DB.owners[1].address, clusterResult1.clusterId, minDepositAmount)).to.emit(ssvNetworkContract, 'FundsDeposit'); }); - it('Deposit as owner returns error - ClusterNotExists', async () => { + it('Deposit as owner returns an error - ClusterNotExists', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[1])['deposit(bytes32,uint256)']('0x392791df626408017a264f53fde61065d5a93a32b60171df9d8a46afdf82992c', minDepositAmount)).to.be.revertedWith('ClusterNotExists'); }); - it('Deposit as non-owner returns error - ClusterNotExists', async () => { + it('Deposit as non-owner returns an error - ClusterNotExists', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['deposit(address,bytes32,uint256)'](helpers.DB.owners[1].address, '0x392791df626408017a264f53fde61065d5a93a32b60171df9d8a46afdf82992c', minDepositAmount)).to.be.revertedWith('ClusterNotExists'); }); diff --git a/test/account/withdraw.ts b/test/account/withdraw.ts index 8e1e96a5..04895502 100644 --- a/test/account/withdraw.ts +++ b/test/account/withdraw.ts @@ -24,11 +24,11 @@ describe('Withdraw Tests', () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).withdrawPodBalance(clusterResult1.clusterId, helpers.CONFIG.minimalOperatorFee)).to.emit(ssvNetworkContract, 'PodFundsWithdrawal'); }); - it('Withdraw pod balance returns error - NotEnoughBalance', async () => { + it('Withdraw pod balance returns an error - NotEnoughBalance', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).withdrawPodBalance(clusterResult1.clusterId, minDepositAmount)).to.be.revertedWith('NotEnoughBalance'); }); - it('Withdraw balance of liquidatable pod returns error - NotEnoughBalance', async () => { + it('Withdraw balance of liquidatable pod returns an error - NotEnoughBalance', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).withdrawPodBalance(clusterResult1.clusterId, helpers.CONFIG.minimalOperatorFee)).to.be.revertedWith('NotEnoughBalance'); }); @@ -49,19 +49,19 @@ describe('Withdraw Tests', () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorBalance(uint64,uint256)'](1, helpers.CONFIG.minimalOperatorFee)).to.emit(ssvNetworkContract, 'OperatorFundsWithdrawal'); }); - it('Withdraw operator balance returns error - CallerNotOwner', async () => { + it('Withdraw operator balance returns an error - CallerNotOwner', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[2])['withdrawOperatorBalance(uint64,uint256)'](1, minDepositAmount)).to.be.revertedWith('CallerNotOwner'); }); - it('Withdraw operator balance returns error - NotEnoughBalance', async () => { + it('Withdraw operator balance returns an error - NotEnoughBalance', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorBalance(uint64,uint256)'](1, minDepositAmount)).to.be.revertedWith('NotEnoughBalance'); }); - it('Withdraw total operator balance returns error - CallerNotOwner', async () => { + it('Withdraw total operator balance returns an error - CallerNotOwner', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[2])['withdrawOperatorBalance(uint64)'](12)).to.be.revertedWith('CallerNotOwner'); }); - it('Withdraw total operator balance returns error - NotEnoughBalance', async () => { + it('Withdraw total operator balance returns an error - NotEnoughBalance', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorBalance(uint64)'](12)).to.be.revertedWith('NotEnoughBalance'); }); diff --git a/test/helpers/contract-helpers.ts b/test/helpers/contract-helpers.ts index 79964775..76c100b4 100644 --- a/test/helpers/contract-helpers.ts +++ b/test/helpers/contract-helpers.ts @@ -108,14 +108,14 @@ export const deposit = async (ownerId: number, clusterId: string, amount: string export const registerPodAndDeposit = async(ownerId: number, operatorIds: number[], amount: string): Promise => { let clusterId; try { + await DB.ssvToken.connect(DB.owners[ownerId]).approve(DB.ssvNetwork.contract.address, amount); + const clusterTx = await (await DB.ssvNetwork.contract.connect(DB.owners[ownerId]).registerPod(operatorIds, amount)).wait(); + clusterId = clusterTx.events[0].args.clusterId; + } catch (e) { clusterId = await DB.ssvNetwork.contract.getClusterId(operatorIds); if (+amount > 0) { await deposit(ownerId, clusterId, amount); } - } catch (e) { - await DB.ssvToken.connect(DB.owners[ownerId]).approve(DB.ssvNetwork.contract.address, amount); - const clusterTx = await (await DB.ssvNetwork.contract.connect(DB.owners[ownerId]).registerPod(operatorIds, amount)).wait(); - clusterId = clusterTx.events[0].args.clusterId; } return { clusterId }; }; @@ -189,7 +189,7 @@ export const bulkTransferValidator = async (ownerId: number, publicKey: string[] export const liquidate = async (executorOwnerId: number, liquidatedOwnerId: number, operatorIds: number[], gasGroups?: GasGroup[]) => { const { eventsByName } = await trackGas(DB.ssvNetwork.contract.connect(DB.owners[executorOwnerId]).liquidate( DB.owners[liquidatedOwnerId].address, - await DB.ssvNetwork.contract.getClusterId(operatorIds), + await DB.ssvNetwork.contract.getPod(operatorIds), ), gasGroups); const clusterId = eventsByName.AccountLiquidated[0].args.clusterId; diff --git a/test/liquidate/reactivate.ts b/test/liquidate/reactivate.ts index 492a3c35..94beb4aa 100644 --- a/test/liquidate/reactivate.ts +++ b/test/liquidate/reactivate.ts @@ -28,11 +28,11 @@ describe('Reactivate Validator Tests', () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).reactivatePod(clusterResult1.clusterId, minDepositAmount)).to.emit(ssvNetworkContract, 'PodEnabled'); }); - it('Reactivate returns error - PodAlreadyEnabled', async () => { + it('Reactivate returns an error - PodAlreadyEnabled', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).reactivatePod(clusterResult1.clusterId, minDepositAmount)).to.be.revertedWith('PodAlreadyEnabled'); }); - it('Reactivate returns error - NegativeBalance', async () => { + it('Reactivate returns an error - NegativeBalance', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); await ssvNetworkContract.liquidate(helpers.DB.owners[4].address, clusterResult1.clusterId); await helpers.DB.ssvToken.connect(helpers.DB.owners[4]).approve(ssvNetworkContract.address, helpers.CONFIG.minimalOperatorFee * 4); diff --git a/test/operators/fee.ts b/test/operators/fee.ts index c4024cac..031e8de3 100644 --- a/test/operators/fee.ts +++ b/test/operators/fee.ts @@ -173,7 +173,7 @@ describe('Operator Fee Tests', () => { expect(await ssvNetworkContract.getOperatorFee(1)).to.equal(initialFee); }); - it('Get fee returns error - OperatorNotFound', async () => { + it('Get fee returns an error - OperatorNotFound', async () => { await expect(ssvNetworkContract.getOperatorFee(12)).to.be.revertedWith('OperatorNotFound'); }); diff --git a/test/validators/register.ts b/test/validators/register.ts index d7f2b3ef..0511a92a 100644 --- a/test/validators/register.ts +++ b/test/validators/register.ts @@ -35,9 +35,24 @@ describe('Register Validator Tests', () => { await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerPod(helpers.DataGenerator.cluster.byId(clusterResult.clusterId), minDepositAmount), [GasGroup.REGISTER_POD]); }); - it('Register pod does not happen (existed already), just deposit', async () => { - await helpers.DB.ssvToken.approve(ssvNetworkContract.address, minDepositAmount); - await trackGas(ssvNetworkContract.registerPod(helpers.DataGenerator.cluster.byId(clusterResult.clusterId), minDepositAmount), [GasGroup.REGISTER_POD]); + it('Register pod returns an error - PodAlreadyExists', async () => { + await expect(ssvNetworkContract.registerPod(helpers.DataGenerator.cluster.byId(clusterResult.clusterId), 0)).to.be.revertedWith('PodAlreadyExists'); + }); + + it('Get cluster id returns an error - ClusterNotExists', async () => { + await expect(ssvNetworkContract.getClusterId([5,6,7,8])).to.be.revertedWith('ClusterNotExists'); + }); + + it('Get pod returns an error - PoNotExists', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).getPod(helpers.DataGenerator.cluster.byId(clusterResult.clusterId))).to.be.revertedWith('PodNotExists'); + }); + + it('Get pod returns a cluster id', async () => { + expect(await ssvNetworkContract.getPod(helpers.DataGenerator.cluster.byId(clusterResult.clusterId))).to.equal(clusterResult.clusterId); + }); + + it('Register pod returns an error - OperatorDoesNotExist', async () => { + await expect(ssvNetworkContract.registerPod([1, 2, 3, 25], minDepositAmount)).to.be.revertedWith('OperatorDoesNotExist'); }); it('Register validator emits ValidatorAdded event', async () => { @@ -62,14 +77,14 @@ describe('Register Validator Tests', () => { }); it('Register two validators in the same pod', async () => { - await helpers.registerValidators(0, 1, minDepositAmount, helpers.DataGenerator.cluster.byId(clusterResult.clusterId), [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]); + await helpers.registerValidators(0, 1, `${minDepositAmount * 2}`, helpers.DataGenerator.cluster.byId(clusterResult.clusterId), [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]); }); it('Register two validators into an existing cluster', async () => { await helpers.registerValidators(1, 1, `${minDepositAmount * 2}`, helpers.DataGenerator.cluster.byId(clusterResult.clusterId), [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]); }); - it('Register pod returns error - The operators list should be in ascending order', async () => { + it('Register pod returns an error - The operators list should be in ascending order', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).registerPod([3,2,1,4], minDepositAmount)).to.be.revertedWith('The operators list should be in ascending order'); }); @@ -84,7 +99,7 @@ describe('Register Validator Tests', () => { await expect(helpers.registerPodAndDeposit(0, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], minDepositAmount)).to.be.revertedWith('OperatorIdsStructureInvalid'); }); - it('Invalid public key length', async () => { + it('Register validator returns an error - InvalidPublicKeyLength', async () => { await expect(ssvNetworkContract.registerValidator( helpers.DataGenerator.shares(0), (await helpers.registerPodAndDeposit(0, helpers.DataGenerator.cluster.new(), minDepositAmount)).clusterId, @@ -92,7 +107,7 @@ describe('Register Validator Tests', () => { )).to.be.revertedWith('InvalidPublicKeyLength'); }); - it('Not enough amount', async () => { + it('Register validator returns an error - NotEnoughBalance', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( helpers.DataGenerator.publicKey(1), (await helpers.registerPodAndDeposit(0, helpers.DataGenerator.cluster.new(), '0')).clusterId, @@ -100,11 +115,7 @@ describe('Register Validator Tests', () => { )).to.be.revertedWith('NotEnoughBalance'); }); - it('Non existent operator', async () => { - await expect(helpers.registerPodAndDeposit(0, [1, 2, 3, 25], minDepositAmount)).to.be.revertedWith('OperatorDoesNotExist'); - }); - - it('Register with existing validator', async () => { + it('Register validator returns an error - ValidatorAlreadyExists', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( helpers.DataGenerator.publicKey(0), (await helpers.registerPodAndDeposit(1, [1, 2, 3, 4], minDepositAmount)).clusterId, @@ -112,6 +123,14 @@ describe('Register Validator Tests', () => { )).to.be.revertedWith('ValidatorAlreadyExists'); }); + it('Register validator returns an error - ClusterNotExists', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( + helpers.DataGenerator.publicKey(0), + clusterResult.clusterId.replace(/.$/,'0'), + helpers.DataGenerator.shares(0), + )).to.be.revertedWith('ClusterNotExists'); + }); + // ABOVE GAS LIMIT it('Register with 7 operators', async () => { // await helpers.registerValidators(0, 1, '10000', helpers.DataGenerator.cluster.new(7), [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]); From 47c00d1196a5908d4341b5a33b227d40ef096bbd Mon Sep 17 00:00:00 2001 From: Wadym Date: Tue, 15 Nov 2022 11:04:56 +0100 Subject: [PATCH 096/149] remove operator with withdraw (#117) Co-authored-by: Vadim --- contracts/SSVNetwork.sol | 21 ++++++++++++--------- test/helpers/gas-usage.ts | 2 ++ test/operators/remove.ts | 12 ++++++++++++ test/validators/remove.ts | 3 +-- 4 files changed, 27 insertions(+), 11 deletions(-) diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index 1b38c04b..87f95ec4 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -178,7 +178,11 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { Operator memory operator = _operators[operatorId]; if (operator.owner != msg.sender) revert CallerNotOwner(); - // TODO withdraw remaining balance before delete + operator.snapshot = _getSnapshot(operator, uint64(block.number)); + + if (operator.snapshot.balance > 0) { + _transferOperatorBalanceUnsafe(operatorId, operator.snapshot.balance.expand()); + } delete _operators[operatorId]; emit OperatorRemoved(operatorId); @@ -588,9 +592,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _operators[operatorId] = operator; - _token.transfer(msg.sender, shrunkAmount); - - emit OperatorFundsWithdrawal(amount.shrink(), operatorId, msg.sender); + _transferOperatorBalanceUnsafe(operatorId, amount); } function withdrawOperatorBalance(uint64 operatorId) external override { @@ -610,11 +612,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _operators[operatorId] = operator; - uint256 expandedOperatorBalance = operatorBalance.expand(); - - _token.transfer(msg.sender, expandedOperatorBalance); - - emit OperatorFundsWithdrawal(expandedOperatorBalance, operatorId, msg.sender); + _transferOperatorBalanceUnsafe(operatorId, operatorBalance.expand()); } function withdrawPodBalance(bytes32 clusterId, uint256 amount) external override { @@ -913,6 +911,11 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { return operator.snapshot; } + function _transferOperatorBalanceUnsafe(uint64 operatorId, uint256 amount) private { + _token.transfer(msg.sender, amount); + emit OperatorFundsWithdrawal(amount, operatorId, msg.sender); + } + /*************************/ /* Pod Private Functions */ /*************************/ diff --git a/test/helpers/gas-usage.ts b/test/helpers/gas-usage.ts index 07c03520..e31290f8 100644 --- a/test/helpers/gas-usage.ts +++ b/test/helpers/gas-usage.ts @@ -3,6 +3,7 @@ import { expect } from 'chai'; export enum GasGroup { REGISTER_OPERATOR, REMOVE_OPERATOR, + REMOVE_OPERATOR_WITH_WITHDRAW, REGISTER_VALIDATOR_EXISTING_POD, REGISTER_VALIDATOR_EXISTING_CLUSTER, REGISTER_VALIDATOR_NEW_STATE, @@ -23,6 +24,7 @@ const MAX_GAS_PER_GROUP: any = { /* REAL GAS LIMITS */ [GasGroup.REGISTER_OPERATOR]: 105000, [GasGroup.REMOVE_OPERATOR]: 45000, + [GasGroup.REMOVE_OPERATOR_WITH_WITHDRAW]: 52000, [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]: 199000, [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]: 216000, [GasGroup.REGISTER_VALIDATOR_NEW_STATE]: 313000, diff --git a/test/operators/remove.ts b/test/operators/remove.ts index ed12f1f3..3e63e44d 100644 --- a/test/operators/remove.ts +++ b/test/operators/remove.ts @@ -1,4 +1,5 @@ import * as helpers from '../helpers/contract-helpers'; +import * as utils from '../helpers/utils'; import { expect } from 'chai'; import { trackGas, GasGroup } from '../helpers/gas-usage'; @@ -27,4 +28,15 @@ describe('Remove Operator Tests', () => { await trackGas(ssvNetworkContract.removeOperator(1), [GasGroup.REMOVE_OPERATOR]); }); + it('Remove operator with withdraw emits OperatorFundsWithdrawal event', async () => { + await helpers.registerOperators(0, 4, helpers.CONFIG.minimalOperatorFee); + await helpers.registerValidators(4, 1, `${helpers.CONFIG.minimalBlocksBeforeLiquidation * helpers.CONFIG.minimalOperatorFee * 4}`, [1,2,3,4], [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + await expect(ssvNetworkContract.removeOperator(1)).to.emit(ssvNetworkContract, 'OperatorFundsWithdrawal'); + }); + + it('Remove operator with withdraw gas limits', async () => { + await helpers.registerOperators(0, 4, helpers.CONFIG.minimalOperatorFee); + await helpers.registerValidators(4, 1, `${helpers.CONFIG.minimalBlocksBeforeLiquidation * helpers.CONFIG.minimalOperatorFee * 4}`, [1,2,3,4], [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + await trackGas(ssvNetworkContract.removeOperator(1), [GasGroup.REMOVE_OPERATOR_WITH_WITHDRAW]); + }); }); diff --git a/test/validators/remove.ts b/test/validators/remove.ts index 025e11fe..770a9d00 100644 --- a/test/validators/remove.ts +++ b/test/validators/remove.ts @@ -1,5 +1,4 @@ import * as helpers from '../helpers/contract-helpers'; -import * as utils from '../helpers/utils'; import { expect } from 'chai'; import { trackGas, GasGroup } from '../helpers/gas-usage'; @@ -31,7 +30,7 @@ describe('Remove Validator Tests', () => { }); it('Remove validator with removed operator in a cluster', async () => { - await trackGas(ssvNetworkContract.removeOperator(1), [GasGroup.REMOVE_OPERATOR]); + await trackGas(ssvNetworkContract.removeOperator(1), [GasGroup.REMOVE_OPERATOR_WITH_WITHDRAW]); await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator(clusterResult.validators[0].publicKey), [GasGroup.REMOVE_VALIDATOR]); }); From cd8330d67b52fe3b75684ae19c8b71bdbc6c33bc Mon Sep 17 00:00:00 2001 From: Or-blox <117833150+Or-blox@users.noreply.github.com> Date: Tue, 29 Nov 2022 14:05:57 +0200 Subject: [PATCH 097/149] Or-update liquidate test names * Change test names in liquidate and reactive files * more changes * Liquidate - tests in order * Liquidate is done * Liquidate is done_2 --- test/liquidate/liquidate.ts | 57 ++++++++++++++++-------------------- test/liquidate/reactivate.ts | 41 +++++++++++++------------- 2 files changed, 46 insertions(+), 52 deletions(-) diff --git a/test/liquidate/liquidate.ts b/test/liquidate/liquidate.ts index 30bd720a..8c3f8682 100644 --- a/test/liquidate/liquidate.ts +++ b/test/liquidate/liquidate.ts @@ -1,12 +1,13 @@ +// Decalre imports import * as helpers from '../helpers/contract-helpers'; import * as utils from '../helpers/utils'; - import { expect } from 'chai'; import { trackGas, GasGroup } from '../helpers/gas-usage'; +// Declare globals let ssvNetworkContract: any, clusterResult1: any, minDepositAmount: any; -describe('Liquidate Validator Tests', () => { +describe('Liquidate Tests', () => { beforeEach(async () => { // Initialize contract ssvNetworkContract = (await helpers.initializeContract()).contract; @@ -20,23 +21,35 @@ describe('Liquidate Validator Tests', () => { clusterResult1 = await helpers.registerValidators(4, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); }); - it('Liquidatable', async () => { + it('Liquidate a pod emits "PodLiquidated"', async () => { + await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); + await expect(ssvNetworkContract.liquidate(helpers.DB.owners[4].address, clusterResult1.clusterId + )).to.emit(ssvNetworkContract, 'PodLiquidated'); + }); + + it('Liquidate a pod gas limits', async () => { + await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).liquidate(helpers.DB.owners[4].address, clusterResult1.clusterId), [GasGroup.LIQUIDATE_POD]); + }); + + it('Get if the pod is liquidatable', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); expect(await ssvNetworkContract.isLiquidatable(helpers.DB.owners[4].address, clusterResult1.clusterId)).to.equal(true); }); - it('Liquidate emits PodLiquidated event', async () => { + it('Get if the pod is liquidated', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - await expect(ssvNetworkContract.liquidate(helpers.DB.owners[4].address, clusterResult1.clusterId)).to.emit(ssvNetworkContract, 'PodLiquidated'); + await ssvNetworkContract.liquidate(helpers.DB.owners[4].address, clusterResult1.clusterId); + expect(await ssvNetworkContract.isLiquidated(helpers.DB.owners[4].address, clusterResult1.clusterId)).to.equal(true); }); - it('Liquidate validator with removed operator in a cluster', async () => { + it('Liquidate validator with a removed operator in a cluster', async () => { await ssvNetworkContract.removeOperator(1); await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); // TMP IT FAILS WITH PROGRESS BLOCK, CRITICAL ERROR IN INDEX MATH LOGIC await trackGas(ssvNetworkContract.liquidate(helpers.DB.owners[4].address, clusterResult1.clusterId), [GasGroup.LIQUIDATE_POD]); }); - it('Liquidate and register in disabled pod', async () => { + it('Liquidate and register validator to disabled pod', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); await trackGas(ssvNetworkContract.liquidate(helpers.DB.owners[4].address, clusterResult1.clusterId), [GasGroup.LIQUIDATE_POD]); await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); @@ -44,29 +57,9 @@ describe('Liquidate Validator Tests', () => { await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4])['deposit(bytes32,uint256)'](clusterResult1.clusterId, minDepositAmount), [GasGroup.DEPOSIT]); await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).registerValidator(helpers.DataGenerator.publicKey(9), clusterResult1.clusterId, helpers.DataGenerator.shares(0)), [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]); }); - - it('Liquidate and register validator in disabled pod', async () => { - await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - await trackGas(ssvNetworkContract.liquidate(helpers.DB.owners[4].address, clusterResult1.clusterId), [GasGroup.LIQUIDATE_POD]); - await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - await helpers.DB.ssvToken.connect(helpers.DB.owners[4]).approve(ssvNetworkContract.address, minDepositAmount); - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4])['deposit(bytes32,uint256)'](clusterResult1.clusterId, minDepositAmount), [GasGroup.DEPOSIT]); - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).registerValidator(helpers.DataGenerator.publicKey(9), clusterResult1.clusterId, helpers.DataGenerator.shares(0)), [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]); - }); - - it('Liquidate errors', async () => { - await expect(ssvNetworkContract.liquidate(helpers.DB.owners[4].address, clusterResult1.clusterId)).to.be.revertedWith('PodNotLiquidatable'); - }); - - it('Is liquidated', async () => { - await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - await ssvNetworkContract.liquidate(helpers.DB.owners[4].address, clusterResult1.clusterId); - expect(await ssvNetworkContract.isLiquidated(helpers.DB.owners[4].address, clusterResult1.clusterId)).to.equal(true); - }); - - it('Liquidate gas limits', async () => { - await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).liquidate(helpers.DB.owners[4].address, clusterResult1.clusterId), [GasGroup.LIQUIDATE_POD]); + + it('Liquidate a pod that is not liquidatable reverts "PodNotLiquidatable"', async () => { + await expect(ssvNetworkContract.liquidate(helpers.DB.owners[4].address, clusterResult1.clusterId + )).to.be.revertedWith('PodNotLiquidatable'); }); -}); +}); \ No newline at end of file diff --git a/test/liquidate/reactivate.ts b/test/liquidate/reactivate.ts index 94beb4aa..ed183753 100644 --- a/test/liquidate/reactivate.ts +++ b/test/liquidate/reactivate.ts @@ -1,12 +1,13 @@ +// Declare imports import * as helpers from '../helpers/contract-helpers'; import * as utils from '../helpers/utils'; - import { expect } from 'chai'; import { trackGas, GasGroup } from '../helpers/gas-usage'; +// Declare globals let ssvNetworkContract: any, clusterResult1: any, minDepositAmount: any; -describe('Reactivate Validator Tests', () => { +describe('Reactivate Tests', () => { beforeEach(async () => { // Initialize contract ssvNetworkContract = (await helpers.initializeContract()).contract; @@ -20,27 +21,22 @@ describe('Reactivate Validator Tests', () => { clusterResult1 = await helpers.registerValidators(4, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); }); - it('Reactivate emits PodEnabled', async () => { + it('Reactivate a disabled pod emits "PodEnabled"', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); await ssvNetworkContract.liquidate(helpers.DB.owners[4].address, clusterResult1.clusterId); await helpers.DB.ssvToken.connect(helpers.DB.owners[4]).approve(ssvNetworkContract.address, minDepositAmount); - - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).reactivatePod(clusterResult1.clusterId, minDepositAmount)).to.emit(ssvNetworkContract, 'PodEnabled'); - }); - - it('Reactivate returns an error - PodAlreadyEnabled', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).reactivatePod(clusterResult1.clusterId, minDepositAmount)).to.be.revertedWith('PodAlreadyEnabled'); + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).reactivatePod(clusterResult1.clusterId, minDepositAmount + )).to.emit(ssvNetworkContract, 'PodEnabled'); }); - - it('Reactivate returns an error - NegativeBalance', async () => { + + it('Reactivate a disabled pod gas limits', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); await ssvNetworkContract.liquidate(helpers.DB.owners[4].address, clusterResult1.clusterId); - await helpers.DB.ssvToken.connect(helpers.DB.owners[4]).approve(ssvNetworkContract.address, helpers.CONFIG.minimalOperatorFee * 4); - - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).reactivatePod(clusterResult1.clusterId, helpers.CONFIG.minimalOperatorFee * 4)).to.be.revertedWith('NegativeBalance'); + await helpers.DB.ssvToken.connect(helpers.DB.owners[4]).approve(ssvNetworkContract.address, minDepositAmount); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).reactivatePod(clusterResult1.clusterId, minDepositAmount), [GasGroup.REACTIVATE_POD]); }); - it('Reactivate with removed operator in a cluster', async () => { + it('Reactivate a pod with a removed operator in the cluster', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); await ssvNetworkContract.liquidate(helpers.DB.owners[4].address, clusterResult1.clusterId); await ssvNetworkContract.removeOperator(1); @@ -48,11 +44,16 @@ describe('Reactivate Validator Tests', () => { await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).reactivatePod(clusterResult1.clusterId, minDepositAmount), [GasGroup.REACTIVATE_POD]); }); - it('Reactivate gas limits', async () => { + it('Reactivate an enabled pod reverts "PodAlreadyEnabled"', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).reactivatePod(clusterResult1.clusterId, minDepositAmount + )).to.be.revertedWith('PodAlreadyEnabled'); + }); + + it('Reactivate a pod when the amount is not enough reverts "NegativeBalance"', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); await ssvNetworkContract.liquidate(helpers.DB.owners[4].address, clusterResult1.clusterId); - await helpers.DB.ssvToken.connect(helpers.DB.owners[4]).approve(ssvNetworkContract.address, minDepositAmount); - - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).reactivatePod(clusterResult1.clusterId, minDepositAmount), [GasGroup.REACTIVATE_POD]); + await helpers.DB.ssvToken.connect(helpers.DB.owners[4]).approve(ssvNetworkContract.address, helpers.CONFIG.minimalOperatorFee * 4); + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).reactivatePod(clusterResult1.clusterId, helpers.CONFIG.minimalOperatorFee * 4 + )).to.be.revertedWith('NegativeBalance'); }); -}); +}); \ No newline at end of file From 94ab6fa8360234cffe358d7e2592de56b6b975fa Mon Sep 17 00:00:00 2001 From: Or-blox <117833150+Or-blox@users.noreply.github.com> Date: Tue, 29 Nov 2022 14:07:52 +0200 Subject: [PATCH 098/149] Or- update validator test names * Changes in validator test names * Vaildator test names * Validator - tests in order * Final updates * Final updates_2 * Final --- test/validators/register.ts | 100 ++++++++++++++++--------------- test/validators/remove.ts | 39 ++++++------ test/validators/transfer-bulk.ts | 81 ++++++++++++------------- test/validators/transfer.ts | 73 +++++++++++----------- 4 files changed, 147 insertions(+), 146 deletions(-) diff --git a/test/validators/register.ts b/test/validators/register.ts index 0511a92a..c25413af 100644 --- a/test/validators/register.ts +++ b/test/validators/register.ts @@ -1,9 +1,10 @@ +// Declare imports import * as helpers from '../helpers/contract-helpers'; import * as utils from '../helpers/utils'; - import { expect } from 'chai'; import { trackGas, GasGroup } from '../helpers/gas-usage'; +// Declare globals let ssvNetworkContract: any, clusterResult: any, minDepositAmount: any; describe('Register Validator Tests', () => { @@ -20,42 +21,23 @@ describe('Register Validator Tests', () => { clusterResult = await helpers.registerValidators(0, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); }); - it('Register new pod emits PodCreated event', async () => { + it('Register new pod emits "PodCreated"', async () => { await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); - await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).registerPod(helpers.DataGenerator.cluster.new(), minDepositAmount)).to.emit(ssvNetworkContract, 'PodCreated'); + await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).registerPod(helpers.DataGenerator.cluster.new(), minDepositAmount + )).to.emit(ssvNetworkContract, 'PodCreated'); }); - it('Register new pod with new cluster gas limit', async () => { + it('Register new pod with a new cluster gas limit', async () => { await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerPod(helpers.DataGenerator.cluster.new(), minDepositAmount), [GasGroup.REGISTER_POD]); }); - it('Register new pod in existed cluster gas limit', async () => { + it('Register a new pod to an existing cluster gas limit', async () => { await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerPod(helpers.DataGenerator.cluster.byId(clusterResult.clusterId), minDepositAmount), [GasGroup.REGISTER_POD]); }); - it('Register pod returns an error - PodAlreadyExists', async () => { - await expect(ssvNetworkContract.registerPod(helpers.DataGenerator.cluster.byId(clusterResult.clusterId), 0)).to.be.revertedWith('PodAlreadyExists'); - }); - - it('Get cluster id returns an error - ClusterNotExists', async () => { - await expect(ssvNetworkContract.getClusterId([5,6,7,8])).to.be.revertedWith('ClusterNotExists'); - }); - - it('Get pod returns an error - PoNotExists', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).getPod(helpers.DataGenerator.cluster.byId(clusterResult.clusterId))).to.be.revertedWith('PodNotExists'); - }); - - it('Get pod returns a cluster id', async () => { - expect(await ssvNetworkContract.getPod(helpers.DataGenerator.cluster.byId(clusterResult.clusterId))).to.equal(clusterResult.clusterId); - }); - - it('Register pod returns an error - OperatorDoesNotExist', async () => { - await expect(ssvNetworkContract.registerPod([1, 2, 3, 25], minDepositAmount)).to.be.revertedWith('OperatorDoesNotExist'); - }); - - it('Register validator emits ValidatorAdded event', async () => { + it('Register validator emits ValidatorAdded', async () => { // register validator using cluster Id await expect(ssvNetworkContract.registerValidator( helpers.DataGenerator.publicKey(1), @@ -64,7 +46,7 @@ describe('Register Validator Tests', () => { )).to.emit(ssvNetworkContract, 'ValidatorAdded'); }); - it('Register validator with removed operator in a cluster', async () => { + it('Register validator with a removed operator in the cluster', async () => { await ssvNetworkContract.removeOperator(1); await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); // TMP IT FAILS WITH PROGRESS BLOCK, CRITICAL ERROR IN INDEX MATH LOGIC await helpers.DB.ssvToken.connect(helpers.DB.owners[4]).approve(ssvNetworkContract.address, minDepositAmount); @@ -72,11 +54,11 @@ describe('Register Validator Tests', () => { await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).registerValidator(helpers.DataGenerator.publicKey(9), clusterResult.clusterId, helpers.DataGenerator.shares(0)), [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]); }); - it('Register one validator into an empty cluster', async () => { + it('Register a validator into an empty cluster', async () => { await helpers.registerValidators(0, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); }); - it('Register two validators in the same pod', async () => { + it('Register two validators into the same pod', async () => { await helpers.registerValidators(0, 1, `${minDepositAmount * 2}`, helpers.DataGenerator.cluster.byId(clusterResult.clusterId), [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]); }); @@ -84,22 +66,50 @@ describe('Register Validator Tests', () => { await helpers.registerValidators(1, 1, `${minDepositAmount * 2}`, helpers.DataGenerator.cluster.byId(clusterResult.clusterId), [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]); }); - it('Register pod returns an error - The operators list should be in ascending order', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).registerPod([3,2,1,4], minDepositAmount)).to.be.revertedWith('The operators list should be in ascending order'); + it('Get pod returns the cluster id', async () => { + expect(await ssvNetworkContract.getPod(helpers.DataGenerator.cluster.byId(clusterResult.clusterId))).to.equal(clusterResult.clusterId); + }); + + it('Register an existing pod reverts "PodAlreadyExists"', async () => { + await expect(ssvNetworkContract.registerPod(helpers.DataGenerator.cluster.byId(clusterResult.clusterId), 0 + )).to.be.revertedWith('PodAlreadyExists'); + }); + + it('Get the cluster id of a cluster that does not exist reverts "ClusterNotExists"', async () => { + await expect(ssvNetworkContract.getClusterId([5, 6, 7, 8] + )).to.be.revertedWith('ClusterNotExists'); + }); + + it('Get the pod address of a pod that does not exist reverts "PodNotExists"', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).getPod(helpers.DataGenerator.cluster.byId(clusterResult.clusterId) + )).to.be.revertedWith('PodNotExists'); + }); + + it('Register a pod when an operator does not exsit in the cluster reverts "OperatorDoesNotExist"', async () => { + await expect(ssvNetworkContract.registerPod([1, 2, 3, 25], minDepositAmount + )).to.be.revertedWith('OperatorDoesNotExist'); + }); + + it('Register a pod with unsorted operators reverts "The operators list should be in ascending order"', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).registerPod([3, 2, 1, 4], minDepositAmount + )).to.be.revertedWith('The operators list should be in ascending order'); }); - it('Invalid operator amount', async () => { + it('Invalid operator amount reverts "OperatorIdsStructureInvalid"', async () => { // 2 Operators - await expect(helpers.registerPodAndDeposit(0, [1, 2], minDepositAmount)).to.be.revertedWith('OperatorIdsStructureInvalid'); + await expect(helpers.registerPodAndDeposit(0, [1, 2], minDepositAmount + )).to.be.revertedWith('OperatorIdsStructureInvalid'); // 6 Operators - await expect(helpers.registerPodAndDeposit(0, [1, 2, 3, 4, 5, 6], minDepositAmount)).to.be.revertedWith('OperatorIdsStructureInvalid'); + await expect(helpers.registerPodAndDeposit(0, [1, 2, 3, 4, 5, 6], minDepositAmount + )).to.be.revertedWith('OperatorIdsStructureInvalid'); // 14 Operators - await expect(helpers.registerPodAndDeposit(0, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], minDepositAmount)).to.be.revertedWith('OperatorIdsStructureInvalid'); + await expect(helpers.registerPodAndDeposit(0, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], minDepositAmount + )).to.be.revertedWith('OperatorIdsStructureInvalid'); }); - it('Register validator returns an error - InvalidPublicKeyLength', async () => { + it('Register validator with an invalild public key reverts "InvalidPublicKeyLength"', async () => { await expect(ssvNetworkContract.registerValidator( helpers.DataGenerator.shares(0), (await helpers.registerPodAndDeposit(0, helpers.DataGenerator.cluster.new(), minDepositAmount)).clusterId, @@ -107,7 +117,7 @@ describe('Register Validator Tests', () => { )).to.be.revertedWith('InvalidPublicKeyLength'); }); - it('Register validator returns an error - NotEnoughBalance', async () => { + it('Register validator with not enough amount reverts "NotEnoughBalance', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( helpers.DataGenerator.publicKey(1), (await helpers.registerPodAndDeposit(0, helpers.DataGenerator.cluster.new(), '0')).clusterId, @@ -115,7 +125,7 @@ describe('Register Validator Tests', () => { )).to.be.revertedWith('NotEnoughBalance'); }); - it('Register validator returns an error - ValidatorAlreadyExists', async () => { + it('Register an existing validator reverts "ValidatorAlreadyExists"', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( helpers.DataGenerator.publicKey(0), (await helpers.registerPodAndDeposit(1, [1, 2, 3, 4], minDepositAmount)).clusterId, @@ -123,10 +133,10 @@ describe('Register Validator Tests', () => { )).to.be.revertedWith('ValidatorAlreadyExists'); }); - it('Register validator returns an error - ClusterNotExists', async () => { + it('Register validator with a cluster that does not exist reverts "ClusterNotExists"', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( helpers.DataGenerator.publicKey(0), - clusterResult.clusterId.replace(/.$/,'0'), + clusterResult.clusterId.replace(/.$/, '0'), helpers.DataGenerator.shares(0), )).to.be.revertedWith('ClusterNotExists'); }); @@ -145,12 +155,4 @@ describe('Register Validator Tests', () => { // '100005' // )).to.be.revertedWith('NotEnoughBalance'); }); -}); - - - - - - - - +}); \ No newline at end of file diff --git a/test/validators/remove.ts b/test/validators/remove.ts index 770a9d00..bcf8e4ce 100644 --- a/test/validators/remove.ts +++ b/test/validators/remove.ts @@ -1,8 +1,9 @@ +// Decalre imports import * as helpers from '../helpers/contract-helpers'; - import { expect } from 'chai'; import { trackGas, GasGroup } from '../helpers/gas-usage'; +// Decalre globals let ssvNetworkContract: any, clusterResult: any, minDepositAmount: any; describe('Remove Validator Tests', () => { @@ -19,34 +20,22 @@ describe('Remove Validator Tests', () => { clusterResult = await helpers.registerValidators(4, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); }); - it('Remove validator emits ValidatorRemoved event', async () => { + it('Remove validator emits "ValidatorRemoved"', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator( clusterResult.validators[0].publicKey, )).to.emit(ssvNetworkContract, 'ValidatorRemoved'); }); - it('Remove validator track gas', async () => { + it('Remove validator gas limits', async () => { await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator(clusterResult.validators[0].publicKey), [GasGroup.REMOVE_VALIDATOR]); }); - it('Remove validator with removed operator in a cluster', async () => { + 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[4]).removeValidator(clusterResult.validators[0].publicKey), [GasGroup.REMOVE_VALIDATOR]); }); - it('Remove validator with an invalid owner', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[3]).removeValidator(clusterResult.validators[0].publicKey)).to.be.revertedWith('ValidatorNotOwned'); - }); - - it('Remove validator twice', async () => { - // Remove validator - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator(clusterResult.validators[0].publicKey), [GasGroup.REMOVE_VALIDATOR]); - - // Remove validator again - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator(clusterResult.validators[0].publicKey)).to.be.revertedWith('ValidatorNotOwned'); - }); - - it('Register / remove validator twice', async () => { + it('Register a removed validator and remove the same validator again', async () => { // Remove validator await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator(clusterResult.validators[0].publicKey), [GasGroup.REMOVE_VALIDATOR]); @@ -61,6 +50,20 @@ describe('Remove Validator Tests', () => { await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator(helpers.DataGenerator.publicKey(0)), [GasGroup.REMOVE_VALIDATOR]); }); + it('Remove validator I do not own reverts "ValidatorNotOwned"', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[3]).removeValidator(clusterResult.validators[0].publicKey + )).to.be.revertedWith('ValidatorNotOwned'); + }); + + it('Remove the same validator twice reverts "ValidatorNotOwned"', async () => { + // Remove validator + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator(clusterResult.validators[0].publicKey), [GasGroup.REMOVE_VALIDATOR]); + + // Remove validator again + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator(clusterResult.validators[0].publicKey + )).to.be.revertedWith('ValidatorNotOwned'); + }); + // TODO: Once liquidation is updated it('Remove validator from a liquidated cluster', async () => { // // Register validator @@ -73,4 +76,4 @@ describe('Remove Validator Tests', () => { // validators[0].publicKey, // )).to.emit(ssvNetworkContract, 'ValidatorRemoved'); }); -}); +}); \ No newline at end of file diff --git a/test/validators/transfer-bulk.ts b/test/validators/transfer-bulk.ts index 8b86cc4e..4c52e5c4 100644 --- a/test/validators/transfer-bulk.ts +++ b/test/validators/transfer-bulk.ts @@ -1,8 +1,9 @@ +// Decalre imports import * as helpers from '../helpers/contract-helpers'; - import { expect } from 'chai'; import { GasGroup } from '../helpers/gas-usage'; +// Decalre globals let ssvNetworkContract: any, clusterResult1: any, clusterResult2: any, clusterResult3: any, minDepositAmount: any; describe('Bulk Transfer Validator Tests', () => { @@ -21,9 +22,8 @@ describe('Bulk Transfer Validator Tests', () => { clusterResult3 = await helpers.registerValidators(4, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); }); - it('Bulk transfer 10 validators emits BulkValidatorTransferred event', async () => { + it('Bulk transfer 10 validators emits "BulkValidatorTransferred"', async () => { await helpers.registerPodAndDeposit(4, helpers.DataGenerator.cluster.byId(clusterResult3.clusterId), `${minDepositAmount * (clusterResult2.validators.length + 1) }`); - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], clusterResult1.clusterId, @@ -32,40 +32,7 @@ describe('Bulk Transfer Validator Tests', () => { )).to.emit(ssvNetworkContract, 'BulkValidatorTransferred'); }); - it('Bulk transfer validator with an invalid owner', async () => { - await helpers.registerPodAndDeposit(5, helpers.DataGenerator.cluster.byId(clusterResult3.clusterId), `${minDepositAmount * (clusterResult2.validators.length + 1) }`); - - await expect(ssvNetworkContract.connect(helpers.DB.owners[5]).bulkTransferValidators( - [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], - clusterResult1.clusterId, - clusterResult3.clusterId, - Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)), - )).to.be.revertedWith('ValidatorNotOwned'); - }); - - it('Bulk transfer validator with an unowned validator', async () => { - const account5cluster = await helpers.registerValidators(5, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); - - await helpers.registerPodAndDeposit(4, helpers.DataGenerator.cluster.byId(clusterResult3.clusterId), `${minDepositAmount * (clusterResult2.validators.length + 1) }`); - - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( - [clusterResult1.validators[0].publicKey, account5cluster.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], - clusterResult1.clusterId, - clusterResult3.clusterId, - Array(clusterResult2.validators.length + 2).fill(helpers.DataGenerator.shares(0)), - )).to.be.revertedWith('ValidatorNotOwned'); - }); - - it('Bulk transfer with an invalid public key', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( - [clusterResult1.validators[0].publicKey, helpers.DataGenerator.shares(0), ...clusterResult2.validators.map((validator: any) => validator.publicKey)], - clusterResult1.clusterId, - clusterResult3.clusterId, - Array(clusterResult2.validators.length + 2).fill(helpers.DataGenerator.shares(0)), - )).to.be.revertedWith('InvalidPublicKeyLength'); - }); - - it('Bulk transfer 10 validators', async () => { + it('Bulk transfer 10 validators gas limits', async () => { await helpers.bulkTransferValidator( 4, [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], @@ -89,7 +56,7 @@ describe('Bulk Transfer Validator Tests', () => { [GasGroup.BULK_TRANSFER_VALIDATOR_NON_EXISTING_POD]); }); - it('Bulk transfer 10 validators to cluster created by other owner', async () => { + it('Bulk transfer 10 validators to a cluster created by other owner', async () => { // Register validator with 7 operators const { clusterId } = await helpers.registerValidators(5, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); @@ -103,7 +70,37 @@ describe('Bulk Transfer Validator Tests', () => { [GasGroup.BULK_TRANSFER_VALIDATOR_NON_EXISTING_POD]); }); - it('Bulk transfer 10 validators to an invalid cluster', async () => { + it('Bulk transfer 10 validators I do not own reverts "ValidatorNotOwned"', async () => { + await helpers.registerPodAndDeposit(5, helpers.DataGenerator.cluster.byId(clusterResult3.clusterId), `${minDepositAmount * (clusterResult2.validators.length + 1) }`); + await expect(ssvNetworkContract.connect(helpers.DB.owners[5]).bulkTransferValidators( + [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], + clusterResult1.clusterId, + clusterResult3.clusterId, + Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)), + )).to.be.revertedWith('ValidatorNotOwned'); + }); + + it('Bulk transfer 10 validators with one validator I do not own reverts "ValidatorNotOwned"', async () => { + const account5cluster = await helpers.registerValidators(5, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + await helpers.registerPodAndDeposit(4, helpers.DataGenerator.cluster.byId(clusterResult3.clusterId), `${minDepositAmount * (clusterResult2.validators.length + 1) }`); + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( + [clusterResult1.validators[0].publicKey, account5cluster.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], + clusterResult1.clusterId, + clusterResult3.clusterId, + Array(clusterResult2.validators.length + 2).fill(helpers.DataGenerator.shares(0)), + )).to.be.revertedWith('ValidatorNotOwned'); + }); + + it('Bulk transfer 10 validators with an invalid public key reverts "InvalidPublicKeyLength"', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( + [clusterResult1.validators[0].publicKey, helpers.DataGenerator.shares(0), ...clusterResult2.validators.map((validator: any) => validator.publicKey)], + clusterResult1.clusterId, + clusterResult3.clusterId, + Array(clusterResult2.validators.length + 2).fill(helpers.DataGenerator.shares(0)), + )).to.be.revertedWith('InvalidPublicKeyLength'); + }); + + it('Bulk transfer 10 validators to a cluster that does not exist reverts "ClusterNotExists"', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], clusterResult1.clusterId.slice(0, -1) + 'a', @@ -112,7 +109,7 @@ describe('Bulk Transfer Validator Tests', () => { )).to.be.revertedWith('ClusterNotExists'); }); - it('Validator and share length mismatch', async () => { + it('Validator and share length parameters are not the same length reverts "ParametersMismatch"', async () => { // 10 validators and 11 shares await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], @@ -130,7 +127,7 @@ describe('Bulk Transfer Validator Tests', () => { )).to.be.revertedWith('ParametersMismatch'); }); - it('Bulk transfer validator with not enough amount', async () => { + it('Bulk transfer 10 validators with not enough amount reverts "PodLiquidatable"', async () => { const { clusterId } = await helpers.registerValidators(5, 1, minDepositAmount, [9, 10, 11, 12], [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], @@ -150,4 +147,4 @@ describe('Bulk Transfer Validator Tests', () => { // '10000000' // )).to.be.revertedWith('NotEnoughDeposited'); }); -}); +}); \ No newline at end of file diff --git a/test/validators/transfer.ts b/test/validators/transfer.ts index b6f04623..28c63e26 100644 --- a/test/validators/transfer.ts +++ b/test/validators/transfer.ts @@ -1,9 +1,10 @@ +// Decalre imports import * as helpers from '../helpers/contract-helpers'; import * as utils from '../helpers/utils'; - import { expect } from 'chai'; import { GasGroup } from '../helpers/gas-usage'; +// Declare globals let ssvNetworkContract: any, clusterResult1: any, clusterResult2: any, minDepositAmount: any, clusters: any; describe('Transfer Validator Tests', () => { @@ -26,7 +27,7 @@ describe('Transfer Validator Tests', () => { clusters.three = helpers.DataGenerator.cluster.new(); }); - it('Transfer validator emits ValidatorTransferred event', async () => { + it('Transfer validator emits "ValidatorTransferred"', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( clusterResult1.validators[0].publicKey, (await helpers.registerPodAndDeposit(4, helpers.DataGenerator.cluster.new(), minDepositAmount)).clusterId, @@ -34,31 +35,15 @@ describe('Transfer Validator Tests', () => { )).to.emit(ssvNetworkContract, 'ValidatorTransferred'); }); - it('Transfer validator into a new cluster A-Z', async () => { + it('Transfer validator from pod with one validator into an empty pod', async () => { await helpers.transferValidator(4, clusterResult2.validators[0].publicKey, clusters.three, minDepositAmount, [GasGroup.TRANSFER_VALIDATOR_NEW_CLUSTER]); }); - it('Transfer validator into a new cluster Z-A', async () => { + it('Transfer validator from pod with two validators into an empty pod', async () => { const cluster = await helpers.registerValidators(4, 1, minDepositAmount, clusters.three, [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); await helpers.transferValidator(4, cluster.validators[0].publicKey, clusters.one, minDepositAmount, [GasGroup.TRANSFER_VALIDATOR_NEW_CLUSTER]); }); - it('Transfer validator with an invalid owner', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[5]).transferValidator( - clusterResult1.validators[0].publicKey, - (await helpers.registerPodAndDeposit(4, helpers.DataGenerator.cluster.byId(clusterResult2.clusterId), minDepositAmount)).clusterId, - helpers.DataGenerator.shares(helpers.DB.validators.length), - )).to.be.revertedWith('ValidatorNotOwned'); - }); - - it('transfer with an invalid public key', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( - helpers.DataGenerator.shares(0), - (await helpers.registerPodAndDeposit(4, helpers.DataGenerator.cluster.byId(clusterResult2.clusterId), minDepositAmount)).clusterId, - helpers.DataGenerator.shares(helpers.DB.validators.length), - )).to.be.revertedWith('InvalidPublicKeyLength'); - }); - it('Transfer validator to a cluster with 7 operators', async () => { // Register validator with 7 operators const { clusterId } = await helpers.registerValidators(4, 1, `${minDepositAmount / 4 * 7}`, [1, 2, 3, 4, 5, 6, 7]); @@ -67,18 +52,6 @@ describe('Transfer Validator Tests', () => { await helpers.transferValidator(4, clusterResult1.validators[0].publicKey, helpers.DataGenerator.cluster.byId(clusterId), `${minDepositAmount / 4 * 7 * 2}`, [GasGroup.TRANSFER_VALIDATOR_NON_EXISTING_POD]); }); - it('Transfer validator with not enough amount', async () => { - // Register validator - const { clusterId } = await helpers.registerValidators(4, 1, minDepositAmount, [1, 2, 3, 9]); - - // Transfer to cluster with not enough amount - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( - clusterResult1.validators[0].publicKey, - (await helpers.registerPodAndDeposit(4, helpers.DataGenerator.cluster.byId(clusterId), helpers.CONFIG.minimalOperatorFee)).clusterId, - helpers.DataGenerator.shares(helpers.DB.validators.length), - )).to.be.revertedWith('NotEnoughBalance'); - }); - // GOING ABOVE GAS LIMIT it('Transfer validator to an existing pod', async () => { await helpers.transferValidator(4, clusterResult1.validators[0].publicKey, helpers.DataGenerator.cluster.byId(clusterResult2.clusterId), `${minDepositAmount * 2}`, [GasGroup.TRANSFER_VALIDATOR]); @@ -95,31 +68,57 @@ describe('Transfer Validator Tests', () => { // expect(clusterResult3.clusterId).equals(transfredValidator1.eventsByName.ValidatorTransferred[0].args.podId); }); - it('Transfer validator with removed operator in old cluster A-Z', async () => { + it('Transfer validator in a pod with one validator and a removed operator into an existing pod', async () => { await ssvNetworkContract.removeOperator(helpers.DataGenerator.cluster.byId(clusterResult1.clusterId)[0]); await helpers.transferValidator(4, clusterResult1.validators[0].publicKey, helpers.DataGenerator.cluster.byId(clusterResult2.clusterId), `${minDepositAmount * 2}`, [GasGroup.TRANSFER_VALIDATOR]); }); - it('Transfer validator with removed operator in new cluster A-Z', async () => { + it('Transfer validator in a pod with one validator and a removed operator into an empty pod', async () => { await ssvNetworkContract.removeOperator(helpers.DataGenerator.cluster.byId(clusterResult2.clusterId)[0]); await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); // TMP IT FAILS WITH PROGRESS BLOCK, CRITICAL ERROR IN INDEX MATH LOGIC await helpers.transferValidator(4, clusterResult1.validators[0].publicKey, helpers.DataGenerator.cluster.byId(clusterResult2.clusterId), `${minDepositAmount * 2}`, [GasGroup.TRANSFER_VALIDATOR]); }); - it('Transfer validator with removed operator in old cluster Z-A', async () => { + it('Transfer validator in a pod with two validators and a removed operator into an existing pod', async () => { const cluster = await helpers.registerValidators(4, 1, minDepositAmount, clusters.three, [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); await ssvNetworkContract.removeOperator(clusters.three[0]); await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); // TMP IT FAILS WITH PROGRESS BLOCK, CRITICAL ERROR IN INDEX MATH LOGIC await helpers.transferValidator(4, cluster.validators[0].publicKey, clusters.one, `${minDepositAmount * 2}`, [GasGroup.TRANSFER_VALIDATOR_NEW_CLUSTER]); }); - it('Transfer validator with removed operator in new cluster Z-A', async () => { + it('Transfer validator in a pod with two validators and a removed operator into an empty pod', async () => { const cluster = await helpers.registerValidators(4, 1, minDepositAmount, clusters.three, [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); await ssvNetworkContract.removeOperator(clusters.one[0]); await helpers.transferValidator(4, cluster.validators[0].publicKey, clusters.one, minDepositAmount, [GasGroup.TRANSFER_VALIDATOR_NEW_CLUSTER]); }); + it('Transfer validator I do not own reverts "ValidatorNotOwned"', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[5]).transferValidator( + clusterResult1.validators[0].publicKey, + (await helpers.registerPodAndDeposit(4, helpers.DataGenerator.cluster.byId(clusterResult2.clusterId), minDepositAmount)).clusterId, + helpers.DataGenerator.shares(helpers.DB.validators.length), + )).to.be.revertedWith('ValidatorNotOwned'); + }); + + it('Transfer validator with an invalid public key reverts "InvalidPublicKeyLength"', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( + helpers.DataGenerator.shares(0), + (await helpers.registerPodAndDeposit(4, helpers.DataGenerator.cluster.byId(clusterResult2.clusterId), minDepositAmount)).clusterId, + helpers.DataGenerator.shares(helpers.DB.validators.length), + )).to.be.revertedWith('InvalidPublicKeyLength'); + }); + + it('Transfer validator to a pod with not enough amount reverts "NotEnoughBalance"', async () => { + // Register validator + const { clusterId } = await helpers.registerValidators(4, 1, minDepositAmount, [1, 2, 3, 9]); + // Transfer to cluster with not enough amount + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( + clusterResult1.validators[0].publicKey, + (await helpers.registerPodAndDeposit(4, helpers.DataGenerator.cluster.byId(clusterId), helpers.CONFIG.minimalOperatorFee)).clusterId, + helpers.DataGenerator.shares(helpers.DB.validators.length), + )).to.be.revertedWith('NotEnoughBalance'); + }); // TODO: fix after connecting the token it('Transfer validator with not enough balance', async () => { @@ -130,4 +129,4 @@ describe('Transfer Validator Tests', () => { // '1000001' // )).to.be.revertedWith('NotEnoughBalance'); }); -}); +}); \ No newline at end of file From 68e4de9e40897b1032e0622bf923aa0a2fe8d1bb Mon Sep 17 00:00:00 2001 From: Or-blox <117833150+Or-blox@users.noreply.github.com> Date: Tue, 29 Nov 2022 14:09:44 +0200 Subject: [PATCH 099/149] Or-Changes in test names * change register test * change name in register test * changed test names * Deposit tests with corrections * Withdraw changes * with corrections * register corrections * remove operator changes * spaces * Update-fee changes * spaces * Dao test names changes * changes * Corrections after the comments * Account, Dao and Operator after correction and reorganized * Withdaaw is done * Final updates * lines --- test/account/deposit.ts | 44 ++++---- test/account/withdraw.ts | 66 ++++++------ test/dao/network-fee-change.ts | 25 +++-- test/dao/network-fee-withdraw.ts | 32 +++--- test/operators/fee.ts | 180 ------------------------------- test/operators/register.ts | 20 ++-- test/operators/remove.ts | 34 +++--- test/operators/update-fee.ts | 174 ++++++++++++++++++++++++++++++ test/operators/update.ts | 23 ---- 9 files changed, 295 insertions(+), 303 deletions(-) delete mode 100644 test/operators/fee.ts create mode 100644 test/operators/update-fee.ts delete mode 100644 test/operators/update.ts diff --git a/test/account/deposit.ts b/test/account/deposit.ts index 215487ae..9dfe1ed9 100644 --- a/test/account/deposit.ts +++ b/test/account/deposit.ts @@ -1,8 +1,9 @@ +// Declare imports import * as helpers from '../helpers/contract-helpers'; - import { expect } from 'chai'; import { trackGas, GasGroup } from '../helpers/gas-usage'; +// Declare globals let ssvNetworkContract: any, clusterResult1: any, minDepositAmount: any; describe('Deposit Tests', () => { @@ -12,38 +13,43 @@ describe('Deposit Tests', () => { // Register operators await helpers.registerOperators(0, 12, helpers.CONFIG.minimalOperatorFee); - + + // Define the operator fee minDepositAmount = (helpers.CONFIG.minimalBlocksBeforeLiquidation + 10) * helpers.CONFIG.minimalOperatorFee * 4; // Register validators clusterResult1 = await helpers.registerValidators(4, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); }); - - it('Deposit as owner emits FundsDeposit event', async () => { + + it('Deposit to a pod I own emits "FundsDeposit"', async () => { await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); - await expect(ssvNetworkContract.connect(helpers.DB.owners[1])['deposit(bytes32,uint256)'](clusterResult1.clusterId, minDepositAmount)).to.emit(ssvNetworkContract, 'FundsDeposit'); + await expect(ssvNetworkContract.connect(helpers.DB.owners[1])['deposit(bytes32,uint256)'](clusterResult1.clusterId, minDepositAmount + )).to.emit(ssvNetworkContract, 'FundsDeposit'); }); - it('Deposit as non-owner emits FundsDeposit event', async () => { - await helpers.DB.ssvToken.connect(helpers.DB.owners[0]).approve(ssvNetworkContract.address, minDepositAmount); - await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['deposit(address,bytes32,uint256)'](helpers.DB.owners[1].address, clusterResult1.clusterId, minDepositAmount)).to.emit(ssvNetworkContract, 'FundsDeposit'); + it('Deposit to a pod I own gas limits', async () => { + await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1])['deposit(bytes32,uint256)'](clusterResult1.clusterId, minDepositAmount), [GasGroup.DEPOSIT]); }); - it('Deposit as owner returns an error - ClusterNotExists', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[1])['deposit(bytes32,uint256)']('0x392791df626408017a264f53fde61065d5a93a32b60171df9d8a46afdf82992c', minDepositAmount)).to.be.revertedWith('ClusterNotExists'); + it('Deposit to a pod I do not own emits "FundsDeposit"', async () => { + await helpers.DB.ssvToken.connect(helpers.DB.owners[0]).approve(ssvNetworkContract.address, minDepositAmount); + await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['deposit(address,bytes32,uint256)'](helpers.DB.owners[1].address, clusterResult1.clusterId, minDepositAmount + )).to.emit(ssvNetworkContract, 'FundsDeposit'); }); - it('Deposit as non-owner returns an error - ClusterNotExists', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['deposit(address,bytes32,uint256)'](helpers.DB.owners[1].address, '0x392791df626408017a264f53fde61065d5a93a32b60171df9d8a46afdf82992c', minDepositAmount)).to.be.revertedWith('ClusterNotExists'); + it('Deposit to a pod 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(address,bytes32,uint256)'](helpers.DB.owners[1].address, clusterResult1.clusterId, minDepositAmount), [GasGroup.DEPOSIT]); }); - it('Deposit as owner gas limits', async () => { - await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1])['deposit(bytes32,uint256)'](clusterResult1.clusterId, minDepositAmount), [GasGroup.DEPOSIT]); + it('Deposit to a pod I do own with a cluster that does not exist reverts "ClusterNotExists"', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[1])['deposit(bytes32,uint256)']('0x392791df626408017a264f53fde61065d5a93a32b60171df9d8a46afdf82992c', minDepositAmount + )).to.be.revertedWith('ClusterNotExists'); }); - it('Deposit as non-owner 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(address,bytes32,uint256)'](helpers.DB.owners[1].address, clusterResult1.clusterId, minDepositAmount), [GasGroup.DEPOSIT]); + it('Deposit to a pod I do not own with a cluster that does not exist reverts "ClusterNotExists"', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['deposit(address,bytes32,uint256)'](helpers.DB.owners[1].address, '0x392791df626408017a264f53fde61065d5a93a32b60171df9d8a46afdf82992c', minDepositAmount + )).to.be.revertedWith('ClusterNotExists'); }); -}); +}); \ No newline at end of file diff --git a/test/account/withdraw.ts b/test/account/withdraw.ts index 04895502..44e9c1d0 100644 --- a/test/account/withdraw.ts +++ b/test/account/withdraw.ts @@ -1,9 +1,10 @@ +// Declare imports import * as helpers from '../helpers/contract-helpers'; import * as utils from '../helpers/utils'; - import { expect } from 'chai'; import { trackGas, GasGroup } from '../helpers/gas-usage'; +// Declare globals let ssvNetworkContract: any, clusterResult1: any, minDepositAmount: any; describe('Withdraw Tests', () => { @@ -20,56 +21,61 @@ describe('Withdraw Tests', () => { clusterResult1 = await helpers.registerValidators(4, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); }); - it('Withdraw pod balance emits PodFundsWithdrawal event', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).withdrawPodBalance(clusterResult1.clusterId, helpers.CONFIG.minimalOperatorFee)).to.emit(ssvNetworkContract, 'PodFundsWithdrawal'); + it('Withdraw from pod emits "PodFundsWithdrawal"', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).withdrawPodBalance(clusterResult1.clusterId, helpers.CONFIG.minimalOperatorFee + )).to.emit(ssvNetworkContract, 'PodFundsWithdrawal'); }); - it('Withdraw pod balance returns an error - NotEnoughBalance', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).withdrawPodBalance(clusterResult1.clusterId, minDepositAmount)).to.be.revertedWith('NotEnoughBalance'); + it('Withdraw from pod gas limits', async () => { + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).withdrawPodBalance(clusterResult1.clusterId, helpers.CONFIG.minimalOperatorFee), [GasGroup.WITHDRAW]); }); - it('Withdraw balance of liquidatable pod returns an error - NotEnoughBalance', async () => { - await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).withdrawPodBalance(clusterResult1.clusterId, helpers.CONFIG.minimalOperatorFee)).to.be.revertedWith('NotEnoughBalance'); + it('Withdraw from operator balance emits "OperatorFundsWithdrawal"', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorBalance(uint64,uint256)'](1, helpers.CONFIG.minimalOperatorFee + )).to.emit(ssvNetworkContract, 'OperatorFundsWithdrawal'); }); - it('Withdraw pod balance gas limits', async () => { - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).withdrawPodBalance(clusterResult1.clusterId, helpers.CONFIG.minimalOperatorFee), [GasGroup.WITHDRAW]); + it('Withdraw from operator balance gas limits', async () => { + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorBalance(uint64,uint256)'](1, helpers.CONFIG.minimalOperatorFee), [GasGroup.WITHDRAW]); }); - it('Withdraw total operator balance emits OperatorFundsWithdrawal event', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorBalance(uint64)'](1)).to.emit(ssvNetworkContract, 'OperatorFundsWithdrawal'); + it('Withdraw the total operator balance emits "OperatorFundsWithdrawal"', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorBalance(uint64)'](1 + )).to.emit(ssvNetworkContract, 'OperatorFundsWithdrawal'); }); - it('Withdraw total operator balance gas limits', async () => { + it('Withdraw the total operator balance gas limits', async () => { await trackGas(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorBalance(uint64)'](1), [GasGroup.WITHDRAW]); }); - it('Withdraw operator balance emits OperatorFundsWithdrawal event', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorBalance(uint64,uint256)'](1, helpers.CONFIG.minimalOperatorFee)).to.emit(ssvNetworkContract, 'OperatorFundsWithdrawal'); + it('Withdraw more than the operators balance reverts "NotEnoughBalance"', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).withdrawPodBalance(clusterResult1.clusterId, minDepositAmount + )).to.be.revertedWith('NotEnoughBalance'); }); - it('Withdraw operator balance returns an error - CallerNotOwner', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[2])['withdrawOperatorBalance(uint64,uint256)'](1, minDepositAmount)).to.be.revertedWith('CallerNotOwner'); + it('Withdraw from a liquidatable pod reverts "NotEnoughBalance"', async () => { + await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).withdrawPodBalance(clusterResult1.clusterId, helpers.CONFIG.minimalOperatorFee + )).to.be.revertedWith('NotEnoughBalance'); }); - it('Withdraw operator balance returns an error - NotEnoughBalance', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorBalance(uint64,uint256)'](1, minDepositAmount)).to.be.revertedWith('NotEnoughBalance'); + it('Withdraw balance from an operator I do not own reverts "CallerNotOwner"', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[2])['withdrawOperatorBalance(uint64,uint256)'](1, minDepositAmount + )).to.be.revertedWith('CallerNotOwner'); }); - it('Withdraw total operator balance returns an error - CallerNotOwner', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[2])['withdrawOperatorBalance(uint64)'](12)).to.be.revertedWith('CallerNotOwner'); + it('Withdraw more than the operator balance reverts "NotEnoughBalance"', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorBalance(uint64,uint256)'](1, minDepositAmount + )).to.be.revertedWith('NotEnoughBalance'); }); - it('Withdraw total operator balance returns an error - NotEnoughBalance', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorBalance(uint64)'](12)).to.be.revertedWith('NotEnoughBalance'); + it('Withdraw the total balance from an operator I do not own reverts "CallerNotOwner"', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[2])['withdrawOperatorBalance(uint64)'](12 + )).to.be.revertedWith('CallerNotOwner'); }); - it('Withdraw operator balance gas limits', async () => { - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorBalance(uint64,uint256)'](1, helpers.CONFIG.minimalOperatorFee), [GasGroup.WITHDRAW]); - }); - - it('Withdraw total operator balance gas limits', async () => { - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorBalance(uint64)'](1), [GasGroup.WITHDRAW]); + it('Withdraw more than the operator total balance reverts "NotEnoughBalance"', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorBalance(uint64)'](12 + )).to.be.revertedWith('NotEnoughBalance'); }); -}); +}); \ No newline at end of file diff --git a/test/dao/network-fee-change.ts b/test/dao/network-fee-change.ts index 2adaca8e..8020512a 100644 --- a/test/dao/network-fee-change.ts +++ b/test/dao/network-fee-change.ts @@ -1,7 +1,8 @@ +// Declare imports import * as helpers from '../helpers/contract-helpers'; - import { expect } from 'chai'; +// Declare globals let ssvNetworkContract: any, networkFee: any; describe('Network Fee Tests', () => { @@ -12,21 +13,23 @@ describe('Network Fee Tests', () => { // Define minumum allowed network fee to pass shrinkable validation networkFee = helpers.CONFIG.minimalOperatorFee / 10; }); + + it('Change network fee emits "NetworkFeeUpdate"', async () => { + await expect(ssvNetworkContract.updateNetworkFee(networkFee + )).to.emit(ssvNetworkContract, 'NetworkFeeUpdate').withArgs(0, networkFee); + }); it('Get network fee', async () => { expect(await ssvNetworkContract.getNetworkFee()).to.equal(0); }); - it('Change network fee emits NetworkFeeUpdate event', async () => { - await expect(ssvNetworkContract.updateNetworkFee(networkFee)) - .to.emit(ssvNetworkContract, 'NetworkFeeUpdate').withArgs(0, networkFee); - }); - - it('Change network fee fails small number error', async () => { - await expect(ssvNetworkContract.updateNetworkFee(networkFee - 1)).to.be.revertedWith('Precision is over the maximum defined'); + it('Change the network fee to a number below the minimum fee reverts "Precision is over the maximum defined"', async () => { + await expect(ssvNetworkContract.updateNetworkFee(networkFee - 1 + )).to.be.revertedWith('Precision is over the maximum defined'); }); - it('Change network fee fails no owner', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[3]).updateNetworkFee(networkFee)).to.be.revertedWith('caller is not the owner'); + it('Change network fee from an address thats not the DAO reverts "caller is not the owner"', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[3]).updateNetworkFee(networkFee + )).to.be.revertedWith('caller is not the owner'); }); -}); +}); \ No newline at end of file diff --git a/test/dao/network-fee-withdraw.ts b/test/dao/network-fee-withdraw.ts index 17d440bf..245a9989 100644 --- a/test/dao/network-fee-withdraw.ts +++ b/test/dao/network-fee-withdraw.ts @@ -1,9 +1,10 @@ +// Declare imports import * as helpers from '../helpers/contract-helpers'; import * as utils from '../helpers/utils'; - import { expect } from 'chai'; import { GasGroup } from '../helpers/gas-usage'; +// Declare globals let ssvNetworkContract: any, minDepositAmount: any, burnPerBlock: any, networkFee: any; describe('DAO Network Fee Withdraw Tests', () => { @@ -34,28 +35,31 @@ describe('DAO Network Fee Withdraw Tests', () => { // Mint tokens await helpers.DB.ssvToken.mint(ssvNetworkContract.address, minDepositAmount); }); + + it('Withdraw network earnings emits "NetworkFeesWithdrawal"', async () => { + const amount = await ssvNetworkContract.getNetworkBalance(); + await expect(ssvNetworkContract.withdrawDAOEarnings(amount + )).to.emit(ssvNetworkContract, 'NetworkFeesWithdrawal').withArgs(amount, helpers.DB.owners[0].address); + }); it('Get withdrawable network earnings', async () => { expect(await ssvNetworkContract.getNetworkBalance()).to.above(0); }); - it('Get withdrawable network earnings fails no owner', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[3]).getNetworkBalance()).to.be.revertedWith('caller is not the owner'); - }); - - it('Withdraw network earnings emits NetworkFeesWithdrawal event', async () => { - const amount = await ssvNetworkContract.getNetworkBalance(); - await expect(ssvNetworkContract.withdrawDAOEarnings(amount)) - .to.emit(ssvNetworkContract, 'NetworkFeesWithdrawal').withArgs(amount, helpers.DB.owners[0].address); + it('Get withdrawable network earnings reverts "caller is not the owner"', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[3]).getNetworkBalance( + )).to.be.revertedWith('caller is not the owner'); }); - it('Withdraw network earnings fails balance is lower', async () => { + it('Withdraw network earnings with not enough balance reverts "NotEnoughBalance"', async () => { const amount = await ssvNetworkContract.getNetworkBalance() * 2; - await expect(ssvNetworkContract.withdrawDAOEarnings(amount)).to.be.revertedWith('NotEnoughBalance'); + await expect(ssvNetworkContract.withdrawDAOEarnings(amount + )).to.be.revertedWith('NotEnoughBalance'); }); - it('Withdraw network earnings fails no owner', async () => { + it('Withdraw network earnings from an address thats not the DAO reverts "caller is not the owner"', async () => { const amount = await ssvNetworkContract.getNetworkBalance(); - await expect(ssvNetworkContract.connect(helpers.DB.owners[3]).withdrawDAOEarnings(amount)).to.be.revertedWith('caller is not the owner'); + await expect(ssvNetworkContract.connect(helpers.DB.owners[3]).withdrawDAOEarnings(amount + )).to.be.revertedWith('caller is not the owner'); }); -}); +}); \ No newline at end of file diff --git a/test/operators/fee.ts b/test/operators/fee.ts deleted file mode 100644 index 031e8de3..00000000 --- a/test/operators/fee.ts +++ /dev/null @@ -1,180 +0,0 @@ -import * as helpers from '../helpers/contract-helpers'; - -import { expect } from 'chai'; -import { progressTime } from '../helpers/utils'; -import { trackGas, GasGroup } from '../helpers/gas-usage'; - -let ssvNetworkContract: any, initialFee: any; - -describe('Operator Fee Tests', () => { - beforeEach(async () => { - ssvNetworkContract = (await helpers.initializeContract()).contract; - initialFee = helpers.CONFIG.minimalOperatorFee * 10; - await helpers.registerOperators(2, 1, initialFee); - }); - - it('Declare fee success emits OperatorFeeDeclaration event', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[2]).declareOperatorFee(1, initialFee + initialFee / 10)) - .to.emit(ssvNetworkContract, 'OperatorFeeDeclaration'); - }); - - it('Declare fee success as contract owner', async () => { - await trackGas(ssvNetworkContract.declareOperatorFee(1, initialFee + initialFee / 10), [GasGroup.REGISTER_OPERATOR]); - }); - - it('Declare fee < than initial more than 10% success', async () => { - await trackGas(ssvNetworkContract.declareOperatorFee(1, initialFee - initialFee / 20), [GasGroup.REGISTER_OPERATOR]); - }); - - it('Declare fee fails no owner', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).declareOperatorFee(1, initialFee + initialFee / 10 )) - .to.be.revertedWith('CallerNotOwner'); - }); - - it('Declare fee fails no owner', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).declareOperatorFee(1, initialFee + initialFee / 10 )) - .to.be.revertedWith('CallerNotOwner'); - }); - - it('Declare fee fails no operator with public key', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).declareOperatorFee(12, initialFee + initialFee / 10 )) - .to.be.revertedWith('OperatorWithPublicKeyNotExist'); - }); - - it('Declare fee fails fee too low', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[2]).declareOperatorFee(1, helpers.CONFIG.minimalOperatorFee - 1)) - .to.be.revertedWith('FeeTooLow'); - }); - - it('Declare fee fails fee exceeds increase limit', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[2]).declareOperatorFee(1, initialFee + initialFee / 5)) - .to.be.revertedWith('FeeExceedsIncreaseLimit'); - }); - - it('Cancel declared fee success emits DeclaredOperatorFeeCancelation event', async () => { - await ssvNetworkContract.declareOperatorFee(1, initialFee + initialFee / 10); - - await expect(ssvNetworkContract.connect(helpers.DB.owners[2]).cancelDeclaredOperatorFee(1)) - .to.emit(ssvNetworkContract, 'DeclaredOperatorFeeCancelation'); - }); - - it('Cancel declared fee success as contract owner', async () => { - await trackGas(ssvNetworkContract.declareOperatorFee(1, initialFee + initialFee / 10), [GasGroup.REGISTER_OPERATOR]); - await trackGas(ssvNetworkContract.cancelDeclaredOperatorFee(1), [GasGroup.REGISTER_OPERATOR]); - }); - - it('Cancel declared fee fails no pending request', async () => { - await expect(ssvNetworkContract.cancelDeclaredOperatorFee(1)) - .to.be.revertedWith('NoPendingFeeChangeRequest'); - }); - - it('Cancel declared fee fails no owner', async () => { - await trackGas(ssvNetworkContract.declareOperatorFee(1, initialFee + initialFee / 10), [GasGroup.REGISTER_OPERATOR]); - - await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).cancelDeclaredOperatorFee(1)) - .to.be.revertedWith('CallerNotOwner'); - }); - - it('Execute declared fee success emits OperatorFeeExecution event', async () => { - await ssvNetworkContract.declareOperatorFee(1, initialFee + initialFee / 10); - await progressTime(helpers.CONFIG.declareOperatorFeePeriod); - await expect(ssvNetworkContract.connect(helpers.DB.owners[2]).executeOperatorFee(1)) - .to.emit(ssvNetworkContract, 'OperatorFeeExecution'); - }); - - it('Execute declared fee success as contract owner', async () => { - await trackGas(ssvNetworkContract.declareOperatorFee(1, initialFee + initialFee / 10), [GasGroup.REGISTER_OPERATOR]); - await progressTime(helpers.CONFIG.declareOperatorFeePeriod); - await trackGas(ssvNetworkContract.executeOperatorFee(1), [GasGroup.REGISTER_OPERATOR]); - }); - - it('Execute declared fee fee fails no owner', async () => { - await trackGas(ssvNetworkContract.declareOperatorFee(1, initialFee + initialFee / 10), [GasGroup.REGISTER_OPERATOR]); - - await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).executeOperatorFee(1)) - .to.be.revertedWith('CallerNotOwner'); - }); - - it('Execute declared fee fails no pending request', async () => { - await expect(ssvNetworkContract.executeOperatorFee(1)) - .to.be.revertedWith('NoPendingFeeChangeRequest'); - }); - - it('Execute declared fee fails too earlier', async () => { - await trackGas(ssvNetworkContract.declareOperatorFee(1, initialFee + initialFee / 10), [GasGroup.REGISTER_OPERATOR]); - await progressTime(helpers.CONFIG.declareOperatorFeePeriod - 10); - await expect(ssvNetworkContract.executeOperatorFee(1)) - .to.be.revertedWith('ApprovalNotWithinTimeframe'); - }); - - it('Execute declared fee fails too late', async () => { - await trackGas(ssvNetworkContract.declareOperatorFee(1, initialFee + initialFee / 10), [GasGroup.REGISTER_OPERATOR]); - await progressTime(helpers.CONFIG.declareOperatorFeePeriod + helpers.CONFIG.executeOperatorFeePeriod + 1); - await expect(ssvNetworkContract.executeOperatorFee(1)) - .to.be.revertedWith('ApprovalNotWithinTimeframe'); - }); - - it('DAO: update fee increase limit success emits OperatorFeeIncreaseLimitUpdate event', async () => { - await expect(ssvNetworkContract.updateOperatorFeeIncreaseLimit(1000)) - .to.emit(ssvNetworkContract, 'OperatorFeeIncreaseLimitUpdate'); - }); - - it('DAO: update fee increase limit fails no owner', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).updateOperatorFeeIncreaseLimit(1000)) - .to.be.revertedWith('caller is not the owner'); - }); - - it('DAO: update declare fee period success emits DeclareOperatorFeePeriodUpdate event', async () => { - await expect(ssvNetworkContract.updateDeclareOperatorFeePeriod(1200)) - .to.emit(ssvNetworkContract, 'DeclareOperatorFeePeriodUpdate'); - }); - - it('DAO: update declare fee period fails no owner', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).updateDeclareOperatorFeePeriod(1200)) - .to.be.revertedWith('caller is not the owner'); - }); - - it('DAO: update execute fee period success emits ExecuteOperatorFeePeriodUpdate event', async () => { - await expect(ssvNetworkContract.updateExecuteOperatorFeePeriod(1200)) - .to.emit(ssvNetworkContract, 'ExecuteOperatorFeePeriodUpdate'); - }); - - it('DAO: update execute fee period fails no owner', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).updateExecuteOperatorFeePeriod(1200)) - .to.be.revertedWith('caller is not the owner'); - }); - - it('DAO: get fee increase limit equal init value', async () => { - expect(await ssvNetworkContract.getOperatorFeeIncreaseLimit()).to.equal(helpers.CONFIG.operatorMaxFeeIncrease); - }); - - it('DAO: get declared fee', async () => { - const newFee = initialFee + initialFee / 10; - await trackGas(ssvNetworkContract.declareOperatorFee(1, newFee), [GasGroup.REGISTER_OPERATOR]); - const [ feeDeclaredInContract ] = await ssvNetworkContract.getOperatorDeclaredFee(1); - expect(feeDeclaredInContract).to.equal(newFee); - }); - - it('DAO: get declared fee fails no pending request', async () => { - await trackGas(ssvNetworkContract.declareOperatorFee(1, initialFee + initialFee / 10), [GasGroup.REGISTER_OPERATOR]); - await expect(ssvNetworkContract.getOperatorDeclaredFee(2)) - .to.be.revertedWith('NoPendingFeeChangeRequest'); - }); - - it('DAO: get execute fee period equal init value', async () => { - expect(await ssvNetworkContract.getExecuteOperatorFeePeriod()).to.equal(helpers.CONFIG.executeOperatorFeePeriod); - }); - - it('DAO: get declared fee period equal init value', async () => { - expect(await ssvNetworkContract.getDeclaredOperatorFeePeriod()).to.equal(helpers.CONFIG.declareOperatorFeePeriod); - }); - - it('Get fee', async () => { - expect(await ssvNetworkContract.getOperatorFee(1)).to.equal(initialFee); - }); - - it('Get fee returns an error - OperatorNotFound', async () => { - await expect(ssvNetworkContract.getOperatorFee(12)).to.be.revertedWith('OperatorNotFound'); - }); - -}); diff --git a/test/operators/register.ts b/test/operators/register.ts index 99885059..339bcaaa 100644 --- a/test/operators/register.ts +++ b/test/operators/register.ts @@ -1,8 +1,9 @@ +// Declare imports import * as helpers from '../helpers/contract-helpers'; - import { expect } from 'chai'; import { trackGas, GasGroup } from '../helpers/gas-usage'; +// Declare globals let ssvNetworkContract: any; describe('Register Operator Tests', () => { @@ -10,7 +11,7 @@ describe('Register Operator Tests', () => { ssvNetworkContract = (await helpers.initializeContract()).contract; }); - it('Register operator', async () => { + it('Register operator emits "OperatorAdded"', async () => { const publicKey = helpers.DataGenerator.publicKey(0); await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).registerOperator( publicKey, @@ -18,13 +19,6 @@ describe('Register Operator Tests', () => { )).to.emit(ssvNetworkContract, 'OperatorAdded').withArgs(1, helpers.DB.owners[1].address, publicKey, helpers.CONFIG.minimalOperatorFee); }); - it('Fails to register with low fee', async () => { - await expect(ssvNetworkContract.registerOperator( - helpers.DataGenerator.publicKey(0), - '10' - )).to.be.revertedWith('FeeTooLow'); - }); - it('Register operator gas limits', async () => { await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerOperator( helpers.DataGenerator.publicKey(0), @@ -32,4 +26,10 @@ describe('Register Operator Tests', () => { ), [GasGroup.REGISTER_OPERATOR]); }); -}); + it('Register an operator with a fee thats too low reverts "FeeTooLow"', async () => { + await expect(ssvNetworkContract.registerOperator( + helpers.DataGenerator.publicKey(0), + '10' + )).to.be.revertedWith('FeeTooLow'); + }); +}); \ No newline at end of file diff --git a/test/operators/remove.ts b/test/operators/remove.ts index 3e63e44d..be0237da 100644 --- a/test/operators/remove.ts +++ b/test/operators/remove.ts @@ -1,9 +1,10 @@ +// Declare imports import * as helpers from '../helpers/contract-helpers'; import * as utils from '../helpers/utils'; - import { expect } from 'chai'; import { trackGas, GasGroup } from '../helpers/gas-usage'; +// Declare globals let ssvNetworkContract: any; describe('Remove Operator Tests', () => { @@ -11,16 +12,10 @@ describe('Remove Operator Tests', () => { ssvNetworkContract = (await helpers.initializeContract()).contract; }); - it('Remove operator emits OperatorRemoved event', async () => { - await helpers.registerOperators(0, 1, helpers.CONFIG.minimalOperatorFee); - await expect(ssvNetworkContract.connect(helpers.DB.owners[0]).removeOperator(1)) - .to.emit(ssvNetworkContract, 'OperatorRemoved').withArgs(1); - }); - - it('Fails to remove operator with no owner', async () => { + it('Remove operator emits "OperatorRemoved"', async () => { await helpers.registerOperators(0, 1, helpers.CONFIG.minimalOperatorFee); - await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).removeOperator(1)) - .to.be.revertedWith('CallerNotOwner'); + await expect(ssvNetworkContract.connect(helpers.DB.owners[0]).removeOperator(1 + )).to.emit(ssvNetworkContract, 'OperatorRemoved').withArgs(1); }); it('Remove operator gas limits', async () => { @@ -28,15 +23,22 @@ describe('Remove Operator Tests', () => { await trackGas(ssvNetworkContract.removeOperator(1), [GasGroup.REMOVE_OPERATOR]); }); - it('Remove operator with withdraw emits OperatorFundsWithdrawal event', async () => { + it('Remove operator with a balance emits "OperatorFundsWithdrawal"', async () => { await helpers.registerOperators(0, 4, helpers.CONFIG.minimalOperatorFee); - await helpers.registerValidators(4, 1, `${helpers.CONFIG.minimalBlocksBeforeLiquidation * helpers.CONFIG.minimalOperatorFee * 4}`, [1,2,3,4], [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); - await expect(ssvNetworkContract.removeOperator(1)).to.emit(ssvNetworkContract, 'OperatorFundsWithdrawal'); + await helpers.registerValidators(4, 1, `${helpers.CONFIG.minimalBlocksBeforeLiquidation * helpers.CONFIG.minimalOperatorFee * 4}`, [1, 2, 3, 4], [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + await expect(ssvNetworkContract.removeOperator(1 + )).to.emit(ssvNetworkContract, 'OperatorFundsWithdrawal'); }); - it('Remove operator with withdraw gas limits', async () => { + it('Remove operator with a balance gas limits', async () => { await helpers.registerOperators(0, 4, helpers.CONFIG.minimalOperatorFee); - 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, 1, `${helpers.CONFIG.minimalBlocksBeforeLiquidation * helpers.CONFIG.minimalOperatorFee * 4}`, [1, 2, 3, 4], [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 helpers.registerOperators(0, 1, helpers.CONFIG.minimalOperatorFee); + await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).removeOperator(1 + )).to.be.revertedWith('CallerNotOwner'); + }); +}); \ No newline at end of file diff --git a/test/operators/update-fee.ts b/test/operators/update-fee.ts new file mode 100644 index 00000000..02f62e27 --- /dev/null +++ b/test/operators/update-fee.ts @@ -0,0 +1,174 @@ +// Declare imports +import * as helpers from '../helpers/contract-helpers'; +import { expect } from 'chai'; +import { progressTime } from '../helpers/utils'; +import { trackGas, GasGroup } from '../helpers/gas-usage'; + +// Declare globals +let ssvNetworkContract: any, initialFee: any; + +describe('Operator Fee Tests', () => { + beforeEach(async () => { + ssvNetworkContract = (await helpers.initializeContract()).contract; + initialFee = helpers.CONFIG.minimalOperatorFee * 10; + await helpers.registerOperators(2, 1, initialFee); + }); + + it('Declare fee emits "OperatorFeeDeclaration"', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[2]).declareOperatorFee(1, initialFee + initialFee / 10 + )).to.emit(ssvNetworkContract, 'OperatorFeeDeclaration'); + }); + + it('Declare a lower fee gas limits', async () => { + await trackGas(ssvNetworkContract.declareOperatorFee(1, initialFee + initialFee / 10), [GasGroup.REGISTER_OPERATOR]); + }); + + it('Declare a higher fee gas limit', async () => { + await trackGas(ssvNetworkContract.declareOperatorFee(1, initialFee - initialFee / 20), [GasGroup.REGISTER_OPERATOR]); + }); + + it('Cancel declared fee emits "DeclaredOperatorFeeCancelation"', async () => { + await ssvNetworkContract.declareOperatorFee(1, initialFee + initialFee / 10); + await expect(ssvNetworkContract.connect(helpers.DB.owners[2]).cancelDeclaredOperatorFee(1 + )).to.emit(ssvNetworkContract, 'DeclaredOperatorFeeCancelation'); + }); + + it('Cancel declared fee gas limits', async () => { + await trackGas(ssvNetworkContract.declareOperatorFee(1, initialFee + initialFee / 10), [GasGroup.REGISTER_OPERATOR]); + await trackGas(ssvNetworkContract.cancelDeclaredOperatorFee(1), [GasGroup.REGISTER_OPERATOR]); + }); + + it('Execute declared fee emits "OperatorFeeExecution"', async () => { + await ssvNetworkContract.declareOperatorFee(1, initialFee + initialFee / 10); + await progressTime(helpers.CONFIG.declareOperatorFeePeriod); + await expect(ssvNetworkContract.connect(helpers.DB.owners[2]).executeOperatorFee(1 + )).to.emit(ssvNetworkContract, 'OperatorFeeExecution'); + }); + + it('Execute declared fee gas limits', async () => { + await trackGas(ssvNetworkContract.declareOperatorFee(1, initialFee + initialFee / 10), [GasGroup.REGISTER_OPERATOR]); + await progressTime(helpers.CONFIG.declareOperatorFeePeriod); + await trackGas(ssvNetworkContract.executeOperatorFee(1), [GasGroup.REGISTER_OPERATOR]); + }); + + it('Get operator fee', async () => { + expect(await ssvNetworkContract.getOperatorFee(1)).to.equal(initialFee); + }); + + it('Get fee from operator that does not exist reverts "OperatorNotFound"', async () => { + await expect(ssvNetworkContract.getOperatorFee(12 + )).to.be.revertedWith('OperatorNotFound'); + }); + + it('Declare fee of operator I do not own reverts "CallerNotOwner"', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).declareOperatorFee(1, initialFee + initialFee / 10 + )).to.be.revertedWith('CallerNotOwner'); + }); + + it('Declare fee with a wrong Publickey reverts "OperatorWithPublicKeyNotExist"', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).declareOperatorFee(12, initialFee + initialFee / 10 + )).to.be.revertedWith('OperatorWithPublicKeyNotExist'); + }); + + it('Declare fee with too low of a fee reverts "FeeTooLow"', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[2]).declareOperatorFee(1, helpers.CONFIG.minimalOperatorFee - 1 + )).to.be.revertedWith('FeeTooLow'); + }); + + it('Declare fee above the operators max fee increase limit reverts "FeeExceedsIncreaseLimit"', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[2]).declareOperatorFee(1, initialFee + initialFee / 5 + )).to.be.revertedWith('FeeExceedsIncreaseLimit'); + }); + + it('Cancel declared fee without a pending request reverts "NoPendingFeeChangeRequest"', async () => { + await expect(ssvNetworkContract.cancelDeclaredOperatorFee(1 + )).to.be.revertedWith('NoPendingFeeChangeRequest'); + }); + + it('Cancel declared fee of an operator I do not own reverts "CallerNotOwner"', async () => { + await trackGas(ssvNetworkContract.declareOperatorFee(1, initialFee + initialFee / 10), [GasGroup.REGISTER_OPERATOR]); + await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).cancelDeclaredOperatorFee(1 + )).to.be.revertedWith('CallerNotOwner'); + }); + + it('Execute declared fee of an operator I do not own reverts "CallerNotOwner"', async () => { + await trackGas(ssvNetworkContract.declareOperatorFee(1, initialFee + initialFee / 10), [GasGroup.REGISTER_OPERATOR]); + await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).executeOperatorFee(1 + )).to.be.revertedWith('CallerNotOwner'); + }); + + it('Execute declared fee without a pending request reverts "NoPendingFeeChangeRequest"', async () => { + await expect(ssvNetworkContract.executeOperatorFee(1 + )).to.be.revertedWith('NoPendingFeeChangeRequest'); + }); + + it('Execute declared fee too early reverts "ApprovalNotWithinTimeframe"', async () => { + await trackGas(ssvNetworkContract.declareOperatorFee(1, initialFee + initialFee / 10), [GasGroup.REGISTER_OPERATOR]); + await progressTime(helpers.CONFIG.declareOperatorFeePeriod - 10); + await expect(ssvNetworkContract.executeOperatorFee(1 + )).to.be.revertedWith('ApprovalNotWithinTimeframe'); + }); + + it('Execute declared fee too late reverts "ApprovalNotWithinTimeframe"', async () => { + await trackGas(ssvNetworkContract.declareOperatorFee(1, initialFee + initialFee / 10), [GasGroup.REGISTER_OPERATOR]); + await progressTime(helpers.CONFIG.declareOperatorFeePeriod + helpers.CONFIG.executeOperatorFeePeriod + 1); + await expect(ssvNetworkContract.executeOperatorFee(1 + )).to.be.revertedWith('ApprovalNotWithinTimeframe'); + }); + + //Dao + it('DAO increase the fee emits "OperatorFeeIncreaseLimitUpdate"', async () => { + await expect(ssvNetworkContract.updateOperatorFeeIncreaseLimit(1000 + )).to.emit(ssvNetworkContract, 'OperatorFeeIncreaseLimitUpdate'); + }); + + it('DAO update the declare fee period emits "DeclareOperatorFeePeriodUpdate"', async () => { + await expect(ssvNetworkContract.updateDeclareOperatorFeePeriod(1200 + )).to.emit(ssvNetworkContract, 'DeclareOperatorFeePeriodUpdate'); + }); + + it('DAO update the execute fee period emits "ExecuteOperatorFeePeriodUpdate"', async () => { + await expect(ssvNetworkContract.updateExecuteOperatorFeePeriod(1200 + )).to.emit(ssvNetworkContract, 'ExecuteOperatorFeePeriodUpdate'); + }); + + it('DAO get fee increase limit', async () => { + expect(await ssvNetworkContract.getOperatorFeeIncreaseLimit()).to.equal(helpers.CONFIG.operatorMaxFeeIncrease); + }); + + it('DAO get declared fee', async () => { + const newFee = initialFee + initialFee / 10; + await trackGas(ssvNetworkContract.declareOperatorFee(1, newFee), [GasGroup.REGISTER_OPERATOR]); + const [feeDeclaredInContract] = await ssvNetworkContract.getOperatorDeclaredFee(1); + expect(feeDeclaredInContract).to.equal(newFee); + }); + + it('DAO get declared fee period', async () => { + expect(await ssvNetworkContract.getDeclaredOperatorFeePeriod()).to.equal(helpers.CONFIG.declareOperatorFeePeriod); + }); + + it('DAO get execute fee period', async () => { + expect(await ssvNetworkContract.getExecuteOperatorFeePeriod()).to.equal(helpers.CONFIG.executeOperatorFeePeriod); + }); + + it('Increase fee from an address thats not the DAO reverts "caller is not the owner"', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).updateOperatorFeeIncreaseLimit(1000 + )).to.be.revertedWith('caller is not the owner'); + }); + + it('Update the declare fee period from an address thats not the DAO reverts "caller is not the owner"', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).updateDeclareOperatorFeePeriod(1200 + )).to.be.revertedWith('caller is not the owner'); + }); + + it('Update the execute fee period from an address thats not the DAO reverts "caller is not the owner"', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).updateExecuteOperatorFeePeriod(1200)) + .to.be.revertedWith('caller is not the owner'); + }); + + it('DAO declared fee without a pending request reverts "NoPendingFeeChangeRequest"', async () => { + await trackGas(ssvNetworkContract.declareOperatorFee(1, initialFee + initialFee / 10), [GasGroup.REGISTER_OPERATOR]); + await expect(ssvNetworkContract.getOperatorDeclaredFee(2 + )).to.be.revertedWith('NoPendingFeeChangeRequest'); + }); +}); \ No newline at end of file diff --git a/test/operators/update.ts b/test/operators/update.ts deleted file mode 100644 index f71667dd..00000000 --- a/test/operators/update.ts +++ /dev/null @@ -1,23 +0,0 @@ -import * as helpers from '../helpers/contract-helpers'; - -let ssvNetworkContract: any; - -describe('Update Operator Tests', () => { - beforeEach(async () => { - const contractData = await helpers.initializeContract(); - ssvNetworkContract = contractData.contract; - }); - - it('Update operator', async () => { - - }); - - it('Update operator errors', async () => { - - }); - - it('Update operator gas limits', async () => { - - }); - -}); From 72afcf3913e830338de53a2816f0191017f5ccca Mon Sep 17 00:00:00 2001 From: Wadym Date: Tue, 20 Dec 2022 10:27:51 +0100 Subject: [PATCH 100/149] Poc validator bytes (#132) Store pod hash data in storage --- contracts/ISSVNetwork.sol | 166 +++--- contracts/SSVNetwork.sol | 699 ++++++++++-------------- scripts/deploy.ts | 22 + scripts/ssv-registry-deploy.ts | 19 - scripts/ssv-registry-upgrade.ts | 19 - test/account/deposit.ts | 63 ++- test/account/withdraw.ts | 80 +-- test/dao/network-fee-withdraw.ts | 17 + test/helpers/contract-helpers.ts | 49 +- test/helpers/gas-usage.ts | 39 +- test/liquidate/liquidate.ts | 157 +++++- test/liquidate/liquidation-threshold.ts | 28 - test/liquidate/reactivate.ts | 95 +++- test/operators/remove.ts | 53 +- test/sanity/balances.ts | 86 ++- test/validators/register.ts | 565 ++++++++++++++++--- test/validators/remove.ts | 158 ++++-- test/validators/transfer-bulk.ts | 150 ----- test/validators/transfer.ts | 132 ----- 19 files changed, 1436 insertions(+), 1161 deletions(-) create mode 100644 scripts/deploy.ts delete mode 100644 scripts/ssv-registry-deploy.ts delete mode 100644 scripts/ssv-registry-upgrade.ts delete mode 100644 test/liquidate/liquidation-threshold.ts delete mode 100644 test/validators/transfer-bulk.ts delete mode 100644 test/validators/transfer.ts diff --git a/contracts/ISSVNetwork.sol b/contracts/ISSVNetwork.sol index 27cf7d4c..44d26ad7 100644 --- a/contracts/ISSVNetwork.sol +++ b/contracts/ISSVNetwork.sol @@ -5,6 +5,19 @@ import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; interface ISSVNetwork { + + struct Pod { + uint32 validatorCount; + + uint64 networkFee; + uint64 networkFeeIndex; + + uint64 index; + uint64 balance; + + bool disabled; + } + /**********/ /* Events */ /**********/ @@ -32,45 +45,26 @@ interface ISSVNetwork { /** * @dev Emitted when the validator has been added. * @param publicKey The public key of a validator. - * @param clusterId The cluster id the validator been added to. + * @param operatorIds The operator ids list. * @param shares snappy compressed shares(a set of encrypted and public shares). */ event ValidatorAdded( + address ownerAddress, + uint64[] operatorIds, bytes publicKey, - bytes32 clusterId, - bytes shares - ); - - /** - * @dev Emitted when validator was transferred between pods. - * @param publicKey The public key of a validator. - * @param clusterId The validator's new cluster id. - * @param shares snappy compressed shares(a set of encrypted and public shares). - */ - event ValidatorTransferred( - bytes publicKey, - bytes32 clusterId, bytes shares ); - /** - * @dev Emitted when validators were transferred between pods. - * @param publicKeys An array of transferred public keys. - * @param clusterId The validators new pod id. - * @param shares an array of snappy compressed shares(a set of encrypted and public shares). - */ - event BulkValidatorTransferred( - bytes[] publicKeys, - bytes32 clusterId, - bytes[] shares - ); - /** * @dev Emitted when the validator is removed. * @param publicKey The public key of a validator. - * @param clusterId The pod id the validator has been removed from. + * @param operatorIds The operator ids list. */ - event ValidatorRemoved(bytes publicKey, bytes32 clusterId); + event ValidatorRemoved( + address ownerAddress, + uint64[] operatorIds, + bytes publicKey + ); event OperatorFeeDeclaration( address indexed ownerAddress, @@ -101,9 +95,9 @@ interface ISSVNetwork { uint256 fee ); - event PodLiquidated(address ownerAddress, bytes32 clusterId); + event PodLiquidated(address ownerAddress, uint64[] operatorIds); - event PodEnabled(address ownerAddress, bytes32 clusterId); + event PodEnabled(address ownerAddress, uint64[] operatorIds); event OperatorFeeIncreaseLimitUpdate(uint64 value); @@ -111,7 +105,6 @@ interface ISSVNetwork { event ExecuteOperatorFeePeriodUpdate(uint256 value); - event PodCreated(address ownerAddress, bytes32 clusterId); /** * @dev Emitted when the network fee is updated. * @param oldFee The old fee @@ -126,11 +119,17 @@ interface ISSVNetwork { */ event NetworkFeesWithdrawal(uint256 value, address recipient); - event PodFundsWithdrawal(uint256 value, bytes32 clusterId, address owner); - event OperatorFundsWithdrawal(uint256 value, uint64 operatorId, address owner); + event PodFundsWithdrawal(address ownerAddress, uint64[] operatorIds, uint256 value); + event OperatorFundsWithdrawal(uint256 value, uint64 operatorId, address ownerAddress); - event FundsDeposit(uint256 value, bytes32 clusterId, address owner); + event FundsDeposit(uint256 value, bytes32 hashedPod, address owner); + + event PodMetadataUpdated( + address ownerAddress, + uint64[] operatorIds, + Pod pod + ); /**********/ /* Errors */ @@ -151,15 +150,14 @@ interface ISSVNetwork { error InvalidPublicKeyLength(); error OperatorIdsStructureInvalid(); error ValidatorNotOwned(); - error InvalidCluster(); error ParametersMismatch(); error NegativeBalance(); - error ClusterAlreadyExists(); - error ClusterNotExists(); error PodAlreadyEnabled(); - error PodAlreadyExists(); + error PodIsLiquidated(); error PodNotExists(); error BurnRatePositive(); + error PodDataIsBroken(); + error OperatorsListDoesNotSorted(); /****************/ /* Initializers */ @@ -209,66 +207,62 @@ interface ISSVNetwork { /* Validator External Functions */ /********************************/ - /** - * @dev Registers a new validator. - * @param publicKey Validator public key. - * @param clusterId Cluster id. - * @param shares snappy compressed shares(a set of encrypted and public shares). - */ function registerValidator( bytes calldata publicKey, - bytes32 clusterId, - bytes calldata shares + uint64[] memory operatorIds, + bytes calldata shares, + uint256 amount, + Pod memory pod ) external; - /** - * @dev Removes a validator. - * @param publicKey Validator's public key. - */ - function removeValidator(bytes calldata publicKey) external; - - /** - * @dev Transfers a validator. - * @param publicKey Validator public key. - * @param newClusterId new cluster id to transfer the validator to. - * @param shares snappy compressed shares(a set of encrypted and public shares). - */ - function transferValidator( + function removeValidator( bytes calldata publicKey, - bytes32 newClusterId, - bytes calldata shares - ) external; - - function bulkTransferValidators( - bytes[] calldata publicKey, - bytes32 fromClusterId, - bytes32 toClusterId, - bytes[] calldata shares + uint64[] memory operatorIds, + Pod memory pod ) external; /**************************/ /* Pod External Functions */ /**************************/ - function registerPod(uint64[] memory operatorIds, uint256 amount) external; - - function liquidate(address ownerAddress, bytes32 clusterId) external; + function liquidatePod( + address ownerAddress, + uint64[] memory operatorIds, + Pod memory pod + ) external; - function reactivatePod(bytes32 clusterId, uint256 amount) external; + function reactivatePod( + uint64[] memory operatorIds, + uint256 amount, + Pod memory pod + ) external; /******************************/ /* Balance External Functions */ /******************************/ - function deposit(address owner, bytes32 clusterId, uint256 amount) external; + function deposit( + address owner, + uint64[] memory operatorIds, + uint256 amount, + Pod memory pod + ) external; - function deposit(bytes32 clusterId, uint256 amount) external; + function deposit( + uint64[] memory operatorIds, + uint256 amount, + Pod memory pod + ) external; function withdrawOperatorBalance(uint64 operatorId, uint256 tokenAmount) external; function withdrawOperatorBalance(uint64 operatorId) external; - function withdrawPodBalance(bytes32 clusterId, uint256 tokenAmount) external; + function withdrawPodBalance( + uint64[] memory operatorIds, + uint256 tokenAmount, + Pod memory pod + ) external; /**************************/ /* DAO External Functions */ @@ -297,13 +291,17 @@ interface ISSVNetwork { /* Pod External View Functions */ /*******************************/ - function getClusterId(uint64[] memory operatorIds) external view returns(bytes32); - - function getPod(uint64[] memory operatorIds) external view returns(bytes32); - - function isLiquidatable(address ownerAddress, bytes32 clusterId) external view returns(bool); + function isLiquidatable( + address ownerAddress, + uint64[] memory operatorIds, + Pod memory pod + ) external view returns(bool); - function isLiquidated(address ownerAddress, bytes32 clusterId) external view returns(bool); + function isLiquidated( + address ownerAddress, + uint64[] memory operatorIds, + Pod memory pod + ) external view returns(bool); /***********************************/ /* Balance External View Functions */ @@ -318,7 +316,11 @@ interface ISSVNetwork { */ function operatorSnapshot(uint64 id) external view returns (uint64 currentBlock, uint64 index, uint256 balance); - function podBalanceOf(address owner, bytes32 clusterId) external view returns (uint256); + function podBalanceOf( + address ownerAddress, + uint64[] memory operatorIds, + Pod memory pod + ) external view returns (uint256); /*******************************/ /* DAO External View Functions */ diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index 87f95ec4..7571ab36 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -55,24 +55,13 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { Snapshot earnings; } - + /* struct Cluster { uint64[] operatorIds; } - - struct Pod { - uint32 validatorCount; - - uint64 networkFee; - uint64 networkFeeIndex; - - Snapshot usage; - - bool disabled; - } + */ struct Validator { - bytes32 clusterId; address owner; bool active; } @@ -96,8 +85,8 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { mapping(uint64 => Operator) private _operators; mapping(uint64 => OperatorFeeChangeRequest) private _operatorFeeChangeRequests; - mapping(bytes32 => Cluster) private _clusters; - mapping(bytes32 => Pod) private _pods; + // mapping(bytes32 => Cluster) private _clusters; + mapping(bytes32 => bytes32) private _pods; mapping(bytes32 => Validator) _validatorPKs; uint64 private _networkFee; @@ -242,337 +231,278 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { /********************************/ /* Validator External Functions */ /********************************/ - function registerValidator( bytes calldata publicKey, - bytes32 clusterId, - bytes calldata shares + uint64[] memory operatorIds, + bytes calldata shares, + uint256 amount, + Pod memory pod ) external override { - _validateClusterId(clusterId); - _validatePublicKey(publicKey); - - uint64[] memory operatorIds = _clusters[clusterId].operatorIds; - - bytes32 hashedValidator = keccak256(publicKey); - if (_validatorPKs[hashedValidator].clusterId > 0) { - revert ValidatorAlreadyExists(); + { + _validateOperatorIds(operatorIds); + _validatePublicKey(publicKey); } - bytes32 hashedPod = keccak256(abi.encodePacked(msg.sender, clusterId)); { - Pod memory pod; - - pod = _updatePodData(clusterId, 0, hashedPod, 1); - - { - if (!pod.disabled) { - for (uint64 i = 0; i < operatorIds.length; ++i) { - Operator memory operator = _operators[operatorIds[i]]; - if (operator.owner != address(0)) { - operator.snapshot = _getSnapshot(operator, uint64(block.number)); - ++operator.validatorCount; - _operators[operatorIds[i]] = operator; - } - } - } + if (_validatorPKs[keccak256(publicKey)].owner != address(0)) { + revert ValidatorAlreadyExists(); } + _validatorPKs[keccak256(publicKey)] = Validator({ owner: msg.sender, active: true}); + } - { - if (!pod.disabled) { - DAO memory dao = _dao; - dao = _updateDAOEarnings(dao); - ++dao.validatorCount; - _dao = dao; + uint64 podIndex; + uint64 burnRate; + { + if (!pod.disabled) { + for (uint8 i = 0; i < operatorIds.length; ++i) { + Operator memory operator = _operators[operatorIds[i]]; + if (operator.owner == address(0)) { + revert OperatorDoesNotExist(); + } else if (i+1 < operatorIds.length && operatorIds[i] > operatorIds[i+1]) { + revert OperatorsListDoesNotSorted(); + } + operator.snapshot = _getSnapshot(operator, uint64(block.number)); + ++operator.validatorCount; + podIndex += operator.snapshot.index + (uint64(block.number) - operator.snapshot.block) * operator.fee; + burnRate += operator.fee; + _operators[operatorIds[i]] = operator; } } + } - if (_liquidatable(pod.disabled, _podBalance(pod, _clusterCurrentIndex(clusterId)), pod.validatorCount, operatorIds)) { - revert NotEnoughBalance(); + bytes32 hashedPod = keccak256(abi.encodePacked(msg.sender, operatorIds)); + { + bytes32 hashedPodData = keccak256(abi.encodePacked(pod.validatorCount, pod.networkFee, pod.networkFeeIndex, pod.index, pod.balance, pod.disabled )); + if (_pods[hashedPod] == bytes32(0)) { + pod = Pod({ validatorCount: 0, networkFee: 0, networkFeeIndex: 0, index: 0, balance: 0, disabled: false }); + } else if (_pods[hashedPod] != hashedPodData) { + revert PodDataIsBroken(); } - - _pods[hashedPod] = pod; } - _validatorPKs[hashedValidator] = Validator({ owner: msg.sender, clusterId: clusterId, active: true}); + if (amount > 0) { + _deposit(msg.sender, hashedPod, amount.shrink()); + pod.balance += amount.shrink(); + } - emit ValidatorAdded(publicKey, clusterId, shares); - } + pod = _updatePodData(pod, podIndex, 1); - function removeValidator( - bytes calldata publicKey - ) external override { - _validatePublicKey(publicKey); - - bytes32 hashedValidator = keccak256(publicKey); - if (_validatorPKs[hashedValidator].owner != msg.sender) { - revert ValidatorNotOwned(); + if (_liquidatable(_podBalance(pod, podIndex), pod.validatorCount, burnRate)) { + revert NotEnoughBalance(); } - bytes32 clusterId = _validatorPKs[hashedValidator].clusterId; - bytes32 hashedPod = keccak256(abi.encodePacked(msg.sender, clusterId)); - { - _pods[hashedPod] = _updatePodData(clusterId, 0, hashedPod, -1); - - Cluster memory cluster = _clusters[clusterId]; - - for (uint64 i = 0; i < cluster.operatorIds.length; ++i) { - uint64 id = cluster.operatorIds[i]; - Operator memory operator = _operators[id]; - - if (operator.owner != address(0)) { - operator.snapshot = _getSnapshot(operator, uint64(block.number)); - --operator.validatorCount; - _operators[id] = operator; - } - } - - { - // update DAO earnings + if (!pod.disabled) { DAO memory dao = _dao; dao = _updateDAOEarnings(dao); - --dao.validatorCount; + ++dao.validatorCount; _dao = dao; } } - delete _validatorPKs[hashedValidator]; + _pods[hashedPod] = keccak256(abi.encodePacked(pod.validatorCount, pod.networkFee, pod.networkFeeIndex, pod.index, pod.balance, pod.disabled )); - emit ValidatorRemoved(publicKey, clusterId); + emit ValidatorAdded(msg.sender, operatorIds, publicKey, shares); + emit PodMetadataUpdated(msg.sender, operatorIds, pod); } - function transferValidator( + function removeValidator( bytes calldata publicKey, - bytes32 newClusterId, - bytes calldata shares + uint64[] memory operatorIds, + Pod memory pod ) external override { - _validateClusterId(newClusterId); - _validatePublicKey(publicKey); - - uint64[] memory operatorIds = _clusters[newClusterId].operatorIds; + { + _validateOperatorIds(operatorIds); + _validatePublicKey(publicKey); + } bytes32 hashedValidator = keccak256(publicKey); - bytes32 clusterId = _validatorPKs[hashedValidator].clusterId; - if (_validatorPKs[hashedValidator].owner != msg.sender) { revert ValidatorNotOwned(); } + uint64 podIndex; { - bytes32 hashedPod = keccak256(abi.encodePacked(msg.sender, clusterId)); - _pods[hashedPod] = _updatePodData(clusterId, 0, hashedPod, -1); - } - - { - _updateOperatorsOnTransfer(_clusters[clusterId].operatorIds, operatorIds, 1); - } - - { - Pod memory pod; - { - bytes32 hashedPod = keccak256(abi.encodePacked(msg.sender, newClusterId)); - - pod = _updatePodData(newClusterId, 0, hashedPod, 1); - _validatorPKs[hashedValidator].clusterId = newClusterId; - _pods[hashedPod] = pod; - } - - if (_liquidatable(pod.disabled, _podBalance(pod, _clusterCurrentIndex(newClusterId)), pod.validatorCount, operatorIds)) { - revert NotEnoughBalance(); + if (!pod.disabled) { + for (uint8 i = 0; i < operatorIds.length; ++i) { + Operator memory operator = _operators[operatorIds[i]]; + if (operator.owner != address(0)) { + operator.snapshot = _getSnapshot(operator, uint64(block.number)); + --operator.validatorCount; + podIndex += operator.snapshot.index + (uint64(block.number) - operator.snapshot.block) * operator.fee; + _operators[operatorIds[i]] = operator; + } + } } - - emit ValidatorTransferred(publicKey, newClusterId, shares); - } - } - - function bulkTransferValidators( - bytes[] calldata publicKeys, - bytes32 fromClusterId, - bytes32 toClusterId, - bytes[] calldata shares - ) external override { - _validateClusterId(fromClusterId); - _validateClusterId(toClusterId); - - if (publicKeys.length != shares.length) { - revert ParametersMismatch(); } - uint32 activeValidatorCount = 0; - - for (uint64 index = 0; index < publicKeys.length; ++index) { - _validatePublicKey(publicKeys[index]); + bytes32 hashedPod = _validateHashedPod(msg.sender, operatorIds, pod); - bytes32 hashedValidator = keccak256(publicKeys[index]); - Validator memory validator = _validatorPKs[hashedValidator]; - - if (validator.owner != msg.sender) { - revert ValidatorNotOwned(); - } + pod = _updatePodData(pod, podIndex, -1); - validator.clusterId = toClusterId; - _validatorPKs[hashedValidator] = validator; - - if (validator.active) { - ++activeValidatorCount; + { + if (!pod.disabled) { + DAO memory dao = _dao; + dao = _updateDAOEarnings(dao); + --dao.validatorCount; + _dao = dao; } - // Changing to a single event reducing by 15K gas - } - emit BulkValidatorTransferred(publicKeys, toClusterId, shares); - - uint64[] memory oldOperatorIds = _clusters[fromClusterId].operatorIds; - uint64[] memory newOperatorIds = _clusters[toClusterId].operatorIds; - - _updateOperatorsOnTransfer(oldOperatorIds, newOperatorIds, activeValidatorCount); - - Pod memory pod = _pods[keccak256(abi.encodePacked(msg.sender, fromClusterId))]; - uint64 podIndex = _clusterCurrentIndex(fromClusterId); - pod.usage.balance = _podBalance(pod, podIndex); - pod.usage.index = podIndex; - pod.usage.block = uint64(block.number); - pod.validatorCount -= activeValidatorCount; - - _pods[keccak256(abi.encodePacked(msg.sender, fromClusterId))] = pod; - - pod = _pods[keccak256(abi.encodePacked(msg.sender, toClusterId))]; - podIndex = _clusterCurrentIndex(toClusterId); - pod.usage.balance = _podBalance(pod, podIndex); - pod.usage.index = podIndex; - pod.usage.block = uint64(block.number); - pod.validatorCount += activeValidatorCount; - - _pods[keccak256(abi.encodePacked(msg.sender, toClusterId))] = pod; - - if (_liquidatable(pod.disabled, _podBalance(pod, podIndex), pod.validatorCount, newOperatorIds)) { - revert PodLiquidatable(); - } - } - - /**************************/ - /* Pod External Functions */ - /**************************/ - - function registerPod(uint64[] memory operatorIds, uint256 amount) external override { - _validateOperatorIds(operatorIds); - - bytes32 clusterId = keccak256(abi.encodePacked(operatorIds)); - - if (_clusters[clusterId].operatorIds.length == 0) { - _createClusterUnsafe(clusterId, operatorIds); - } - - bytes32 hashedPod = keccak256(abi.encodePacked(msg.sender, clusterId)); - - if (_pods[hashedPod].usage.block != 0) { - revert PodAlreadyExists(); } + delete _validatorPKs[hashedValidator]; - _pods[hashedPod].usage.block = uint64(block.number); - - emit PodCreated(msg.sender, clusterId); + _pods[hashedPod] = keccak256(abi.encodePacked(pod.validatorCount, pod.networkFee, pod.networkFeeIndex, pod.index, pod.balance, pod.disabled )); - _deposit(msg.sender, clusterId, amount.shrink()); + emit ValidatorRemoved(msg.sender, operatorIds, publicKey); + emit PodMetadataUpdated(msg.sender, operatorIds, pod); } - function liquidate(address ownerAddress, bytes32 clusterId) external override { - _validateClusterId(clusterId); + function liquidatePod( + address owner, + uint64[] memory operatorIds, + Pod memory pod + ) external override { + _validatePodIsNotLiquidated(pod); - uint64[] memory operatorIds = _clusters[clusterId].operatorIds; - bytes32 hashedPod = keccak256(abi.encodePacked(ownerAddress, clusterId)); + bytes32 hashedPod = _validateHashedPod(owner, operatorIds, pod); - Pod memory pod = _pods[hashedPod]; - uint64 podBalance = _podBalance(pod, _clusterCurrentIndex(clusterId)); // 4k gas usage + uint64 podIndex; + uint64 burnRate; { - if (!_liquidatable(pod.disabled, podBalance, pod.validatorCount, operatorIds)) { - revert PodNotLiquidatable(); - } - - for (uint64 index = 0; index < operatorIds.length; ++index) { // 19k gas usage - uint64 id = operatorIds[index]; - Operator memory operator = _operators[id]; - + for (uint8 i = 0; i < operatorIds.length; ++i) { + Operator memory operator = _operators[operatorIds[i]]; + uint64 currentBlock = uint64(block.number); if (operator.owner != address(0)) { - operator.snapshot = _getSnapshot(operator, uint64(block.number)); + operator.snapshot = _getSnapshot(operator, currentBlock); operator.validatorCount -= pod.validatorCount; - _operators[operatorIds[index]] = operator; + podIndex += operator.snapshot.index + (currentBlock - operator.snapshot.block) * operator.fee; + burnRate += operator.fee; + _operators[operatorIds[i]] = operator; } } + } - { - // update DAO earnings - DAO memory dao = _dao; - dao = _updateDAOEarnings(dao); - dao.validatorCount -= pod.validatorCount; - _dao = dao; + { + if (!_liquidatable(_podBalance(pod, podIndex), pod.validatorCount, burnRate)) { + revert PodNotLiquidatable(); } - _token.transfer(msg.sender, podBalance.expand()); - } + _token.transfer(msg.sender, _podBalance(pod, podIndex).expand()); - pod.disabled = true; - pod.usage.balance -= podBalance; + pod.disabled = true; + pod.balance = 0; + pod.index = 0; + } - emit PodLiquidated(ownerAddress, clusterId); + { + DAO memory dao = _dao; + dao = _updateDAOEarnings(dao); + dao.validatorCount -= pod.validatorCount; + _dao = dao; + } - _pods[hashedPod] = pod; + _pods[hashedPod] = keccak256(abi.encodePacked(pod.validatorCount, pod.networkFee, pod.networkFeeIndex, pod.index, pod.balance, pod.disabled )); + emit PodLiquidated(owner, operatorIds); + emit PodMetadataUpdated(owner, operatorIds, pod); } - function reactivatePod(bytes32 clusterId, uint256 amount) external override { - _validateClusterId(clusterId); - - bytes32 hashedPod = keccak256(abi.encodePacked(msg.sender, clusterId)); - Pod memory pod = _pods[hashedPod]; + function reactivatePod( + uint64[] memory operatorIds, + uint256 amount, + Pod memory pod + ) external override { if (!pod.disabled) { revert PodAlreadyEnabled(); } - _deposit(msg.sender, clusterId, amount.shrink()); // 28k gas usage - - uint64[] memory operatorIds = _clusters[clusterId].operatorIds; - - { // 112k gas usage - for (uint64 index = 0; index < operatorIds.length; ++index) { - uint64 id = operatorIds[index]; - Operator memory operator = _operators[id]; - + uint64 podIndex; + uint64 burnRate; + { + for (uint8 i = 0; i < operatorIds.length; ++i) { + Operator memory operator = _operators[operatorIds[i]]; if (operator.owner != address(0)) { operator.snapshot = _getSnapshot(operator, uint64(block.number)); operator.validatorCount += pod.validatorCount; - _operators[operatorIds[index]] = operator; + podIndex += operator.snapshot.index + (uint64(block.number) - operator.snapshot.block) * operator.fee; + burnRate += operator.fee; + _operators[operatorIds[i]] = operator; } } } - { // 30k gas usage + bytes32 hashedPod = _validateHashedPod(msg.sender, operatorIds, pod); + + if (amount > 0) { + _deposit(msg.sender, hashedPod, amount.shrink()); + pod.balance += amount.shrink(); + } + + pod.disabled = false; + pod.index = podIndex; + + pod = _updatePodData(pod, podIndex, 0); + + { DAO memory dao = _dao; dao = _updateDAOEarnings(dao); dao.validatorCount += pod.validatorCount; _dao = dao; } - pod.disabled = false; - pod = _updatePodData(clusterId, 0, hashedPod, 0); // 16k gas usage - _pods[hashedPod] = pod; + if (_liquidatable(_podBalance(pod, podIndex), pod.validatorCount, burnRate)) { + revert NotEnoughBalance(); + } + + _pods[hashedPod] = keccak256(abi.encodePacked(pod.validatorCount, pod.networkFee, pod.networkFeeIndex, pod.index, pod.balance, pod.disabled )); - emit PodEnabled(msg.sender, clusterId); + emit PodEnabled(msg.sender, operatorIds); + emit PodMetadataUpdated(msg.sender, operatorIds, pod); } /******************************/ /* Balance External Functions */ /******************************/ - function deposit(address owner, bytes32 clusterId, uint256 amount) external override { - _validateClusterId(clusterId); + function deposit( + address owner, + uint64[] memory operatorIds, + uint256 amount, + Pod memory pod + ) external override { + _validatePodIsNotLiquidated(pod); + + uint64 shrunkAmount = amount.shrink(); + + bytes32 hashedPod = _validateHashedPod(owner, operatorIds, pod); + + pod.balance += shrunkAmount; + + _deposit(owner, hashedPod, shrunkAmount); - _deposit(owner, clusterId, amount.shrink()); + _pods[hashedPod] = keccak256(abi.encodePacked(pod.validatorCount, pod.networkFee, pod.networkFeeIndex, pod.index, pod.balance, pod.disabled )); + + emit PodMetadataUpdated(owner, operatorIds, pod); } - function deposit(bytes32 clusterId, uint256 amount) external override { - _validateClusterId(clusterId); + function deposit( + uint64[] memory operatorIds, + uint256 amount, + Pod memory pod + ) external override { + _validatePodIsNotLiquidated(pod); + + uint64 shrunkAmount = amount.shrink(); + + bytes32 hashedPod = _validateHashedPod(msg.sender, operatorIds, pod); + + pod.balance += shrunkAmount; + + _deposit(msg.sender, hashedPod, shrunkAmount); - _deposit(msg.sender, clusterId, amount.shrink()); + _pods[hashedPod] = keccak256(abi.encodePacked(pod.validatorCount, pod.networkFee, pod.networkFeeIndex, pod.index, pod.balance, pod.disabled )); + + emit PodMetadataUpdated(msg.sender, operatorIds, pod); } function withdrawOperatorBalance(uint64 operatorId, uint256 amount) external override { @@ -615,28 +545,43 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _transferOperatorBalanceUnsafe(operatorId, operatorBalance.expand()); } - function withdrawPodBalance(bytes32 clusterId, uint256 amount) external override { - _validateClusterId(clusterId); + function withdrawPodBalance( + uint64[] memory operatorIds, + uint256 amount, + Pod memory pod + ) external override { + _validatePodIsNotLiquidated(pod); - bytes32 hashedPod = keccak256(abi.encodePacked(msg.sender, clusterId)); - uint64[] memory operatorIds = _clusters[clusterId].operatorIds; + uint64 shrunkAmount = amount.shrink(); - Pod memory pod = _pods[hashedPod]; - uint64 podBalance = _podBalance(pod, _clusterCurrentIndex(clusterId)); + uint64 podIndex; + uint64 burnRate; + { + for (uint8 i = 0; i < operatorIds.length; ++i) { + Operator memory operator = _operators[operatorIds[i]]; + if (operator.owner != address(0)) { + podIndex += operator.snapshot.index + (uint64(block.number) - operator.snapshot.block) * operator.fee; + burnRate += operator.fee; + } + } + } - uint64 shrunkAmount = amount.shrink(); + bytes32 hashedPod = _validateHashedPod(msg.sender, operatorIds, pod); - if (podBalance < shrunkAmount || _liquidatable(pod.disabled, podBalance, pod.validatorCount, operatorIds)) { + uint64 podBalance = _podBalance(pod, podIndex); + + if (podBalance < shrunkAmount || _liquidatable(_podBalance(pod, podIndex), pod.validatorCount, burnRate)) { revert NotEnoughBalance(); } - pod.usage.balance -= shrunkAmount; - - _pods[hashedPod] = pod; + pod.balance -= shrunkAmount; _token.transfer(msg.sender, amount); - emit PodFundsWithdrawal(amount, clusterId, msg.sender); + _pods[hashedPod] = keccak256(abi.encodePacked(pod.validatorCount, pod.networkFee, pod.networkFeeIndex, pod.index, pod.balance, pod.disabled )); + + emit PodFundsWithdrawal(msg.sender, operatorIds, amount); + emit PodMetadataUpdated(msg.sender, operatorIds, pod); } /**************************/ @@ -713,47 +658,36 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { /* Pod External View Functions */ /*******************************/ - function getClusterId(uint64[] memory operatorIds) external view override returns(bytes32) { - _validateOperatorIds(operatorIds); - - bytes32 clusterId = keccak256(abi.encodePacked(operatorIds)); - - if (_clusters[clusterId].operatorIds.length == 0) { - revert ClusterNotExists(); - } - - return clusterId; - } - - function getPod(uint64[] memory operatorIds) external view override returns(bytes32) { - _validateOperatorIds(operatorIds); - - bytes32 clusterId = keccak256(abi.encodePacked(operatorIds)); - - if (_pods[keccak256(abi.encodePacked(msg.sender, clusterId))].usage.block == 0) { - revert PodNotExists(); + function isLiquidatable( + address owner, + uint64[] memory operatorIds, + Pod memory pod + ) external view override returns (bool) { + uint64 podIndex; + uint64 burnRate; + { + for (uint8 i = 0; i < operatorIds.length; ++i) { + Operator memory operator = _operators[operatorIds[i]]; + if (operator.owner != address(0)) { + podIndex += operator.snapshot.index + (uint64(block.number) - operator.snapshot.block) * operator.fee; + burnRate += operator.fee; + } + } } - return clusterId; - } - - function isLiquidatable(address ownerAddress, bytes32 clusterId) external view override returns (bool) { - _validateClusterId(clusterId); - - uint64[] memory operatorIds = _clusters[clusterId].operatorIds; - bytes32 hashedPod = keccak256(abi.encodePacked(ownerAddress, clusterId)); + _validateHashedPod(owner, operatorIds, pod); - Pod memory pod = _pods[hashedPod]; - - return _liquidatable(pod.disabled, _podBalance(pod, _clusterCurrentIndex(clusterId)), pod.validatorCount, operatorIds); + return _liquidatable(_podBalance(pod, podIndex), pod.validatorCount, burnRate); } - function isLiquidated(address ownerAddress, bytes32 clusterId) external view override returns (bool) { - _validateClusterId(clusterId); - - bytes32 hashedPod = keccak256(abi.encodePacked(ownerAddress, clusterId)); + function isLiquidated( + address owner, + uint64[] memory operatorIds, + Pod memory pod + ) external view override returns (bool) { + _validateHashedPod(owner, operatorIds, pod); - return _pods[hashedPod].disabled; + return pod.disabled; } /***********************************/ @@ -765,9 +699,26 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { return (s.block, s.index, s.balance.expand()); } - function podBalanceOf(address owner, bytes32 clusterId) external view override returns (uint256) { - Pod memory pod = _pods[keccak256(abi.encodePacked(owner, clusterId))]; - return _podBalance(pod, _clusterCurrentIndex(clusterId)).expand(); + function podBalanceOf( + address owner, + uint64[] memory operatorIds, + Pod memory pod + ) external view override returns (uint256) { + _validatePodIsNotLiquidated(pod); + + uint64 podIndex; + { + for (uint8 i = 0; i < operatorIds.length; ++i) { + Operator memory operator = _operators[operatorIds[i]]; + if (operator.owner != address(0)) { + podIndex += operator.snapshot.index + (uint64(block.number) - operator.snapshot.block) * operator.fee; + } + } + } + + _validateHashedPod(owner, operatorIds, pod); + + return _podBalance(pod, podIndex).expand(); } /*******************************/ @@ -811,12 +762,6 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } } - function _validateClusterId(bytes32 clusterId) private view { - if (_clusters[clusterId].operatorIds.length == 0) { - revert ClusterNotExists(); - } - } - function _validatePublicKey(bytes memory publicKey) private pure { if (publicKey.length != 48) { revert InvalidPublicKeyLength(); @@ -829,63 +774,16 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } } + function _validatePodIsNotLiquidated(Pod memory pod) private pure { + if (pod.disabled) { + revert PodIsLiquidated(); + } + } + /******************************/ /* Operator Private Functions */ /******************************/ - function _updateOperatorsOnTransfer( - uint64[] memory oldOperatorIds, - uint64[] memory newOperatorIds, - uint32 validatorCount - ) private { - uint64 oldIndex; - uint64 newIndex; - uint64 currentBlock = uint64(block.number); - - while (oldIndex < oldOperatorIds.length && newIndex < newOperatorIds.length) { - if (oldOperatorIds[oldIndex] < newOperatorIds[newIndex]) { - Operator memory operator = _operators[oldOperatorIds[oldIndex]]; - if (operator.owner != address(0)) { - operator.snapshot = _getSnapshot(operator, currentBlock); - operator.validatorCount -= validatorCount; - _operators[oldOperatorIds[oldIndex]] = operator; - } - ++oldIndex; - } else if (newOperatorIds[newIndex] < oldOperatorIds[oldIndex]) { - Operator memory operator = _operators[newOperatorIds[newIndex]]; - if (operator.owner != address(0)) { - operator.snapshot = _getSnapshot(operator, currentBlock); - operator.validatorCount += validatorCount; - _operators[newOperatorIds[newIndex]] = operator; - } - ++newIndex; - } else { - ++oldIndex; - ++newIndex; - } - } - - while (oldIndex < oldOperatorIds.length) { - Operator memory operator = _operators[oldOperatorIds[oldIndex]]; - if (operator.owner != address(0)) { - operator.snapshot = _getSnapshot(operator, currentBlock); - operator.validatorCount -= validatorCount; - _operators[oldOperatorIds[oldIndex]] = operator; - } - ++oldIndex; - } - - while (newIndex < newOperatorIds.length) { - Operator memory operator = _operators[newOperatorIds[newIndex]]; - if (operator.owner != address(0)) { - operator.snapshot = _getSnapshot(operator, currentBlock); - operator.validatorCount += validatorCount; - _operators[newOperatorIds[newIndex]] = operator; - } - ++newIndex; - } - } - function _setFee(Operator memory operator, uint64 fee) private view returns (Operator memory) { operator.snapshot = _getSnapshot(operator, uint64(block.number)); operator.fee = fee; @@ -920,28 +818,28 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { /* Pod Private Functions */ /*************************/ - function _createClusterUnsafe(bytes32 key, uint64[] memory operatorIds) private { - for (uint64 i = 0; i < operatorIds.length; i++) { - if (_operators[operatorIds[i]].owner == address(0)) { - revert OperatorDoesNotExist(); - } - if (i+1 < operatorIds.length) { - require(operatorIds[i] <= operatorIds[i+1], "The operators list should be in ascending order"); + function _validateHashedPod(address owner, uint64[] memory operatorIds, Pod memory pod) private view returns (bytes32) { + bytes32 hashedPod = keccak256(abi.encodePacked(owner, operatorIds)); + { + bytes32 hashedPodData = keccak256(abi.encodePacked(pod.validatorCount, pod.networkFee, pod.networkFeeIndex, pod.index, pod.balance, pod.disabled )); + if (_pods[hashedPod] == bytes32(0)) { + revert PodNotExists(); + } else if (_pods[hashedPod] != hashedPodData) { + revert PodDataIsBroken(); } } - _clusters[key] = Cluster({operatorIds: operatorIds}); + return hashedPod; } - function _updatePodData(bytes32 clusterId, uint64 amount, bytes32 hashedPod, int8 changedTo) private view returns (Pod memory) { - Pod memory pod = _pods[hashedPod]; - uint64 podIndex = _clusterCurrentIndex(clusterId); - pod.usage.balance = _podBalance(pod, podIndex) + amount; - pod.usage.index = podIndex; - pod.usage.block = uint64(block.number); + function _updatePodData(Pod memory pod, uint64 podIndex, int8 changedTo) private view returns (Pod memory) { + if (!pod.disabled) { + pod.balance = _podBalance(pod, podIndex); + pod.index = podIndex; - pod.networkFee = _podNetworkFee(pod); - pod.networkFeeIndex = _currentNetworkFeeIndex(); + pod.networkFee = _podNetworkFee(pod.networkFee, pod.networkFeeIndex, pod.validatorCount); + pod.networkFeeIndex = _currentNetworkFeeIndex(); + } if (changedTo == 1) { ++pod.validatorCount; @@ -952,25 +850,17 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { return pod; } - function _liquidatable(bool disabled, uint64 balance, uint64 validatorCount, uint64[] memory operatorIds) private view returns (bool) { - return !disabled && balance < LIQUIDATION_MIN_BLOCKS * (_burnRatePerValidator(operatorIds) + _networkFee) * validatorCount; + function _liquidatable(uint64 balance, uint64 validatorCount, uint64 burnRate) private view returns (bool) { + return balance < LIQUIDATION_MIN_BLOCKS * (burnRate + _networkFee) * validatorCount; } - /*****************************/ /* Balance Private Functions */ /*****************************/ - function _deposit(address owner, bytes32 clusterId, uint64 amount) private { - bytes32 hashedPod = keccak256(abi.encodePacked(owner, clusterId)); - - _pods[hashedPod].usage.balance += amount; // 22k gas usage - - uint256 expandedAmount = amount.expand(); - - _token.transferFrom(msg.sender, address(this), expandedAmount); // 20k gas usage - - emit FundsDeposit(expandedAmount, clusterId, owner); // 2k gas usage + function _deposit(address owner, bytes32 hashedPod, uint64 amount) private { + _token.transferFrom(msg.sender, address(this), amount.expand()); + emit FundsDeposit(amount.expand(), hashedPod, owner); } function _updateNetworkFeeIndex() private { @@ -997,32 +887,17 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { return _networkTotalEarnings(dao) - dao.withdrawn; } - function _clusterCurrentIndex(bytes32 podId) private view returns (uint64 podIndex) { - Cluster memory cluster = _clusters[podId]; - uint64 currentBlock = uint64(block.number); - for (uint64 i = 0; i < cluster.operatorIds.length; ++i) { - Snapshot memory s = _operators[cluster.operatorIds[i]].snapshot; - podIndex += s.index + (currentBlock - s.block) * _operators[cluster.operatorIds[i]].fee; - } - } - - function _podBalance(Pod memory pod, uint64 currentPodIndex) private view returns (uint64) { - uint64 usage = (currentPodIndex - pod.usage.index) * pod.validatorCount + _podNetworkFee(pod); + function _podBalance(Pod memory pod, uint64 newIndex) private view returns (uint64) { + uint64 usage = (newIndex - pod.index) * pod.validatorCount + _podNetworkFee(pod.networkFee, pod.networkFeeIndex, pod.validatorCount); - if (usage > pod.usage.balance) { + if (usage > pod.balance) { revert NegativeBalance(); } - return pod.usage.balance - usage; + return pod.balance - usage; } - function _podNetworkFee(Pod memory pod) private view returns (uint64) { - return pod.networkFee + uint64(_currentNetworkFeeIndex() - pod.networkFeeIndex) * pod.validatorCount; - } - - function _burnRatePerValidator(uint64[] memory operatorIds) private view returns (uint64 rate) { - for (uint64 i = 0; i < operatorIds.length; ++i) { - rate += _operators[operatorIds[i]].fee; - } + function _podNetworkFee(uint64 networkFee, uint64 networkFeeIndex, uint32 validatorCount) private view returns (uint64) { + return networkFee + uint64(_currentNetworkFeeIndex() - networkFeeIndex) * validatorCount; } } diff --git a/scripts/deploy.ts b/scripts/deploy.ts new file mode 100644 index 00000000..24f33a46 --- /dev/null +++ b/scripts/deploy.ts @@ -0,0 +1,22 @@ +import { ethers, upgrades } from 'hardhat'; + +async function main() { + const ssvTokenAddress = process.env.SSVTOKEN_ADDRESS; + const ssvNetworkFactory = await ethers.getContractFactory('SSVNetwork'); + console.log(`Deploying SSVNetwork with ssvToken ${ssvTokenAddress}...`); + const contract = await upgrades.deployProxy(ssvNetworkFactory, [ + ssvTokenAddress, + process.env.OPERATOR_MAX_FEE_INCREASE, + process.env.DECLARE_OPERATOR_FEE_PERIOD, + process.env.EXECUTE_OPERATOR_FEE_PERIOD + ]); + await contract.deployed(); + console.log(`SSVNetwork deployed to: ${contract.address}`); +} + +main() + .then(() => process.exit(0)) + .catch(error => { + console.error(error); + process.exit(1); + }); diff --git a/scripts/ssv-registry-deploy.ts b/scripts/ssv-registry-deploy.ts deleted file mode 100644 index e95361c7..00000000 --- a/scripts/ssv-registry-deploy.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { ethers, upgrades } from 'hardhat'; -import { publishAbi } from './utils'; - -async function main() { - await publishAbi('SSVRegistry'); - - const ssvRegistryFactory = await ethers.getContractFactory('SSVRegistry'); - console.log('Deploying ssvRegistryFactory...'); - const contract = await upgrades.deployProxy(ssvRegistryFactory, { initializer: false }); - await contract.deployed(); - console.log(`SSVRegistry deployed to: ${contract.address}`); -} - -main() - .then(() => process.exit(0)) - .catch(error => { - console.error(error); - process.exit(1); - }); diff --git a/scripts/ssv-registry-upgrade.ts b/scripts/ssv-registry-upgrade.ts deleted file mode 100644 index c8978625..00000000 --- a/scripts/ssv-registry-upgrade.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { ethers, upgrades } from 'hardhat'; -import { publishAbi } from './utils'; - -async function main() { - await publishAbi('SSVNetwork'); - - const proxyAddress = process.env.PROXY_ADDRESS || ''; - const ContractUpgraded = await ethers.getContractFactory('SSVRegistry'); - console.log('Running upgrade...'); - const newContract = await upgrades.upgradeProxy(proxyAddress, ContractUpgraded); - console.log(`SSVRegistry upgraded at: ${newContract.address}`); -} - -main() - .then(() => process.exit(0)) - .catch(error => { - console.error(error); - process.exit(1); - }); diff --git a/test/account/deposit.ts b/test/account/deposit.ts index 9dfe1ed9..d485c287 100644 --- a/test/account/deposit.ts +++ b/test/account/deposit.ts @@ -3,53 +3,64 @@ import * as helpers from '../helpers/contract-helpers'; import { expect } from 'chai'; import { trackGas, GasGroup } from '../helpers/gas-usage'; -// Declare globals -let ssvNetworkContract: any, clusterResult1: any, minDepositAmount: any; +let ssvNetworkContract: any, pod1: any, minDepositAmount: any; describe('Deposit Tests', () => { beforeEach(async () => { // Initialize contract ssvNetworkContract = (await helpers.initializeContract()).contract; - // Register operators await helpers.registerOperators(0, 12, helpers.CONFIG.minimalOperatorFee); - + // Define the operator fee minDepositAmount = (helpers.CONFIG.minimalBlocksBeforeLiquidation + 10) * helpers.CONFIG.minimalOperatorFee * 4; + // cold register + await helpers.DB.ssvToken.connect(helpers.DB.owners[6]).approve(helpers.DB.ssvNetwork.contract.address, '1000000000000000'); + await ssvNetworkContract.connect(helpers.DB.owners[6]).registerValidator( + '0x221111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111119', + [1,2,3,4], + helpers.DataGenerator.shares(0), + '1000000000000000', + { + validatorCount: 0, + networkFee: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + disabled: false + } + ); + // Register validators - clusterResult1 = await helpers.registerValidators(4, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); - }); - - it('Deposit to a pod I own emits "FundsDeposit"', async () => { - await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); - await expect(ssvNetworkContract.connect(helpers.DB.owners[1])['deposit(bytes32,uint256)'](clusterResult1.clusterId, minDepositAmount - )).to.emit(ssvNetworkContract, 'FundsDeposit'); + pod1 = await helpers.registerValidators(4, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); }); - it('Deposit to a pod I own gas limits', async () => { - await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1])['deposit(bytes32,uint256)'](clusterResult1.clusterId, minDepositAmount), [GasGroup.DEPOSIT]); + it('Deposit to a pod I own emits "FundsDeposit', async () => { + await helpers.DB.ssvToken.connect(helpers.DB.owners[4]).approve(ssvNetworkContract.address, minDepositAmount); + await expect(ssvNetworkContract.connect(helpers.DB.owners[4])['deposit(uint64[],uint256,(uint32,uint64,uint64,uint64,uint64,bool))'](pod1.args.operatorIds, minDepositAmount, pod1.args.pod)).to.emit(ssvNetworkContract, 'FundsDeposit'); }); it('Deposit to a pod I do not own emits "FundsDeposit"', async () => { await helpers.DB.ssvToken.connect(helpers.DB.owners[0]).approve(ssvNetworkContract.address, minDepositAmount); - await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['deposit(address,bytes32,uint256)'](helpers.DB.owners[1].address, clusterResult1.clusterId, minDepositAmount - )).to.emit(ssvNetworkContract, 'FundsDeposit'); + await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['deposit(address,uint64[],uint256,(uint32,uint64,uint64,uint64,uint64,bool))'](helpers.DB.owners[4].address, pod1.args.operatorIds, minDepositAmount, pod1.args.pod)).to.emit(ssvNetworkContract, 'FundsDeposit'); }); - it('Deposit to a pod 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(address,bytes32,uint256)'](helpers.DB.owners[1].address, clusterResult1.clusterId, minDepositAmount), [GasGroup.DEPOSIT]); + it('Deposit to a pod I do own with a pod that does not exist reverts "PodNotExists"', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[1])['deposit(uint64[],uint256,(uint32,uint64,uint64,uint64,uint64,bool))'](pod1.args.operatorIds, minDepositAmount, pod1.args.pod)).to.be.revertedWith('PodNotExists'); + }); + + it('Deposit to a pod I do not own with a pod that does not exist reverts "PodNotExists"', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[4])['deposit(uint64[],uint256,(uint32,uint64,uint64,uint64,uint64,bool))']([1,2,4,5], minDepositAmount, pod1.args.pod)).to.be.revertedWith('PodNotExists'); }); - it('Deposit to a pod I do own with a cluster that does not exist reverts "ClusterNotExists"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[1])['deposit(bytes32,uint256)']('0x392791df626408017a264f53fde61065d5a93a32b60171df9d8a46afdf82992c', minDepositAmount - )).to.be.revertedWith('ClusterNotExists'); + it('Deposit to a pod 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(uint64[],uint256,(uint32,uint64,uint64,uint64,uint64,bool))'](pod1.args.operatorIds, minDepositAmount, pod1.args.pod), [GasGroup.DEPOSIT]); }); - it('Deposit to a pod I do not own with a cluster that does not exist reverts "ClusterNotExists"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['deposit(address,bytes32,uint256)'](helpers.DB.owners[1].address, '0x392791df626408017a264f53fde61065d5a93a32b60171df9d8a46afdf82992c', minDepositAmount - )).to.be.revertedWith('ClusterNotExists'); + it('Deposit to a pod 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(address,uint64[],uint256,(uint32,uint64,uint64,uint64,uint64,bool))'](helpers.DB.owners[4].address, pod1.args.operatorIds, minDepositAmount, pod1.args.pod), [GasGroup.DEPOSIT]); }); -}); \ No newline at end of file +}); diff --git a/test/account/withdraw.ts b/test/account/withdraw.ts index 44e9c1d0..cf25ea5f 100644 --- a/test/account/withdraw.ts +++ b/test/account/withdraw.ts @@ -4,8 +4,7 @@ import * as utils from '../helpers/utils'; import { expect } from 'chai'; import { trackGas, GasGroup } from '../helpers/gas-usage'; -// Declare globals -let ssvNetworkContract: any, clusterResult1: any, minDepositAmount: any; +let ssvNetworkContract: any, pod1: any, minDepositAmount: any; describe('Withdraw Tests', () => { beforeEach(async () => { @@ -18,50 +17,71 @@ describe('Withdraw Tests', () => { minDepositAmount = (helpers.CONFIG.minimalBlocksBeforeLiquidation + 10) * helpers.CONFIG.minimalOperatorFee * 4; // Register validators - clusterResult1 = await helpers.registerValidators(4, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + // cold register + await helpers.DB.ssvToken.connect(helpers.DB.owners[6]).approve(helpers.DB.ssvNetwork.contract.address, '1000000000000000'); + await ssvNetworkContract.connect(helpers.DB.owners[6]).registerValidator( + '0x221111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111119', + [1,2,3,4], + helpers.DataGenerator.shares(0), + '1000000000000000', + { + validatorCount: 0, + networkFee: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + disabled: false + } + ); + + pod1 = await helpers.registerValidators(4, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); }); it('Withdraw from pod emits "PodFundsWithdrawal"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).withdrawPodBalance(clusterResult1.clusterId, helpers.CONFIG.minimalOperatorFee - )).to.emit(ssvNetworkContract, 'PodFundsWithdrawal'); + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).withdrawPodBalance(pod1.args.operatorIds, helpers.CONFIG.minimalOperatorFee, pod1.args.pod)).to.emit(ssvNetworkContract, 'PodFundsWithdrawal'); }); - it('Withdraw from pod gas limits', async () => { - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).withdrawPodBalance(clusterResult1.clusterId, helpers.CONFIG.minimalOperatorFee), [GasGroup.WITHDRAW]); + it('Withdraw from pod emits "PodFundsWithdrawal" after removed operator', async () => { + await ssvNetworkContract.removeOperator(1); // TODO remove operator logic rething + await utils.progressBlocks(10); + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).withdrawPodBalance(pod1.args.operatorIds, helpers.CONFIG.minimalOperatorFee, pod1.args.pod)).to.emit(ssvNetworkContract, 'PodFundsWithdrawal'); }); - it('Withdraw from operator balance emits "OperatorFundsWithdrawal"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorBalance(uint64,uint256)'](1, helpers.CONFIG.minimalOperatorFee - )).to.emit(ssvNetworkContract, 'OperatorFundsWithdrawal'); + it('Withdraw from a pod reverts "NotEnoughBalance"', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).withdrawPodBalance(pod1.args.operatorIds, minDepositAmount, pod1.args.pod)).to.be.revertedWith('NotEnoughBalance'); }); - it('Withdraw from operator balance gas limits', async () => { - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorBalance(uint64,uint256)'](1, helpers.CONFIG.minimalOperatorFee), [GasGroup.WITHDRAW]); + it('Withdraw from a liquidatable pod reverts "NotEnoughBalance"', async () => { + await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).withdrawPodBalance(pod1.args.operatorIds, helpers.CONFIG.minimalOperatorFee, pod1.args.pod)).to.be.revertedWith('NotEnoughBalance'); + }); + + it('Withdraw from pod gas limits', async () => { + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).withdrawPodBalance(pod1.args.operatorIds, helpers.CONFIG.minimalOperatorFee, pod1.args.pod), [GasGroup.WITHDRAW_POD_BALANCE]); + }); + + it('Withdraw from operator balance emits "OperatorFundsWithdrawal"', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorBalance(uint64,uint256)'](1, helpers.CONFIG.minimalOperatorFee)).to.emit(ssvNetworkContract, 'OperatorFundsWithdrawal'); }); it('Withdraw the total operator balance emits "OperatorFundsWithdrawal"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorBalance(uint64)'](1 - )).to.emit(ssvNetworkContract, 'OperatorFundsWithdrawal'); + await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorBalance(uint64)'](1)).to.emit(ssvNetworkContract, 'OperatorFundsWithdrawal'); }); - it('Withdraw the total operator balance gas limits', async () => { - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorBalance(uint64)'](1), [GasGroup.WITHDRAW]); + it('Withdraw balance from an operator I do not own reverts "CallerNotOwner"', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[2])['withdrawOperatorBalance(uint64,uint256)'](1, minDepositAmount)).to.be.revertedWith('CallerNotOwner'); }); - it('Withdraw more than the operators balance reverts "NotEnoughBalance"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).withdrawPodBalance(clusterResult1.clusterId, minDepositAmount - )).to.be.revertedWith('NotEnoughBalance'); + it('Withdraw operator balance returns an error - NotEnoughBalance', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorBalance(uint64,uint256)'](1, minDepositAmount)).to.be.revertedWith('NotEnoughBalance'); }); - it('Withdraw from a liquidatable pod reverts "NotEnoughBalance"', async () => { - await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).withdrawPodBalance(clusterResult1.clusterId, helpers.CONFIG.minimalOperatorFee - )).to.be.revertedWith('NotEnoughBalance'); + it('Withdraw from operator balance gas limits', async () => { + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorBalance(uint64,uint256)'](1, helpers.CONFIG.minimalOperatorFee), [GasGroup.WITHDRAW_OPERATOR_BALANCE]); }); - it('Withdraw balance from an operator I do not own reverts "CallerNotOwner"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[2])['withdrawOperatorBalance(uint64,uint256)'](1, minDepositAmount - )).to.be.revertedWith('CallerNotOwner'); + it('Withdraw the total operator balance gas limits', async () => { + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorBalance(uint64)'](1), [GasGroup.WITHDRAW_OPERATOR_BALANCE]); }); it('Withdraw more than the operator balance reverts "NotEnoughBalance"', async () => { @@ -70,12 +90,10 @@ describe('Withdraw Tests', () => { }); it('Withdraw the total balance from an operator I do not own reverts "CallerNotOwner"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[2])['withdrawOperatorBalance(uint64)'](12 - )).to.be.revertedWith('CallerNotOwner'); + await expect(ssvNetworkContract.connect(helpers.DB.owners[2])['withdrawOperatorBalance(uint64)'](12)).to.be.revertedWith('CallerNotOwner'); }); it('Withdraw more than the operator total balance reverts "NotEnoughBalance"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorBalance(uint64)'](12 - )).to.be.revertedWith('NotEnoughBalance'); + await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorBalance(uint64)'](12)).to.be.revertedWith('NotEnoughBalance'); }); -}); \ No newline at end of file +}); diff --git a/test/dao/network-fee-withdraw.ts b/test/dao/network-fee-withdraw.ts index 245a9989..bc7a092c 100644 --- a/test/dao/network-fee-withdraw.ts +++ b/test/dao/network-fee-withdraw.ts @@ -28,6 +28,23 @@ describe('DAO Network Fee Withdraw Tests', () => { await ssvNetworkContract.updateNetworkFee(networkFee); // Register validators + // cold register + await helpers.DB.ssvToken.connect(helpers.DB.owners[6]).approve(helpers.DB.ssvNetwork.contract.address, '1000000000000000'); + await ssvNetworkContract.connect(helpers.DB.owners[6]).registerValidator( + '0x221111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111119', + [1,2,3,4], + helpers.DataGenerator.shares(0), + '1000000000000000', + { + validatorCount: 0, + networkFee: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + disabled: false + } + ); + await helpers.registerValidators(4, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); await utils.progressBlocks(10); diff --git a/test/helpers/contract-helpers.ts b/test/helpers/contract-helpers.ts index 76c100b4..3d818fd0 100644 --- a/test/helpers/contract-helpers.ts +++ b/test/helpers/contract-helpers.ts @@ -83,6 +83,7 @@ export const initializeContract = async () => { await DB.ssvToken.mint(DB.owners[3].address, '1000000000000000'); await DB.ssvToken.mint(DB.owners[4].address, '1000000000000000'); await DB.ssvToken.mint(DB.owners[5].address, '1000000000000000'); + await DB.ssvToken.mint(DB.owners[6].address, '1000000000000000'); return { contract: DB.ssvNetwork.contract, owner: DB.ssvNetwork.owner, ssvToken: DB.ssvToken }; }; @@ -105,44 +106,44 @@ export const deposit = async (ownerId: number, clusterId: string, amount: string await DB.ssvNetwork.contract.connect(DB.owners[ownerId])['deposit(bytes32,uint256)'](clusterId, amount); }; -export const registerPodAndDeposit = async(ownerId: number, operatorIds: number[], amount: string): Promise => { - let clusterId; - try { - await DB.ssvToken.connect(DB.owners[ownerId]).approve(DB.ssvNetwork.contract.address, amount); - const clusterTx = await (await DB.ssvNetwork.contract.connect(DB.owners[ownerId]).registerPod(operatorIds, amount)).wait(); - clusterId = clusterTx.events[0].args.clusterId; - } catch (e) { - clusterId = await DB.ssvNetwork.contract.getClusterId(operatorIds); - if (+amount > 0) { - await deposit(ownerId, clusterId, amount); - } - } - return { clusterId }; -}; - export const registerValidators = async (ownerId: number, numberOfValidators: number, amount: string, operatorIds: number[], gasGroups?: GasGroup[]) => { const validators: any = []; - let clusterId: any; - + let args: any; // Register validators to contract for (let i = 0; i < numberOfValidators; i++) { const publicKey = DataGenerator.publicKey(DB.validators.length); const shares = DataGenerator.shares(DB.validators.length); - const { eventsByName } = await trackGas(DB.ssvNetwork.contract.connect(DB.owners[ownerId]).registerValidator( + 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, - (await registerPodAndDeposit(ownerId, operatorIds, amount)).clusterId, + operatorIds, shares, + amount, + { + validatorCount: 0, + networkFee: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + disabled: false + } ), gasGroups); - clusterId = eventsByName.ValidatorAdded[0].args.clusterId; - DB.clusters[clusterId] = ({ id: clusterId, operatorIds }); - DB.validators.push({ publicKey, clusterId, shares }); + args = result.eventsByName.PodMetadataUpdated[0].args; + + DB.validators.push({ publicKey, operatorIds, shares }); validators.push({ publicKey, shares }); } - return { validators, clusterId }; + return { validators, args }; }; +export const getPod = (payload: any) => ethers.utils.AbiCoder.prototype.encode( + ['tuple(uint32 validatorCount, uint64 networkFee, uint64 networkFeeIndex, uint64 index, uint64 balance, bool disabled) pod'], + [ payload ] +); + +/* export const transferValidator = async (ownerId: number, publicKey: string, operatorIds: number[], amount: string, gasGroups?: GasGroup[]) => { // let podId: any; const shares = DataGenerator.shares(DB.validators.length); @@ -195,4 +196,4 @@ export const liquidate = async (executorOwnerId: number, liquidatedOwnerId: numb const clusterId = eventsByName.AccountLiquidated[0].args.clusterId; return { clusterId }; }; - +*/ diff --git a/test/helpers/gas-usage.ts b/test/helpers/gas-usage.ts index e31290f8..be830cfb 100644 --- a/test/helpers/gas-usage.ts +++ b/test/helpers/gas-usage.ts @@ -5,8 +5,17 @@ export enum GasGroup { REMOVE_OPERATOR, REMOVE_OPERATOR_WITH_WITHDRAW, REGISTER_VALIDATOR_EXISTING_POD, - REGISTER_VALIDATOR_EXISTING_CLUSTER, REGISTER_VALIDATOR_NEW_STATE, + REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT, + + REGISTER_VALIDATOR_EXISTING_POD_7, + REGISTER_VALIDATOR_NEW_STATE_7, + REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_7, + + REGISTER_VALIDATOR_EXISTING_POD_13, + REGISTER_VALIDATOR_NEW_STATE_13, + REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_13, + REMOVE_VALIDATOR, TRANSFER_VALIDATOR_NEW_CLUSTER, TRANSFER_VALIDATOR, @@ -14,7 +23,8 @@ export enum GasGroup { BULK_TRANSFER_VALIDATOR, BULK_TRANSFER_VALIDATOR_NON_EXISTING_POD, DEPOSIT, - WITHDRAW, + WITHDRAW_POD_BALANCE, + WITHDRAW_OPERATOR_BALANCE, REGISTER_POD, LIQUIDATE_POD, REACTIVATE_POD, @@ -23,11 +33,21 @@ export enum GasGroup { const MAX_GAS_PER_GROUP: any = { /* REAL GAS LIMITS */ [GasGroup.REGISTER_OPERATOR]: 105000, - [GasGroup.REMOVE_OPERATOR]: 45000, + [GasGroup.REMOVE_OPERATOR]: 51500, [GasGroup.REMOVE_OPERATOR_WITH_WITHDRAW]: 52000, - [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]: 199000, - [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]: 216000, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE]: 313000, + + [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]: 174000, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE]: 191100, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT]: 151100, + + [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_7]: 217100, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]: 234100, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_7]: 194100, + + [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_13]: 303200, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]: 320200, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_13]: 280200, + [GasGroup.REMOVE_VALIDATOR]: 120000, [GasGroup.TRANSFER_VALIDATOR_NEW_CLUSTER]: 400000, [GasGroup.TRANSFER_VALIDATOR]: 260000, @@ -35,10 +55,11 @@ const MAX_GAS_PER_GROUP: any = { [GasGroup.BULK_TRANSFER_VALIDATOR]: 366000, [GasGroup.BULK_TRANSFER_VALIDATOR_NON_EXISTING_POD]: 383000, [GasGroup.DEPOSIT]: 77500, - [GasGroup.WITHDRAW]: 102000, + [GasGroup.WITHDRAW_POD_BALANCE]: 93100, + [GasGroup.WITHDRAW_OPERATOR_BALANCE]: 59000, [GasGroup.REGISTER_POD]: 137000, - [GasGroup.LIQUIDATE_POD]: 156000, - [GasGroup.REACTIVATE_POD]: 163000, + [GasGroup.LIQUIDATE_POD]: 135000, + [GasGroup.REACTIVATE_POD]: 135000, }; class GasStats { diff --git a/test/liquidate/liquidate.ts b/test/liquidate/liquidate.ts index 8c3f8682..6bb6bef1 100644 --- a/test/liquidate/liquidate.ts +++ b/test/liquidate/liquidate.ts @@ -4,8 +4,7 @@ import * as utils from '../helpers/utils'; import { expect } from 'chai'; import { trackGas, GasGroup } from '../helpers/gas-usage'; -// Declare globals -let ssvNetworkContract: any, clusterResult1: any, minDepositAmount: any; +let ssvNetworkContract: any, minDepositAmount: any, firstPod: any; describe('Liquidate Tests', () => { beforeEach(async () => { @@ -17,49 +16,153 @@ describe('Liquidate Tests', () => { minDepositAmount = (helpers.CONFIG.minimalBlocksBeforeLiquidation + 10) * helpers.CONFIG.minimalOperatorFee * 4; - // Register validators - clusterResult1 = await helpers.registerValidators(4, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); - }); + // cold register + await helpers.DB.ssvToken.connect(helpers.DB.owners[6]).approve(helpers.DB.ssvNetwork.contract.address, '1000000000000000'); + await ssvNetworkContract.connect(helpers.DB.owners[6]).registerValidator( + '0x221111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111119', + [1,2,3,4], + helpers.DataGenerator.shares(0), + '1000000000000000', + { + validatorCount: 0, + networkFee: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + disabled: false + } + ); - it('Liquidate a pod emits "PodLiquidated"', async () => { - await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - await expect(ssvNetworkContract.liquidate(helpers.DB.owners[4].address, clusterResult1.clusterId - )).to.emit(ssvNetworkContract, 'PodLiquidated'); + // 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(0), + minDepositAmount, + { + validatorCount: 0, + networkFee: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + disabled: false + } + ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + firstPod = register.eventsByName.PodMetadataUpdated[0].args; }); - it('Liquidate a pod gas limits', async () => { + it('Get if the pod is liquidatable', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).liquidate(helpers.DB.owners[4].address, clusterResult1.clusterId), [GasGroup.LIQUIDATE_POD]); + expect(await ssvNetworkContract.isLiquidatable(firstPod.ownerAddress, firstPod.operatorIds, firstPod.pod)).to.equal(true); }); - it('Get if the pod is liquidatable', async () => { - await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - expect(await ssvNetworkContract.isLiquidatable(helpers.DB.owners[4].address, clusterResult1.clusterId)).to.equal(true); + it('Liquidatable with removed operator', async () => { + await ssvNetworkContract.removeOperator(1); + await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); // TMP IT FAILS WITH PROGRESS BLOCK, CRITICAL ERROR IN INDEX MATH LOGIC + expect(await ssvNetworkContract.isLiquidatable(firstPod.ownerAddress, firstPod.operatorIds, firstPod.pod)).to.equal(true); }); - it('Get if the pod is liquidated', async () => { + it('Liquidate emits PodLiquidated event', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - await ssvNetworkContract.liquidate(helpers.DB.owners[4].address, clusterResult1.clusterId); - expect(await ssvNetworkContract.isLiquidated(helpers.DB.owners[4].address, clusterResult1.clusterId)).to.equal(true); + + await expect(ssvNetworkContract.liquidatePod( + firstPod.ownerAddress, + firstPod.operatorIds, + firstPod.pod + )).to.emit(ssvNetworkContract, 'PodLiquidated'); }); - it('Liquidate validator with a removed operator in a cluster', async () => { + it('Liquidate validator with removed operator in a pod', async () => { await ssvNetworkContract.removeOperator(1); await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); // TMP IT FAILS WITH PROGRESS BLOCK, CRITICAL ERROR IN INDEX MATH LOGIC - await trackGas(ssvNetworkContract.liquidate(helpers.DB.owners[4].address, clusterResult1.clusterId), [GasGroup.LIQUIDATE_POD]); + await trackGas(ssvNetworkContract.liquidatePod( + firstPod.ownerAddress, + firstPod.operatorIds, + firstPod.pod + ), [GasGroup.LIQUIDATE_POD]); }); - it('Liquidate and register validator to disabled pod', async () => { + it('Liquidate and register validator in disabled pod', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - await trackGas(ssvNetworkContract.liquidate(helpers.DB.owners[4].address, clusterResult1.clusterId), [GasGroup.LIQUIDATE_POD]); + const liquidatedPod = await trackGas(ssvNetworkContract.liquidatePod( + firstPod.ownerAddress, + firstPod.operatorIds, + firstPod.pod + ), [GasGroup.LIQUIDATE_POD]); + const updatedPod = liquidatedPod.eventsByName.PodMetadataUpdated[0].args; await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - await helpers.DB.ssvToken.connect(helpers.DB.owners[4]).approve(ssvNetworkContract.address, minDepositAmount); - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4])['deposit(bytes32,uint256)'](clusterResult1.clusterId, minDepositAmount), [GasGroup.DEPOSIT]); - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).registerValidator(helpers.DataGenerator.publicKey(9), clusterResult1.clusterId, helpers.DataGenerator.shares(0)), [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]); + await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, `${minDepositAmount*2}`); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( + helpers.DataGenerator.publicKey(2), + updatedPod.operatorIds, + helpers.DataGenerator.shares(0), + `${minDepositAmount*2}`, + updatedPod.pod + ), [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]); }); - + it('Liquidate a pod that is not liquidatable reverts "PodNotLiquidatable"', async () => { - await expect(ssvNetworkContract.liquidate(helpers.DB.owners[4].address, clusterResult1.clusterId + await expect(ssvNetworkContract.liquidatePod( + firstPod.ownerAddress, + firstPod.operatorIds, + firstPod.pod )).to.be.revertedWith('PodNotLiquidatable'); }); -}); \ No newline at end of file + + it('Liquidate a pod that is not liquidatable reverts "PodDataIsBroken"', async () => { + await expect(ssvNetworkContract.liquidatePod( + firstPod.ownerAddress, + firstPod.operatorIds, + { + validatorCount: 0, + networkFee: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + disabled: false + } + )).to.be.revertedWith('PodDataIsBroken'); + }); + + it('Liquidate second time a pod that is liquidated already reverts "PodIsLiquidated"', async () => { + await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); + const liquidatedPod = await trackGas(ssvNetworkContract.liquidatePod( + firstPod.ownerAddress, + firstPod.operatorIds, + firstPod.pod + ), [GasGroup.LIQUIDATE_POD]); + const updatedPod = liquidatedPod.eventsByName.PodMetadataUpdated[0].args; + + await expect(ssvNetworkContract.liquidatePod( + firstPod.ownerAddress, + updatedPod.operatorIds, + updatedPod.pod + )).to.be.revertedWith('PodIsLiquidated'); + }); + + it('Is liquidated', async () => { + await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); + const liquidatedPod = await trackGas(ssvNetworkContract.liquidatePod( + firstPod.ownerAddress, + firstPod.operatorIds, + firstPod.pod + ), [GasGroup.LIQUIDATE_POD]); + const updatedPod = liquidatedPod.eventsByName.PodMetadataUpdated[0].args; + + expect(await ssvNetworkContract.isLiquidated(firstPod.ownerAddress, firstPod.operatorIds, updatedPod.pod)).to.equal(true); + }); + + it('Is liquidated reverts "PodNotExists"', async () => { + await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); + const liquidatedPod = await trackGas(ssvNetworkContract.liquidatePod( + firstPod.ownerAddress, + firstPod.operatorIds, + firstPod.pod + ), [GasGroup.LIQUIDATE_POD]); + const updatedPod = liquidatedPod.eventsByName.PodMetadataUpdated[0].args; + + await expect(ssvNetworkContract.isLiquidated(helpers.DB.owners[0].address, firstPod.operatorIds, updatedPod.pod)).to.be.revertedWith('PodNotExists'); + }); + +}); diff --git a/test/liquidate/liquidation-threshold.ts b/test/liquidate/liquidation-threshold.ts deleted file mode 100644 index 18bcbd05..00000000 --- a/test/liquidate/liquidation-threshold.ts +++ /dev/null @@ -1,28 +0,0 @@ -import * as helpers from '../helpers/contract-helpers'; - -let ssvNetworkContract: any; - - -describe('Liquidation Threshold Tests', () => { - beforeEach(async () => { - const contractData = await helpers.initializeContract(); - ssvNetworkContract = contractData.contract; - }); - - it('Get liquidation threshold', async () => { - - }); - - it('Change liquidation threshold', async () => { - - }); - - it('Change liquidation threshold errors', async () => { - - }); - - it('Liquidation threshold gas limits', async () => { - - }); - -}); diff --git a/test/liquidate/reactivate.ts b/test/liquidate/reactivate.ts index ed183753..a8ffe9f1 100644 --- a/test/liquidate/reactivate.ts +++ b/test/liquidate/reactivate.ts @@ -4,8 +4,7 @@ import * as utils from '../helpers/utils'; import { expect } from 'chai'; import { trackGas, GasGroup } from '../helpers/gas-usage'; -// Declare globals -let ssvNetworkContract: any, clusterResult1: any, minDepositAmount: any; +let ssvNetworkContract: any, minDepositAmount: any, firstPod: any; describe('Reactivate Tests', () => { beforeEach(async () => { @@ -18,42 +17,86 @@ describe('Reactivate Tests', () => { minDepositAmount = (helpers.CONFIG.minimalBlocksBeforeLiquidation + 10) * helpers.CONFIG.minimalOperatorFee * 4; // Register validators - clusterResult1 = await helpers.registerValidators(4, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + // cold register + await helpers.DB.ssvToken.connect(helpers.DB.owners[6]).approve(helpers.DB.ssvNetwork.contract.address, '1000000000000000'); + await ssvNetworkContract.connect(helpers.DB.owners[6]).registerValidator( + '0x221111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111119', + [1,2,3,4], + helpers.DataGenerator.shares(0), + '1000000000000000', + { + validatorCount: 0, + networkFee: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + disabled: false + } + ); + + // 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(0), + minDepositAmount, + { + validatorCount: 0, + networkFee: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + disabled: false + } + ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + firstPod = register.eventsByName.PodMetadataUpdated[0].args; }); it('Reactivate a disabled pod emits "PodEnabled"', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - await ssvNetworkContract.liquidate(helpers.DB.owners[4].address, clusterResult1.clusterId); - await helpers.DB.ssvToken.connect(helpers.DB.owners[4]).approve(ssvNetworkContract.address, minDepositAmount); - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).reactivatePod(clusterResult1.clusterId, minDepositAmount - )).to.emit(ssvNetworkContract, 'PodEnabled'); - }); - - it('Reactivate a disabled pod gas limits', async () => { - await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - await ssvNetworkContract.liquidate(helpers.DB.owners[4].address, clusterResult1.clusterId); - await helpers.DB.ssvToken.connect(helpers.DB.owners[4]).approve(ssvNetworkContract.address, minDepositAmount); - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).reactivatePod(clusterResult1.clusterId, minDepositAmount), [GasGroup.REACTIVATE_POD]); + const liquidatedPod = await trackGas(ssvNetworkContract.liquidatePod(firstPod.ownerAddress, firstPod.operatorIds, firstPod.pod), [GasGroup.LIQUIDATE_POD]); + const updatedPod = liquidatedPod.eventsByName.PodMetadataUpdated[0].args; + await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); + + await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).reactivatePod(updatedPod.operatorIds, minDepositAmount, updatedPod.pod)).to.emit(ssvNetworkContract, 'PodEnabled'); }); - it('Reactivate a pod with a removed operator in the cluster', async () => { + it('Reactivate with 0 deposit and no validators emits PodEnabled', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - await ssvNetworkContract.liquidate(helpers.DB.owners[4].address, clusterResult1.clusterId); - await ssvNetworkContract.removeOperator(1); - await helpers.DB.ssvToken.connect(helpers.DB.owners[4]).approve(ssvNetworkContract.address, minDepositAmount); - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).reactivatePod(clusterResult1.clusterId, minDepositAmount), [GasGroup.REACTIVATE_POD]); + const liquidatedPod = await trackGas(ssvNetworkContract.liquidatePod(firstPod.ownerAddress, firstPod.operatorIds, firstPod.pod), [GasGroup.LIQUIDATE_POD]); + const updatedPod = liquidatedPod.eventsByName.PodMetadataUpdated[0].args; + + const remove = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).removeValidator( + helpers.DataGenerator.publicKey(1), + firstPod.operatorIds, + updatedPod.pod + ), [GasGroup.REMOVE_VALIDATOR]); + const updatedPodAfrerRemove = remove.eventsByName.PodMetadataUpdated[0].args; + + await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).reactivatePod(updatedPodAfrerRemove.operatorIds, 0, updatedPodAfrerRemove.pod)).to.emit(ssvNetworkContract, 'PodEnabled'); }); it('Reactivate an enabled pod reverts "PodAlreadyEnabled"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).reactivatePod(clusterResult1.clusterId, minDepositAmount - )).to.be.revertedWith('PodAlreadyEnabled'); + await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).reactivatePod(firstPod.operatorIds, minDepositAmount, firstPod.pod)).to.be.revertedWith('PodAlreadyEnabled'); }); it('Reactivate a pod when the amount is not enough reverts "NegativeBalance"', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - await ssvNetworkContract.liquidate(helpers.DB.owners[4].address, clusterResult1.clusterId); - await helpers.DB.ssvToken.connect(helpers.DB.owners[4]).approve(ssvNetworkContract.address, helpers.CONFIG.minimalOperatorFee * 4); - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).reactivatePod(clusterResult1.clusterId, helpers.CONFIG.minimalOperatorFee * 4 - )).to.be.revertedWith('NegativeBalance'); + const liquidatedPod = await trackGas(ssvNetworkContract.liquidatePod(firstPod.ownerAddress, firstPod.operatorIds, firstPod.pod), [GasGroup.LIQUIDATE_POD]); + const updatedPod = liquidatedPod.eventsByName.PodMetadataUpdated[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]).reactivatePod(updatedPod.operatorIds, helpers.CONFIG.minimalOperatorFee, updatedPod.pod)).to.be.revertedWith('NotEnoughBalance'); + }); + + it('Reactivate a pod with a removed operator in the cluster', async () => { + await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); + const liquidatedPod = await trackGas(ssvNetworkContract.liquidatePod(firstPod.ownerAddress, firstPod.operatorIds, firstPod.pod), [GasGroup.LIQUIDATE_POD]); + const updatedPod = liquidatedPod.eventsByName.PodMetadataUpdated[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]).reactivatePod(updatedPod.operatorIds, minDepositAmount, updatedPod.pod), [GasGroup.REACTIVATE_POD]); }); -}); \ No newline at end of file +}); diff --git a/test/operators/remove.ts b/test/operators/remove.ts index be0237da..e6788da1 100644 --- a/test/operators/remove.ts +++ b/test/operators/remove.ts @@ -1,6 +1,5 @@ // Declare imports import * as helpers from '../helpers/contract-helpers'; -import * as utils from '../helpers/utils'; import { expect } from 'chai'; import { trackGas, GasGroup } from '../helpers/gas-usage'; @@ -10,35 +9,53 @@ let ssvNetworkContract: any; describe('Remove Operator Tests', () => { beforeEach(async () => { ssvNetworkContract = (await helpers.initializeContract()).contract; + // Register operators + await helpers.registerOperators(0, 5, helpers.CONFIG.minimalOperatorFee); + + // Register a validator + // cold register + await helpers.DB.ssvToken.connect(helpers.DB.owners[6]).approve(helpers.DB.ssvNetwork.contract.address, '1000000000000000'); + await ssvNetworkContract.connect(helpers.DB.owners[6]).registerValidator( + '0x221111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111119', + [1,2,3,4], + helpers.DataGenerator.shares(0), + '1000000000000000', + { + validatorCount: 0, + networkFee: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + disabled: false + } + ); }); it('Remove operator emits "OperatorRemoved"', async () => { - await helpers.registerOperators(0, 1, helpers.CONFIG.minimalOperatorFee); - await expect(ssvNetworkContract.connect(helpers.DB.owners[0]).removeOperator(1 - )).to.emit(ssvNetworkContract, 'OperatorRemoved').withArgs(1); + await expect(ssvNetworkContract.connect(helpers.DB.owners[0]).removeOperator(1)) + .to.emit(ssvNetworkContract, 'OperatorRemoved').withArgs(1); + }); + + it('Remove operator I do not own reverts "CallerNotOwner"', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).removeOperator(1)) + .to.be.revertedWith('CallerNotOwner'); }); it('Remove operator gas limits', async () => { - await helpers.registerOperators(0, 1, helpers.CONFIG.minimalOperatorFee); await trackGas(ssvNetworkContract.removeOperator(1), [GasGroup.REMOVE_OPERATOR]); }); + it('Remove operator with 0 balance', async () => { + await expect(ssvNetworkContract.removeOperator(5)).not.to.emit(ssvNetworkContract, 'OperatorFundsWithdrawal'); + }); + it('Remove operator with a balance emits "OperatorFundsWithdrawal"', async () => { - await helpers.registerOperators(0, 4, helpers.CONFIG.minimalOperatorFee); - await helpers.registerValidators(4, 1, `${helpers.CONFIG.minimalBlocksBeforeLiquidation * helpers.CONFIG.minimalOperatorFee * 4}`, [1, 2, 3, 4], [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); - await expect(ssvNetworkContract.removeOperator(1 - )).to.emit(ssvNetworkContract, 'OperatorFundsWithdrawal'); + await helpers.registerValidators(4, 1, `${helpers.CONFIG.minimalBlocksBeforeLiquidation * helpers.CONFIG.minimalOperatorFee * 4}`, [1,2,3,4], [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + await expect(ssvNetworkContract.removeOperator(1)).to.emit(ssvNetworkContract, 'OperatorFundsWithdrawal'); }); it('Remove operator with a balance gas limits', async () => { - await helpers.registerOperators(0, 4, helpers.CONFIG.minimalOperatorFee); - 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, 1, `${helpers.CONFIG.minimalBlocksBeforeLiquidation * helpers.CONFIG.minimalOperatorFee * 4}`, [1,2,3,4], [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 helpers.registerOperators(0, 1, helpers.CONFIG.minimalOperatorFee); - await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).removeOperator(1 - )).to.be.revertedWith('CallerNotOwner'); - }); -}); \ No newline at end of file +}); diff --git a/test/sanity/balances.ts b/test/sanity/balances.ts index 14ce6b7d..9291dc23 100644 --- a/test/sanity/balances.ts +++ b/test/sanity/balances.ts @@ -4,7 +4,7 @@ import * as utils from '../helpers/utils'; import { expect } from 'chai'; import { GasGroup } from '../helpers/gas-usage'; -let ssvNetworkContract: any, clusterResult1: any, minDepositAmount: any, burnPerBlock: any, networkFee: any; +let ssvNetworkContract: any, pod1: any, minDepositAmount: any, burnPerBlock: any, networkFee: any, initNetworkFeeBalance: any; describe('Balance Tests', () => { beforeEach(async () => { @@ -25,68 +25,98 @@ describe('Balance Tests', () => { await ssvNetworkContract.updateNetworkFee(networkFee); // Register validators - clusterResult1 = await helpers.registerValidators(4, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + // cold register + await helpers.DB.ssvToken.connect(helpers.DB.owners[6]).approve(helpers.DB.ssvNetwork.contract.address, '1000000000000000'); + await ssvNetworkContract.connect(helpers.DB.owners[6]).registerValidator( + '0x221111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111119', + [1,2,3,4], + helpers.DataGenerator.shares(0), + '1000000000000000', + { + validatorCount: 0, + networkFee: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + disabled: false + } + ); + + pod1 = await helpers.registerValidators(4, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + initNetworkFeeBalance = await ssvNetworkContract.getNetworkBalance(); }); it('Check pod balance in three blocks, one after the other', async () => { await utils.progressBlocks(1); - expect(await ssvNetworkContract.podBalanceOf(helpers.DB.owners[4].address, clusterResult1.clusterId)).to.equal(minDepositAmount - burnPerBlock); + expect(await ssvNetworkContract.podBalanceOf(helpers.DB.owners[4].address, pod1.args.operatorIds, pod1.args.pod)).to.equal(minDepositAmount - burnPerBlock); await utils.progressBlocks(1); - expect(await ssvNetworkContract.podBalanceOf(helpers.DB.owners[4].address, clusterResult1.clusterId)).to.equal(minDepositAmount - burnPerBlock * 2); + expect(await ssvNetworkContract.podBalanceOf(helpers.DB.owners[4].address, pod1.args.operatorIds, pod1.args.pod)).to.equal(minDepositAmount - burnPerBlock * 2); await utils.progressBlocks(1); - expect(await ssvNetworkContract.podBalanceOf(helpers.DB.owners[4].address, clusterResult1.clusterId)).to.equal(minDepositAmount - burnPerBlock * 3); + expect(await ssvNetworkContract.podBalanceOf(helpers.DB.owners[4].address, pod1.args.operatorIds, pod1.args.pod)).to.equal(minDepositAmount - burnPerBlock * 3); }); it('Check pod balance in two and twelve blocks, after network fee updates', async () => { await utils.progressBlocks(1); - expect(await ssvNetworkContract.podBalanceOf(helpers.DB.owners[4].address, clusterResult1.clusterId)).to.equal(minDepositAmount - burnPerBlock); + expect(await ssvNetworkContract.podBalanceOf(helpers.DB.owners[4].address, pod1.args.operatorIds, pod1.args.pod)).to.equal(minDepositAmount - burnPerBlock); const newBurnPerBlock = burnPerBlock + networkFee; await ssvNetworkContract.updateNetworkFee(networkFee * 2); await utils.progressBlocks(1); - expect(await ssvNetworkContract.podBalanceOf(helpers.DB.owners[4].address, clusterResult1.clusterId)).to.equal(minDepositAmount - burnPerBlock * 2 - newBurnPerBlock); + expect(await ssvNetworkContract.podBalanceOf(helpers.DB.owners[4].address, pod1.args.operatorIds, pod1.args.pod)).to.equal(minDepositAmount - burnPerBlock * 2 - newBurnPerBlock); await utils.progressBlocks(1); - expect(await ssvNetworkContract.podBalanceOf(helpers.DB.owners[4].address, clusterResult1.clusterId)).to.equal(minDepositAmount - burnPerBlock * 2 - newBurnPerBlock * 2); + expect(await ssvNetworkContract.podBalanceOf(helpers.DB.owners[4].address, pod1.args.operatorIds, pod1.args.pod)).to.equal(minDepositAmount - burnPerBlock * 2 - newBurnPerBlock * 2); await utils.progressBlocks(10); - expect(await ssvNetworkContract.podBalanceOf(helpers.DB.owners[4].address, clusterResult1.clusterId)).to.equal(minDepositAmount - burnPerBlock * 2 - newBurnPerBlock * 12); + expect(await ssvNetworkContract.podBalanceOf(helpers.DB.owners[4].address, pod1.args.operatorIds, pod1.args.pod)).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 ssvNetworkContract.getNetworkBalance()).to.equal(networkFee); + expect(await ssvNetworkContract.getNetworkBalance() - initNetworkFeeBalance).to.equal(networkFee * 2); await utils.progressBlocks(1); - expect(await ssvNetworkContract.getNetworkBalance()).to.equal(networkFee * 2); + expect(await ssvNetworkContract.getNetworkBalance() - initNetworkFeeBalance).to.equal(networkFee * 4); await utils.progressBlocks(1); - expect(await ssvNetworkContract.getNetworkBalance()).to.equal(networkFee * 3); + expect(await ssvNetworkContract.getNetworkBalance() - 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 ssvNetworkContract.getNetworkBalance()).to.equal(networkFee); + expect(await ssvNetworkContract.getNetworkBalance() - initNetworkFeeBalance).to.equal(networkFee * 2); const newNetworkFee = networkFee * 2; await ssvNetworkContract.updateNetworkFee(newNetworkFee); await utils.progressBlocks(1); - expect(await ssvNetworkContract.getNetworkBalance()).to.equal(networkFee * 2 + newNetworkFee); + expect(await ssvNetworkContract.getNetworkBalance() - initNetworkFeeBalance).to.equal(networkFee * 4 + newNetworkFee * 2); await utils.progressBlocks(1); - expect(await ssvNetworkContract.getNetworkBalance()).to.equal(networkFee * 2 + newNetworkFee * 2); + expect(await ssvNetworkContract.getNetworkBalance() - initNetworkFeeBalance).to.equal(networkFee * 4 + newNetworkFee * 4); await utils.progressBlocks(10); - expect(await ssvNetworkContract.getNetworkBalance()).to.equal(networkFee * 2 + newNetworkFee * 12); + expect(await ssvNetworkContract.getNetworkBalance() - 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 ssvNetworkContract.operatorSnapshot(1)).balance).to.equal(helpers.CONFIG.minimalOperatorFee); - expect((await ssvNetworkContract.operatorSnapshot(2)).balance).to.equal(helpers.CONFIG.minimalOperatorFee); - expect((await ssvNetworkContract.operatorSnapshot(3)).balance).to.equal(helpers.CONFIG.minimalOperatorFee); - expect((await ssvNetworkContract.operatorSnapshot(4)).balance).to.equal(helpers.CONFIG.minimalOperatorFee); + expect((await ssvNetworkContract.operatorSnapshot(1)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 2 + helpers.CONFIG.minimalOperatorFee * 2); + expect((await ssvNetworkContract.operatorSnapshot(2)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 2 + helpers.CONFIG.minimalOperatorFee * 2); + expect((await ssvNetworkContract.operatorSnapshot(3)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 2 + helpers.CONFIG.minimalOperatorFee * 2); + expect((await ssvNetworkContract.operatorSnapshot(4)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 2 + helpers.CONFIG.minimalOperatorFee * 2); await utils.progressBlocks(1); - expect((await ssvNetworkContract.operatorSnapshot(1)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 2); - expect((await ssvNetworkContract.operatorSnapshot(2)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 2); - expect((await ssvNetworkContract.operatorSnapshot(3)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 2); - expect((await ssvNetworkContract.operatorSnapshot(4)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 2); + expect((await ssvNetworkContract.operatorSnapshot(1)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 4 + helpers.CONFIG.minimalOperatorFee * 2); + expect((await ssvNetworkContract.operatorSnapshot(2)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 4 + helpers.CONFIG.minimalOperatorFee * 2); + expect((await ssvNetworkContract.operatorSnapshot(3)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 4 + helpers.CONFIG.minimalOperatorFee * 2); + expect((await ssvNetworkContract.operatorSnapshot(4)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 4 + helpers.CONFIG.minimalOperatorFee * 2); await utils.progressBlocks(1); - expect((await ssvNetworkContract.operatorSnapshot(1)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 3); - expect((await ssvNetworkContract.operatorSnapshot(2)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 3); - expect((await ssvNetworkContract.operatorSnapshot(3)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 3); - expect((await ssvNetworkContract.operatorSnapshot(4)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 3); + expect((await ssvNetworkContract.operatorSnapshot(1)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 6 + helpers.CONFIG.minimalOperatorFee * 2); + expect((await ssvNetworkContract.operatorSnapshot(2)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 6 + helpers.CONFIG.minimalOperatorFee * 2); + expect((await ssvNetworkContract.operatorSnapshot(3)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 6 + helpers.CONFIG.minimalOperatorFee * 2); + expect((await ssvNetworkContract.operatorSnapshot(4)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 6 + helpers.CONFIG.minimalOperatorFee * 2); + }); + + it('Check pod balance returns error - NegativeBalance', async () => { + await utils.progressBlocks(1000); + await expect(ssvNetworkContract.podBalanceOf(helpers.DB.owners[4].address, pod1.args.operatorIds, pod1.args.pod)).to.be.revertedWith('NegativeBalance'); }); + + it('Check pod balance with removed operator', async () => { + await ssvNetworkContract.removeOperator(1); // TODO remove operator logic rething + await utils.progressBlocks(10); + expect(await ssvNetworkContract.podBalanceOf(helpers.DB.owners[4].address, pod1.args.operatorIds, pod1.args.pod)).not.equals(0); + }); + }); diff --git a/test/validators/register.ts b/test/validators/register.ts index c25413af..55355139 100644 --- a/test/validators/register.ts +++ b/test/validators/register.ts @@ -1,11 +1,10 @@ // Declare imports import * as helpers from '../helpers/contract-helpers'; -import * as utils from '../helpers/utils'; import { expect } from 'chai'; + import { trackGas, GasGroup } from '../helpers/gas-usage'; -// Declare globals -let ssvNetworkContract: any, clusterResult: any, minDepositAmount: any; +let ssvNetworkContract: any, minDepositAmount: any; describe('Register Validator Tests', () => { beforeEach(async () => { @@ -13,146 +12,540 @@ describe('Register Validator Tests', () => { ssvNetworkContract = (await helpers.initializeContract()).contract; // Register operators - await helpers.registerOperators(0, 11, helpers.CONFIG.minimalOperatorFee); + await helpers.registerOperators(0, 14, helpers.CONFIG.minimalOperatorFee); - minDepositAmount = (helpers.CONFIG.minimalBlocksBeforeLiquidation + 2) * helpers.CONFIG.minimalOperatorFee * 4; + minDepositAmount = (helpers.CONFIG.minimalBlocksBeforeLiquidation + 2) * helpers.CONFIG.minimalOperatorFee * 13; - // Register a validator - clusterResult = await helpers.registerValidators(0, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + // cold register + await helpers.DB.ssvToken.connect(helpers.DB.owners[6]).approve(helpers.DB.ssvNetwork.contract.address, '1000000000000000'); + await ssvNetworkContract.connect(helpers.DB.owners[6]).registerValidator( + '0x221111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111119', + [1,2,3,4], + helpers.DataGenerator.shares(0), + '1000000000000000', + { + validatorCount: 0, + networkFee: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + disabled: false + } + ); }); - it('Register new pod emits "PodCreated"', async () => { + it('4 operators: Register 1 new validator gas usage', async () => { await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); - await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).registerPod(helpers.DataGenerator.cluster.new(), minDepositAmount - )).to.emit(ssvNetworkContract, 'PodCreated'); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( + helpers.DataGenerator.publicKey(1), + helpers.DataGenerator.cluster.new(), + helpers.DataGenerator.shares(0), + minDepositAmount, + { + validatorCount: 0, + networkFee: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + disabled: false + } + ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); }); - it('Register new pod with a new cluster gas limit', async () => { + it('4 operators: Register 2 validators in same pod gas usage', async () => { await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerPod(helpers.DataGenerator.cluster.new(), minDepositAmount), [GasGroup.REGISTER_POD]); + const { eventsByName } = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( + helpers.DataGenerator.publicKey(1), + [1,2,3,4], + helpers.DataGenerator.shares(0), + minDepositAmount, + { + validatorCount: 0, + networkFee: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + disabled: false + } + ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + + const args = eventsByName.PodMetadataUpdated[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(0), + minDepositAmount, + args.pod + ), [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]); }); - it('Register a new pod to an existing cluster gas limit', async () => { + it('4 operators: Register 2 validators in same pod and 1 validator in new pod gas usage', 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(0), + minDepositAmount, + { + validatorCount: 0, + networkFee: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + disabled: false + } + ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + + const args = eventsByName.PodMetadataUpdated[0].args; + await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerPod(helpers.DataGenerator.cluster.byId(clusterResult.clusterId), minDepositAmount), [GasGroup.REGISTER_POD]); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( + helpers.DataGenerator.publicKey(2), + [1,2,3,4], + helpers.DataGenerator.shares(0), + minDepositAmount, + args.pod + ), [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]); + + 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(0), + minDepositAmount, + { + validatorCount: 0, + networkFee: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + disabled: false + } + ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); }); - it('Register validator emits ValidatorAdded', async () => { - // register validator using cluster Id - await expect(ssvNetworkContract.registerValidator( + it('4 operators: Register 2 validators in same pod with one time deposit gas usage', 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), - (await helpers.registerPodAndDeposit(0, helpers.DataGenerator.cluster.new(), minDepositAmount)).clusterId, - helpers.DataGenerator.shares(0) - )).to.emit(ssvNetworkContract, 'ValidatorAdded'); + [1,2,3,4], + helpers.DataGenerator.shares(0), + `${minDepositAmount*2}`, + { + validatorCount: 0, + networkFee: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + disabled: false + } + ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + + const args = eventsByName.PodMetadataUpdated[0].args; + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( + helpers.DataGenerator.publicKey(2), + [1,2,3,4], + helpers.DataGenerator.shares(0), + 0, + args.pod + ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT]); }); - it('Register validator with a removed operator in the cluster', async () => { - await ssvNetworkContract.removeOperator(1); - await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); // TMP IT FAILS WITH PROGRESS BLOCK, CRITICAL ERROR IN INDEX MATH LOGIC - await helpers.DB.ssvToken.connect(helpers.DB.owners[4]).approve(ssvNetworkContract.address, minDepositAmount); - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4])['deposit(bytes32,uint256)'](clusterResult.clusterId, minDepositAmount), [GasGroup.DEPOSIT]); - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).registerValidator(helpers.DataGenerator.publicKey(9), clusterResult.clusterId, helpers.DataGenerator.shares(0)), [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]); + // 7 operators + + it('7 operators: Register 1 new validator gas usage', 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(0), + minDepositAmount, + { + validatorCount: 0, + networkFee: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + disabled: false + } + ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]); }); - it('Register a validator into an empty cluster', async () => { - await helpers.registerValidators(0, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + it('7 operators: Register 2 validators in same pod gas usage', 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(0), + minDepositAmount, + { + validatorCount: 0, + networkFee: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + disabled: false + } + ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]); + + const args = eventsByName.PodMetadataUpdated[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(0), + minDepositAmount, + args.pod + ), [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_7]); }); - it('Register two validators into the same pod', async () => { - await helpers.registerValidators(0, 1, `${minDepositAmount * 2}`, helpers.DataGenerator.cluster.byId(clusterResult.clusterId), [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]); + it('7 operators: Register 2 validators in same pod and 1 validator in new pod gas usage', 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(0), + minDepositAmount, + { + validatorCount: 0, + networkFee: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + disabled: false + } + ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]); + + const args = eventsByName.PodMetadataUpdated[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(0), + minDepositAmount, + args.pod + ), [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_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(0), + minDepositAmount, + { + validatorCount: 0, + networkFee: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + disabled: false + } + ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]); }); - it('Register two validators into an existing cluster', async () => { - await helpers.registerValidators(1, 1, `${minDepositAmount * 2}`, helpers.DataGenerator.cluster.byId(clusterResult.clusterId), [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]); + it('7 operators: Register 2 validators in same pod with one time deposit gas usage', 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(0), + `${minDepositAmount*2}`, + { + validatorCount: 0, + networkFee: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + disabled: false + } + ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]); + + const args = eventsByName.PodMetadataUpdated[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(0), + 0, + args.pod + ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_7]); }); - it('Get pod returns the cluster id', async () => { - expect(await ssvNetworkContract.getPod(helpers.DataGenerator.cluster.byId(clusterResult.clusterId))).to.equal(clusterResult.clusterId); + // 13 operators + + it('13 operators: Register 1 new validator gas usage', 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(0), + minDepositAmount, + { + validatorCount: 0, + networkFee: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + disabled: false + } + ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]); }); - it('Register an existing pod reverts "PodAlreadyExists"', async () => { - await expect(ssvNetworkContract.registerPod(helpers.DataGenerator.cluster.byId(clusterResult.clusterId), 0 - )).to.be.revertedWith('PodAlreadyExists'); + it('13 operators: Register 2 validators in same pod gas usage', 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(0), + minDepositAmount, + { + validatorCount: 0, + networkFee: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + disabled: false + } + ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]); + + const args = eventsByName.PodMetadataUpdated[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(0), + minDepositAmount, + args.pod + ), [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_13]); + }); + + it('13 operators: Register 2 validators in same pod and 1 validator in new pod gas usage', 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(0), + minDepositAmount, + { + validatorCount: 0, + networkFee: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + disabled: false + } + ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]); + + const args = eventsByName.PodMetadataUpdated[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(0), + minDepositAmount, + args.pod + ), [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_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(0), + minDepositAmount, + { + validatorCount: 0, + networkFee: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + disabled: false + } + ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]); }); - it('Get the cluster id of a cluster that does not exist reverts "ClusterNotExists"', async () => { - await expect(ssvNetworkContract.getClusterId([5, 6, 7, 8] - )).to.be.revertedWith('ClusterNotExists'); + it('13 operators: Register 2 validators in same pod with one time deposit gas usage', 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(0), + `${minDepositAmount*2}`, + { + validatorCount: 0, + networkFee: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + disabled: false + } + ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]); + + const args = eventsByName.PodMetadataUpdated[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(0), + 0, + args.pod + ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_13]); }); - it('Get the pod address of a pod that does not exist reverts "PodNotExists"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).getPod(helpers.DataGenerator.cluster.byId(clusterResult.clusterId) - )).to.be.revertedWith('PodNotExists'); + it('Register validator returns an error - PodDataIsBroken', 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(0), + minDepositAmount, + { + validatorCount: 0, + networkFee: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + disabled: false + } + ); + + await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( + helpers.DataGenerator.publicKey(3), + [1, 2, 3, 4], + helpers.DataGenerator.shares(0), + minDepositAmount, + { + validatorCount: 2, + networkFee: 10, + networkFeeIndex: 0, + index: 0, + balance: 0, + disabled: false + } + )).to.be.revertedWith('PodDataIsBroken'); }); - it('Register a pod when an operator does not exsit in the cluster reverts "OperatorDoesNotExist"', async () => { - await expect(ssvNetworkContract.registerPod([1, 2, 3, 25], minDepositAmount + it('Register validator returns an error - OperatorDoesNotExist', async () => { + await expect(ssvNetworkContract.registerValidator( + helpers.DataGenerator.publicKey(2), + [1, 2, 3, 25], + helpers.DataGenerator.shares(0), + minDepositAmount, + { + validatorCount: 0, + networkFee: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + disabled: false + } )).to.be.revertedWith('OperatorDoesNotExist'); }); - it('Register a pod with unsorted operators reverts "The operators list should be in ascending order"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).registerPod([3, 2, 1, 4], minDepositAmount - )).to.be.revertedWith('The operators list should be in ascending order'); + it('Register validator with removed operator returns an error - OperatorDoesNotExist', async () => { + await ssvNetworkContract.removeOperator(1); + await expect(ssvNetworkContract.registerValidator( + helpers.DataGenerator.publicKey(2), + [1, 2, 3, 4], + helpers.DataGenerator.shares(0), + minDepositAmount, + { + validatorCount: 0, + networkFee: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + disabled: false + } + )).to.be.revertedWith('OperatorDoesNotExist'); + }); + + it('Register validator emits ValidatorAdded event', async () => { + await helpers.DB.ssvToken.approve(ssvNetworkContract.address, minDepositAmount); + await expect(ssvNetworkContract.registerValidator( + helpers.DataGenerator.publicKey(1), + [1, 2, 3, 4], + helpers.DataGenerator.shares(0), + minDepositAmount, + { + validatorCount: 0, + networkFee: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + disabled: false + } + )).to.emit(ssvNetworkContract, 'ValidatorAdded'); + }); + + it('Register pod returns an error - The operators list should be in ascending order', async () => { + await expect(helpers.registerValidators(2, 1, minDepositAmount, [3, 2, 1, 4])).to.be.revertedWith('OperatorsListDoesNotSorted'); }); it('Invalid operator amount reverts "OperatorIdsStructureInvalid"', async () => { // 2 Operators - await expect(helpers.registerPodAndDeposit(0, [1, 2], minDepositAmount - )).to.be.revertedWith('OperatorIdsStructureInvalid'); + await expect(helpers.registerValidators(2, 1, minDepositAmount, [1, 2])).to.be.revertedWith('OperatorIdsStructureInvalid'); // 6 Operators - await expect(helpers.registerPodAndDeposit(0, [1, 2, 3, 4, 5, 6], minDepositAmount - )).to.be.revertedWith('OperatorIdsStructureInvalid'); + await expect(helpers.registerValidators(2, 1, minDepositAmount, [1, 2, 3, 4, 5, 6])).to.be.revertedWith('OperatorIdsStructureInvalid'); // 14 Operators - await expect(helpers.registerPodAndDeposit(0, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], minDepositAmount - )).to.be.revertedWith('OperatorIdsStructureInvalid'); + await expect(helpers.registerValidators(2, 1, minDepositAmount, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])).to.be.revertedWith('OperatorIdsStructureInvalid'); }); it('Register validator with an invalild public key reverts "InvalidPublicKeyLength"', async () => { await expect(ssvNetworkContract.registerValidator( helpers.DataGenerator.shares(0), - (await helpers.registerPodAndDeposit(0, helpers.DataGenerator.cluster.new(), minDepositAmount)).clusterId, + [1, 2, 3, 4], helpers.DataGenerator.shares(0), + minDepositAmount, + { + validatorCount: 0, + networkFee: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + disabled: false + } )).to.be.revertedWith('InvalidPublicKeyLength'); }); - it('Register validator with not enough amount reverts "NotEnoughBalance', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( + it('Register validator returns an error - NotEnoughBalance', async () => { + await helpers.DB.ssvToken.approve(ssvNetworkContract.address, helpers.CONFIG.minimalOperatorFee); + await expect(ssvNetworkContract.registerValidator( helpers.DataGenerator.publicKey(1), - (await helpers.registerPodAndDeposit(0, helpers.DataGenerator.cluster.new(), '0')).clusterId, + [1, 2, 3, 4], helpers.DataGenerator.shares(0), + helpers.CONFIG.minimalOperatorFee, + { + validatorCount: 0, + networkFee: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + disabled: false + } )).to.be.revertedWith('NotEnoughBalance'); }); - it('Register an existing validator reverts "ValidatorAlreadyExists"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(0), - (await helpers.registerPodAndDeposit(1, [1, 2, 3, 4], minDepositAmount)).clusterId, + it('Register validator returns an error - ValidatorAlreadyExists', async () => { + await helpers.DB.ssvToken.approve(ssvNetworkContract.address, helpers.CONFIG.minimalOperatorFee); + await expect(ssvNetworkContract.connect(helpers.DB.owners[6]).registerValidator( + '0x221111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111119', + [1,2,3,4], helpers.DataGenerator.shares(0), + minDepositAmount, + { + validatorCount: 0, + networkFee: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + disabled: false + } )).to.be.revertedWith('ValidatorAlreadyExists'); }); - - it('Register validator with a cluster that does not exist reverts "ClusterNotExists"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( - helpers.DataGenerator.publicKey(0), - clusterResult.clusterId.replace(/.$/, '0'), - helpers.DataGenerator.shares(0), - )).to.be.revertedWith('ClusterNotExists'); - }); - - // ABOVE GAS LIMIT - it('Register with 7 operators', async () => { - // await helpers.registerValidators(0, 1, '10000', helpers.DataGenerator.cluster.new(7), [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]); - }); - - // TODO: fix after connecting the token - it('Not enough balance', async () => { - // await expect(ssvNetworkContract.registerValidator( - // helpers.DataGenerator.publicKey(0), - // [1, 2, 3, 4], - // helpers.DataGenerator.shares(0), - // '100005' - // )).to.be.revertedWith('NotEnoughBalance'); - }); -}); \ No newline at end of file +}); diff --git a/test/validators/remove.ts b/test/validators/remove.ts index bcf8e4ce..3e8c3e5c 100644 --- a/test/validators/remove.ts +++ b/test/validators/remove.ts @@ -1,79 +1,149 @@ // Decalre imports import * as helpers from '../helpers/contract-helpers'; +import * as utils from '../helpers/utils'; + import { expect } from 'chai'; import { trackGas, GasGroup } from '../helpers/gas-usage'; -// Decalre globals -let ssvNetworkContract: any, clusterResult: any, minDepositAmount: any; +let ssvNetworkContract: any, minDepositAmount: any, firstPod: any; describe('Remove Validator Tests', () => { beforeEach(async () => { // Initialize contract ssvNetworkContract = (await helpers.initializeContract()).contract; - minDepositAmount = helpers.CONFIG.minimalBlocksBeforeLiquidation * helpers.CONFIG.minimalOperatorFee * 4; + minDepositAmount = (helpers.CONFIG.minimalBlocksBeforeLiquidation + 10) * helpers.CONFIG.minimalOperatorFee * 4; // Register operators - await helpers.registerOperators(0, 4, helpers.CONFIG.minimalOperatorFee); + await helpers.registerOperators(0, 14, helpers.CONFIG.minimalOperatorFee); // Register a validator - clusterResult = await helpers.registerValidators(4, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + // cold register + await helpers.DB.ssvToken.connect(helpers.DB.owners[6]).approve(helpers.DB.ssvNetwork.contract.address, '1000000000000000'); + await ssvNetworkContract.connect(helpers.DB.owners[6]).registerValidator( + '0x221111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111119', + [1,2,3,4], + helpers.DataGenerator.shares(0), + '1000000000000000', + { + validatorCount: 0, + networkFee: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + disabled: false + } + ); + + // 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(0), + minDepositAmount, + { + validatorCount: 0, + networkFee: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + disabled: false + } + ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); + firstPod = register.eventsByName.PodMetadataUpdated[0].args; }); - it('Remove validator emits "ValidatorRemoved"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator( - clusterResult.validators[0].publicKey, + it('Remove validator emits ValidatorRemoved event', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).removeValidator( + helpers.DataGenerator.publicKey(1), + firstPod.operatorIds, + firstPod.pod )).to.emit(ssvNetworkContract, 'ValidatorRemoved'); }); - it('Remove validator gas limits', async () => { - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator(clusterResult.validators[0].publicKey), [GasGroup.REMOVE_VALIDATOR]); + it('Remove validator track gas', async () => { + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).removeValidator( + helpers.DataGenerator.publicKey(1), + firstPod.operatorIds, + firstPod.pod + ), [GasGroup.REMOVE_VALIDATOR]); }); - it('Remove validator with a removed operator in the cluster', async () => { + it('Remove validator with removed operator in a pod', async () => { await trackGas(ssvNetworkContract.removeOperator(1), [GasGroup.REMOVE_OPERATOR_WITH_WITHDRAW]); - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator(clusterResult.validators[0].publicKey), [GasGroup.REMOVE_VALIDATOR]); + await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).removeValidator( + helpers.DataGenerator.publicKey(1), + firstPod.operatorIds, + firstPod.pod + ), [GasGroup.REMOVE_VALIDATOR]); }); - it('Register a removed validator and remove the same validator again', async () => { - // Remove validator - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator(clusterResult.validators[0].publicKey), [GasGroup.REMOVE_VALIDATOR]); - - // Re-register validator - await ssvNetworkContract.connect(helpers.DB.owners[4]).registerValidator( - helpers.DataGenerator.publicKey(0), - (await helpers.registerPodAndDeposit(4, [1, 2, 3, 4], minDepositAmount)).clusterId, - helpers.DataGenerator.shares(0), - ); - - // Remove the validator again - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator(helpers.DataGenerator.publicKey(0)), [GasGroup.REMOVE_VALIDATOR]); - }); - - it('Remove validator I do not own reverts "ValidatorNotOwned"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[3]).removeValidator(clusterResult.validators[0].publicKey + it('Remove validator with an invalid owner', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[3]).removeValidator( + helpers.DataGenerator.publicKey(1), + firstPod.operatorIds, + firstPod.pod )).to.be.revertedWith('ValidatorNotOwned'); }); - it('Remove the same validator twice reverts "ValidatorNotOwned"', async () => { + it('Remove validator twice', async () => { // Remove validator - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator(clusterResult.validators[0].publicKey), [GasGroup.REMOVE_VALIDATOR]); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).removeValidator( + helpers.DataGenerator.publicKey(1), + firstPod.operatorIds, + firstPod.pod + ), [GasGroup.REMOVE_VALIDATOR]); // Remove validator again - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator(clusterResult.validators[0].publicKey + await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).removeValidator( + helpers.DataGenerator.publicKey(1), + firstPod.operatorIds, + firstPod.pod )).to.be.revertedWith('ValidatorNotOwned'); }); - // TODO: Once liquidation is updated - it('Remove validator from a liquidated cluster', async () => { - // // Register validator - // const { validators } = await helpers.registerValidators(4, 1, '10000', helpers.DataGenerator.cluster.new()); - // // Liquidate cluster - // // Progress blocks to liquidatable state - // // Liquidate cluster - // // Remove validator - // await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).removeValidator( - // validators[0].publicKey, - // )).to.emit(ssvNetworkContract, 'ValidatorRemoved'); + it('Register / remove validator twice', async () => { + // Remove validator + const remove = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).removeValidator( + helpers.DataGenerator.publicKey(1), + firstPod.operatorIds, + firstPod.pod + ), [GasGroup.REMOVE_VALIDATOR]); + const updatedPod = remove.eventsByName.PodMetadataUpdated[0].args; + + // Re-register validator + const newRegister = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( + helpers.DataGenerator.publicKey(1), + updatedPod.operatorIds, + helpers.DataGenerator.shares(0), + 0, + updatedPod.pod + ), [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]); + const afterRegisterPod = newRegister.eventsByName.PodMetadataUpdated[0].args; + + // Remove the validator again + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).removeValidator( + helpers.DataGenerator.publicKey(1), + afterRegisterPod.operatorIds, + afterRegisterPod.pod + ), [GasGroup.REMOVE_VALIDATOR]); + }); + + it('Remove validator from a liquidated pod', async () => { + await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); + const liquidatedPod = await trackGas(ssvNetworkContract.liquidatePod( + firstPod.ownerAddress, + firstPod.operatorIds, + firstPod.pod + ), [GasGroup.LIQUIDATE_POD]); + const updatedPod = liquidatedPod.eventsByName.PodMetadataUpdated[0].args; + + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).removeValidator( + helpers.DataGenerator.publicKey(1), + updatedPod.operatorIds, + updatedPod.pod + ), [GasGroup.REMOVE_VALIDATOR]); }); -}); \ No newline at end of file +}); diff --git a/test/validators/transfer-bulk.ts b/test/validators/transfer-bulk.ts deleted file mode 100644 index 4c52e5c4..00000000 --- a/test/validators/transfer-bulk.ts +++ /dev/null @@ -1,150 +0,0 @@ -// Decalre imports -import * as helpers from '../helpers/contract-helpers'; -import { expect } from 'chai'; -import { GasGroup } from '../helpers/gas-usage'; - -// Decalre globals -let ssvNetworkContract: any, clusterResult1: any, clusterResult2: any, clusterResult3: any, minDepositAmount: any; - -describe('Bulk Transfer Validator Tests', () => { - beforeEach(async () => { - // Initialize contract - ssvNetworkContract = (await helpers.initializeContract()).contract; - - // Register operators - await helpers.registerOperators(0, 15, helpers.CONFIG.minimalOperatorFee); - - minDepositAmount = (helpers.CONFIG.minimalBlocksBeforeLiquidation + 2) * helpers.CONFIG.minimalOperatorFee * 4; - - // Register validators - clusterResult1 = await helpers.registerValidators(4, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); - clusterResult2 = await helpers.registerValidators(4, 9, `${minDepositAmount * 9}`, helpers.DataGenerator.cluster.byId(clusterResult1.clusterId), [GasGroup.REGISTER_VALIDATOR_EXISTING_CLUSTER]); - clusterResult3 = await helpers.registerValidators(4, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); - }); - - it('Bulk transfer 10 validators emits "BulkValidatorTransferred"', async () => { - await helpers.registerPodAndDeposit(4, helpers.DataGenerator.cluster.byId(clusterResult3.clusterId), `${minDepositAmount * (clusterResult2.validators.length + 1) }`); - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( - [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], - clusterResult1.clusterId, - clusterResult3.clusterId, - Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)), - )).to.emit(ssvNetworkContract, 'BulkValidatorTransferred'); - }); - - it('Bulk transfer 10 validators gas limits', async () => { - await helpers.bulkTransferValidator( - 4, - [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], - clusterResult1.clusterId, - clusterResult3.clusterId, - `${minDepositAmount * 10 }`, - [GasGroup.BULK_TRANSFER_VALIDATOR]); - }); - - it('Bulk transfer 10 validators to a cluster with 7 operators', async () => { - // Register validator with 7 operators - const { clusterId } = await helpers.registerValidators(4, 1, `${(minDepositAmount / 4) * 7}`, [1, 2, 3, 4, 5, 6, 7]); - - // Transfer validator to an existing cluster - await helpers.bulkTransferValidator( - 4, - [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], - clusterResult1.clusterId, - clusterId, - `${(minDepositAmount / 4) * 7 * 10}`, - [GasGroup.BULK_TRANSFER_VALIDATOR_NON_EXISTING_POD]); - }); - - it('Bulk transfer 10 validators to a cluster created by other owner', async () => { - // Register validator with 7 operators - const { clusterId } = await helpers.registerValidators(5, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); - - // Bulk transfer 10 validators - await helpers.bulkTransferValidator( - 4, - [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], - clusterResult1.clusterId, - clusterId, - `${minDepositAmount * 10}`, - [GasGroup.BULK_TRANSFER_VALIDATOR_NON_EXISTING_POD]); - }); - - it('Bulk transfer 10 validators I do not own reverts "ValidatorNotOwned"', async () => { - await helpers.registerPodAndDeposit(5, helpers.DataGenerator.cluster.byId(clusterResult3.clusterId), `${minDepositAmount * (clusterResult2.validators.length + 1) }`); - await expect(ssvNetworkContract.connect(helpers.DB.owners[5]).bulkTransferValidators( - [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], - clusterResult1.clusterId, - clusterResult3.clusterId, - Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)), - )).to.be.revertedWith('ValidatorNotOwned'); - }); - - it('Bulk transfer 10 validators with one validator I do not own reverts "ValidatorNotOwned"', async () => { - const account5cluster = await helpers.registerValidators(5, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); - await helpers.registerPodAndDeposit(4, helpers.DataGenerator.cluster.byId(clusterResult3.clusterId), `${minDepositAmount * (clusterResult2.validators.length + 1) }`); - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( - [clusterResult1.validators[0].publicKey, account5cluster.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], - clusterResult1.clusterId, - clusterResult3.clusterId, - Array(clusterResult2.validators.length + 2).fill(helpers.DataGenerator.shares(0)), - )).to.be.revertedWith('ValidatorNotOwned'); - }); - - it('Bulk transfer 10 validators with an invalid public key reverts "InvalidPublicKeyLength"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( - [clusterResult1.validators[0].publicKey, helpers.DataGenerator.shares(0), ...clusterResult2.validators.map((validator: any) => validator.publicKey)], - clusterResult1.clusterId, - clusterResult3.clusterId, - Array(clusterResult2.validators.length + 2).fill(helpers.DataGenerator.shares(0)), - )).to.be.revertedWith('InvalidPublicKeyLength'); - }); - - it('Bulk transfer 10 validators to a cluster that does not exist reverts "ClusterNotExists"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( - [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], - clusterResult1.clusterId.slice(0, -1) + 'a', - clusterResult1.clusterId, - Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)), - )).to.be.revertedWith('ClusterNotExists'); - }); - - it('Validator and share length parameters are not the same length reverts "ParametersMismatch"', async () => { - // 10 validators and 11 shares - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( - [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], - clusterResult1.clusterId, - clusterResult3.clusterId, - Array(clusterResult2.validators.length).fill(helpers.DataGenerator.shares(0)), - )).to.be.revertedWith('ParametersMismatch'); - - // 9 validators and 8 shares - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( - clusterResult2.validators.map((validator: any) => validator.publicKey), - clusterResult1.clusterId, - clusterResult3.clusterId, - Array(clusterResult2.validators.length - 1).fill(helpers.DataGenerator.shares(0)), - )).to.be.revertedWith('ParametersMismatch'); - }); - - it('Bulk transfer 10 validators with not enough amount reverts "PodLiquidatable"', async () => { - const { clusterId } = await helpers.registerValidators(5, 1, minDepositAmount, [9, 10, 11, 12], [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( - [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], - clusterResult1.clusterId, - clusterId, - Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)), - )).to.be.revertedWith('PodLiquidatable'); - }); - - // TODO: fix after connecting the token - it('Bulk transfer validator with not enough balance', async () => { - // await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).bulkTransferValidators( - // [clusterResult1.validators[0].publicKey, ...clusterResult2.validators.map((validator: any) => validator.publicKey)], - // clusterResult1.clusterId, - // clusterResult3.clusterId, - // Array(clusterResult2.validators.length + 1).fill(helpers.DataGenerator.shares(0)), - // '10000000' - // )).to.be.revertedWith('NotEnoughDeposited'); - }); -}); \ No newline at end of file diff --git a/test/validators/transfer.ts b/test/validators/transfer.ts deleted file mode 100644 index 28c63e26..00000000 --- a/test/validators/transfer.ts +++ /dev/null @@ -1,132 +0,0 @@ -// Decalre imports -import * as helpers from '../helpers/contract-helpers'; -import * as utils from '../helpers/utils'; -import { expect } from 'chai'; -import { GasGroup } from '../helpers/gas-usage'; - -// Declare globals -let ssvNetworkContract: any, clusterResult1: any, clusterResult2: any, minDepositAmount: any, clusters: any; - -describe('Transfer Validator Tests', () => { - beforeEach(async () => { - // Initialize contract - ssvNetworkContract = (await helpers.initializeContract()).contract; - - // Register operators - await helpers.registerOperators(0, 15, helpers.CONFIG.minimalOperatorFee); - - minDepositAmount = helpers.CONFIG.minimalBlocksBeforeLiquidation * helpers.CONFIG.minimalOperatorFee * 5; - - - clusters = {}; - // Register validators - clusters.one = helpers.DataGenerator.cluster.new(); - clusterResult1 = await helpers.registerValidators(4, 1, minDepositAmount, clusters.one, [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); - clusters.two = helpers.DataGenerator.cluster.new(); - clusterResult2 = await helpers.registerValidators(4, 1, minDepositAmount, clusters.two, [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); - clusters.three = helpers.DataGenerator.cluster.new(); - }); - - it('Transfer validator emits "ValidatorTransferred"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( - clusterResult1.validators[0].publicKey, - (await helpers.registerPodAndDeposit(4, helpers.DataGenerator.cluster.new(), minDepositAmount)).clusterId, - helpers.DataGenerator.shares(helpers.DB.validators.length), - )).to.emit(ssvNetworkContract, 'ValidatorTransferred'); - }); - - it('Transfer validator from pod with one validator into an empty pod', async () => { - await helpers.transferValidator(4, clusterResult2.validators[0].publicKey, clusters.three, minDepositAmount, [GasGroup.TRANSFER_VALIDATOR_NEW_CLUSTER]); - }); - - it('Transfer validator from pod with two validators into an empty pod', async () => { - const cluster = await helpers.registerValidators(4, 1, minDepositAmount, clusters.three, [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); - await helpers.transferValidator(4, cluster.validators[0].publicKey, clusters.one, minDepositAmount, [GasGroup.TRANSFER_VALIDATOR_NEW_CLUSTER]); - }); - - it('Transfer validator to a cluster with 7 operators', async () => { - // Register validator with 7 operators - const { clusterId } = await helpers.registerValidators(4, 1, `${minDepositAmount / 4 * 7}`, [1, 2, 3, 4, 5, 6, 7]); - - // Transfer validator to an existing cluster - await helpers.transferValidator(4, clusterResult1.validators[0].publicKey, helpers.DataGenerator.cluster.byId(clusterId), `${minDepositAmount / 4 * 7 * 2}`, [GasGroup.TRANSFER_VALIDATOR_NON_EXISTING_POD]); - }); - - // GOING ABOVE GAS LIMIT - it('Transfer validator to an existing pod', async () => { - await helpers.transferValidator(4, clusterResult1.validators[0].publicKey, helpers.DataGenerator.cluster.byId(clusterResult2.clusterId), `${minDepositAmount * 2}`, [GasGroup.TRANSFER_VALIDATOR]); - }); - - // GOING ABOVE GAS LIMIT - it('Transfer validator to an existing cluster', async () => { - // Register validator with different user - const clusterResult3 = await helpers.registerValidators(5, 1, minDepositAmount, clusters.one, [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); - - // Transfer validator - await helpers.transferValidator(4, clusterResult1.validators[0].publicKey, helpers.DataGenerator.cluster.byId(clusterResult3.clusterId), `${minDepositAmount * 2}`, [GasGroup.TRANSFER_VALIDATOR_NON_EXISTING_POD]); - - // expect(clusterResult3.clusterId).equals(transfredValidator1.eventsByName.ValidatorTransferred[0].args.podId); - }); - - it('Transfer validator in a pod with one validator and a removed operator into an existing pod', async () => { - await ssvNetworkContract.removeOperator(helpers.DataGenerator.cluster.byId(clusterResult1.clusterId)[0]); - await helpers.transferValidator(4, clusterResult1.validators[0].publicKey, helpers.DataGenerator.cluster.byId(clusterResult2.clusterId), `${minDepositAmount * 2}`, [GasGroup.TRANSFER_VALIDATOR]); - }); - - it('Transfer validator in a pod with one validator and a removed operator into an empty pod', async () => { - await ssvNetworkContract.removeOperator(helpers.DataGenerator.cluster.byId(clusterResult2.clusterId)[0]); - await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); // TMP IT FAILS WITH PROGRESS BLOCK, CRITICAL ERROR IN INDEX MATH LOGIC - await helpers.transferValidator(4, clusterResult1.validators[0].publicKey, helpers.DataGenerator.cluster.byId(clusterResult2.clusterId), `${minDepositAmount * 2}`, [GasGroup.TRANSFER_VALIDATOR]); - }); - - it('Transfer validator in a pod with two validators and a removed operator into an existing pod', async () => { - const cluster = await helpers.registerValidators(4, 1, minDepositAmount, clusters.three, [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); - await ssvNetworkContract.removeOperator(clusters.three[0]); - await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); // TMP IT FAILS WITH PROGRESS BLOCK, CRITICAL ERROR IN INDEX MATH LOGIC - await helpers.transferValidator(4, cluster.validators[0].publicKey, clusters.one, `${minDepositAmount * 2}`, [GasGroup.TRANSFER_VALIDATOR_NEW_CLUSTER]); - }); - - it('Transfer validator in a pod with two validators and a removed operator into an empty pod', async () => { - const cluster = await helpers.registerValidators(4, 1, minDepositAmount, clusters.three, [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); - await ssvNetworkContract.removeOperator(clusters.one[0]); - await helpers.transferValidator(4, cluster.validators[0].publicKey, clusters.one, minDepositAmount, [GasGroup.TRANSFER_VALIDATOR_NEW_CLUSTER]); - }); - - it('Transfer validator I do not own reverts "ValidatorNotOwned"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[5]).transferValidator( - clusterResult1.validators[0].publicKey, - (await helpers.registerPodAndDeposit(4, helpers.DataGenerator.cluster.byId(clusterResult2.clusterId), minDepositAmount)).clusterId, - helpers.DataGenerator.shares(helpers.DB.validators.length), - )).to.be.revertedWith('ValidatorNotOwned'); - }); - - it('Transfer validator with an invalid public key reverts "InvalidPublicKeyLength"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( - helpers.DataGenerator.shares(0), - (await helpers.registerPodAndDeposit(4, helpers.DataGenerator.cluster.byId(clusterResult2.clusterId), minDepositAmount)).clusterId, - helpers.DataGenerator.shares(helpers.DB.validators.length), - )).to.be.revertedWith('InvalidPublicKeyLength'); - }); - - it('Transfer validator to a pod with not enough amount reverts "NotEnoughBalance"', async () => { - // Register validator - const { clusterId } = await helpers.registerValidators(4, 1, minDepositAmount, [1, 2, 3, 9]); - - // Transfer to cluster with not enough amount - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( - clusterResult1.validators[0].publicKey, - (await helpers.registerPodAndDeposit(4, helpers.DataGenerator.cluster.byId(clusterId), helpers.CONFIG.minimalOperatorFee)).clusterId, - helpers.DataGenerator.shares(helpers.DB.validators.length), - )).to.be.revertedWith('NotEnoughBalance'); - }); - - // TODO: fix after connecting the token - it('Transfer validator with not enough balance', async () => { - // await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).transferValidator( - // clusterResult1.validators[0].publicKey, - // helpers.DataGenerator.cluster.byId(clusterResult2.clusterId), - // helpers.DataGenerator.shares(helpers.DB.validators.length), - // '1000001' - // )).to.be.revertedWith('NotEnoughBalance'); - }); -}); \ No newline at end of file From db119e6d32aaa6904cc632d33e352b0efa1eb919 Mon Sep 17 00:00:00 2001 From: Or-blox <117833150+Or-blox@users.noreply.github.com> Date: Tue, 20 Dec 2022 17:59:51 +0200 Subject: [PATCH 101/149] Or deposit tests (#135) * Changed deposit tests order * deposit tests --- test/account/deposit.ts | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/test/account/deposit.ts b/test/account/deposit.ts index d485c287..1d47e6d1 100644 --- a/test/account/deposit.ts +++ b/test/account/deposit.ts @@ -3,6 +3,7 @@ import * as helpers from '../helpers/contract-helpers'; import { expect } from 'chai'; import { trackGas, GasGroup } from '../helpers/gas-usage'; +// Declare globals let ssvNetworkContract: any, pod1: any, minDepositAmount: any; describe('Deposit Tests', () => { @@ -41,11 +42,21 @@ describe('Deposit Tests', () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[4])['deposit(uint64[],uint256,(uint32,uint64,uint64,uint64,uint64,bool))'](pod1.args.operatorIds, minDepositAmount, pod1.args.pod)).to.emit(ssvNetworkContract, 'FundsDeposit'); }); + it('Deposit to a pod 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(uint64[],uint256,(uint32,uint64,uint64,uint64,uint64,bool))'](pod1.args.operatorIds, minDepositAmount, pod1.args.pod), [GasGroup.DEPOSIT]); + }); + it('Deposit to a pod I do not own emits "FundsDeposit"', async () => { await helpers.DB.ssvToken.connect(helpers.DB.owners[0]).approve(ssvNetworkContract.address, minDepositAmount); await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['deposit(address,uint64[],uint256,(uint32,uint64,uint64,uint64,uint64,bool))'](helpers.DB.owners[4].address, pod1.args.operatorIds, minDepositAmount, pod1.args.pod)).to.emit(ssvNetworkContract, 'FundsDeposit'); }); + it('Deposit to a pod 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(address,uint64[],uint256,(uint32,uint64,uint64,uint64,uint64,bool))'](helpers.DB.owners[4].address, pod1.args.operatorIds, minDepositAmount, pod1.args.pod), [GasGroup.DEPOSIT]); + }); + it('Deposit to a pod I do own with a pod that does not exist reverts "PodNotExists"', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[1])['deposit(uint64[],uint256,(uint32,uint64,uint64,uint64,uint64,bool))'](pod1.args.operatorIds, minDepositAmount, pod1.args.pod)).to.be.revertedWith('PodNotExists'); }); @@ -53,14 +64,4 @@ describe('Deposit Tests', () => { it('Deposit to a pod I do not own with a pod that does not exist reverts "PodNotExists"', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[4])['deposit(uint64[],uint256,(uint32,uint64,uint64,uint64,uint64,bool))']([1,2,4,5], minDepositAmount, pod1.args.pod)).to.be.revertedWith('PodNotExists'); }); - - it('Deposit to a pod 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(uint64[],uint256,(uint32,uint64,uint64,uint64,uint64,bool))'](pod1.args.operatorIds, minDepositAmount, pod1.args.pod), [GasGroup.DEPOSIT]); - }); - - it('Deposit to a pod 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(address,uint64[],uint256,(uint32,uint64,uint64,uint64,uint64,bool))'](helpers.DB.owners[4].address, pod1.args.operatorIds, minDepositAmount, pod1.args.pod), [GasGroup.DEPOSIT]); - }); -}); +}); \ No newline at end of file From 66a17568b924a385fc67208fe79a7284fd9f60da Mon Sep 17 00:00:00 2001 From: Wadym Date: Wed, 21 Dec 2022 10:47:29 +0100 Subject: [PATCH 102/149] fee recipient logic (#134) * fee recipient logic --- contracts/ISSVNetwork.sol | 7 +++++++ contracts/SSVNetwork.sol | 4 ++++ test/operators/others.ts | 20 ++++++++++++++++++++ 3 files changed, 31 insertions(+) create mode 100644 test/operators/others.ts diff --git a/contracts/ISSVNetwork.sol b/contracts/ISSVNetwork.sol index 44d26ad7..25cc041c 100644 --- a/contracts/ISSVNetwork.sol +++ b/contracts/ISSVNetwork.sol @@ -131,6 +131,11 @@ interface ISSVNetwork { Pod pod ); + event FeeRecipientAddressAdded( + address ownerAddress, + address recipientAddress + ); + /**********/ /* Errors */ /**********/ @@ -287,6 +292,8 @@ interface ISSVNetwork { function getOperatorDeclaredFee(uint64 operatorId) external view returns (uint256, uint256, uint256); + function feeRecipientAddress(address feeRecipientAddress) external; + /*******************************/ /* Pod External View Functions */ /*******************************/ diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index 7571ab36..953af563 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -654,6 +654,10 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { return (feeChangeRequest.fee.expand(), feeChangeRequest.approvalBeginTime, feeChangeRequest.approvalEndTime); } + function feeRecipientAddress(address recipientAddress) external override { + emit FeeRecipientAddressAdded(msg.sender, recipientAddress); + } + /*******************************/ /* Pod External View Functions */ /*******************************/ diff --git a/test/operators/others.ts b/test/operators/others.ts new file mode 100644 index 00000000..0e75a72a --- /dev/null +++ b/test/operators/others.ts @@ -0,0 +1,20 @@ +// Declare imports +import * as helpers from '../helpers/contract-helpers'; +import { expect } from 'chai'; + +// Declare globals +let ssvNetworkContract: any; + +describe('Others Operator Tests', () => { + beforeEach(async () => { + ssvNetworkContract = (await helpers.initializeContract()).contract; + }); + + it('Add fee recipient address emits "FeeRecipientAddressAdded"', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).feeRecipientAddress( + helpers.DB.owners[2].address + )) + .to.emit(ssvNetworkContract, 'FeeRecipientAddressAdded') + .withArgs(helpers.DB.owners[1].address, helpers.DB.owners[2].address); + }); +}); From 94f13a4e08e5e7304f6c11c56998033ee69f16db Mon Sep 17 00:00:00 2001 From: Or-blox <117833150+Or-blox@users.noreply.github.com> Date: Wed, 21 Dec 2022 13:11:45 +0200 Subject: [PATCH 103/149] Or withdraw tests (#136) * Changed deposit tests order * deposit tests * Changed withdraw's tests order * changed test name --- test/account/withdraw.ts | 45 +++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/test/account/withdraw.ts b/test/account/withdraw.ts index cf25ea5f..14b79f46 100644 --- a/test/account/withdraw.ts +++ b/test/account/withdraw.ts @@ -4,6 +4,7 @@ import * as utils from '../helpers/utils'; import { expect } from 'chai'; import { trackGas, GasGroup } from '../helpers/gas-usage'; +// Declare globals let ssvNetworkContract: any, pod1: any, minDepositAmount: any; describe('Withdraw Tests', () => { @@ -41,21 +42,6 @@ describe('Withdraw Tests', () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).withdrawPodBalance(pod1.args.operatorIds, helpers.CONFIG.minimalOperatorFee, pod1.args.pod)).to.emit(ssvNetworkContract, 'PodFundsWithdrawal'); }); - it('Withdraw from pod emits "PodFundsWithdrawal" after removed operator', async () => { - await ssvNetworkContract.removeOperator(1); // TODO remove operator logic rething - await utils.progressBlocks(10); - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).withdrawPodBalance(pod1.args.operatorIds, helpers.CONFIG.minimalOperatorFee, pod1.args.pod)).to.emit(ssvNetworkContract, 'PodFundsWithdrawal'); - }); - - it('Withdraw from a pod reverts "NotEnoughBalance"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).withdrawPodBalance(pod1.args.operatorIds, minDepositAmount, pod1.args.pod)).to.be.revertedWith('NotEnoughBalance'); - }); - - it('Withdraw from a liquidatable pod reverts "NotEnoughBalance"', async () => { - await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).withdrawPodBalance(pod1.args.operatorIds, helpers.CONFIG.minimalOperatorFee, pod1.args.pod)).to.be.revertedWith('NotEnoughBalance'); - }); - it('Withdraw from pod gas limits', async () => { await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).withdrawPodBalance(pod1.args.operatorIds, helpers.CONFIG.minimalOperatorFee, pod1.args.pod), [GasGroup.WITHDRAW_POD_BALANCE]); }); @@ -64,24 +50,35 @@ describe('Withdraw Tests', () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorBalance(uint64,uint256)'](1, helpers.CONFIG.minimalOperatorFee)).to.emit(ssvNetworkContract, 'OperatorFundsWithdrawal'); }); + it('Withdraw from operator balance gas limits', async () => { + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorBalance(uint64,uint256)'](1, helpers.CONFIG.minimalOperatorFee), [GasGroup.WITHDRAW_OPERATOR_BALANCE]); + }); + it('Withdraw the total operator balance emits "OperatorFundsWithdrawal"', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorBalance(uint64)'](1)).to.emit(ssvNetworkContract, 'OperatorFundsWithdrawal'); }); - it('Withdraw balance from an operator I do not own reverts "CallerNotOwner"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[2])['withdrawOperatorBalance(uint64,uint256)'](1, minDepositAmount)).to.be.revertedWith('CallerNotOwner'); + it('Withdraw the total operator balance gas limits', async () => { + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorBalance(uint64)'](1), [GasGroup.WITHDRAW_OPERATOR_BALANCE]); }); - it('Withdraw operator balance returns an error - NotEnoughBalance', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorBalance(uint64,uint256)'](1, minDepositAmount)).to.be.revertedWith('NotEnoughBalance'); + it('Withdraw from a pod that has a removed operator emits "PodFundsWithdrawal"', async () => { + await ssvNetworkContract.removeOperator(1); // TODO remove operator logic rething + await utils.progressBlocks(10); + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).withdrawPodBalance(pod1.args.operatorIds, helpers.CONFIG.minimalOperatorFee, pod1.args.pod)).to.emit(ssvNetworkContract, 'PodFundsWithdrawal'); }); - it('Withdraw from operator balance gas limits', async () => { - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorBalance(uint64,uint256)'](1, helpers.CONFIG.minimalOperatorFee), [GasGroup.WITHDRAW_OPERATOR_BALANCE]); + it('Withdraw more than the pod balance reverts "NotEnoughBalance"', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).withdrawPodBalance(pod1.args.operatorIds, minDepositAmount, pod1.args.pod)).to.be.revertedWith('NotEnoughBalance'); }); - it('Withdraw the total operator balance gas limits', async () => { - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorBalance(uint64)'](1), [GasGroup.WITHDRAW_OPERATOR_BALANCE]); + it('Withdraw from a liquidatable pod reverts "NotEnoughBalance"', async () => { + await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).withdrawPodBalance(pod1.args.operatorIds, helpers.CONFIG.minimalOperatorFee, pod1.args.pod)).to.be.revertedWith('NotEnoughBalance'); + }); + + it('Withdraw balance from an operator I do not own reverts "CallerNotOwner"', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[2])['withdrawOperatorBalance(uint64,uint256)'](1, minDepositAmount)).to.be.revertedWith('CallerNotOwner'); }); it('Withdraw more than the operator balance reverts "NotEnoughBalance"', async () => { @@ -96,4 +93,4 @@ describe('Withdraw Tests', () => { it('Withdraw more than the operator total balance reverts "NotEnoughBalance"', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorBalance(uint64)'](12)).to.be.revertedWith('NotEnoughBalance'); }); -}); +}); \ No newline at end of file From e8a1f8f3add5964efb0e5f0b06d3f5b014aa3e41 Mon Sep 17 00:00:00 2001 From: Wadym Date: Wed, 28 Dec 2022 10:46:42 +0100 Subject: [PATCH 104/149] operator removal logic (#151) * operator removal logic * missed merged line of code * change the way to identify operator exists or not * update gas numbers Co-authored-by: Vadim --- contracts/SSVNetwork.sol | 63 +++++++++++++++++-------------------- test/account/withdraw.ts | 5 ++- test/helpers/gas-usage.ts | 4 +-- test/liquidate/liquidate.ts | 4 +-- test/sanity/balances.ts | 3 +- test/validators/remove.ts | 1 - 6 files changed, 36 insertions(+), 44 deletions(-) diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index 953af563..70b49fec 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -173,24 +173,26 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _transferOperatorBalanceUnsafe(operatorId, operator.snapshot.balance.expand()); } - delete _operators[operatorId]; + operator.snapshot.block = 0; + operator.snapshot.balance = 0; + operator.validatorCount = 0; + operator.fee = 0; + + _operators[operatorId] = operator; emit OperatorRemoved(operatorId); } function declareOperatorFee(uint64 operatorId, uint256 fee) onlyOperatorOwnerOrContractOwner(operatorId) external override { Operator memory operator = _operators[operatorId]; - if (fee < MINIMAL_OPERATOR_FEE) { - revert FeeTooLow(); - } + if (fee < MINIMAL_OPERATOR_FEE) revert FeeTooLow(); uint64 shrunkFee = fee.shrink(); // @dev 100% = 10000, 10% = 1000 - using 10000 to represent 2 digit precision uint64 maxAllowedFee = operator.fee * (10000 + _operatorMaxFeeIncrease) / 10000; - if (shrunkFee > maxAllowedFee) { - revert FeeExceedsIncreaseLimit(); - } + + if (shrunkFee > maxAllowedFee) revert FeeExceedsIncreaseLimit(); _operatorFeeChangeRequests[operatorId] = OperatorFeeChangeRequest( shrunkFee, @@ -203,9 +205,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { function executeOperatorFee(uint64 operatorId) onlyOperatorOwnerOrContractOwner(operatorId) external override { OperatorFeeChangeRequest memory feeChangeRequest = _operatorFeeChangeRequests[operatorId]; - if(feeChangeRequest.fee == 0) { - revert NoPendingFeeChangeRequest(); - } + if(feeChangeRequest.fee == 0) revert NoPendingFeeChangeRequest(); if(block.timestamp < feeChangeRequest.approvalBeginTime || block.timestamp > feeChangeRequest.approvalEndTime) { revert ApprovalNotWithinTimeframe(); @@ -219,9 +219,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { function cancelDeclaredOperatorFee(uint64 operatorId) onlyOperatorOwnerOrContractOwner(operatorId) external override { OperatorFeeChangeRequest memory feeChangeRequest = _operatorFeeChangeRequests[operatorId]; - if(feeChangeRequest.fee == 0) { - revert NoPendingFeeChangeRequest(); - } + if(feeChangeRequest.fee == 0) revert NoPendingFeeChangeRequest(); delete _operatorFeeChangeRequests[operatorId]; @@ -256,14 +254,14 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { if (!pod.disabled) { for (uint8 i = 0; i < operatorIds.length; ++i) { Operator memory operator = _operators[operatorIds[i]]; - if (operator.owner == address(0)) { + if (operator.snapshot.block == 0) { revert OperatorDoesNotExist(); } else if (i+1 < operatorIds.length && operatorIds[i] > operatorIds[i+1]) { revert OperatorsListDoesNotSorted(); } operator.snapshot = _getSnapshot(operator, uint64(block.number)); ++operator.validatorCount; - podIndex += operator.snapshot.index + (uint64(block.number) - operator.snapshot.block) * operator.fee; + podIndex += operator.snapshot.index; burnRate += operator.fee; _operators[operatorIds[i]] = operator; } @@ -326,12 +324,13 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { if (!pod.disabled) { for (uint8 i = 0; i < operatorIds.length; ++i) { Operator memory operator = _operators[operatorIds[i]]; - if (operator.owner != address(0)) { + if (operator.snapshot.block != 0) { operator.snapshot = _getSnapshot(operator, uint64(block.number)); --operator.validatorCount; - podIndex += operator.snapshot.index + (uint64(block.number) - operator.snapshot.block) * operator.fee; _operators[operatorIds[i]] = operator; } + + podIndex += operator.snapshot.index; } } } @@ -371,13 +370,14 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { for (uint8 i = 0; i < operatorIds.length; ++i) { Operator memory operator = _operators[operatorIds[i]]; uint64 currentBlock = uint64(block.number); - if (operator.owner != address(0)) { + if (operator.snapshot.block != 0) { operator.snapshot = _getSnapshot(operator, currentBlock); operator.validatorCount -= pod.validatorCount; - podIndex += operator.snapshot.index + (currentBlock - operator.snapshot.block) * operator.fee; burnRate += operator.fee; _operators[operatorIds[i]] = operator; } + + podIndex += operator.snapshot.index; } } @@ -421,13 +421,14 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { { for (uint8 i = 0; i < operatorIds.length; ++i) { Operator memory operator = _operators[operatorIds[i]]; - if (operator.owner != address(0)) { + if (operator.snapshot.block != 0) { operator.snapshot = _getSnapshot(operator, uint64(block.number)); operator.validatorCount += pod.validatorCount; - podIndex += operator.snapshot.index + (uint64(block.number) - operator.snapshot.block) * operator.fee; burnRate += operator.fee; _operators[operatorIds[i]] = operator; } + + podIndex += operator.snapshot.index; } } @@ -559,10 +560,8 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { { for (uint8 i = 0; i < operatorIds.length; ++i) { Operator memory operator = _operators[operatorIds[i]]; - if (operator.owner != address(0)) { - podIndex += operator.snapshot.index + (uint64(block.number) - operator.snapshot.block) * operator.fee; - burnRate += operator.fee; - } + podIndex += operator.snapshot.index + (uint64(block.number) - operator.snapshot.block) * operator.fee; + burnRate += operator.fee; } } @@ -639,7 +638,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { function getOperatorFee(uint64 operatorId) external view override returns (uint256) { Operator memory operator = _operators[operatorId]; - if (operator.owner == address(0)) revert OperatorNotFound(); + if (operator.snapshot.block == 0) revert OperatorNotFound(); return operator.fee.expand(); } @@ -672,10 +671,8 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { { for (uint8 i = 0; i < operatorIds.length; ++i) { Operator memory operator = _operators[operatorIds[i]]; - if (operator.owner != address(0)) { - podIndex += operator.snapshot.index + (uint64(block.number) - operator.snapshot.block) * operator.fee; - burnRate += operator.fee; - } + podIndex += operator.snapshot.index + (uint64(block.number) - operator.snapshot.block) * operator.fee; + burnRate += operator.fee; } } @@ -714,9 +711,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { { for (uint8 i = 0; i < operatorIds.length; ++i) { Operator memory operator = _operators[operatorIds[i]]; - if (operator.owner != address(0)) { - podIndex += operator.snapshot.index + (uint64(block.number) - operator.snapshot.block) * operator.fee; - } + podIndex += operator.snapshot.index + (uint64(block.number) - operator.snapshot.block) * operator.fee; } } @@ -757,7 +752,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { function _onlyOperatorOwnerOrContractOwner(uint64 operatorId) private view { Operator memory operator = _operators[operatorId]; - if(operator.owner == address(0)) { + if(operator.snapshot.block == 0) { revert OperatorWithPublicKeyNotExist(); } diff --git a/test/account/withdraw.ts b/test/account/withdraw.ts index 14b79f46..0004f719 100644 --- a/test/account/withdraw.ts +++ b/test/account/withdraw.ts @@ -63,8 +63,7 @@ describe('Withdraw Tests', () => { }); it('Withdraw from a pod that has a removed operator emits "PodFundsWithdrawal"', async () => { - await ssvNetworkContract.removeOperator(1); // TODO remove operator logic rething - await utils.progressBlocks(10); + await ssvNetworkContract.removeOperator(1); await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).withdrawPodBalance(pod1.args.operatorIds, helpers.CONFIG.minimalOperatorFee, pod1.args.pod)).to.emit(ssvNetworkContract, 'PodFundsWithdrawal'); }); @@ -93,4 +92,4 @@ describe('Withdraw Tests', () => { it('Withdraw more than the operator total balance reverts "NotEnoughBalance"', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorBalance(uint64)'](12)).to.be.revertedWith('NotEnoughBalance'); }); -}); \ No newline at end of file +}); diff --git a/test/helpers/gas-usage.ts b/test/helpers/gas-usage.ts index be830cfb..2c92d852 100644 --- a/test/helpers/gas-usage.ts +++ b/test/helpers/gas-usage.ts @@ -33,8 +33,8 @@ export enum GasGroup { const MAX_GAS_PER_GROUP: any = { /* REAL GAS LIMITS */ [GasGroup.REGISTER_OPERATOR]: 105000, - [GasGroup.REMOVE_OPERATOR]: 51500, - [GasGroup.REMOVE_OPERATOR_WITH_WITHDRAW]: 52000, + [GasGroup.REMOVE_OPERATOR]: 62000, + [GasGroup.REMOVE_OPERATOR_WITH_WITHDRAW]: 62000, [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]: 174000, [GasGroup.REGISTER_VALIDATOR_NEW_STATE]: 191100, diff --git a/test/liquidate/liquidate.ts b/test/liquidate/liquidate.ts index 6bb6bef1..6ebcf03b 100644 --- a/test/liquidate/liquidate.ts +++ b/test/liquidate/liquidate.ts @@ -58,8 +58,8 @@ describe('Liquidate Tests', () => { }); it('Liquidatable with removed operator', async () => { + await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); await ssvNetworkContract.removeOperator(1); - await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); // TMP IT FAILS WITH PROGRESS BLOCK, CRITICAL ERROR IN INDEX MATH LOGIC expect(await ssvNetworkContract.isLiquidatable(firstPod.ownerAddress, firstPod.operatorIds, firstPod.pod)).to.equal(true); }); @@ -74,8 +74,8 @@ describe('Liquidate Tests', () => { }); it('Liquidate validator with removed operator in a pod', async () => { + await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); await ssvNetworkContract.removeOperator(1); - await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); // TMP IT FAILS WITH PROGRESS BLOCK, CRITICAL ERROR IN INDEX MATH LOGIC await trackGas(ssvNetworkContract.liquidatePod( firstPod.ownerAddress, firstPod.operatorIds, diff --git a/test/sanity/balances.ts b/test/sanity/balances.ts index 9291dc23..00fbd452 100644 --- a/test/sanity/balances.ts +++ b/test/sanity/balances.ts @@ -114,8 +114,7 @@ describe('Balance Tests', () => { }); it('Check pod balance with removed operator', async () => { - await ssvNetworkContract.removeOperator(1); // TODO remove operator logic rething - await utils.progressBlocks(10); + await ssvNetworkContract.removeOperator(1); expect(await ssvNetworkContract.podBalanceOf(helpers.DB.owners[4].address, pod1.args.operatorIds, pod1.args.pod)).not.equals(0); }); diff --git a/test/validators/remove.ts b/test/validators/remove.ts index 3e8c3e5c..9dbd6e12 100644 --- a/test/validators/remove.ts +++ b/test/validators/remove.ts @@ -72,7 +72,6 @@ describe('Remove Validator Tests', () => { it('Remove validator with removed operator in a pod', async () => { await trackGas(ssvNetworkContract.removeOperator(1), [GasGroup.REMOVE_OPERATOR_WITH_WITHDRAW]); - await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).removeValidator( helpers.DataGenerator.publicKey(1), firstPod.operatorIds, From 939c45a7e2aa15d90ff24e065a6148efabb0f314 Mon Sep 17 00:00:00 2001 From: Wadym Date: Wed, 28 Dec 2022 11:45:00 +0100 Subject: [PATCH 105/149] Get DAO functions + pod burn rate (#153) * wip * test coverage Co-authored-by: Vadim --- contracts/ISSVNetwork.sol | 25 +++++++--- contracts/SSVNetwork.sol | 78 +++++++++++++++++++++---------- test/dao/liquidation-threshold.ts | 32 +++++++++++++ test/dao/network-fee-withdraw.ts | 27 ++++++----- test/helpers/contract-helpers.ts | 5 +- test/helpers/gas-usage.ts | 24 +++++----- test/operators/register.ts | 22 ++++++++- test/sanity/balances.ts | 18 +++---- test/validators/register.ts | 8 ++++ 9 files changed, 170 insertions(+), 69 deletions(-) create mode 100644 test/dao/liquidation-threshold.ts diff --git a/contracts/ISSVNetwork.sol b/contracts/ISSVNetwork.sol index 25cc041c..f98e6cac 100644 --- a/contracts/ISSVNetwork.sol +++ b/contracts/ISSVNetwork.sol @@ -101,9 +101,11 @@ interface ISSVNetwork { event OperatorFeeIncreaseLimitUpdate(uint64 value); - event DeclareOperatorFeePeriodUpdate(uint256 value); + event DeclareOperatorFeePeriodUpdate(uint64 value); - event ExecuteOperatorFeePeriodUpdate(uint256 value); + event ExecuteOperatorFeePeriodUpdate(uint64 value); + + event LiquidationThresholdPeriodUpdate(uint64 value); /** * @dev Emitted when the network fee is updated. @@ -117,7 +119,7 @@ interface ISSVNetwork { * @param value The amount of tokens withdrawn. * @param recipient The recipient address. */ - event NetworkFeesWithdrawal(uint256 value, address recipient); + event NetworkEarningsWithdrawal(uint256 value, address recipient); event PodFundsWithdrawal(address ownerAddress, uint64[] operatorIds, uint256 value); event OperatorFundsWithdrawal(uint256 value, uint64 operatorId, address ownerAddress); @@ -163,6 +165,7 @@ interface ISSVNetwork { error BurnRatePositive(); error PodDataIsBroken(); error OperatorsListDoesNotSorted(); + error BelowMinimumBlockPeriod(); /****************/ /* Initializers */ @@ -179,7 +182,8 @@ interface ISSVNetwork { IERC20 token_, uint64 operatorMaxFeeIncrease_, uint64 declareOperatorFeePeriod_, - uint64 executeOperatorFeePeriod_ + uint64 executeOperatorFeePeriod_, + uint64 minimumBlocksBeforeLiquidation_ ) external; /*******************************/ @@ -208,6 +212,8 @@ interface ISSVNetwork { function cancelDeclaredOperatorFee(uint64 operatorId) external; + function feeRecipientAddress(address feeRecipientAddress) external; + /********************************/ /* Validator External Functions */ /********************************/ @@ -275,7 +281,7 @@ interface ISSVNetwork { function updateNetworkFee(uint256 fee) external; - function withdrawDAOEarnings(uint256 amount) external; + function withdrawNetworkEarnings(uint256 amount) external; function updateOperatorFeeIncreaseLimit(uint64 newOperatorMaxFeeIncrease) external; @@ -283,6 +289,7 @@ interface ISSVNetwork { function updateExecuteOperatorFeePeriod(uint64 newExecuteOperatorFeePeriod) external; + function updateLiquidationThresholdPeriod(uint64 blocks) external; /************************************/ /* Operator External View Functions */ @@ -292,7 +299,7 @@ interface ISSVNetwork { function getOperatorDeclaredFee(uint64 operatorId) external view returns (uint256, uint256, uint256); - function feeRecipientAddress(address feeRecipientAddress) external; + function getOperatorById(uint64 operatorId) external view returns (address owner, uint256 fee, uint32 validatorCount); /*******************************/ /* Pod External View Functions */ @@ -310,6 +317,8 @@ interface ISSVNetwork { Pod memory pod ) external view returns(bool); + function getPodBurnRate(uint64[] memory operatorIds) external view returns (uint256); + /***********************************/ /* Balance External View Functions */ /***********************************/ @@ -335,11 +344,13 @@ interface ISSVNetwork { function getNetworkFee() external view returns (uint256); - function getNetworkBalance() external view returns (uint256); + function getNetworkEarnings() external view returns (uint256); function getOperatorFeeIncreaseLimit() external view returns (uint64); function getExecuteOperatorFeePeriod() external view returns (uint64); function getDeclaredOperatorFeePeriod() external view returns (uint64); + + function getLiquidationThresholdPeriod() external view returns (uint64); } \ No newline at end of file diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index 70b49fec..f19d93e7 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -70,7 +70,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { /* Constants */ /*************/ - uint64 constant LIQUIDATION_MIN_BLOCKS = 50; + uint64 constant MINIMAL_LIQUIDATION_THRESHOLD = 6570; uint64 constant MINIMAL_OPERATOR_FEE = 100000000; /********************/ @@ -96,7 +96,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { uint64 private _declareOperatorFeePeriod; uint64 private _executeOperatorFeePeriod; uint64 private _operatorMaxFeeIncrease; - + uint64 private _minimumBlocksBeforeLiquidation; DAO private _dao; IERC20 private _token; @@ -109,31 +109,35 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { IERC20 token_, uint64 operatorMaxFeeIncrease_, uint64 declareOperatorFeePeriod_, - uint64 executeOperatorFeePeriod_ + uint64 executeOperatorFeePeriod_, + uint64 minimumBlocksBeforeLiquidation_ ) external override { - __SSVNetwork_init(token_, operatorMaxFeeIncrease_, declareOperatorFeePeriod_, executeOperatorFeePeriod_); + __SSVNetwork_init(token_, operatorMaxFeeIncrease_, declareOperatorFeePeriod_, executeOperatorFeePeriod_, minimumBlocksBeforeLiquidation_); } function __SSVNetwork_init( IERC20 token_, uint64 operatorMaxFeeIncrease_, uint64 declareOperatorFeePeriod_, - uint64 executeOperatorFeePeriod_ + uint64 executeOperatorFeePeriod_, + uint64 minimumBlocksBeforeLiquidation_ ) internal initializer { __Ownable_init_unchained(); - __SSVNetwork_init_unchained(token_, operatorMaxFeeIncrease_, declareOperatorFeePeriod_, executeOperatorFeePeriod_); + __SSVNetwork_init_unchained(token_, operatorMaxFeeIncrease_, declareOperatorFeePeriod_, executeOperatorFeePeriod_, minimumBlocksBeforeLiquidation_); } function __SSVNetwork_init_unchained( IERC20 token_, uint64 operatorMaxFeeIncrease_, uint64 declareOperatorFeePeriod_, - uint64 executeOperatorFeePeriod_ + uint64 executeOperatorFeePeriod_, + uint64 minimumBlocksBeforeLiquidation_ ) internal onlyInitializing { _token = token_; _operatorMaxFeeIncrease = operatorMaxFeeIncrease_; _declareOperatorFeePeriod = declareOperatorFeePeriod_; _executeOperatorFeePeriod = executeOperatorFeePeriod_; + _minimumBlocksBeforeLiquidation = minimumBlocksBeforeLiquidation_; } /*************/ @@ -226,6 +230,10 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { emit DeclaredOperatorFeeCancelation(msg.sender, operatorId); } + function feeRecipientAddress(address recipientAddress) external override { + emit FeeRecipientAddressAdded(msg.sender, recipientAddress); + } + /********************************/ /* Validator External Functions */ /********************************/ @@ -599,7 +607,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _networkFee = fee.shrink(); } - function withdrawDAOEarnings(uint256 amount) external onlyOwner override { + function withdrawNetworkEarnings(uint256 amount) external onlyOwner override { DAO memory dao = _dao; uint64 shrunkAmount = amount.shrink(); @@ -613,7 +621,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _token.transfer(msg.sender, amount); - emit NetworkFeesWithdrawal(amount, msg.sender); + emit NetworkEarningsWithdrawal(amount, msg.sender); } function updateOperatorFeeIncreaseLimit(uint64 newOperatorMaxFeeIncrease) external onlyOwner override { @@ -631,16 +639,23 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { emit ExecuteOperatorFeePeriodUpdate(newExecuteOperatorFeePeriod); } + function updateLiquidationThresholdPeriod(uint64 blocks) external onlyOwner override { + if(blocks < MINIMAL_LIQUIDATION_THRESHOLD) { + revert BelowMinimumBlockPeriod(); + } + + _minimumBlocksBeforeLiquidation = blocks; + emit LiquidationThresholdPeriodUpdate(blocks); + } + /************************************/ /* Operator External View Functions */ /************************************/ function getOperatorFee(uint64 operatorId) external view override returns (uint256) { - Operator memory operator = _operators[operatorId]; + if (_operators[operatorId].snapshot.block == 0) revert OperatorNotFound(); - if (operator.snapshot.block == 0) revert OperatorNotFound(); - - return operator.fee.expand(); + return _operators[operatorId].fee.expand(); } function getOperatorDeclaredFee(uint64 operatorId) external view override returns (uint256, uint256, uint256) { @@ -653,8 +668,10 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { return (feeChangeRequest.fee.expand(), feeChangeRequest.approvalBeginTime, feeChangeRequest.approvalEndTime); } - function feeRecipientAddress(address recipientAddress) external override { - emit FeeRecipientAddressAdded(msg.sender, recipientAddress); + function getOperatorById(uint64 operatorId) external view override returns (address owner, uint256 fee, uint32 validatorCount) { + if (_operators[operatorId].owner == address(0)) revert OperatorNotFound(); + + return (_operators[operatorId].owner, _operators[operatorId].fee.expand(), _operators[operatorId].validatorCount); } /*******************************/ @@ -668,12 +685,10 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { ) external view override returns (bool) { uint64 podIndex; uint64 burnRate; - { - for (uint8 i = 0; i < operatorIds.length; ++i) { - Operator memory operator = _operators[operatorIds[i]]; - podIndex += operator.snapshot.index + (uint64(block.number) - operator.snapshot.block) * operator.fee; - burnRate += operator.fee; - } + for (uint8 i = 0; i < operatorIds.length; ++i) { + Operator memory operator = _operators[operatorIds[i]]; + podIndex += operator.snapshot.index + (uint64(block.number) - operator.snapshot.block) * operator.fee; + burnRate += operator.fee; } _validateHashedPod(owner, operatorIds, pod); @@ -683,7 +698,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { function isLiquidated( address owner, - uint64[] memory operatorIds, + uint64[] calldata operatorIds, Pod memory pod ) external view override returns (bool) { _validateHashedPod(owner, operatorIds, pod); @@ -691,6 +706,17 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { return pod.disabled; } + function getPodBurnRate(uint64[] memory operatorIds) external view override returns (uint256) { + uint64 burnRate; + for (uint8 i = 0; i < operatorIds.length; ++i) { + Operator memory operator = _operators[operatorIds[i]]; + if (operator.owner != address(0)) { + burnRate += operator.fee; + } + } + return burnRate.expand(); + } + /***********************************/ /* Balance External View Functions */ /***********************************/ @@ -728,7 +754,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { return _networkFee.expand(); } - function getNetworkBalance() external view onlyOwner override returns (uint256) { + function getNetworkEarnings() external view override returns (uint256) { DAO memory dao = _dao; return _networkBalance(dao).expand(); } @@ -745,6 +771,10 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { return _declareOperatorFeePeriod; } + function getLiquidationThresholdPeriod() external view override returns (uint64) { + return _minimumBlocksBeforeLiquidation; + } + /********************************/ /* Validation Private Functions */ /********************************/ @@ -850,7 +880,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } function _liquidatable(uint64 balance, uint64 validatorCount, uint64 burnRate) private view returns (bool) { - return balance < LIQUIDATION_MIN_BLOCKS * (burnRate + _networkFee) * validatorCount; + return balance < _minimumBlocksBeforeLiquidation * (burnRate + _networkFee) * validatorCount; } /*****************************/ diff --git a/test/dao/liquidation-threshold.ts b/test/dao/liquidation-threshold.ts new file mode 100644 index 00000000..7047d61b --- /dev/null +++ b/test/dao/liquidation-threshold.ts @@ -0,0 +1,32 @@ +// Declare imports +import * as helpers from '../helpers/contract-helpers'; +import { expect } from 'chai'; + +// Declare globals +let ssvNetworkContract: any, networkFee: any; + +describe('Liquidation Threshold Tests', () => { + beforeEach(async () => { + // Initialize contract + ssvNetworkContract = (await helpers.initializeContract()).contract; + + // Define minumum allowed network fee to pass shrinkable validation + networkFee = helpers.CONFIG.minimalOperatorFee / 10; + }); + + it('Change liquidation threshold period emits "LiquidationThresholdPeriodUpdate"', async () => { + await expect(ssvNetworkContract.updateLiquidationThresholdPeriod(helpers.CONFIG.minimalBlocksBeforeLiquidation + 10)).to.emit(ssvNetworkContract, 'LiquidationThresholdPeriodUpdate').withArgs(helpers.CONFIG.minimalBlocksBeforeLiquidation + 10); + }); + + it('Get liquidation threshold period', async () => { + expect(await ssvNetworkContract.getLiquidationThresholdPeriod()).to.equal(helpers.CONFIG.minimalBlocksBeforeLiquidation); + }); + + it('Change liquidation threshold period reverts "BelowMinimumBlockPeriod"', async () => { + await expect(ssvNetworkContract.updateLiquidationThresholdPeriod(helpers.CONFIG.minimalBlocksBeforeLiquidation - 10)).to.be.revertedWith('BelowMinimumBlockPeriod'); + }); + + it('Change liquidation threshold period reverts "caller is not the owner"', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[3]).updateLiquidationThresholdPeriod(helpers.CONFIG.minimalBlocksBeforeLiquidation)).to.be.revertedWith('caller is not the owner'); + }); +}); diff --git a/test/dao/network-fee-withdraw.ts b/test/dao/network-fee-withdraw.ts index bc7a092c..91ac7e75 100644 --- a/test/dao/network-fee-withdraw.ts +++ b/test/dao/network-fee-withdraw.ts @@ -52,31 +52,30 @@ describe('DAO Network Fee Withdraw Tests', () => { // Mint tokens await helpers.DB.ssvToken.mint(ssvNetworkContract.address, minDepositAmount); }); - - it('Withdraw network earnings emits "NetworkFeesWithdrawal"', async () => { - const amount = await ssvNetworkContract.getNetworkBalance(); - await expect(ssvNetworkContract.withdrawDAOEarnings(amount - )).to.emit(ssvNetworkContract, 'NetworkFeesWithdrawal').withArgs(amount, helpers.DB.owners[0].address); + + it('Withdraw network earnings emits "NetworkEarningsWithdrawal"', async () => { + const amount = await ssvNetworkContract.getNetworkEarnings(); + await expect(ssvNetworkContract.withdrawNetworkEarnings(amount + )).to.emit(ssvNetworkContract, 'NetworkEarningsWithdrawal').withArgs(amount, helpers.DB.owners[0].address); }); it('Get withdrawable network earnings', async () => { - expect(await ssvNetworkContract.getNetworkBalance()).to.above(0); + expect(await ssvNetworkContract.getNetworkEarnings()).to.above(0); }); - it('Get withdrawable network earnings reverts "caller is not the owner"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[3]).getNetworkBalance( - )).to.be.revertedWith('caller is not the owner'); + it('Get withdrawable network earnings as not owner', async () => { + await ssvNetworkContract.connect(helpers.DB.owners[3]).getNetworkEarnings(); }); it('Withdraw network earnings with not enough balance reverts "NotEnoughBalance"', async () => { - const amount = await ssvNetworkContract.getNetworkBalance() * 2; - await expect(ssvNetworkContract.withdrawDAOEarnings(amount + const amount = await ssvNetworkContract.getNetworkEarnings() * 2; + await expect(ssvNetworkContract.withdrawNetworkEarnings(amount )).to.be.revertedWith('NotEnoughBalance'); }); it('Withdraw network earnings from an address thats not the DAO reverts "caller is not the owner"', async () => { - const amount = await ssvNetworkContract.getNetworkBalance(); - await expect(ssvNetworkContract.connect(helpers.DB.owners[3]).withdrawDAOEarnings(amount + const amount = await ssvNetworkContract.getNetworkEarnings(); + await expect(ssvNetworkContract.connect(helpers.DB.owners[3]).withdrawNetworkEarnings(amount )).to.be.revertedWith('caller is not the owner'); }); -}); \ No newline at end of file +}); diff --git a/test/helpers/contract-helpers.ts b/test/helpers/contract-helpers.ts index 3d818fd0..9287bcab 100644 --- a/test/helpers/contract-helpers.ts +++ b/test/helpers/contract-helpers.ts @@ -45,7 +45,7 @@ export const initializeContract = async () => { declareOperatorFeePeriod: 3600, // HOUR executeOperatorFeePeriod: 86400, // DAY minimalOperatorFee: 100000000, - minimalBlocksBeforeLiquidation: 50, + minimalBlocksBeforeLiquidation: 6570, }; DB = { @@ -71,7 +71,8 @@ export const initializeContract = async () => { DB.ssvToken.address, CONFIG.operatorMaxFeeIncrease, CONFIG.declareOperatorFeePeriod, - CONFIG.executeOperatorFeePeriod + CONFIG.executeOperatorFeePeriod, + CONFIG.minimalBlocksBeforeLiquidation ]); await DB.ssvNetwork.contract.deployed(); diff --git a/test/helpers/gas-usage.ts b/test/helpers/gas-usage.ts index 2c92d852..61777cbe 100644 --- a/test/helpers/gas-usage.ts +++ b/test/helpers/gas-usage.ts @@ -36,17 +36,17 @@ const MAX_GAS_PER_GROUP: any = { [GasGroup.REMOVE_OPERATOR]: 62000, [GasGroup.REMOVE_OPERATOR_WITH_WITHDRAW]: 62000, - [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]: 174000, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE]: 191100, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT]: 151100, + [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]: 176500, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE]: 194500, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT]: 153500, - [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_7]: 217100, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]: 234100, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_7]: 194100, + [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_7]: 219500, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]: 236500, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_7]: 196500, - [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_13]: 303200, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]: 320200, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_13]: 280200, + [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_13]: 306200, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]: 323200, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_13]: 283200, [GasGroup.REMOVE_VALIDATOR]: 120000, [GasGroup.TRANSFER_VALIDATOR_NEW_CLUSTER]: 400000, @@ -55,11 +55,11 @@ const MAX_GAS_PER_GROUP: any = { [GasGroup.BULK_TRANSFER_VALIDATOR]: 366000, [GasGroup.BULK_TRANSFER_VALIDATOR_NON_EXISTING_POD]: 383000, [GasGroup.DEPOSIT]: 77500, - [GasGroup.WITHDRAW_POD_BALANCE]: 93100, + [GasGroup.WITHDRAW_POD_BALANCE]: 95500, [GasGroup.WITHDRAW_OPERATOR_BALANCE]: 59000, [GasGroup.REGISTER_POD]: 137000, - [GasGroup.LIQUIDATE_POD]: 135000, - [GasGroup.REACTIVATE_POD]: 135000, + [GasGroup.LIQUIDATE_POD]: 137000, + [GasGroup.REACTIVATE_POD]: 137000, }; class GasStats { diff --git a/test/operators/register.ts b/test/operators/register.ts index 339bcaaa..7f3423a0 100644 --- a/test/operators/register.ts +++ b/test/operators/register.ts @@ -32,4 +32,24 @@ describe('Register Operator Tests', () => { '10' )).to.be.revertedWith('FeeTooLow'); }); -}); \ No newline at end of file + + it('Get operator by id', async () => { + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerOperator( + helpers.DataGenerator.publicKey(0), + helpers.CONFIG.minimalOperatorFee, + ), [GasGroup.REGISTER_OPERATOR]); + + expect((await ssvNetworkContract.getOperatorById(1)).owner).to.equal(helpers.DB.owners[1].address); + expect((await ssvNetworkContract.getOperatorById(1)).fee).to.equal(helpers.CONFIG.minimalOperatorFee); + expect((await ssvNetworkContract.getOperatorById(1)).validatorCount).to.equal(0); + }); + + it('Get operator by id reverts "OperatorNotFound"', async () => { + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerOperator( + helpers.DataGenerator.publicKey(0), + helpers.CONFIG.minimalOperatorFee, + ), [GasGroup.REGISTER_OPERATOR]); + + await expect(ssvNetworkContract.getOperatorById(3)).to.be.revertedWith('OperatorNotFound'); + }); +}); diff --git a/test/sanity/balances.ts b/test/sanity/balances.ts index 00fbd452..4d7396ac 100644 --- a/test/sanity/balances.ts +++ b/test/sanity/balances.ts @@ -43,7 +43,7 @@ describe('Balance Tests', () => { ); pod1 = await helpers.registerValidators(4, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); - initNetworkFeeBalance = await ssvNetworkContract.getNetworkBalance(); + initNetworkFeeBalance = await ssvNetworkContract.getNetworkEarnings(); }); it('Check pod balance in three blocks, one after the other', async () => { @@ -70,24 +70,24 @@ describe('Balance Tests', () => { it('Check DAO earnings in three blocks, one after the other', async () => { await utils.progressBlocks(1); - expect(await ssvNetworkContract.getNetworkBalance() - initNetworkFeeBalance).to.equal(networkFee * 2); + expect(await ssvNetworkContract.getNetworkEarnings() - initNetworkFeeBalance).to.equal(networkFee * 2); await utils.progressBlocks(1); - expect(await ssvNetworkContract.getNetworkBalance() - initNetworkFeeBalance).to.equal(networkFee * 4); + expect(await ssvNetworkContract.getNetworkEarnings() - initNetworkFeeBalance).to.equal(networkFee * 4); await utils.progressBlocks(1); - expect(await ssvNetworkContract.getNetworkBalance() - initNetworkFeeBalance).to.equal(networkFee * 6); + expect(await ssvNetworkContract.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 ssvNetworkContract.getNetworkBalance() - initNetworkFeeBalance).to.equal(networkFee * 2); + expect(await ssvNetworkContract.getNetworkEarnings() - initNetworkFeeBalance).to.equal(networkFee * 2); const newNetworkFee = networkFee * 2; await ssvNetworkContract.updateNetworkFee(newNetworkFee); await utils.progressBlocks(1); - expect(await ssvNetworkContract.getNetworkBalance() - initNetworkFeeBalance).to.equal(networkFee * 4 + newNetworkFee * 2); + expect(await ssvNetworkContract.getNetworkEarnings() - initNetworkFeeBalance).to.equal(networkFee * 4 + newNetworkFee * 2); await utils.progressBlocks(1); - expect(await ssvNetworkContract.getNetworkBalance() - initNetworkFeeBalance).to.equal(networkFee * 4 + newNetworkFee * 4); + expect(await ssvNetworkContract.getNetworkEarnings() - initNetworkFeeBalance).to.equal(networkFee * 4 + newNetworkFee * 4); await utils.progressBlocks(10); - expect(await ssvNetworkContract.getNetworkBalance() - initNetworkFeeBalance).to.equal(networkFee * 4 + newNetworkFee * 24); + expect(await ssvNetworkContract.getNetworkEarnings() - initNetworkFeeBalance).to.equal(networkFee * 4 + newNetworkFee * 24); }); it('Check operators earnings in three blocks, one after the other', async () => { @@ -109,7 +109,7 @@ describe('Balance Tests', () => { }); it('Check pod balance returns error - NegativeBalance', async () => { - await utils.progressBlocks(1000); + await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation + 10); await expect(ssvNetworkContract.podBalanceOf(helpers.DB.owners[4].address, pod1.args.operatorIds, pod1.args.pod)).to.be.revertedWith('NegativeBalance'); }); diff --git a/test/validators/register.ts b/test/validators/register.ts index 55355139..47850aac 100644 --- a/test/validators/register.ts +++ b/test/validators/register.ts @@ -548,4 +548,12 @@ describe('Register Validator Tests', () => { } )).to.be.revertedWith('ValidatorAlreadyExists'); }); + + it('Get pod burn rate', async () => { + expect(await ssvNetworkContract.getPodBurnRate([1,2,3,4])).to.equal(helpers.CONFIG.minimalOperatorFee * 4); + }); + + it('Get pod burn rate by not existed operator in the list', async () => { + expect(await ssvNetworkContract.getPodBurnRate([1,2,3,41])).to.equal(helpers.CONFIG.minimalOperatorFee * 3); + }); }); From 5e39c4e2569d881b26b3cc8bc1e2f3d34b67c255 Mon Sep 17 00:00:00 2001 From: Wadym Date: Wed, 28 Dec 2022 13:41:57 +0100 Subject: [PATCH 106/149] Revert "Get DAO functions + pod burn rate (#153)" (#154) This reverts commit 939c45a7e2aa15d90ff24e065a6148efabb0f314. --- contracts/ISSVNetwork.sol | 25 +++------- contracts/SSVNetwork.sol | 78 ++++++++++--------------------- test/dao/liquidation-threshold.ts | 32 ------------- test/dao/network-fee-withdraw.ts | 27 +++++------ test/helpers/contract-helpers.ts | 5 +- test/helpers/gas-usage.ts | 24 +++++----- test/operators/register.ts | 22 +-------- test/sanity/balances.ts | 18 +++---- test/validators/register.ts | 8 ---- 9 files changed, 69 insertions(+), 170 deletions(-) delete mode 100644 test/dao/liquidation-threshold.ts diff --git a/contracts/ISSVNetwork.sol b/contracts/ISSVNetwork.sol index f98e6cac..25cc041c 100644 --- a/contracts/ISSVNetwork.sol +++ b/contracts/ISSVNetwork.sol @@ -101,11 +101,9 @@ interface ISSVNetwork { event OperatorFeeIncreaseLimitUpdate(uint64 value); - event DeclareOperatorFeePeriodUpdate(uint64 value); + event DeclareOperatorFeePeriodUpdate(uint256 value); - event ExecuteOperatorFeePeriodUpdate(uint64 value); - - event LiquidationThresholdPeriodUpdate(uint64 value); + event ExecuteOperatorFeePeriodUpdate(uint256 value); /** * @dev Emitted when the network fee is updated. @@ -119,7 +117,7 @@ interface ISSVNetwork { * @param value The amount of tokens withdrawn. * @param recipient The recipient address. */ - event NetworkEarningsWithdrawal(uint256 value, address recipient); + event NetworkFeesWithdrawal(uint256 value, address recipient); event PodFundsWithdrawal(address ownerAddress, uint64[] operatorIds, uint256 value); event OperatorFundsWithdrawal(uint256 value, uint64 operatorId, address ownerAddress); @@ -165,7 +163,6 @@ interface ISSVNetwork { error BurnRatePositive(); error PodDataIsBroken(); error OperatorsListDoesNotSorted(); - error BelowMinimumBlockPeriod(); /****************/ /* Initializers */ @@ -182,8 +179,7 @@ interface ISSVNetwork { IERC20 token_, uint64 operatorMaxFeeIncrease_, uint64 declareOperatorFeePeriod_, - uint64 executeOperatorFeePeriod_, - uint64 minimumBlocksBeforeLiquidation_ + uint64 executeOperatorFeePeriod_ ) external; /*******************************/ @@ -212,8 +208,6 @@ interface ISSVNetwork { function cancelDeclaredOperatorFee(uint64 operatorId) external; - function feeRecipientAddress(address feeRecipientAddress) external; - /********************************/ /* Validator External Functions */ /********************************/ @@ -281,7 +275,7 @@ interface ISSVNetwork { function updateNetworkFee(uint256 fee) external; - function withdrawNetworkEarnings(uint256 amount) external; + function withdrawDAOEarnings(uint256 amount) external; function updateOperatorFeeIncreaseLimit(uint64 newOperatorMaxFeeIncrease) external; @@ -289,7 +283,6 @@ interface ISSVNetwork { function updateExecuteOperatorFeePeriod(uint64 newExecuteOperatorFeePeriod) external; - function updateLiquidationThresholdPeriod(uint64 blocks) external; /************************************/ /* Operator External View Functions */ @@ -299,7 +292,7 @@ interface ISSVNetwork { function getOperatorDeclaredFee(uint64 operatorId) external view returns (uint256, uint256, uint256); - function getOperatorById(uint64 operatorId) external view returns (address owner, uint256 fee, uint32 validatorCount); + function feeRecipientAddress(address feeRecipientAddress) external; /*******************************/ /* Pod External View Functions */ @@ -317,8 +310,6 @@ interface ISSVNetwork { Pod memory pod ) external view returns(bool); - function getPodBurnRate(uint64[] memory operatorIds) external view returns (uint256); - /***********************************/ /* Balance External View Functions */ /***********************************/ @@ -344,13 +335,11 @@ interface ISSVNetwork { function getNetworkFee() external view returns (uint256); - function getNetworkEarnings() external view returns (uint256); + function getNetworkBalance() external view returns (uint256); function getOperatorFeeIncreaseLimit() external view returns (uint64); function getExecuteOperatorFeePeriod() external view returns (uint64); function getDeclaredOperatorFeePeriod() external view returns (uint64); - - function getLiquidationThresholdPeriod() external view returns (uint64); } \ No newline at end of file diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index f19d93e7..70b49fec 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -70,7 +70,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { /* Constants */ /*************/ - uint64 constant MINIMAL_LIQUIDATION_THRESHOLD = 6570; + uint64 constant LIQUIDATION_MIN_BLOCKS = 50; uint64 constant MINIMAL_OPERATOR_FEE = 100000000; /********************/ @@ -96,7 +96,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { uint64 private _declareOperatorFeePeriod; uint64 private _executeOperatorFeePeriod; uint64 private _operatorMaxFeeIncrease; - uint64 private _minimumBlocksBeforeLiquidation; + DAO private _dao; IERC20 private _token; @@ -109,35 +109,31 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { IERC20 token_, uint64 operatorMaxFeeIncrease_, uint64 declareOperatorFeePeriod_, - uint64 executeOperatorFeePeriod_, - uint64 minimumBlocksBeforeLiquidation_ + uint64 executeOperatorFeePeriod_ ) external override { - __SSVNetwork_init(token_, operatorMaxFeeIncrease_, declareOperatorFeePeriod_, executeOperatorFeePeriod_, minimumBlocksBeforeLiquidation_); + __SSVNetwork_init(token_, operatorMaxFeeIncrease_, declareOperatorFeePeriod_, executeOperatorFeePeriod_); } function __SSVNetwork_init( IERC20 token_, uint64 operatorMaxFeeIncrease_, uint64 declareOperatorFeePeriod_, - uint64 executeOperatorFeePeriod_, - uint64 minimumBlocksBeforeLiquidation_ + uint64 executeOperatorFeePeriod_ ) internal initializer { __Ownable_init_unchained(); - __SSVNetwork_init_unchained(token_, operatorMaxFeeIncrease_, declareOperatorFeePeriod_, executeOperatorFeePeriod_, minimumBlocksBeforeLiquidation_); + __SSVNetwork_init_unchained(token_, operatorMaxFeeIncrease_, declareOperatorFeePeriod_, executeOperatorFeePeriod_); } function __SSVNetwork_init_unchained( IERC20 token_, uint64 operatorMaxFeeIncrease_, uint64 declareOperatorFeePeriod_, - uint64 executeOperatorFeePeriod_, - uint64 minimumBlocksBeforeLiquidation_ + uint64 executeOperatorFeePeriod_ ) internal onlyInitializing { _token = token_; _operatorMaxFeeIncrease = operatorMaxFeeIncrease_; _declareOperatorFeePeriod = declareOperatorFeePeriod_; _executeOperatorFeePeriod = executeOperatorFeePeriod_; - _minimumBlocksBeforeLiquidation = minimumBlocksBeforeLiquidation_; } /*************/ @@ -230,10 +226,6 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { emit DeclaredOperatorFeeCancelation(msg.sender, operatorId); } - function feeRecipientAddress(address recipientAddress) external override { - emit FeeRecipientAddressAdded(msg.sender, recipientAddress); - } - /********************************/ /* Validator External Functions */ /********************************/ @@ -607,7 +599,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _networkFee = fee.shrink(); } - function withdrawNetworkEarnings(uint256 amount) external onlyOwner override { + function withdrawDAOEarnings(uint256 amount) external onlyOwner override { DAO memory dao = _dao; uint64 shrunkAmount = amount.shrink(); @@ -621,7 +613,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _token.transfer(msg.sender, amount); - emit NetworkEarningsWithdrawal(amount, msg.sender); + emit NetworkFeesWithdrawal(amount, msg.sender); } function updateOperatorFeeIncreaseLimit(uint64 newOperatorMaxFeeIncrease) external onlyOwner override { @@ -639,23 +631,16 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { emit ExecuteOperatorFeePeriodUpdate(newExecuteOperatorFeePeriod); } - function updateLiquidationThresholdPeriod(uint64 blocks) external onlyOwner override { - if(blocks < MINIMAL_LIQUIDATION_THRESHOLD) { - revert BelowMinimumBlockPeriod(); - } - - _minimumBlocksBeforeLiquidation = blocks; - emit LiquidationThresholdPeriodUpdate(blocks); - } - /************************************/ /* Operator External View Functions */ /************************************/ function getOperatorFee(uint64 operatorId) external view override returns (uint256) { - if (_operators[operatorId].snapshot.block == 0) revert OperatorNotFound(); + Operator memory operator = _operators[operatorId]; - return _operators[operatorId].fee.expand(); + if (operator.snapshot.block == 0) revert OperatorNotFound(); + + return operator.fee.expand(); } function getOperatorDeclaredFee(uint64 operatorId) external view override returns (uint256, uint256, uint256) { @@ -668,10 +653,8 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { return (feeChangeRequest.fee.expand(), feeChangeRequest.approvalBeginTime, feeChangeRequest.approvalEndTime); } - function getOperatorById(uint64 operatorId) external view override returns (address owner, uint256 fee, uint32 validatorCount) { - if (_operators[operatorId].owner == address(0)) revert OperatorNotFound(); - - return (_operators[operatorId].owner, _operators[operatorId].fee.expand(), _operators[operatorId].validatorCount); + function feeRecipientAddress(address recipientAddress) external override { + emit FeeRecipientAddressAdded(msg.sender, recipientAddress); } /*******************************/ @@ -685,10 +668,12 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { ) external view override returns (bool) { uint64 podIndex; uint64 burnRate; - for (uint8 i = 0; i < operatorIds.length; ++i) { - Operator memory operator = _operators[operatorIds[i]]; - podIndex += operator.snapshot.index + (uint64(block.number) - operator.snapshot.block) * operator.fee; - burnRate += operator.fee; + { + for (uint8 i = 0; i < operatorIds.length; ++i) { + Operator memory operator = _operators[operatorIds[i]]; + podIndex += operator.snapshot.index + (uint64(block.number) - operator.snapshot.block) * operator.fee; + burnRate += operator.fee; + } } _validateHashedPod(owner, operatorIds, pod); @@ -698,7 +683,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { function isLiquidated( address owner, - uint64[] calldata operatorIds, + uint64[] memory operatorIds, Pod memory pod ) external view override returns (bool) { _validateHashedPod(owner, operatorIds, pod); @@ -706,17 +691,6 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { return pod.disabled; } - function getPodBurnRate(uint64[] memory operatorIds) external view override returns (uint256) { - uint64 burnRate; - for (uint8 i = 0; i < operatorIds.length; ++i) { - Operator memory operator = _operators[operatorIds[i]]; - if (operator.owner != address(0)) { - burnRate += operator.fee; - } - } - return burnRate.expand(); - } - /***********************************/ /* Balance External View Functions */ /***********************************/ @@ -754,7 +728,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { return _networkFee.expand(); } - function getNetworkEarnings() external view override returns (uint256) { + function getNetworkBalance() external view onlyOwner override returns (uint256) { DAO memory dao = _dao; return _networkBalance(dao).expand(); } @@ -771,10 +745,6 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { return _declareOperatorFeePeriod; } - function getLiquidationThresholdPeriod() external view override returns (uint64) { - return _minimumBlocksBeforeLiquidation; - } - /********************************/ /* Validation Private Functions */ /********************************/ @@ -880,7 +850,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } function _liquidatable(uint64 balance, uint64 validatorCount, uint64 burnRate) private view returns (bool) { - return balance < _minimumBlocksBeforeLiquidation * (burnRate + _networkFee) * validatorCount; + return balance < LIQUIDATION_MIN_BLOCKS * (burnRate + _networkFee) * validatorCount; } /*****************************/ diff --git a/test/dao/liquidation-threshold.ts b/test/dao/liquidation-threshold.ts deleted file mode 100644 index 7047d61b..00000000 --- a/test/dao/liquidation-threshold.ts +++ /dev/null @@ -1,32 +0,0 @@ -// Declare imports -import * as helpers from '../helpers/contract-helpers'; -import { expect } from 'chai'; - -// Declare globals -let ssvNetworkContract: any, networkFee: any; - -describe('Liquidation Threshold Tests', () => { - beforeEach(async () => { - // Initialize contract - ssvNetworkContract = (await helpers.initializeContract()).contract; - - // Define minumum allowed network fee to pass shrinkable validation - networkFee = helpers.CONFIG.minimalOperatorFee / 10; - }); - - it('Change liquidation threshold period emits "LiquidationThresholdPeriodUpdate"', async () => { - await expect(ssvNetworkContract.updateLiquidationThresholdPeriod(helpers.CONFIG.minimalBlocksBeforeLiquidation + 10)).to.emit(ssvNetworkContract, 'LiquidationThresholdPeriodUpdate').withArgs(helpers.CONFIG.minimalBlocksBeforeLiquidation + 10); - }); - - it('Get liquidation threshold period', async () => { - expect(await ssvNetworkContract.getLiquidationThresholdPeriod()).to.equal(helpers.CONFIG.minimalBlocksBeforeLiquidation); - }); - - it('Change liquidation threshold period reverts "BelowMinimumBlockPeriod"', async () => { - await expect(ssvNetworkContract.updateLiquidationThresholdPeriod(helpers.CONFIG.minimalBlocksBeforeLiquidation - 10)).to.be.revertedWith('BelowMinimumBlockPeriod'); - }); - - it('Change liquidation threshold period reverts "caller is not the owner"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[3]).updateLiquidationThresholdPeriod(helpers.CONFIG.minimalBlocksBeforeLiquidation)).to.be.revertedWith('caller is not the owner'); - }); -}); diff --git a/test/dao/network-fee-withdraw.ts b/test/dao/network-fee-withdraw.ts index 91ac7e75..bc7a092c 100644 --- a/test/dao/network-fee-withdraw.ts +++ b/test/dao/network-fee-withdraw.ts @@ -52,30 +52,31 @@ describe('DAO Network Fee Withdraw Tests', () => { // Mint tokens await helpers.DB.ssvToken.mint(ssvNetworkContract.address, minDepositAmount); }); - - it('Withdraw network earnings emits "NetworkEarningsWithdrawal"', async () => { - const amount = await ssvNetworkContract.getNetworkEarnings(); - await expect(ssvNetworkContract.withdrawNetworkEarnings(amount - )).to.emit(ssvNetworkContract, 'NetworkEarningsWithdrawal').withArgs(amount, helpers.DB.owners[0].address); + + it('Withdraw network earnings emits "NetworkFeesWithdrawal"', async () => { + const amount = await ssvNetworkContract.getNetworkBalance(); + await expect(ssvNetworkContract.withdrawDAOEarnings(amount + )).to.emit(ssvNetworkContract, 'NetworkFeesWithdrawal').withArgs(amount, helpers.DB.owners[0].address); }); it('Get withdrawable network earnings', async () => { - expect(await ssvNetworkContract.getNetworkEarnings()).to.above(0); + expect(await ssvNetworkContract.getNetworkBalance()).to.above(0); }); - it('Get withdrawable network earnings as not owner', async () => { - await ssvNetworkContract.connect(helpers.DB.owners[3]).getNetworkEarnings(); + it('Get withdrawable network earnings reverts "caller is not the owner"', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[3]).getNetworkBalance( + )).to.be.revertedWith('caller is not the owner'); }); it('Withdraw network earnings with not enough balance reverts "NotEnoughBalance"', async () => { - const amount = await ssvNetworkContract.getNetworkEarnings() * 2; - await expect(ssvNetworkContract.withdrawNetworkEarnings(amount + const amount = await ssvNetworkContract.getNetworkBalance() * 2; + await expect(ssvNetworkContract.withdrawDAOEarnings(amount )).to.be.revertedWith('NotEnoughBalance'); }); it('Withdraw network earnings from an address thats not the DAO reverts "caller is not the owner"', async () => { - const amount = await ssvNetworkContract.getNetworkEarnings(); - await expect(ssvNetworkContract.connect(helpers.DB.owners[3]).withdrawNetworkEarnings(amount + const amount = await ssvNetworkContract.getNetworkBalance(); + await expect(ssvNetworkContract.connect(helpers.DB.owners[3]).withdrawDAOEarnings(amount )).to.be.revertedWith('caller is not the owner'); }); -}); +}); \ No newline at end of file diff --git a/test/helpers/contract-helpers.ts b/test/helpers/contract-helpers.ts index 9287bcab..3d818fd0 100644 --- a/test/helpers/contract-helpers.ts +++ b/test/helpers/contract-helpers.ts @@ -45,7 +45,7 @@ export const initializeContract = async () => { declareOperatorFeePeriod: 3600, // HOUR executeOperatorFeePeriod: 86400, // DAY minimalOperatorFee: 100000000, - minimalBlocksBeforeLiquidation: 6570, + minimalBlocksBeforeLiquidation: 50, }; DB = { @@ -71,8 +71,7 @@ export const initializeContract = async () => { DB.ssvToken.address, CONFIG.operatorMaxFeeIncrease, CONFIG.declareOperatorFeePeriod, - CONFIG.executeOperatorFeePeriod, - CONFIG.minimalBlocksBeforeLiquidation + CONFIG.executeOperatorFeePeriod ]); await DB.ssvNetwork.contract.deployed(); diff --git a/test/helpers/gas-usage.ts b/test/helpers/gas-usage.ts index 61777cbe..2c92d852 100644 --- a/test/helpers/gas-usage.ts +++ b/test/helpers/gas-usage.ts @@ -36,17 +36,17 @@ const MAX_GAS_PER_GROUP: any = { [GasGroup.REMOVE_OPERATOR]: 62000, [GasGroup.REMOVE_OPERATOR_WITH_WITHDRAW]: 62000, - [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]: 176500, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE]: 194500, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT]: 153500, + [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]: 174000, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE]: 191100, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT]: 151100, - [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_7]: 219500, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]: 236500, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_7]: 196500, + [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_7]: 217100, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]: 234100, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_7]: 194100, - [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_13]: 306200, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]: 323200, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_13]: 283200, + [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_13]: 303200, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]: 320200, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_13]: 280200, [GasGroup.REMOVE_VALIDATOR]: 120000, [GasGroup.TRANSFER_VALIDATOR_NEW_CLUSTER]: 400000, @@ -55,11 +55,11 @@ const MAX_GAS_PER_GROUP: any = { [GasGroup.BULK_TRANSFER_VALIDATOR]: 366000, [GasGroup.BULK_TRANSFER_VALIDATOR_NON_EXISTING_POD]: 383000, [GasGroup.DEPOSIT]: 77500, - [GasGroup.WITHDRAW_POD_BALANCE]: 95500, + [GasGroup.WITHDRAW_POD_BALANCE]: 93100, [GasGroup.WITHDRAW_OPERATOR_BALANCE]: 59000, [GasGroup.REGISTER_POD]: 137000, - [GasGroup.LIQUIDATE_POD]: 137000, - [GasGroup.REACTIVATE_POD]: 137000, + [GasGroup.LIQUIDATE_POD]: 135000, + [GasGroup.REACTIVATE_POD]: 135000, }; class GasStats { diff --git a/test/operators/register.ts b/test/operators/register.ts index 7f3423a0..339bcaaa 100644 --- a/test/operators/register.ts +++ b/test/operators/register.ts @@ -32,24 +32,4 @@ describe('Register Operator Tests', () => { '10' )).to.be.revertedWith('FeeTooLow'); }); - - it('Get operator by id', async () => { - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerOperator( - helpers.DataGenerator.publicKey(0), - helpers.CONFIG.minimalOperatorFee, - ), [GasGroup.REGISTER_OPERATOR]); - - expect((await ssvNetworkContract.getOperatorById(1)).owner).to.equal(helpers.DB.owners[1].address); - expect((await ssvNetworkContract.getOperatorById(1)).fee).to.equal(helpers.CONFIG.minimalOperatorFee); - expect((await ssvNetworkContract.getOperatorById(1)).validatorCount).to.equal(0); - }); - - it('Get operator by id reverts "OperatorNotFound"', async () => { - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerOperator( - helpers.DataGenerator.publicKey(0), - helpers.CONFIG.minimalOperatorFee, - ), [GasGroup.REGISTER_OPERATOR]); - - await expect(ssvNetworkContract.getOperatorById(3)).to.be.revertedWith('OperatorNotFound'); - }); -}); +}); \ No newline at end of file diff --git a/test/sanity/balances.ts b/test/sanity/balances.ts index 4d7396ac..00fbd452 100644 --- a/test/sanity/balances.ts +++ b/test/sanity/balances.ts @@ -43,7 +43,7 @@ describe('Balance Tests', () => { ); pod1 = await helpers.registerValidators(4, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); - initNetworkFeeBalance = await ssvNetworkContract.getNetworkEarnings(); + initNetworkFeeBalance = await ssvNetworkContract.getNetworkBalance(); }); it('Check pod balance in three blocks, one after the other', async () => { @@ -70,24 +70,24 @@ describe('Balance Tests', () => { it('Check DAO earnings in three blocks, one after the other', async () => { await utils.progressBlocks(1); - expect(await ssvNetworkContract.getNetworkEarnings() - initNetworkFeeBalance).to.equal(networkFee * 2); + expect(await ssvNetworkContract.getNetworkBalance() - initNetworkFeeBalance).to.equal(networkFee * 2); await utils.progressBlocks(1); - expect(await ssvNetworkContract.getNetworkEarnings() - initNetworkFeeBalance).to.equal(networkFee * 4); + expect(await ssvNetworkContract.getNetworkBalance() - initNetworkFeeBalance).to.equal(networkFee * 4); await utils.progressBlocks(1); - expect(await ssvNetworkContract.getNetworkEarnings() - initNetworkFeeBalance).to.equal(networkFee * 6); + expect(await ssvNetworkContract.getNetworkBalance() - 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 ssvNetworkContract.getNetworkEarnings() - initNetworkFeeBalance).to.equal(networkFee * 2); + expect(await ssvNetworkContract.getNetworkBalance() - initNetworkFeeBalance).to.equal(networkFee * 2); const newNetworkFee = networkFee * 2; await ssvNetworkContract.updateNetworkFee(newNetworkFee); await utils.progressBlocks(1); - expect(await ssvNetworkContract.getNetworkEarnings() - initNetworkFeeBalance).to.equal(networkFee * 4 + newNetworkFee * 2); + expect(await ssvNetworkContract.getNetworkBalance() - initNetworkFeeBalance).to.equal(networkFee * 4 + newNetworkFee * 2); await utils.progressBlocks(1); - expect(await ssvNetworkContract.getNetworkEarnings() - initNetworkFeeBalance).to.equal(networkFee * 4 + newNetworkFee * 4); + expect(await ssvNetworkContract.getNetworkBalance() - initNetworkFeeBalance).to.equal(networkFee * 4 + newNetworkFee * 4); await utils.progressBlocks(10); - expect(await ssvNetworkContract.getNetworkEarnings() - initNetworkFeeBalance).to.equal(networkFee * 4 + newNetworkFee * 24); + expect(await ssvNetworkContract.getNetworkBalance() - initNetworkFeeBalance).to.equal(networkFee * 4 + newNetworkFee * 24); }); it('Check operators earnings in three blocks, one after the other', async () => { @@ -109,7 +109,7 @@ describe('Balance Tests', () => { }); it('Check pod balance returns error - NegativeBalance', async () => { - await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation + 10); + await utils.progressBlocks(1000); await expect(ssvNetworkContract.podBalanceOf(helpers.DB.owners[4].address, pod1.args.operatorIds, pod1.args.pod)).to.be.revertedWith('NegativeBalance'); }); diff --git a/test/validators/register.ts b/test/validators/register.ts index 47850aac..55355139 100644 --- a/test/validators/register.ts +++ b/test/validators/register.ts @@ -548,12 +548,4 @@ describe('Register Validator Tests', () => { } )).to.be.revertedWith('ValidatorAlreadyExists'); }); - - it('Get pod burn rate', async () => { - expect(await ssvNetworkContract.getPodBurnRate([1,2,3,4])).to.equal(helpers.CONFIG.minimalOperatorFee * 4); - }); - - it('Get pod burn rate by not existed operator in the list', async () => { - expect(await ssvNetworkContract.getPodBurnRate([1,2,3,41])).to.equal(helpers.CONFIG.minimalOperatorFee * 3); - }); }); From 5752a44492f527a2133ff29ca7023ec9457989e0 Mon Sep 17 00:00:00 2001 From: Wadym Date: Thu, 29 Dec 2022 11:20:23 +0100 Subject: [PATCH 107/149] Missed get functions (#155) * wip * test coverage * Andrew combine emits (#156) * Get DAO functions + pod burn rate (#153) * wip * test coverage Co-authored-by: Vadim * combine emits Co-authored-by: Wadym Co-authored-by: Vadim Co-authored-by: Vadim Co-authored-by: andrew-blox <102898824+andrew-blox@users.noreply.github.com> --- contracts/ISSVNetwork.sol | 37 +++++++++---- contracts/SSVNetwork.sol | 90 ++++++++++++++++++++----------- test/dao/liquidation-threshold.ts | 32 +++++++++++ test/dao/network-fee-withdraw.ts | 27 +++++----- test/helpers/contract-helpers.ts | 7 +-- test/helpers/gas-usage.ts | 24 ++++----- test/liquidate/liquidate.ts | 10 ++-- test/liquidate/reactivate.ts | 12 ++--- test/operators/register.ts | 22 +++++++- test/sanity/balances.ts | 18 +++---- test/validators/register.ts | 26 +++++---- test/validators/remove.ts | 8 +-- 12 files changed, 207 insertions(+), 106 deletions(-) create mode 100644 test/dao/liquidation-threshold.ts diff --git a/contracts/ISSVNetwork.sol b/contracts/ISSVNetwork.sol index 25cc041c..37ca758b 100644 --- a/contracts/ISSVNetwork.sol +++ b/contracts/ISSVNetwork.sol @@ -47,23 +47,27 @@ interface ISSVNetwork { * @param publicKey The public key of a validator. * @param operatorIds The operator ids list. * @param shares snappy compressed shares(a set of encrypted and public shares). + * @param pod All the pod data. */ event ValidatorAdded( address ownerAddress, uint64[] operatorIds, bytes publicKey, - bytes shares + bytes shares, + Pod pod ); /** * @dev Emitted when the validator is removed. * @param publicKey The public key of a validator. * @param operatorIds The operator ids list. + * @param pod All the pod data. */ event ValidatorRemoved( address ownerAddress, uint64[] operatorIds, - bytes publicKey + bytes publicKey, + Pod pod ); event OperatorFeeDeclaration( @@ -95,15 +99,17 @@ interface ISSVNetwork { uint256 fee ); - event PodLiquidated(address ownerAddress, uint64[] operatorIds); + event PodLiquidated(address ownerAddress, uint64[] operatorIds, Pod pod); - event PodEnabled(address ownerAddress, uint64[] operatorIds); + event PodEnabled(address ownerAddress, uint64[] operatorIds, Pod pod); event OperatorFeeIncreaseLimitUpdate(uint64 value); - event DeclareOperatorFeePeriodUpdate(uint256 value); + event DeclareOperatorFeePeriodUpdate(uint64 value); - event ExecuteOperatorFeePeriodUpdate(uint256 value); + event ExecuteOperatorFeePeriodUpdate(uint64 value); + + event LiquidationThresholdPeriodUpdate(uint64 value); /** * @dev Emitted when the network fee is updated. @@ -117,7 +123,7 @@ interface ISSVNetwork { * @param value The amount of tokens withdrawn. * @param recipient The recipient address. */ - event NetworkFeesWithdrawal(uint256 value, address recipient); + event NetworkEarningsWithdrawal(uint256 value, address recipient); event PodFundsWithdrawal(address ownerAddress, uint64[] operatorIds, uint256 value); event OperatorFundsWithdrawal(uint256 value, uint64 operatorId, address ownerAddress); @@ -163,6 +169,7 @@ interface ISSVNetwork { error BurnRatePositive(); error PodDataIsBroken(); error OperatorsListDoesNotSorted(); + error BelowMinimumBlockPeriod(); /****************/ /* Initializers */ @@ -179,7 +186,8 @@ interface ISSVNetwork { IERC20 token_, uint64 operatorMaxFeeIncrease_, uint64 declareOperatorFeePeriod_, - uint64 executeOperatorFeePeriod_ + uint64 executeOperatorFeePeriod_, + uint64 minimumBlocksBeforeLiquidation_ ) external; /*******************************/ @@ -208,6 +216,8 @@ interface ISSVNetwork { function cancelDeclaredOperatorFee(uint64 operatorId) external; + function feeRecipientAddress(address feeRecipientAddress) external; + /********************************/ /* Validator External Functions */ /********************************/ @@ -275,7 +285,7 @@ interface ISSVNetwork { function updateNetworkFee(uint256 fee) external; - function withdrawDAOEarnings(uint256 amount) external; + function withdrawNetworkEarnings(uint256 amount) external; function updateOperatorFeeIncreaseLimit(uint64 newOperatorMaxFeeIncrease) external; @@ -283,6 +293,7 @@ interface ISSVNetwork { function updateExecuteOperatorFeePeriod(uint64 newExecuteOperatorFeePeriod) external; + function updateLiquidationThresholdPeriod(uint64 blocks) external; /************************************/ /* Operator External View Functions */ @@ -292,7 +303,7 @@ interface ISSVNetwork { function getOperatorDeclaredFee(uint64 operatorId) external view returns (uint256, uint256, uint256); - function feeRecipientAddress(address feeRecipientAddress) external; + function getOperatorById(uint64 operatorId) external view returns (address owner, uint256 fee, uint32 validatorCount); /*******************************/ /* Pod External View Functions */ @@ -310,6 +321,8 @@ interface ISSVNetwork { Pod memory pod ) external view returns(bool); + function getPodBurnRate(uint64[] memory operatorIds) external view returns (uint256); + /***********************************/ /* Balance External View Functions */ /***********************************/ @@ -335,11 +348,13 @@ interface ISSVNetwork { function getNetworkFee() external view returns (uint256); - function getNetworkBalance() external view returns (uint256); + function getNetworkEarnings() external view returns (uint256); function getOperatorFeeIncreaseLimit() external view returns (uint64); function getExecuteOperatorFeePeriod() external view returns (uint64); function getDeclaredOperatorFeePeriod() external view returns (uint64); + + function getLiquidationThresholdPeriod() external view returns (uint64); } \ No newline at end of file diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index 70b49fec..06a32567 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -70,7 +70,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { /* Constants */ /*************/ - uint64 constant LIQUIDATION_MIN_BLOCKS = 50; + uint64 constant MINIMAL_LIQUIDATION_THRESHOLD = 6570; uint64 constant MINIMAL_OPERATOR_FEE = 100000000; /********************/ @@ -96,7 +96,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { uint64 private _declareOperatorFeePeriod; uint64 private _executeOperatorFeePeriod; uint64 private _operatorMaxFeeIncrease; - + uint64 private _minimumBlocksBeforeLiquidation; DAO private _dao; IERC20 private _token; @@ -109,31 +109,35 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { IERC20 token_, uint64 operatorMaxFeeIncrease_, uint64 declareOperatorFeePeriod_, - uint64 executeOperatorFeePeriod_ + uint64 executeOperatorFeePeriod_, + uint64 minimumBlocksBeforeLiquidation_ ) external override { - __SSVNetwork_init(token_, operatorMaxFeeIncrease_, declareOperatorFeePeriod_, executeOperatorFeePeriod_); + __SSVNetwork_init(token_, operatorMaxFeeIncrease_, declareOperatorFeePeriod_, executeOperatorFeePeriod_, minimumBlocksBeforeLiquidation_); } function __SSVNetwork_init( IERC20 token_, uint64 operatorMaxFeeIncrease_, uint64 declareOperatorFeePeriod_, - uint64 executeOperatorFeePeriod_ + uint64 executeOperatorFeePeriod_, + uint64 minimumBlocksBeforeLiquidation_ ) internal initializer { __Ownable_init_unchained(); - __SSVNetwork_init_unchained(token_, operatorMaxFeeIncrease_, declareOperatorFeePeriod_, executeOperatorFeePeriod_); + __SSVNetwork_init_unchained(token_, operatorMaxFeeIncrease_, declareOperatorFeePeriod_, executeOperatorFeePeriod_, minimumBlocksBeforeLiquidation_); } function __SSVNetwork_init_unchained( IERC20 token_, uint64 operatorMaxFeeIncrease_, uint64 declareOperatorFeePeriod_, - uint64 executeOperatorFeePeriod_ + uint64 executeOperatorFeePeriod_, + uint64 minimumBlocksBeforeLiquidation_ ) internal onlyInitializing { _token = token_; _operatorMaxFeeIncrease = operatorMaxFeeIncrease_; _declareOperatorFeePeriod = declareOperatorFeePeriod_; _executeOperatorFeePeriod = executeOperatorFeePeriod_; + _minimumBlocksBeforeLiquidation = minimumBlocksBeforeLiquidation_; } /*************/ @@ -226,6 +230,10 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { emit DeclaredOperatorFeeCancelation(msg.sender, operatorId); } + function feeRecipientAddress(address recipientAddress) external override { + emit FeeRecipientAddressAdded(msg.sender, recipientAddress); + } + /********************************/ /* Validator External Functions */ /********************************/ @@ -300,8 +308,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _pods[hashedPod] = keccak256(abi.encodePacked(pod.validatorCount, pod.networkFee, pod.networkFeeIndex, pod.index, pod.balance, pod.disabled )); - emit ValidatorAdded(msg.sender, operatorIds, publicKey, shares); - emit PodMetadataUpdated(msg.sender, operatorIds, pod); + emit ValidatorAdded(msg.sender, operatorIds, publicKey, shares, pod); } function removeValidator( @@ -351,8 +358,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _pods[hashedPod] = keccak256(abi.encodePacked(pod.validatorCount, pod.networkFee, pod.networkFeeIndex, pod.index, pod.balance, pod.disabled )); - emit ValidatorRemoved(msg.sender, operatorIds, publicKey); - emit PodMetadataUpdated(msg.sender, operatorIds, pod); + emit ValidatorRemoved(msg.sender, operatorIds, publicKey, pod); } function liquidatePod( @@ -402,8 +408,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _pods[hashedPod] = keccak256(abi.encodePacked(pod.validatorCount, pod.networkFee, pod.networkFeeIndex, pod.index, pod.balance, pod.disabled )); - emit PodLiquidated(owner, operatorIds); - emit PodMetadataUpdated(owner, operatorIds, pod); + emit PodLiquidated(owner, operatorIds, pod); } function reactivatePod( @@ -457,8 +462,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _pods[hashedPod] = keccak256(abi.encodePacked(pod.validatorCount, pod.networkFee, pod.networkFeeIndex, pod.index, pod.balance, pod.disabled )); - emit PodEnabled(msg.sender, operatorIds); - emit PodMetadataUpdated(msg.sender, operatorIds, pod); + emit PodEnabled(msg.sender, operatorIds, pod); } /******************************/ @@ -599,7 +603,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _networkFee = fee.shrink(); } - function withdrawDAOEarnings(uint256 amount) external onlyOwner override { + function withdrawNetworkEarnings(uint256 amount) external onlyOwner override { DAO memory dao = _dao; uint64 shrunkAmount = amount.shrink(); @@ -613,7 +617,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _token.transfer(msg.sender, amount); - emit NetworkFeesWithdrawal(amount, msg.sender); + emit NetworkEarningsWithdrawal(amount, msg.sender); } function updateOperatorFeeIncreaseLimit(uint64 newOperatorMaxFeeIncrease) external onlyOwner override { @@ -631,16 +635,23 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { emit ExecuteOperatorFeePeriodUpdate(newExecuteOperatorFeePeriod); } + function updateLiquidationThresholdPeriod(uint64 blocks) external onlyOwner override { + if(blocks < MINIMAL_LIQUIDATION_THRESHOLD) { + revert BelowMinimumBlockPeriod(); + } + + _minimumBlocksBeforeLiquidation = blocks; + emit LiquidationThresholdPeriodUpdate(blocks); + } + /************************************/ /* Operator External View Functions */ /************************************/ function getOperatorFee(uint64 operatorId) external view override returns (uint256) { - Operator memory operator = _operators[operatorId]; - - if (operator.snapshot.block == 0) revert OperatorNotFound(); + if (_operators[operatorId].snapshot.block == 0) revert OperatorNotFound(); - return operator.fee.expand(); + return _operators[operatorId].fee.expand(); } function getOperatorDeclaredFee(uint64 operatorId) external view override returns (uint256, uint256, uint256) { @@ -653,8 +664,10 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { return (feeChangeRequest.fee.expand(), feeChangeRequest.approvalBeginTime, feeChangeRequest.approvalEndTime); } - function feeRecipientAddress(address recipientAddress) external override { - emit FeeRecipientAddressAdded(msg.sender, recipientAddress); + function getOperatorById(uint64 operatorId) external view override returns (address owner, uint256 fee, uint32 validatorCount) { + if (_operators[operatorId].owner == address(0)) revert OperatorNotFound(); + + return (_operators[operatorId].owner, _operators[operatorId].fee.expand(), _operators[operatorId].validatorCount); } /*******************************/ @@ -668,12 +681,10 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { ) external view override returns (bool) { uint64 podIndex; uint64 burnRate; - { - for (uint8 i = 0; i < operatorIds.length; ++i) { - Operator memory operator = _operators[operatorIds[i]]; - podIndex += operator.snapshot.index + (uint64(block.number) - operator.snapshot.block) * operator.fee; - burnRate += operator.fee; - } + for (uint8 i = 0; i < operatorIds.length; ++i) { + Operator memory operator = _operators[operatorIds[i]]; + podIndex += operator.snapshot.index + (uint64(block.number) - operator.snapshot.block) * operator.fee; + burnRate += operator.fee; } _validateHashedPod(owner, operatorIds, pod); @@ -683,7 +694,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { function isLiquidated( address owner, - uint64[] memory operatorIds, + uint64[] calldata operatorIds, Pod memory pod ) external view override returns (bool) { _validateHashedPod(owner, operatorIds, pod); @@ -691,6 +702,17 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { return pod.disabled; } + function getPodBurnRate(uint64[] memory operatorIds) external view override returns (uint256) { + uint64 burnRate; + for (uint8 i = 0; i < operatorIds.length; ++i) { + Operator memory operator = _operators[operatorIds[i]]; + if (operator.owner != address(0)) { + burnRate += operator.fee; + } + } + return burnRate.expand(); + } + /***********************************/ /* Balance External View Functions */ /***********************************/ @@ -728,7 +750,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { return _networkFee.expand(); } - function getNetworkBalance() external view onlyOwner override returns (uint256) { + function getNetworkEarnings() external view override returns (uint256) { DAO memory dao = _dao; return _networkBalance(dao).expand(); } @@ -745,6 +767,10 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { return _declareOperatorFeePeriod; } + function getLiquidationThresholdPeriod() external view override returns (uint64) { + return _minimumBlocksBeforeLiquidation; + } + /********************************/ /* Validation Private Functions */ /********************************/ @@ -850,7 +876,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } function _liquidatable(uint64 balance, uint64 validatorCount, uint64 burnRate) private view returns (bool) { - return balance < LIQUIDATION_MIN_BLOCKS * (burnRate + _networkFee) * validatorCount; + return balance < _minimumBlocksBeforeLiquidation * (burnRate + _networkFee) * validatorCount; } /*****************************/ diff --git a/test/dao/liquidation-threshold.ts b/test/dao/liquidation-threshold.ts new file mode 100644 index 00000000..7047d61b --- /dev/null +++ b/test/dao/liquidation-threshold.ts @@ -0,0 +1,32 @@ +// Declare imports +import * as helpers from '../helpers/contract-helpers'; +import { expect } from 'chai'; + +// Declare globals +let ssvNetworkContract: any, networkFee: any; + +describe('Liquidation Threshold Tests', () => { + beforeEach(async () => { + // Initialize contract + ssvNetworkContract = (await helpers.initializeContract()).contract; + + // Define minumum allowed network fee to pass shrinkable validation + networkFee = helpers.CONFIG.minimalOperatorFee / 10; + }); + + it('Change liquidation threshold period emits "LiquidationThresholdPeriodUpdate"', async () => { + await expect(ssvNetworkContract.updateLiquidationThresholdPeriod(helpers.CONFIG.minimalBlocksBeforeLiquidation + 10)).to.emit(ssvNetworkContract, 'LiquidationThresholdPeriodUpdate').withArgs(helpers.CONFIG.minimalBlocksBeforeLiquidation + 10); + }); + + it('Get liquidation threshold period', async () => { + expect(await ssvNetworkContract.getLiquidationThresholdPeriod()).to.equal(helpers.CONFIG.minimalBlocksBeforeLiquidation); + }); + + it('Change liquidation threshold period reverts "BelowMinimumBlockPeriod"', async () => { + await expect(ssvNetworkContract.updateLiquidationThresholdPeriod(helpers.CONFIG.minimalBlocksBeforeLiquidation - 10)).to.be.revertedWith('BelowMinimumBlockPeriod'); + }); + + it('Change liquidation threshold period reverts "caller is not the owner"', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[3]).updateLiquidationThresholdPeriod(helpers.CONFIG.minimalBlocksBeforeLiquidation)).to.be.revertedWith('caller is not the owner'); + }); +}); diff --git a/test/dao/network-fee-withdraw.ts b/test/dao/network-fee-withdraw.ts index bc7a092c..91ac7e75 100644 --- a/test/dao/network-fee-withdraw.ts +++ b/test/dao/network-fee-withdraw.ts @@ -52,31 +52,30 @@ describe('DAO Network Fee Withdraw Tests', () => { // Mint tokens await helpers.DB.ssvToken.mint(ssvNetworkContract.address, minDepositAmount); }); - - it('Withdraw network earnings emits "NetworkFeesWithdrawal"', async () => { - const amount = await ssvNetworkContract.getNetworkBalance(); - await expect(ssvNetworkContract.withdrawDAOEarnings(amount - )).to.emit(ssvNetworkContract, 'NetworkFeesWithdrawal').withArgs(amount, helpers.DB.owners[0].address); + + it('Withdraw network earnings emits "NetworkEarningsWithdrawal"', async () => { + const amount = await ssvNetworkContract.getNetworkEarnings(); + await expect(ssvNetworkContract.withdrawNetworkEarnings(amount + )).to.emit(ssvNetworkContract, 'NetworkEarningsWithdrawal').withArgs(amount, helpers.DB.owners[0].address); }); it('Get withdrawable network earnings', async () => { - expect(await ssvNetworkContract.getNetworkBalance()).to.above(0); + expect(await ssvNetworkContract.getNetworkEarnings()).to.above(0); }); - it('Get withdrawable network earnings reverts "caller is not the owner"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[3]).getNetworkBalance( - )).to.be.revertedWith('caller is not the owner'); + it('Get withdrawable network earnings as not owner', async () => { + await ssvNetworkContract.connect(helpers.DB.owners[3]).getNetworkEarnings(); }); it('Withdraw network earnings with not enough balance reverts "NotEnoughBalance"', async () => { - const amount = await ssvNetworkContract.getNetworkBalance() * 2; - await expect(ssvNetworkContract.withdrawDAOEarnings(amount + const amount = await ssvNetworkContract.getNetworkEarnings() * 2; + await expect(ssvNetworkContract.withdrawNetworkEarnings(amount )).to.be.revertedWith('NotEnoughBalance'); }); it('Withdraw network earnings from an address thats not the DAO reverts "caller is not the owner"', async () => { - const amount = await ssvNetworkContract.getNetworkBalance(); - await expect(ssvNetworkContract.connect(helpers.DB.owners[3]).withdrawDAOEarnings(amount + const amount = await ssvNetworkContract.getNetworkEarnings(); + await expect(ssvNetworkContract.connect(helpers.DB.owners[3]).withdrawNetworkEarnings(amount )).to.be.revertedWith('caller is not the owner'); }); -}); \ No newline at end of file +}); diff --git a/test/helpers/contract-helpers.ts b/test/helpers/contract-helpers.ts index 3d818fd0..56ab6894 100644 --- a/test/helpers/contract-helpers.ts +++ b/test/helpers/contract-helpers.ts @@ -45,7 +45,7 @@ export const initializeContract = async () => { declareOperatorFeePeriod: 3600, // HOUR executeOperatorFeePeriod: 86400, // DAY minimalOperatorFee: 100000000, - minimalBlocksBeforeLiquidation: 50, + minimalBlocksBeforeLiquidation: 6570, }; DB = { @@ -71,7 +71,8 @@ export const initializeContract = async () => { DB.ssvToken.address, CONFIG.operatorMaxFeeIncrease, CONFIG.declareOperatorFeePeriod, - CONFIG.executeOperatorFeePeriod + CONFIG.executeOperatorFeePeriod, + CONFIG.minimalBlocksBeforeLiquidation ]); await DB.ssvNetwork.contract.deployed(); @@ -129,7 +130,7 @@ export const registerValidators = async (ownerId: number, numberOfValidators: nu disabled: false } ), gasGroups); - args = result.eventsByName.PodMetadataUpdated[0].args; + args = result.eventsByName.ValidatorAdded[0].args; DB.validators.push({ publicKey, operatorIds, shares }); validators.push({ publicKey, shares }); diff --git a/test/helpers/gas-usage.ts b/test/helpers/gas-usage.ts index 2c92d852..61777cbe 100644 --- a/test/helpers/gas-usage.ts +++ b/test/helpers/gas-usage.ts @@ -36,17 +36,17 @@ const MAX_GAS_PER_GROUP: any = { [GasGroup.REMOVE_OPERATOR]: 62000, [GasGroup.REMOVE_OPERATOR_WITH_WITHDRAW]: 62000, - [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]: 174000, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE]: 191100, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT]: 151100, + [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]: 176500, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE]: 194500, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT]: 153500, - [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_7]: 217100, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]: 234100, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_7]: 194100, + [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_7]: 219500, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]: 236500, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_7]: 196500, - [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_13]: 303200, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]: 320200, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_13]: 280200, + [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_13]: 306200, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]: 323200, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_13]: 283200, [GasGroup.REMOVE_VALIDATOR]: 120000, [GasGroup.TRANSFER_VALIDATOR_NEW_CLUSTER]: 400000, @@ -55,11 +55,11 @@ const MAX_GAS_PER_GROUP: any = { [GasGroup.BULK_TRANSFER_VALIDATOR]: 366000, [GasGroup.BULK_TRANSFER_VALIDATOR_NON_EXISTING_POD]: 383000, [GasGroup.DEPOSIT]: 77500, - [GasGroup.WITHDRAW_POD_BALANCE]: 93100, + [GasGroup.WITHDRAW_POD_BALANCE]: 95500, [GasGroup.WITHDRAW_OPERATOR_BALANCE]: 59000, [GasGroup.REGISTER_POD]: 137000, - [GasGroup.LIQUIDATE_POD]: 135000, - [GasGroup.REACTIVATE_POD]: 135000, + [GasGroup.LIQUIDATE_POD]: 137000, + [GasGroup.REACTIVATE_POD]: 137000, }; class GasStats { diff --git a/test/liquidate/liquidate.ts b/test/liquidate/liquidate.ts index 6ebcf03b..e5be36f1 100644 --- a/test/liquidate/liquidate.ts +++ b/test/liquidate/liquidate.ts @@ -49,7 +49,7 @@ describe('Liquidate Tests', () => { disabled: false } ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); - firstPod = register.eventsByName.PodMetadataUpdated[0].args; + firstPod = register.eventsByName.ValidatorAdded[0].args; }); it('Get if the pod is liquidatable', async () => { @@ -90,7 +90,7 @@ describe('Liquidate Tests', () => { firstPod.operatorIds, firstPod.pod ), [GasGroup.LIQUIDATE_POD]); - const updatedPod = liquidatedPod.eventsByName.PodMetadataUpdated[0].args; + const updatedPod = liquidatedPod.eventsByName.PodLiquidated[0].args; await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, `${minDepositAmount*2}`); await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( @@ -132,7 +132,7 @@ describe('Liquidate Tests', () => { firstPod.operatorIds, firstPod.pod ), [GasGroup.LIQUIDATE_POD]); - const updatedPod = liquidatedPod.eventsByName.PodMetadataUpdated[0].args; + const updatedPod = liquidatedPod.eventsByName.PodLiquidated[0].args; await expect(ssvNetworkContract.liquidatePod( firstPod.ownerAddress, @@ -148,7 +148,7 @@ describe('Liquidate Tests', () => { firstPod.operatorIds, firstPod.pod ), [GasGroup.LIQUIDATE_POD]); - const updatedPod = liquidatedPod.eventsByName.PodMetadataUpdated[0].args; + const updatedPod = liquidatedPod.eventsByName.PodLiquidated[0].args; expect(await ssvNetworkContract.isLiquidated(firstPod.ownerAddress, firstPod.operatorIds, updatedPod.pod)).to.equal(true); }); @@ -160,7 +160,7 @@ describe('Liquidate Tests', () => { firstPod.operatorIds, firstPod.pod ), [GasGroup.LIQUIDATE_POD]); - const updatedPod = liquidatedPod.eventsByName.PodMetadataUpdated[0].args; + const updatedPod = liquidatedPod.eventsByName.PodLiquidated[0].args; await expect(ssvNetworkContract.isLiquidated(helpers.DB.owners[0].address, firstPod.operatorIds, updatedPod.pod)).to.be.revertedWith('PodNotExists'); }); diff --git a/test/liquidate/reactivate.ts b/test/liquidate/reactivate.ts index a8ffe9f1..c9d79f8b 100644 --- a/test/liquidate/reactivate.ts +++ b/test/liquidate/reactivate.ts @@ -50,13 +50,13 @@ describe('Reactivate Tests', () => { disabled: false } ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); - firstPod = register.eventsByName.PodMetadataUpdated[0].args; + firstPod = register.eventsByName.ValidatorAdded[0].args; }); it('Reactivate a disabled pod emits "PodEnabled"', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); const liquidatedPod = await trackGas(ssvNetworkContract.liquidatePod(firstPod.ownerAddress, firstPod.operatorIds, firstPod.pod), [GasGroup.LIQUIDATE_POD]); - const updatedPod = liquidatedPod.eventsByName.PodMetadataUpdated[0].args; + const updatedPod = liquidatedPod.eventsByName.PodLiquidated[0].args; await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).reactivatePod(updatedPod.operatorIds, minDepositAmount, updatedPod.pod)).to.emit(ssvNetworkContract, 'PodEnabled'); @@ -65,14 +65,14 @@ describe('Reactivate Tests', () => { it('Reactivate with 0 deposit and no validators emits PodEnabled', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); const liquidatedPod = await trackGas(ssvNetworkContract.liquidatePod(firstPod.ownerAddress, firstPod.operatorIds, firstPod.pod), [GasGroup.LIQUIDATE_POD]); - const updatedPod = liquidatedPod.eventsByName.PodMetadataUpdated[0].args; + const updatedPod = liquidatedPod.eventsByName.PodLiquidated[0].args; const remove = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).removeValidator( helpers.DataGenerator.publicKey(1), firstPod.operatorIds, updatedPod.pod ), [GasGroup.REMOVE_VALIDATOR]); - const updatedPodAfrerRemove = remove.eventsByName.PodMetadataUpdated[0].args; + const updatedPodAfrerRemove = remove.eventsByName.ValidatorRemoved[0].args; await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).reactivatePod(updatedPodAfrerRemove.operatorIds, 0, updatedPodAfrerRemove.pod)).to.emit(ssvNetworkContract, 'PodEnabled'); }); @@ -84,7 +84,7 @@ describe('Reactivate Tests', () => { it('Reactivate a pod when the amount is not enough reverts "NegativeBalance"', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); const liquidatedPod = await trackGas(ssvNetworkContract.liquidatePod(firstPod.ownerAddress, firstPod.operatorIds, firstPod.pod), [GasGroup.LIQUIDATE_POD]); - const updatedPod = liquidatedPod.eventsByName.PodMetadataUpdated[0].args; + const updatedPod = liquidatedPod.eventsByName.PodLiquidated[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]).reactivatePod(updatedPod.operatorIds, helpers.CONFIG.minimalOperatorFee, updatedPod.pod)).to.be.revertedWith('NotEnoughBalance'); @@ -93,7 +93,7 @@ describe('Reactivate Tests', () => { it('Reactivate a pod with a removed operator in the cluster', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); const liquidatedPod = await trackGas(ssvNetworkContract.liquidatePod(firstPod.ownerAddress, firstPod.operatorIds, firstPod.pod), [GasGroup.LIQUIDATE_POD]); - const updatedPod = liquidatedPod.eventsByName.PodMetadataUpdated[0].args; + const updatedPod = liquidatedPod.eventsByName.PodLiquidated[0].args; await ssvNetworkContract.removeOperator(1); await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); diff --git a/test/operators/register.ts b/test/operators/register.ts index 339bcaaa..7f3423a0 100644 --- a/test/operators/register.ts +++ b/test/operators/register.ts @@ -32,4 +32,24 @@ describe('Register Operator Tests', () => { '10' )).to.be.revertedWith('FeeTooLow'); }); -}); \ No newline at end of file + + it('Get operator by id', async () => { + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerOperator( + helpers.DataGenerator.publicKey(0), + helpers.CONFIG.minimalOperatorFee, + ), [GasGroup.REGISTER_OPERATOR]); + + expect((await ssvNetworkContract.getOperatorById(1)).owner).to.equal(helpers.DB.owners[1].address); + expect((await ssvNetworkContract.getOperatorById(1)).fee).to.equal(helpers.CONFIG.minimalOperatorFee); + expect((await ssvNetworkContract.getOperatorById(1)).validatorCount).to.equal(0); + }); + + it('Get operator by id reverts "OperatorNotFound"', async () => { + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerOperator( + helpers.DataGenerator.publicKey(0), + helpers.CONFIG.minimalOperatorFee, + ), [GasGroup.REGISTER_OPERATOR]); + + await expect(ssvNetworkContract.getOperatorById(3)).to.be.revertedWith('OperatorNotFound'); + }); +}); diff --git a/test/sanity/balances.ts b/test/sanity/balances.ts index 00fbd452..4d7396ac 100644 --- a/test/sanity/balances.ts +++ b/test/sanity/balances.ts @@ -43,7 +43,7 @@ describe('Balance Tests', () => { ); pod1 = await helpers.registerValidators(4, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); - initNetworkFeeBalance = await ssvNetworkContract.getNetworkBalance(); + initNetworkFeeBalance = await ssvNetworkContract.getNetworkEarnings(); }); it('Check pod balance in three blocks, one after the other', async () => { @@ -70,24 +70,24 @@ describe('Balance Tests', () => { it('Check DAO earnings in three blocks, one after the other', async () => { await utils.progressBlocks(1); - expect(await ssvNetworkContract.getNetworkBalance() - initNetworkFeeBalance).to.equal(networkFee * 2); + expect(await ssvNetworkContract.getNetworkEarnings() - initNetworkFeeBalance).to.equal(networkFee * 2); await utils.progressBlocks(1); - expect(await ssvNetworkContract.getNetworkBalance() - initNetworkFeeBalance).to.equal(networkFee * 4); + expect(await ssvNetworkContract.getNetworkEarnings() - initNetworkFeeBalance).to.equal(networkFee * 4); await utils.progressBlocks(1); - expect(await ssvNetworkContract.getNetworkBalance() - initNetworkFeeBalance).to.equal(networkFee * 6); + expect(await ssvNetworkContract.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 ssvNetworkContract.getNetworkBalance() - initNetworkFeeBalance).to.equal(networkFee * 2); + expect(await ssvNetworkContract.getNetworkEarnings() - initNetworkFeeBalance).to.equal(networkFee * 2); const newNetworkFee = networkFee * 2; await ssvNetworkContract.updateNetworkFee(newNetworkFee); await utils.progressBlocks(1); - expect(await ssvNetworkContract.getNetworkBalance() - initNetworkFeeBalance).to.equal(networkFee * 4 + newNetworkFee * 2); + expect(await ssvNetworkContract.getNetworkEarnings() - initNetworkFeeBalance).to.equal(networkFee * 4 + newNetworkFee * 2); await utils.progressBlocks(1); - expect(await ssvNetworkContract.getNetworkBalance() - initNetworkFeeBalance).to.equal(networkFee * 4 + newNetworkFee * 4); + expect(await ssvNetworkContract.getNetworkEarnings() - initNetworkFeeBalance).to.equal(networkFee * 4 + newNetworkFee * 4); await utils.progressBlocks(10); - expect(await ssvNetworkContract.getNetworkBalance() - initNetworkFeeBalance).to.equal(networkFee * 4 + newNetworkFee * 24); + expect(await ssvNetworkContract.getNetworkEarnings() - initNetworkFeeBalance).to.equal(networkFee * 4 + newNetworkFee * 24); }); it('Check operators earnings in three blocks, one after the other', async () => { @@ -109,7 +109,7 @@ describe('Balance Tests', () => { }); it('Check pod balance returns error - NegativeBalance', async () => { - await utils.progressBlocks(1000); + await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation + 10); await expect(ssvNetworkContract.podBalanceOf(helpers.DB.owners[4].address, pod1.args.operatorIds, pod1.args.pod)).to.be.revertedWith('NegativeBalance'); }); diff --git a/test/validators/register.ts b/test/validators/register.ts index 55355139..7db82ab9 100644 --- a/test/validators/register.ts +++ b/test/validators/register.ts @@ -69,7 +69,7 @@ describe('Register Validator Tests', () => { } ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); - const args = eventsByName.PodMetadataUpdated[0].args; + 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( @@ -98,7 +98,7 @@ describe('Register Validator Tests', () => { } ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); - const args = eventsByName.PodMetadataUpdated[0].args; + 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( @@ -143,7 +143,7 @@ describe('Register Validator Tests', () => { } ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); - const args = eventsByName.PodMetadataUpdated[0].args; + const args = eventsByName.ValidatorAdded[0].args; await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( helpers.DataGenerator.publicKey(2), [1,2,3,4], @@ -190,7 +190,7 @@ describe('Register Validator Tests', () => { } ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]); - const args = eventsByName.PodMetadataUpdated[0].args; + 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( @@ -219,7 +219,7 @@ describe('Register Validator Tests', () => { } ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]); - const args = eventsByName.PodMetadataUpdated[0].args; + 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( @@ -264,7 +264,7 @@ describe('Register Validator Tests', () => { } ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]); - const args = eventsByName.PodMetadataUpdated[0].args; + 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], @@ -311,7 +311,7 @@ describe('Register Validator Tests', () => { } ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]); - const args = eventsByName.PodMetadataUpdated[0].args; + 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( @@ -340,7 +340,7 @@ describe('Register Validator Tests', () => { } ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]); - const args = eventsByName.PodMetadataUpdated[0].args; + 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( @@ -385,7 +385,7 @@ describe('Register Validator Tests', () => { } ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]); - const args = eventsByName.PodMetadataUpdated[0].args; + 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], @@ -548,4 +548,12 @@ describe('Register Validator Tests', () => { } )).to.be.revertedWith('ValidatorAlreadyExists'); }); + + it('Get pod burn rate', async () => { + expect(await ssvNetworkContract.getPodBurnRate([1,2,3,4])).to.equal(helpers.CONFIG.minimalOperatorFee * 4); + }); + + it('Get pod burn rate by not existed operator in the list', async () => { + expect(await ssvNetworkContract.getPodBurnRate([1,2,3,41])).to.equal(helpers.CONFIG.minimalOperatorFee * 3); + }); }); diff --git a/test/validators/remove.ts b/test/validators/remove.ts index 9dbd6e12..1dde9828 100644 --- a/test/validators/remove.ts +++ b/test/validators/remove.ts @@ -51,7 +51,7 @@ describe('Remove Validator Tests', () => { disabled: false } ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); - firstPod = register.eventsByName.PodMetadataUpdated[0].args; + firstPod = register.eventsByName.ValidatorAdded[0].args; }); it('Remove validator emits ValidatorRemoved event', async () => { @@ -110,7 +110,7 @@ describe('Remove Validator Tests', () => { firstPod.operatorIds, firstPod.pod ), [GasGroup.REMOVE_VALIDATOR]); - const updatedPod = remove.eventsByName.PodMetadataUpdated[0].args; + const updatedPod = remove.eventsByName.ValidatorRemoved[0].args; // Re-register validator const newRegister = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( @@ -120,7 +120,7 @@ describe('Remove Validator Tests', () => { 0, updatedPod.pod ), [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]); - const afterRegisterPod = newRegister.eventsByName.PodMetadataUpdated[0].args; + const afterRegisterPod = newRegister.eventsByName.ValidatorAdded[0].args; // Remove the validator again await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).removeValidator( @@ -137,7 +137,7 @@ describe('Remove Validator Tests', () => { firstPod.operatorIds, firstPod.pod ), [GasGroup.LIQUIDATE_POD]); - const updatedPod = liquidatedPod.eventsByName.PodMetadataUpdated[0].args; + const updatedPod = liquidatedPod.eventsByName.PodLiquidated[0].args; await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).removeValidator( helpers.DataGenerator.publicKey(1), From 43935032f3d6244d83f89664873c428f62dd00aa Mon Sep 17 00:00:00 2001 From: andrew-blox <102898824+andrew-blox@users.noreply.github.com> Date: Mon, 2 Jan 2023 15:01:54 +0200 Subject: [PATCH 108/149] Remove podMetadataUpdated IO1 2182 * Remove podMetadataUpdated event * Add updated stress test location --- contracts/ISSVNetwork.sol | 6 +- contracts/SSVNetwork.sol | 21 +++-- stress-test/stress.ts | 149 +++++++++++++++++++++++++++++++ test/helpers/contract-helpers.ts | 12 +-- test/sanity/stress.ts | 55 ------------ 5 files changed, 168 insertions(+), 75 deletions(-) create mode 100644 stress-test/stress.ts delete mode 100644 test/sanity/stress.ts diff --git a/contracts/ISSVNetwork.sol b/contracts/ISSVNetwork.sol index 37ca758b..af5b27a3 100644 --- a/contracts/ISSVNetwork.sol +++ b/contracts/ISSVNetwork.sol @@ -125,13 +125,13 @@ interface ISSVNetwork { */ event NetworkEarningsWithdrawal(uint256 value, address recipient); - event PodFundsWithdrawal(address ownerAddress, uint64[] operatorIds, uint256 value); + event PodFundsWithdrawal(address ownerAddress, uint64[] operatorIds, uint256 value, Pod pod); event OperatorFundsWithdrawal(uint256 value, uint64 operatorId, address ownerAddress); - event FundsDeposit(uint256 value, bytes32 hashedPod, address owner); + event FundsDeposit(uint256 value, uint64[] operatorIds, address owner); - event PodMetadataUpdated( + event PodDeposited( address ownerAddress, uint64[] operatorIds, Pod pod diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index 06a32567..ca76c36e 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -287,7 +287,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } if (amount > 0) { - _deposit(msg.sender, hashedPod, amount.shrink()); + _deposit(msg.sender, operatorIds, amount.shrink()); pod.balance += amount.shrink(); } @@ -440,7 +440,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { bytes32 hashedPod = _validateHashedPod(msg.sender, operatorIds, pod); if (amount > 0) { - _deposit(msg.sender, hashedPod, amount.shrink()); + _deposit(msg.sender, operatorIds, amount.shrink()); pod.balance += amount.shrink(); } @@ -483,11 +483,11 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { pod.balance += shrunkAmount; - _deposit(owner, hashedPod, shrunkAmount); + _deposit(owner, operatorIds, shrunkAmount); _pods[hashedPod] = keccak256(abi.encodePacked(pod.validatorCount, pod.networkFee, pod.networkFeeIndex, pod.index, pod.balance, pod.disabled )); - emit PodMetadataUpdated(owner, operatorIds, pod); + emit PodDeposited(owner, operatorIds, pod); } function deposit( @@ -503,11 +503,11 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { pod.balance += shrunkAmount; - _deposit(msg.sender, hashedPod, shrunkAmount); + _deposit(msg.sender, operatorIds, shrunkAmount); _pods[hashedPod] = keccak256(abi.encodePacked(pod.validatorCount, pod.networkFee, pod.networkFeeIndex, pod.index, pod.balance, pod.disabled )); - emit PodMetadataUpdated(msg.sender, operatorIds, pod); + emit PodDeposited(msg.sender, operatorIds, pod); } function withdrawOperatorBalance(uint64 operatorId, uint256 amount) external override { @@ -583,8 +583,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _pods[hashedPod] = keccak256(abi.encodePacked(pod.validatorCount, pod.networkFee, pod.networkFeeIndex, pod.index, pod.balance, pod.disabled )); - emit PodFundsWithdrawal(msg.sender, operatorIds, amount); - emit PodMetadataUpdated(msg.sender, operatorIds, pod); + emit PodFundsWithdrawal(msg.sender, operatorIds, amount, pod); } /**************************/ @@ -883,9 +882,9 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { /* Balance Private Functions */ /*****************************/ - function _deposit(address owner, bytes32 hashedPod, uint64 amount) private { + function _deposit(address owner, uint64[] memory operatorIds, uint64 amount) private { _token.transferFrom(msg.sender, address(this), amount.expand()); - emit FundsDeposit(amount.expand(), hashedPod, owner); + emit FundsDeposit(amount.expand(), operatorIds, owner); } function _updateNetworkFeeIndex() private { @@ -925,4 +924,4 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { function _podNetworkFee(uint64 networkFee, uint64 networkFeeIndex, uint32 validatorCount) private view returns (uint64) { return networkFee + uint64(_currentNetworkFeeIndex() - networkFeeIndex) * validatorCount; } -} +} \ No newline at end of file diff --git a/stress-test/stress.ts b/stress-test/stress.ts new file mode 100644 index 00000000..820d148b --- /dev/null +++ b/stress-test/stress.ts @@ -0,0 +1,149 @@ +// Define imports +import * as helpers from '../test/helpers/contract-helpers'; +import { trackGas, GasGroup } from '../test/helpers/gas-usage'; +import { progressTime } from '../test/helpers/utils'; + +// Define global variables +let ssvNetworkContract: any; +let validatorData: any = []; + +describe('Stress Tests', () => { + beforeEach(async () => { + // Initialize contract + ssvNetworkContract = (await helpers.initializeContract()).contract; + + validatorData = []; + + for (let i = 0; i < 7; i++) { + await helpers.DB.ssvToken.connect(helpers.DB.owners[i]).approve(helpers.DB.ssvNetwork.contract.address, '9000000000000000000000'); + } + // Register operators + await helpers.registerOperators(0, 250, helpers.CONFIG.minimalOperatorFee); + await helpers.registerOperators(1, 250, helpers.CONFIG.minimalOperatorFee); + await helpers.registerOperators(2, 250, helpers.CONFIG.minimalOperatorFee); + await helpers.registerOperators(3, 250, helpers.CONFIG.minimalOperatorFee); + + for (let i = 1000; i < 2001; i++) { + // Define random values + const randomOwner = Math.floor(Math.random() * 6); + const randomOperatorPoint = 1 + Math.floor(Math.random() * 995); + const validatorPublicKey = `0x${'0'.repeat(92)}${i}`; + + // Define minimum deposit amount + const minDepositAmount = (helpers.CONFIG.minimalBlocksBeforeLiquidation * 500) * helpers.CONFIG.minimalOperatorFee * 4; + + // Define empty pod data to send + let podData = { + validatorCount: 0, + networkFee: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + disabled: false + }; + + // Loop through all created validators to see if the pod you chose is created or not + for (let j = validatorData.length-1; j >= 0; j--) { + if (validatorData[j].operatorPoint === randomOperatorPoint && validatorData[j].owner === randomOwner) { + podData = validatorData[j].pod; + break; + } + } + + // Register a validator + const tx = await ssvNetworkContract.connect(helpers.DB.owners[randomOwner]).registerValidator( + validatorPublicKey, + [randomOperatorPoint,randomOperatorPoint+1,randomOperatorPoint+2,randomOperatorPoint+3], + helpers.DataGenerator.shares(0), + minDepositAmount, + podData + ); + + const receipt = await tx.wait(); + + // Get the pod event + const args = (receipt.events[3].args[4]); + + // Break the pod event to a struct + const pod = { + validatorCount: args.validatorCount, + networkFee: args.networkFee, + networkFeeIndex: args.networkFeeIndex, + index: args.index, + balance: args.balance, + disabled: args.disabled + }; + + // Push the validator to an array + validatorData.push({publicKey: validatorPublicKey, operatorPoint: randomOperatorPoint, owner: randomOwner, pod: pod}); + } + }); + + it('Update 1000 operators', async () => { + for (let i = 0; i < 1000; i++) { + let owner = 0; + if (i > 249 && i < 500) owner = 1; + else if (i > 499 && i < 750) owner = 2; + else if (i > 749) owner = 3; + await ssvNetworkContract.connect(helpers.DB.owners[owner]).declareOperatorFee(i + 1, 110000000); + await progressTime(helpers.CONFIG.declareOperatorFeePeriod); + await ssvNetworkContract.connect(helpers.DB.owners[owner]).executeOperatorFee(i + 1); + } + }); + + it('Remove 1000 operators', async () => { + for (let i = 0; i < 250; i++) await trackGas(await ssvNetworkContract.connect(helpers.DB.owners[0]).removeOperator(i + 1), [GasGroup.REMOVE_OPERATOR]); + for (let i = 250; i < 500; i++) await trackGas(await ssvNetworkContract.connect(helpers.DB.owners[1]).removeOperator(i + 1), [GasGroup.REMOVE_OPERATOR]); + for (let i = 500; i < 750; i++) await trackGas(await ssvNetworkContract.connect(helpers.DB.owners[2]).removeOperator(i + 1), [GasGroup.REMOVE_OPERATOR]); + for (let i = 750; i < 1000; i++) await trackGas(await ssvNetworkContract.connect(helpers.DB.owners[3]).removeOperator(i + 1), [GasGroup.REMOVE_OPERATOR]); + }); + + it('Remove 1000 validators', async () => { + const newValidatorData: any = []; + + for (let i = 0; i < validatorData.length-1; i++) { + + let podData: any; + + // Loop and get latest pod + for (let j = validatorData.length-1; j >= 0; j--) { + if (validatorData[j].operatorPoint === validatorData[i].operatorPoint && validatorData[j].owner === validatorData[i].owner) { + podData = validatorData[j].pod; + break; + } + } + + // Loop through new emits to get even more up to date pod if neeeded + for (let j = newValidatorData.length-1; j >= 0; j--) { + if (newValidatorData[j].operatorPoint === validatorData[i].operatorPoint && newValidatorData[j].owner === validatorData[i].owner) { + podData = newValidatorData[j].pod; + break; + } + } + + // Remove a validator + const { eventsByName } = await trackGas(await ssvNetworkContract.connect(helpers.DB.owners[validatorData[i].owner]).removeValidator( + validatorData[i].publicKey, + [validatorData[i].operatorPoint, validatorData[i].operatorPoint+1, validatorData[i].operatorPoint+2, validatorData[i].operatorPoint+3], + podData + ), [GasGroup.REMOVE_VALIDATOR]); + + // Get removal event + const args = (eventsByName.ValidatorRemoved[0].args).pod; + + // Form a pod struct + const pod = { + validatorCount: args.validatorCount, + networkFee: args.networkFee, + networkFeeIndex: args.networkFeeIndex, + index: args.index, + balance: args.balance, + disabled: args.disabled + }; + + // Save new validator data + newValidatorData.push({publicKey: validatorData[i].validatorPublicKey, operatorPoint: validatorData[i].operatorPoint, owner: validatorData[i].owner, pod: pod}); + } + }); + +}); diff --git a/test/helpers/contract-helpers.ts b/test/helpers/contract-helpers.ts index 56ab6894..29c24d1a 100644 --- a/test/helpers/contract-helpers.ts +++ b/test/helpers/contract-helpers.ts @@ -79,12 +79,12 @@ export const initializeContract = async () => { DB.ssvNetwork.owner = DB.owners[0]; - await DB.ssvToken.mint(DB.owners[1].address, '1000000000000000'); - await DB.ssvToken.mint(DB.owners[2].address, '1000000000000000'); - await DB.ssvToken.mint(DB.owners[3].address, '1000000000000000'); - await DB.ssvToken.mint(DB.owners[4].address, '1000000000000000'); - await DB.ssvToken.mint(DB.owners[5].address, '1000000000000000'); - await DB.ssvToken.mint(DB.owners[6].address, '1000000000000000'); + await DB.ssvToken.mint(DB.owners[1].address, '10000000000000000000'); + await DB.ssvToken.mint(DB.owners[2].address, '10000000000000000000'); + await DB.ssvToken.mint(DB.owners[3].address, '10000000000000000000'); + await DB.ssvToken.mint(DB.owners[4].address, '10000000000000000000'); + await DB.ssvToken.mint(DB.owners[5].address, '10000000000000000000'); + await DB.ssvToken.mint(DB.owners[6].address, '10000000000000000000'); return { contract: DB.ssvNetwork.contract, owner: DB.ssvNetwork.owner, ssvToken: DB.ssvToken }; }; diff --git a/test/sanity/stress.ts b/test/sanity/stress.ts deleted file mode 100644 index b76e3999..00000000 --- a/test/sanity/stress.ts +++ /dev/null @@ -1,55 +0,0 @@ -/*declare const ethers: any; - -import * as helpers from '../helpers/contract-helpers'; - -import { expect } from 'chai'; - -const numberOfOperators = 1000; -const operatorFee = 1; - -let registryContract: any, operatorIDs: any, shares: any; -const validatorData: any = []; -*/ - -describe('Stress Tests', () => { - // beforeEach(async () => { - // const contractData = await helpers.initializeContract(numberOfOperators, operatorFee); - // registryContract = contractData.contract; - // operatorIDs = contractData.operatorIDs; - // shares = contractData.shares; - - // // Register 1000 validators - // validatorData = await helpers.registerValidators(1000, '10000', numberOfOperators, registryContract); - // }); - - // it('Update 1000 operators', async () => { - // for (let i = 0; i < operatorIDs.length; i++) { - // await registryContract.updateOperatorFee(operatorIDs[i], 10); - // } - // }); - - // it('Transfer 1000 validators', async () => { - // for (let i = 1000; i < (validatorData.length + 1000); i++) { - // const randomOperator = Math.floor(Math.random() * (numberOfOperators - 4)); - // await registryContract.transferValidator( - // validatorData[i-1000].publicKey, - // [randomOperator, randomOperator + 1, randomOperator + 2, randomOperator + 3], - // shares[1], - // '10001' - // ); - // } - // }); - - // it('Remove 1000 operators', async () => { - // for (let i = 0; i < operatorIDs.length; i++) { - // await registryContract.removeOperator(operatorIDs[i]); - // } - // }); - - // it('Remove 1000 validators', async () => { - // for (let i = 0; i < validatorData.length; i++) { - // await registryContract.removeValidator(validatorData[i].publicKey); - // } - // }); - -}); From c6555800f5d51179c20fca5e89b49cdef4cfdd6d Mon Sep 17 00:00:00 2001 From: andrew-blox <102898824+andrew-blox@users.noreply.github.com> Date: Mon, 2 Jan 2023 17:54:23 +0200 Subject: [PATCH 109/149] Add validator gas test io1-2187 * Add validator gas test * change var name * Add operators column --- test-e2e/register-validator-gas.ts | 230 ++++++++++++++++++++++++++++ {stress-test => test-e2e}/stress.ts | 0 2 files changed, 230 insertions(+) create mode 100644 test-e2e/register-validator-gas.ts rename {stress-test => test-e2e}/stress.ts (100%) diff --git a/test-e2e/register-validator-gas.ts b/test-e2e/register-validator-gas.ts new file mode 100644 index 00000000..02b2e835 --- /dev/null +++ b/test-e2e/register-validator-gas.ts @@ -0,0 +1,230 @@ +// Declare imports +import * as helpers from '../test/helpers/contract-helpers'; + +// Declare globals +let ssvNetworkContract: any, minDepositAmount: any; +type gasStruct = { + Operators: number, + New_Pod: number, + Second_Val_With_Deposit: number, + Third_Val_No_Deposit: number, +} +const gasTable: gasStruct [] = []; +let firstPodEverGas = 0; + +describe('Register Validator Gas Tests', () => { + beforeEach(async () => { + // Initialize contract + ssvNetworkContract = (await helpers.initializeContract()).contract; + + // Register operators + await helpers.registerOperators(0, 14, helpers.CONFIG.minimalOperatorFee); + + // Define a minimum deposit amount + minDepositAmount = (helpers.CONFIG.minimalBlocksBeforeLiquidation + 2) * helpers.CONFIG.minimalOperatorFee * 13; + + // Register first validator ever + await helpers.DB.ssvToken.connect(helpers.DB.owners[6]).approve(helpers.DB.ssvNetwork.contract.address, minDepositAmount); + const tx = await ssvNetworkContract.connect(helpers.DB.owners[6]).registerValidator( + helpers.DataGenerator.publicKey(5), + [1,2,3,4], + helpers.DataGenerator.shares(0), + minDepositAmount, + { + validatorCount: 0, + networkFee: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + disabled: false + } + ); + + // Save gas fee for first validator ever + const receipt = await tx.wait(); + firstPodEverGas = +receipt.gasUsed; + + // Approve SSV + await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount * 500); + }); + + it('4 Operators Gas Usage', async () => { + // New Pod + const tx1 = await ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( + helpers.DataGenerator.publicKey(1), + [1,2,3,4], + helpers.DataGenerator.shares(0), + minDepositAmount, + { + validatorCount: 0, + networkFee: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + disabled: false + } + ); + const receipt1 = await tx1.wait(); + const pod1 = (receipt1.events[3].args[4]); + + // Second Validator with a deposit + const tx2 = await ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( + helpers.DataGenerator.publicKey(2), + [1,2,3,4], + helpers.DataGenerator.shares(0), + minDepositAmount, + pod1 + ); + const receipt2 = await tx2.wait(); + const pod2 = (receipt2.events[3].args[4]); + + // Third Validator without a deposit + const tx3 = await ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( + helpers.DataGenerator.publicKey(3), + [1,2,3,4], + helpers.DataGenerator.shares(0), + 0, + pod2 + ); + const receipt3 = await tx3.wait(); + + // Save the gas costs + gasTable.push({ Operators: 4, New_Pod: +receipt1.gasUsed, Second_Val_With_Deposit: +receipt2.gasUsed, Third_Val_No_Deposit: +receipt3.gasUsed}); + }); + + it('7 Operators Gas Usage', async () => { + // New Pod + const tx1 = await ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( + helpers.DataGenerator.publicKey(1), + [1,2,3,4,5,6,7], + helpers.DataGenerator.shares(1), + minDepositAmount * 2, + { + validatorCount: 0, + networkFee: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + disabled: false + } + ); + const receipt1 = await tx1.wait(); + const pod1 = (receipt1.events[3].args[4]); + + // Second Validator with a deposit + const tx2 = await ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( + helpers.DataGenerator.publicKey(2), + [1,2,3,4,5,6,7], + helpers.DataGenerator.shares(1), + minDepositAmount * 2, + pod1 + ); + const receipt2 = await tx2.wait(); + const pod2 = (receipt2.events[3].args[4]); + + // Third Validator without a deposit + const tx3 = await ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( + helpers.DataGenerator.publicKey(3), + [1,2,3,4,5,6,7], + helpers.DataGenerator.shares(1), + 0, + pod2 + ); + const receipt3 = await tx3.wait(); + + // Save the gas costs + gasTable.push({ Operators: 7, New_Pod: +receipt1.gasUsed, Second_Val_With_Deposit: +receipt2.gasUsed, Third_Val_No_Deposit: +receipt3.gasUsed}); + }); + + it('10 Operators Gas Usage', async () => { + // New Pod + const tx1 = await ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( + helpers.DataGenerator.publicKey(1), + [1,2,3,4,5,6,7,8,9,10], + helpers.DataGenerator.shares(2), + minDepositAmount * 3, + { + validatorCount: 0, + networkFee: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + disabled: false + } + ); + const receipt1 = await tx1.wait(); + const pod1 = (receipt1.events[3].args[4]); + + // Second Validator with a deposit + const tx2 = await ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( + helpers.DataGenerator.publicKey(2), + [1,2,3,4,5,6,7,8,9,10], + helpers.DataGenerator.shares(2), + minDepositAmount * 3, + pod1 + ); + const receipt2 = await tx2.wait(); + const pod2 = (receipt2.events[3].args[4]); + + // Third Validator without a deposit + const tx3 = await ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( + helpers.DataGenerator.publicKey(3), + [1,2,3,4,5,6,7,8,9,10], + helpers.DataGenerator.shares(2), + 0, + pod2 + ); + const receipt3 = await tx3.wait(); + + // Save the gas costs + gasTable.push({ Operators: 10, New_Pod: +receipt1.gasUsed, Second_Val_With_Deposit: +receipt2.gasUsed, Third_Val_No_Deposit: +receipt3.gasUsed}); + }); + + it('13 Operators Gas Usage', async () => { + // New Pod + const tx1 = await 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(2), + minDepositAmount * 4, + { + validatorCount: 0, + networkFee: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + disabled: false + } + ); + const receipt1 = await tx1.wait(); + const pod1 = (receipt1.events[3].args[4]); + + // Second Validator with a deposit + const tx2 = await 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(2), + minDepositAmount * 4, + pod1 + ); + const receipt2 = await tx2.wait(); + const pod2 = (receipt2.events[3].args[4]); + + // Third Validator without a deposit + const tx3 = await ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( + helpers.DataGenerator.publicKey(3), + [1,2,3,4,5,6,7,8,9,10,11,12,13], + helpers.DataGenerator.shares(2), + 0, + pod2 + ); + const receipt3 = await tx3.wait(); + + // Save the gas costs + gasTable.push({ Operators: 13, New_Pod: +receipt1.gasUsed, Second_Val_With_Deposit: +receipt2.gasUsed, Third_Val_No_Deposit: +receipt3.gasUsed}); + + // Log the table + console.log(`First validator ever: ${firstPodEverGas}`); + console.table(gasTable); + }); +}); diff --git a/stress-test/stress.ts b/test-e2e/stress.ts similarity index 100% rename from stress-test/stress.ts rename to test-e2e/stress.ts From 6545896dc50680e4433e8b62065d4b1fa37d0405 Mon Sep 17 00:00:00 2001 From: Marco Date: Tue, 3 Jan 2023 19:25:19 +0100 Subject: [PATCH 110/149] apply rules, upgrade solhint --- .solhint.json | 11 +- contracts/ISSVNetwork.sol | 94 +++-- contracts/SSVNetwork.sol | 578 ++++++++++++++++++++++++------- contracts/mocks/SSVTokenMock.sol | 3 +- contracts/utils/Types.sol | 25 +- package.json | 2 +- test/dao/network-fee-change.ts | 4 +- 7 files changed, 536 insertions(+), 181 deletions(-) diff --git a/.solhint.json b/.solhint.json index daee6b89..5234ef46 100644 --- a/.solhint.json +++ b/.solhint.json @@ -4,7 +4,16 @@ "rules": { "avoid-suicide": "error", "avoid-sha3": "warn", + "comprehensive-interface": "warn", + "func-visibility": [ + "warn", + { + "ignoreConstructors": true + } + ], + "ordering": "warn", "mark-callable-contracts": "off", - "compiler-version": "off" + "compiler-version": "off", + "not-rely-on-time": "off" } } \ No newline at end of file diff --git a/contracts/ISSVNetwork.sol b/contracts/ISSVNetwork.sol index af5b27a3..b4ce4fa0 100644 --- a/contracts/ISSVNetwork.sol +++ b/contracts/ISSVNetwork.sol @@ -3,18 +3,13 @@ pragma solidity ^0.8.2; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; - interface ISSVNetwork { - struct Pod { uint32 validatorCount; - uint64 networkFee; uint64 networkFeeIndex; - uint64 index; uint64 balance; - bool disabled; } @@ -23,12 +18,12 @@ interface ISSVNetwork { /**********/ /** - * @dev Emitted when a new operator has been added. - * @param id operator's ID. - * @param owner Operator's ethereum address that can collect fees. - * @param publicKey Operator's public key. Will be used to encrypt secret shares of validators keys. - * @param fee Operator's fee. - */ + * @dev Emitted when a new operator has been added. + * @param id operator's ID. + * @param owner Operator's ethereum address that can collect fees. + * @param publicKey Operator's public key. Will be used to encrypt secret shares of validators keys. + * @param fee Operator's fee. + */ event OperatorAdded( uint64 id, address indexed owner, @@ -84,7 +79,10 @@ interface ISSVNetwork { */ event OperatorFeeSet(uint64 id, uint64 fee); - event DeclaredOperatorFeeCancelation(address indexed ownerAddress, uint64 operatorId); + event DeclaredOperatorFeeCancelation( + address indexed ownerAddress, + uint64 operatorId + ); /** * @dev Emitted when an operator's fee is updated. @@ -125,17 +123,21 @@ interface ISSVNetwork { */ event NetworkEarningsWithdrawal(uint256 value, address recipient); - event PodFundsWithdrawal(address ownerAddress, uint64[] operatorIds, uint256 value, Pod pod); - event OperatorFundsWithdrawal(uint256 value, uint64 operatorId, address ownerAddress); - - - event FundsDeposit(uint256 value, uint64[] operatorIds, address owner); - - event PodDeposited( + event PodFundsWithdrawal( address ownerAddress, uint64[] operatorIds, + uint256 value, Pod pod ); + event OperatorFundsWithdrawal( + uint256 value, + uint64 operatorId, + address ownerAddress + ); + + event FundsDeposit(uint256 value, uint64[] operatorIds, address owner); + + event PodDeposited(address ownerAddress, uint64[] operatorIds, Pod pod); event FeeRecipientAddressAdded( address ownerAddress, @@ -176,12 +178,12 @@ interface ISSVNetwork { /****************/ /** - * @dev Initializes the contract. - * @param token_ The network token. - * @param operatorMaxFeeIncrease_ The step limit to increase the operator fee - * @param declareOperatorFeePeriod_ The period an operator needs to wait before they can approve their fee. - * @param executeOperatorFeePeriod_ The length of the period in which an operator can approve their fee. - */ + * @dev Initializes the contract. + * @param token_ The network token. + * @param operatorMaxFeeIncrease_ The step limit to increase the operator fee + * @param declareOperatorFeePeriod_ The period an operator needs to wait before they can approve their fee. + * @param executeOperatorFeePeriod_ The length of the period in which an operator can approve their fee. + */ function initialize( IERC20 token_, uint64 operatorMaxFeeIncrease_, @@ -269,7 +271,10 @@ interface ISSVNetwork { Pod memory pod ) external; - function withdrawOperatorBalance(uint64 operatorId, uint256 tokenAmount) external; + function withdrawOperatorBalance( + uint64 operatorId, + uint256 tokenAmount + ) external; function withdrawOperatorBalance(uint64 operatorId) external; @@ -287,11 +292,17 @@ interface ISSVNetwork { function withdrawNetworkEarnings(uint256 amount) external; - function updateOperatorFeeIncreaseLimit(uint64 newOperatorMaxFeeIncrease) external; + function updateOperatorFeeIncreaseLimit( + uint64 newOperatorMaxFeeIncrease + ) external; - function updateDeclareOperatorFeePeriod(uint64 newDeclareOperatorFeePeriod) external; + function updateDeclareOperatorFeePeriod( + uint64 newDeclareOperatorFeePeriod + ) external; - function updateExecuteOperatorFeePeriod(uint64 newExecuteOperatorFeePeriod) external; + function updateExecuteOperatorFeePeriod( + uint64 newExecuteOperatorFeePeriod + ) external; function updateLiquidationThresholdPeriod(uint64 blocks) external; @@ -301,9 +312,13 @@ interface ISSVNetwork { function getOperatorFee(uint64 operatorId) external view returns (uint256); - function getOperatorDeclaredFee(uint64 operatorId) external view returns (uint256, uint256, uint256); + function getOperatorDeclaredFee( + uint64 operatorId + ) external view returns (uint256, uint256, uint256); - function getOperatorById(uint64 operatorId) external view returns (address owner, uint256 fee, uint32 validatorCount); + function getOperatorById( + uint64 operatorId + ) external view returns (address owner, uint256 fee, uint32 validatorCount); /*******************************/ /* Pod External View Functions */ @@ -313,15 +328,17 @@ interface ISSVNetwork { address ownerAddress, uint64[] memory operatorIds, Pod memory pod - ) external view returns(bool); + ) external view returns (bool); function isLiquidated( address ownerAddress, uint64[] memory operatorIds, Pod memory pod - ) external view returns(bool); + ) external view returns (bool); - function getPodBurnRate(uint64[] memory operatorIds) external view returns (uint256); + function getPodBurnRate( + uint64[] memory operatorIds + ) external view returns (uint256); /***********************************/ /* Balance External View Functions */ @@ -334,7 +351,12 @@ interface ISSVNetwork { * @return index the index of the operator. * @return balance the current balance of the operator. */ - function operatorSnapshot(uint64 id) external view returns (uint64 currentBlock, uint64 index, uint256 balance); + function operatorSnapshot( + uint64 id + ) + external + view + returns (uint64 currentBlock, uint64 index, uint256 balance); function podBalanceOf( address ownerAddress, @@ -357,4 +379,4 @@ interface ISSVNetwork { function getDeclaredOperatorFeePeriod() external view returns (uint64); function getLiquidationThresholdPeriod() external view returns (uint64); -} \ No newline at end of file +} diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index ca76c36e..59baf1d6 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -21,7 +21,6 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { using Counters for Counters.Counter; - /***********/ /* Structs */ /***********/ @@ -39,7 +38,6 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { address owner; uint64 fee; uint32 validatorCount; - Snapshot snapshot; } @@ -52,7 +50,6 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { struct DAO { uint32 validatorCount; uint64 withdrawn; - Snapshot earnings; } /* @@ -70,8 +67,8 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { /* Constants */ /*************/ - uint64 constant MINIMAL_LIQUIDATION_THRESHOLD = 6570; - uint64 constant MINIMAL_OPERATOR_FEE = 100000000; + uint64 private constant MINIMAL_LIQUIDATION_THRESHOLD = 6570; + uint64 private constant MINIMAL_OPERATOR_FEE = 100000000; /********************/ /* Global Variables */ @@ -84,10 +81,11 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { /*************/ mapping(uint64 => Operator) private _operators; - mapping(uint64 => OperatorFeeChangeRequest) private _operatorFeeChangeRequests; + mapping(uint64 => OperatorFeeChangeRequest) + private _operatorFeeChangeRequests; // mapping(bytes32 => Cluster) private _clusters; mapping(bytes32 => bytes32) private _pods; - mapping(bytes32 => Validator) _validatorPKs; + mapping(bytes32 => Validator) private _validatorPKs; uint64 private _networkFee; uint64 private _networkFeeIndex; @@ -101,6 +99,15 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { DAO private _dao; IERC20 private _token; + /*************/ + /* Modifiers */ + /*************/ + + modifier onlyOperatorOwnerOrContractOwner(uint64 operatorId) { + _onlyOperatorOwnerOrContractOwner(operatorId); + _; + } + /****************/ /* Initializers */ /****************/ @@ -112,41 +119,13 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { uint64 executeOperatorFeePeriod_, uint64 minimumBlocksBeforeLiquidation_ ) external override { - __SSVNetwork_init(token_, operatorMaxFeeIncrease_, declareOperatorFeePeriod_, executeOperatorFeePeriod_, minimumBlocksBeforeLiquidation_); - } - - function __SSVNetwork_init( - IERC20 token_, - uint64 operatorMaxFeeIncrease_, - uint64 declareOperatorFeePeriod_, - uint64 executeOperatorFeePeriod_, - uint64 minimumBlocksBeforeLiquidation_ - ) internal initializer { - __Ownable_init_unchained(); - __SSVNetwork_init_unchained(token_, operatorMaxFeeIncrease_, declareOperatorFeePeriod_, executeOperatorFeePeriod_, minimumBlocksBeforeLiquidation_); - } - - function __SSVNetwork_init_unchained( - IERC20 token_, - uint64 operatorMaxFeeIncrease_, - uint64 declareOperatorFeePeriod_, - uint64 executeOperatorFeePeriod_, - uint64 minimumBlocksBeforeLiquidation_ - ) internal onlyInitializing { - _token = token_; - _operatorMaxFeeIncrease = operatorMaxFeeIncrease_; - _declareOperatorFeePeriod = declareOperatorFeePeriod_; - _executeOperatorFeePeriod = executeOperatorFeePeriod_; - _minimumBlocksBeforeLiquidation = minimumBlocksBeforeLiquidation_; - } - - /*************/ - /* Modifiers */ - /*************/ - - modifier onlyOperatorOwnerOrContractOwner(uint64 operatorId) { - _onlyOperatorOwnerOrContractOwner(operatorId); - _; + __SSVNetwork_init( + token_, + operatorMaxFeeIncrease_, + declareOperatorFeePeriod_, + executeOperatorFeePeriod_, + minimumBlocksBeforeLiquidation_ + ); } /*******************************/ @@ -163,7 +142,16 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { lastOperatorId.increment(); id = uint64(lastOperatorId.current()); - _operators[id] = Operator({ owner: msg.sender, snapshot: Snapshot({ block: uint64(block.number), index: 0, balance: 0}), validatorCount: 0, fee: fee.shrink()}); + _operators[id] = Operator({ + owner: msg.sender, + snapshot: Snapshot({ + block: uint64(block.number), + index: 0, + balance: 0 + }), + validatorCount: 0, + fee: fee.shrink() + }); emit OperatorAdded(id, msg.sender, encryptionPK, fee); } @@ -174,7 +162,10 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { operator.snapshot = _getSnapshot(operator, uint64(block.number)); if (operator.snapshot.balance > 0) { - _transferOperatorBalanceUnsafe(operatorId, operator.snapshot.balance.expand()); + _transferOperatorBalanceUnsafe( + operatorId, + operator.snapshot.balance.expand() + ); } operator.snapshot.block = 0; @@ -186,7 +177,10 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { emit OperatorRemoved(operatorId); } - function declareOperatorFee(uint64 operatorId, uint256 fee) onlyOperatorOwnerOrContractOwner(operatorId) external override { + function declareOperatorFee( + uint64 operatorId, + uint256 fee + ) external override onlyOperatorOwnerOrContractOwner(operatorId) { Operator memory operator = _operators[operatorId]; if (fee < MINIMAL_OPERATOR_FEE) revert FeeTooLow(); @@ -194,24 +188,33 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { uint64 shrunkFee = fee.shrink(); // @dev 100% = 10000, 10% = 1000 - using 10000 to represent 2 digit precision - uint64 maxAllowedFee = operator.fee * (10000 + _operatorMaxFeeIncrease) / 10000; + uint64 maxAllowedFee = (operator.fee * + (10000 + _operatorMaxFeeIncrease)) / 10000; if (shrunkFee > maxAllowedFee) revert FeeExceedsIncreaseLimit(); _operatorFeeChangeRequests[operatorId] = OperatorFeeChangeRequest( shrunkFee, uint64(block.timestamp) + _declareOperatorFeePeriod, - uint64(block.timestamp) + _declareOperatorFeePeriod + _executeOperatorFeePeriod + uint64(block.timestamp) + + _declareOperatorFeePeriod + + _executeOperatorFeePeriod ); emit OperatorFeeDeclaration(msg.sender, operatorId, block.number, fee); } - function executeOperatorFee(uint64 operatorId) onlyOperatorOwnerOrContractOwner(operatorId) external override { - OperatorFeeChangeRequest memory feeChangeRequest = _operatorFeeChangeRequests[operatorId]; + function executeOperatorFee( + uint64 operatorId + ) external override onlyOperatorOwnerOrContractOwner(operatorId) { + OperatorFeeChangeRequest + memory feeChangeRequest = _operatorFeeChangeRequests[operatorId]; - if(feeChangeRequest.fee == 0) revert NoPendingFeeChangeRequest(); + if (feeChangeRequest.fee == 0) revert NoPendingFeeChangeRequest(); - if(block.timestamp < feeChangeRequest.approvalBeginTime || block.timestamp > feeChangeRequest.approvalEndTime) { + if ( + block.timestamp < feeChangeRequest.approvalBeginTime || + block.timestamp > feeChangeRequest.approvalEndTime + ) { revert ApprovalNotWithinTimeframe(); } @@ -220,10 +223,13 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { delete _operatorFeeChangeRequests[operatorId]; } - function cancelDeclaredOperatorFee(uint64 operatorId) onlyOperatorOwnerOrContractOwner(operatorId) external override { - OperatorFeeChangeRequest memory feeChangeRequest = _operatorFeeChangeRequests[operatorId]; + function cancelDeclaredOperatorFee( + uint64 operatorId + ) external override onlyOperatorOwnerOrContractOwner(operatorId) { + OperatorFeeChangeRequest + memory feeChangeRequest = _operatorFeeChangeRequests[operatorId]; - if(feeChangeRequest.fee == 0) revert NoPendingFeeChangeRequest(); + if (feeChangeRequest.fee == 0) revert NoPendingFeeChangeRequest(); delete _operatorFeeChangeRequests[operatorId]; @@ -253,7 +259,10 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { if (_validatorPKs[keccak256(publicKey)].owner != address(0)) { revert ValidatorAlreadyExists(); } - _validatorPKs[keccak256(publicKey)] = Validator({ owner: msg.sender, active: true}); + _validatorPKs[keccak256(publicKey)] = Validator({ + owner: msg.sender, + active: true + }); } uint64 podIndex; @@ -264,10 +273,16 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { Operator memory operator = _operators[operatorIds[i]]; if (operator.snapshot.block == 0) { revert OperatorDoesNotExist(); - } else if (i+1 < operatorIds.length && operatorIds[i] > operatorIds[i+1]) { + } else if ( + i + 1 < operatorIds.length && + operatorIds[i] > operatorIds[i + 1] + ) { revert OperatorsListDoesNotSorted(); } - operator.snapshot = _getSnapshot(operator, uint64(block.number)); + operator.snapshot = _getSnapshot( + operator, + uint64(block.number) + ); ++operator.validatorCount; podIndex += operator.snapshot.index; burnRate += operator.fee; @@ -276,11 +291,29 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } } - bytes32 hashedPod = keccak256(abi.encodePacked(msg.sender, operatorIds)); + bytes32 hashedPod = keccak256( + abi.encodePacked(msg.sender, operatorIds) + ); { - bytes32 hashedPodData = keccak256(abi.encodePacked(pod.validatorCount, pod.networkFee, pod.networkFeeIndex, pod.index, pod.balance, pod.disabled )); + bytes32 hashedPodData = keccak256( + abi.encodePacked( + pod.validatorCount, + pod.networkFee, + pod.networkFeeIndex, + pod.index, + pod.balance, + pod.disabled + ) + ); if (_pods[hashedPod] == bytes32(0)) { - pod = Pod({ validatorCount: 0, networkFee: 0, networkFeeIndex: 0, index: 0, balance: 0, disabled: false }); + pod = Pod({ + validatorCount: 0, + networkFee: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + disabled: false + }); } else if (_pods[hashedPod] != hashedPodData) { revert PodDataIsBroken(); } @@ -293,7 +326,13 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { pod = _updatePodData(pod, podIndex, 1); - if (_liquidatable(_podBalance(pod, podIndex), pod.validatorCount, burnRate)) { + if ( + _liquidatable( + _podBalance(pod, podIndex), + pod.validatorCount, + burnRate + ) + ) { revert NotEnoughBalance(); } @@ -306,7 +345,16 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } } - _pods[hashedPod] = keccak256(abi.encodePacked(pod.validatorCount, pod.networkFee, pod.networkFeeIndex, pod.index, pod.balance, pod.disabled )); + _pods[hashedPod] = keccak256( + abi.encodePacked( + pod.validatorCount, + pod.networkFee, + pod.networkFeeIndex, + pod.index, + pod.balance, + pod.disabled + ) + ); emit ValidatorAdded(msg.sender, operatorIds, publicKey, shares, pod); } @@ -332,11 +380,14 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { for (uint8 i = 0; i < operatorIds.length; ++i) { Operator memory operator = _operators[operatorIds[i]]; if (operator.snapshot.block != 0) { - operator.snapshot = _getSnapshot(operator, uint64(block.number)); + operator.snapshot = _getSnapshot( + operator, + uint64(block.number) + ); --operator.validatorCount; _operators[operatorIds[i]] = operator; } - + podIndex += operator.snapshot.index; } } @@ -356,7 +407,16 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } delete _validatorPKs[hashedValidator]; - _pods[hashedPod] = keccak256(abi.encodePacked(pod.validatorCount, pod.networkFee, pod.networkFeeIndex, pod.index, pod.balance, pod.disabled )); + _pods[hashedPod] = keccak256( + abi.encodePacked( + pod.validatorCount, + pod.networkFee, + pod.networkFeeIndex, + pod.index, + pod.balance, + pod.disabled + ) + ); emit ValidatorRemoved(msg.sender, operatorIds, publicKey, pod); } @@ -382,13 +442,19 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { burnRate += operator.fee; _operators[operatorIds[i]] = operator; } - + podIndex += operator.snapshot.index; } } { - if (!_liquidatable(_podBalance(pod, podIndex), pod.validatorCount, burnRate)) { + if ( + !_liquidatable( + _podBalance(pod, podIndex), + pod.validatorCount, + burnRate + ) + ) { revert PodNotLiquidatable(); } @@ -406,7 +472,16 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _dao = dao; } - _pods[hashedPod] = keccak256(abi.encodePacked(pod.validatorCount, pod.networkFee, pod.networkFeeIndex, pod.index, pod.balance, pod.disabled )); + _pods[hashedPod] = keccak256( + abi.encodePacked( + pod.validatorCount, + pod.networkFee, + pod.networkFeeIndex, + pod.index, + pod.balance, + pod.disabled + ) + ); emit PodLiquidated(owner, operatorIds, pod); } @@ -416,7 +491,6 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { uint256 amount, Pod memory pod ) external override { - if (!pod.disabled) { revert PodAlreadyEnabled(); } @@ -427,7 +501,10 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { for (uint8 i = 0; i < operatorIds.length; ++i) { Operator memory operator = _operators[operatorIds[i]]; if (operator.snapshot.block != 0) { - operator.snapshot = _getSnapshot(operator, uint64(block.number)); + operator.snapshot = _getSnapshot( + operator, + uint64(block.number) + ); operator.validatorCount += pod.validatorCount; burnRate += operator.fee; _operators[operatorIds[i]] = operator; @@ -456,11 +533,26 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _dao = dao; } - if (_liquidatable(_podBalance(pod, podIndex), pod.validatorCount, burnRate)) { + if ( + _liquidatable( + _podBalance(pod, podIndex), + pod.validatorCount, + burnRate + ) + ) { revert NotEnoughBalance(); } - _pods[hashedPod] = keccak256(abi.encodePacked(pod.validatorCount, pod.networkFee, pod.networkFeeIndex, pod.index, pod.balance, pod.disabled )); + _pods[hashedPod] = keccak256( + abi.encodePacked( + pod.validatorCount, + pod.networkFee, + pod.networkFeeIndex, + pod.index, + pod.balance, + pod.disabled + ) + ); emit PodEnabled(msg.sender, operatorIds, pod); } @@ -485,7 +577,16 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _deposit(owner, operatorIds, shrunkAmount); - _pods[hashedPod] = keccak256(abi.encodePacked(pod.validatorCount, pod.networkFee, pod.networkFeeIndex, pod.index, pod.balance, pod.disabled )); + _pods[hashedPod] = keccak256( + abi.encodePacked( + pod.validatorCount, + pod.networkFee, + pod.networkFeeIndex, + pod.index, + pod.balance, + pod.disabled + ) + ); emit PodDeposited(owner, operatorIds, pod); } @@ -505,12 +606,24 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _deposit(msg.sender, operatorIds, shrunkAmount); - _pods[hashedPod] = keccak256(abi.encodePacked(pod.validatorCount, pod.networkFee, pod.networkFeeIndex, pod.index, pod.balance, pod.disabled )); + _pods[hashedPod] = keccak256( + abi.encodePacked( + pod.validatorCount, + pod.networkFee, + pod.networkFeeIndex, + pod.index, + pod.balance, + pod.disabled + ) + ); emit PodDeposited(msg.sender, operatorIds, pod); } - function withdrawOperatorBalance(uint64 operatorId, uint256 amount) external override { + function withdrawOperatorBalance( + uint64 operatorId, + uint256 amount + ) external override { Operator memory operator = _operators[operatorId]; if (operator.owner != msg.sender) revert CallerNotOwner(); @@ -564,7 +677,10 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { { for (uint8 i = 0; i < operatorIds.length; ++i) { Operator memory operator = _operators[operatorIds[i]]; - podIndex += operator.snapshot.index + (uint64(block.number) - operator.snapshot.block) * operator.fee; + podIndex += + operator.snapshot.index + + (uint64(block.number) - operator.snapshot.block) * + operator.fee; burnRate += operator.fee; } } @@ -573,7 +689,14 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { uint64 podBalance = _podBalance(pod, podIndex); - if (podBalance < shrunkAmount || _liquidatable(_podBalance(pod, podIndex), pod.validatorCount, burnRate)) { + if ( + podBalance < shrunkAmount || + _liquidatable( + _podBalance(pod, podIndex), + pod.validatorCount, + burnRate + ) + ) { revert NotEnoughBalance(); } @@ -581,7 +704,16 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _token.transfer(msg.sender, amount); - _pods[hashedPod] = keccak256(abi.encodePacked(pod.validatorCount, pod.networkFee, pod.networkFeeIndex, pod.index, pod.balance, pod.disabled )); + _pods[hashedPod] = keccak256( + abi.encodePacked( + pod.validatorCount, + pod.networkFee, + pod.networkFeeIndex, + pod.index, + pod.balance, + pod.disabled + ) + ); emit PodFundsWithdrawal(msg.sender, operatorIds, amount, pod); } @@ -590,7 +722,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { /* DAO External Functions */ /**************************/ - function updateNetworkFee(uint256 fee) external onlyOwner override { + function updateNetworkFee(uint256 fee) external override onlyOwner { DAO memory dao = _dao; dao = _updateDAOEarnings(dao); _dao = dao; @@ -602,12 +734,14 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _networkFee = fee.shrink(); } - function withdrawNetworkEarnings(uint256 amount) external onlyOwner override { + function withdrawNetworkEarnings( + uint256 amount + ) external override onlyOwner { DAO memory dao = _dao; uint64 shrunkAmount = amount.shrink(); - if(shrunkAmount > _networkBalance(dao)) { + if (shrunkAmount > _networkBalance(dao)) { revert NotEnoughBalance(); } @@ -619,23 +753,31 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { emit NetworkEarningsWithdrawal(amount, msg.sender); } - function updateOperatorFeeIncreaseLimit(uint64 newOperatorMaxFeeIncrease) external onlyOwner override { + function updateOperatorFeeIncreaseLimit( + uint64 newOperatorMaxFeeIncrease + ) external override onlyOwner { _operatorMaxFeeIncrease = newOperatorMaxFeeIncrease; emit OperatorFeeIncreaseLimitUpdate(_operatorMaxFeeIncrease); } - function updateDeclareOperatorFeePeriod(uint64 newDeclareOperatorFeePeriod) external onlyOwner override { + function updateDeclareOperatorFeePeriod( + uint64 newDeclareOperatorFeePeriod + ) external override onlyOwner { _declareOperatorFeePeriod = newDeclareOperatorFeePeriod; emit DeclareOperatorFeePeriodUpdate(newDeclareOperatorFeePeriod); } - function updateExecuteOperatorFeePeriod(uint64 newExecuteOperatorFeePeriod) external onlyOwner override { + function updateExecuteOperatorFeePeriod( + uint64 newExecuteOperatorFeePeriod + ) external override onlyOwner { _executeOperatorFeePeriod = newExecuteOperatorFeePeriod; emit ExecuteOperatorFeePeriodUpdate(newExecuteOperatorFeePeriod); } - function updateLiquidationThresholdPeriod(uint64 blocks) external onlyOwner override { - if(blocks < MINIMAL_LIQUIDATION_THRESHOLD) { + function updateLiquidationThresholdPeriod( + uint64 blocks + ) external override onlyOwner { + if (blocks < MINIMAL_LIQUIDATION_THRESHOLD) { revert BelowMinimumBlockPeriod(); } @@ -647,26 +789,48 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { /* Operator External View Functions */ /************************************/ - function getOperatorFee(uint64 operatorId) external view override returns (uint256) { - if (_operators[operatorId].snapshot.block == 0) revert OperatorNotFound(); + function getOperatorFee( + uint64 operatorId + ) external view override returns (uint256) { + if (_operators[operatorId].snapshot.block == 0) + revert OperatorNotFound(); return _operators[operatorId].fee.expand(); } - function getOperatorDeclaredFee(uint64 operatorId) external view override returns (uint256, uint256, uint256) { - OperatorFeeChangeRequest memory feeChangeRequest = _operatorFeeChangeRequests[operatorId]; + function getOperatorDeclaredFee( + uint64 operatorId + ) external view override returns (uint256, uint256, uint256) { + OperatorFeeChangeRequest + memory feeChangeRequest = _operatorFeeChangeRequests[operatorId]; - if(feeChangeRequest.fee == 0) { + if (feeChangeRequest.fee == 0) { revert NoPendingFeeChangeRequest(); } - return (feeChangeRequest.fee.expand(), feeChangeRequest.approvalBeginTime, feeChangeRequest.approvalEndTime); + return ( + feeChangeRequest.fee.expand(), + feeChangeRequest.approvalBeginTime, + feeChangeRequest.approvalEndTime + ); } - function getOperatorById(uint64 operatorId) external view override returns (address owner, uint256 fee, uint32 validatorCount) { - if (_operators[operatorId].owner == address(0)) revert OperatorNotFound(); - - return (_operators[operatorId].owner, _operators[operatorId].fee.expand(), _operators[operatorId].validatorCount); + function getOperatorById( + uint64 operatorId + ) + external + view + override + returns (address owner, uint256 fee, uint32 validatorCount) + { + if (_operators[operatorId].owner == address(0)) + revert OperatorNotFound(); + + return ( + _operators[operatorId].owner, + _operators[operatorId].fee.expand(), + _operators[operatorId].validatorCount + ); } /*******************************/ @@ -682,13 +846,21 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { uint64 burnRate; for (uint8 i = 0; i < operatorIds.length; ++i) { Operator memory operator = _operators[operatorIds[i]]; - podIndex += operator.snapshot.index + (uint64(block.number) - operator.snapshot.block) * operator.fee; + podIndex += + operator.snapshot.index + + (uint64(block.number) - operator.snapshot.block) * + operator.fee; burnRate += operator.fee; } _validateHashedPod(owner, operatorIds, pod); - return _liquidatable(_podBalance(pod, podIndex), pod.validatorCount, burnRate); + return + _liquidatable( + _podBalance(pod, podIndex), + pod.validatorCount, + burnRate + ); } function isLiquidated( @@ -701,7 +873,9 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { return pod.disabled; } - function getPodBurnRate(uint64[] memory operatorIds) external view override returns (uint256) { + function getPodBurnRate( + uint64[] memory operatorIds + ) external view override returns (uint256) { uint64 burnRate; for (uint8 i = 0; i < operatorIds.length; ++i) { Operator memory operator = _operators[operatorIds[i]]; @@ -716,7 +890,14 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { /* Balance External View Functions */ /***********************************/ - function operatorSnapshot(uint64 id) external view override returns (uint64 currentBlock, uint64 index, uint256 balance) { + function operatorSnapshot( + uint64 id + ) + external + view + override + returns (uint64 currentBlock, uint64 index, uint256 balance) + { Snapshot memory s = _getSnapshot(_operators[id], uint64(block.number)); return (s.block, s.index, s.balance.expand()); } @@ -732,7 +913,10 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { { for (uint8 i = 0; i < operatorIds.length; ++i) { Operator memory operator = _operators[operatorIds[i]]; - podIndex += operator.snapshot.index + (uint64(block.number) - operator.snapshot.block) * operator.fee; + podIndex += + operator.snapshot.index + + (uint64(block.number) - operator.snapshot.block) * + operator.fee; } } @@ -754,22 +938,79 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { return _networkBalance(dao).expand(); } - function getOperatorFeeIncreaseLimit() external view override returns (uint64) { + function getOperatorFeeIncreaseLimit() + external + view + override + returns (uint64) + { return _operatorMaxFeeIncrease; } - function getExecuteOperatorFeePeriod() external view override returns (uint64) { + function getExecuteOperatorFeePeriod() + external + view + override + returns (uint64) + { return _executeOperatorFeePeriod; } - function getDeclaredOperatorFeePeriod() external view override returns (uint64) { + function getDeclaredOperatorFeePeriod() + external + view + override + returns (uint64) + { return _declareOperatorFeePeriod; } - function getLiquidationThresholdPeriod() external view override returns (uint64) { + function getLiquidationThresholdPeriod() + external + view + override + returns (uint64) + { return _minimumBlocksBeforeLiquidation; } + /**********************/ + /* Internal Functions */ + /**********************/ + + // solhint-disable-next-line func-name-mixedcase + function __SSVNetwork_init( + IERC20 token_, + uint64 operatorMaxFeeIncrease_, + uint64 declareOperatorFeePeriod_, + uint64 executeOperatorFeePeriod_, + uint64 minimumBlocksBeforeLiquidation_ + ) internal initializer { + __Ownable_init_unchained(); + __SSVNetwork_init_unchained( + token_, + operatorMaxFeeIncrease_, + declareOperatorFeePeriod_, + executeOperatorFeePeriod_, + minimumBlocksBeforeLiquidation_ + ); + } + + // solhint-disable-next-line func-name-mixedcase + function __SSVNetwork_init_unchained( + IERC20 token_, + uint64 operatorMaxFeeIncrease_, + uint64 declareOperatorFeePeriod_, + uint64 executeOperatorFeePeriod_, + uint64 minimumBlocksBeforeLiquidation_ + ) internal onlyInitializing { + _token = token_; + _operatorMaxFeeIncrease = operatorMaxFeeIncrease_; + _declareOperatorFeePeriod = declareOperatorFeePeriod_; + _executeOperatorFeePeriod = executeOperatorFeePeriod_; + _minimumBlocksBeforeLiquidation = minimumBlocksBeforeLiquidation_; + } + /********************************/ /* Validation Private Functions */ /********************************/ @@ -777,11 +1018,11 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { function _onlyOperatorOwnerOrContractOwner(uint64 operatorId) private view { Operator memory operator = _operators[operatorId]; - if(operator.snapshot.block == 0) { + if (operator.snapshot.block == 0) { revert OperatorWithPublicKeyNotExist(); } - if(msg.sender != operator.owner && msg.sender != owner()) { + if (msg.sender != operator.owner && msg.sender != owner()) { revert CallerNotOwner(); } } @@ -793,7 +1034,11 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } function _validateOperatorIds(uint64[] memory operatorIds) private pure { - if (operatorIds.length < 4 || operatorIds.length > 13 || operatorIds.length % 3 != 1) { + if ( + operatorIds.length < 4 || + operatorIds.length > 13 || + operatorIds.length % 3 != 1 + ) { revert OperatorIdsStructureInvalid(); } } @@ -808,7 +1053,10 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { /* Operator Private Functions */ /******************************/ - function _setFee(Operator memory operator, uint64 fee) private view returns (Operator memory) { + function _setFee( + Operator memory operator, + uint64 fee + ) private view returns (Operator memory) { operator.snapshot = _getSnapshot(operator, uint64(block.number)); operator.fee = fee; @@ -820,11 +1068,20 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _operators[operatorId] = _setFee(operator, fee); - emit OperatorFeeExecution(msg.sender, operatorId, block.number, fee.expand()); + emit OperatorFeeExecution( + msg.sender, + operatorId, + block.number, + fee.expand() + ); } - function _getSnapshot(Operator memory operator, uint64 currentBlock) private pure returns (Snapshot memory) { - uint64 blockDiffFee = (currentBlock - operator.snapshot.block) * operator.fee; + function _getSnapshot( + Operator memory operator, + uint64 currentBlock + ) private pure returns (Snapshot memory) { + uint64 blockDiffFee = (currentBlock - operator.snapshot.block) * + operator.fee; operator.snapshot.index += blockDiffFee; operator.snapshot.balance += blockDiffFee * operator.validatorCount; @@ -833,7 +1090,10 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { return operator.snapshot; } - function _transferOperatorBalanceUnsafe(uint64 operatorId, uint256 amount) private { + function _transferOperatorBalanceUnsafe( + uint64 operatorId, + uint256 amount + ) private { _token.transfer(msg.sender, amount); emit OperatorFundsWithdrawal(amount, operatorId, msg.sender); } @@ -842,10 +1102,23 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { /* Pod Private Functions */ /*************************/ - function _validateHashedPod(address owner, uint64[] memory operatorIds, Pod memory pod) private view returns (bytes32) { + function _validateHashedPod( + address owner, + uint64[] memory operatorIds, + Pod memory pod + ) private view returns (bytes32) { bytes32 hashedPod = keccak256(abi.encodePacked(owner, operatorIds)); { - bytes32 hashedPodData = keccak256(abi.encodePacked(pod.validatorCount, pod.networkFee, pod.networkFeeIndex, pod.index, pod.balance, pod.disabled )); + bytes32 hashedPodData = keccak256( + abi.encodePacked( + pod.validatorCount, + pod.networkFee, + pod.networkFeeIndex, + pod.index, + pod.balance, + pod.disabled + ) + ); if (_pods[hashedPod] == bytes32(0)) { revert PodNotExists(); } else if (_pods[hashedPod] != hashedPodData) { @@ -856,12 +1129,20 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { return hashedPod; } - function _updatePodData(Pod memory pod, uint64 podIndex, int8 changedTo) private view returns (Pod memory) { + function _updatePodData( + Pod memory pod, + uint64 podIndex, + int8 changedTo + ) private view returns (Pod memory) { if (!pod.disabled) { pod.balance = _podBalance(pod, podIndex); pod.index = podIndex; - pod.networkFee = _podNetworkFee(pod.networkFee, pod.networkFeeIndex, pod.validatorCount); + pod.networkFee = _podNetworkFee( + pod.networkFee, + pod.networkFeeIndex, + pod.validatorCount + ); pod.networkFeeIndex = _currentNetworkFeeIndex(); } @@ -874,15 +1155,27 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { return pod; } - function _liquidatable(uint64 balance, uint64 validatorCount, uint64 burnRate) private view returns (bool) { - return balance < _minimumBlocksBeforeLiquidation * (burnRate + _networkFee) * validatorCount; + function _liquidatable( + uint64 balance, + uint64 validatorCount, + uint64 burnRate + ) private view returns (bool) { + return + balance < + _minimumBlocksBeforeLiquidation * + (burnRate + _networkFee) * + validatorCount; } /*****************************/ /* Balance Private Functions */ /*****************************/ - function _deposit(address owner, uint64[] memory operatorIds, uint64 amount) private { + function _deposit( + address owner, + uint64[] memory operatorIds, + uint64 amount + ) private { _token.transferFrom(msg.sender, address(this), amount.expand()); emit FundsDeposit(amount.expand(), operatorIds, owner); } @@ -892,7 +1185,9 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _networkFeeIndexBlockNumber = uint64(block.number); } - function _updateDAOEarnings(DAO memory dao) private view returns (DAO memory) { + function _updateDAOEarnings( + DAO memory dao + ) private view returns (DAO memory) { dao.earnings.balance = _networkTotalEarnings(dao); dao.earnings.block = uint64(block.number); @@ -900,19 +1195,37 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } function _currentNetworkFeeIndex() private view returns (uint64) { - return _networkFeeIndex + uint64(block.number - _networkFeeIndexBlockNumber) * _networkFee; + return + _networkFeeIndex + + uint64(block.number - _networkFeeIndexBlockNumber) * + _networkFee; } - function _networkTotalEarnings(DAO memory dao) private view returns (uint64) { - return dao.earnings.balance + (uint64(block.number) - dao.earnings.block) * _networkFee * dao.validatorCount; + function _networkTotalEarnings( + DAO memory dao + ) private view returns (uint64) { + return + dao.earnings.balance + + (uint64(block.number) - dao.earnings.block) * + _networkFee * + dao.validatorCount; } function _networkBalance(DAO memory dao) private view returns (uint64) { return _networkTotalEarnings(dao) - dao.withdrawn; } - function _podBalance(Pod memory pod, uint64 newIndex) private view returns (uint64) { - uint64 usage = (newIndex - pod.index) * pod.validatorCount + _podNetworkFee(pod.networkFee, pod.networkFeeIndex, pod.validatorCount); + function _podBalance( + Pod memory pod, + uint64 newIndex + ) private view returns (uint64) { + uint64 usage = (newIndex - pod.index) * + pod.validatorCount + + _podNetworkFee( + pod.networkFee, + pod.networkFeeIndex, + pod.validatorCount + ); if (usage > pod.balance) { revert NegativeBalance(); @@ -921,7 +1234,14 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { return pod.balance - usage; } - function _podNetworkFee(uint64 networkFee, uint64 networkFeeIndex, uint32 validatorCount) private view returns (uint64) { - return networkFee + uint64(_currentNetworkFeeIndex() - networkFeeIndex) * validatorCount; + function _podNetworkFee( + uint64 networkFee, + uint64 networkFeeIndex, + uint32 validatorCount + ) private view returns (uint64) { + return + networkFee + + uint64(_currentNetworkFeeIndex() - networkFeeIndex) * + validatorCount; } -} \ No newline at end of file +} diff --git a/contracts/mocks/SSVTokenMock.sol b/contracts/mocks/SSVTokenMock.sol index c9044eed..e5284799 100644 --- a/contracts/mocks/SSVTokenMock.sol +++ b/contracts/mocks/SSVTokenMock.sol @@ -16,7 +16,8 @@ contract SSVTokenMock is Ownable, ERC20 { * @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); } -} \ No newline at end of file +} diff --git a/contracts/utils/Types.sol b/contracts/utils/Types.sol index b5ef29df..6899e167 100644 --- a/contracts/utils/Types.sol +++ b/contracts/utils/Types.sol @@ -5,18 +5,21 @@ pragma solidity ^0.8.2; uint256 constant DEDUCTED_DIGITS = 10000000; library Types64 { - function expand(uint64 value) internal pure returns (uint256) { - return value * DEDUCTED_DIGITS; - } + function expand(uint64 value) internal pure returns (uint256) { + return value * DEDUCTED_DIGITS; + } } library Types256 { - function shrink(uint256 value) internal pure returns (uint64) { - return uint64(shrinkable(value) / DEDUCTED_DIGITS); - } + function shrink(uint256 value) internal pure returns (uint64) { + return uint64(shrinkable(value) / DEDUCTED_DIGITS); + } - function shrinkable(uint256 value) internal pure returns (uint256) { - require(value % DEDUCTED_DIGITS == 0, "Precision is over the maximum defined"); - return value; - } -} \ No newline at end of file + function shrinkable(uint256 value) internal pure returns (uint256) { + require( + value % DEDUCTED_DIGITS == 0, + "Max precision exceeded" + ); + return value; + } +} diff --git a/package.json b/package.json index afe36864..6cea1bd1 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "devDependencies": { "@nomiclabs/hardhat-ethers": "^2.0.5", "@nomiclabs/hardhat-etherscan": "^3.0.3", - "@nomiclabs/hardhat-solhint": "^2.0.0", + "@nomiclabs/hardhat-solhint": "^3.0.0", "@nomiclabs/hardhat-waffle": "^2.0.3", "@openzeppelin/contracts": "4.6.0", "@openzeppelin/contracts-upgradeable": "4.6.0", diff --git a/test/dao/network-fee-change.ts b/test/dao/network-fee-change.ts index 8020512a..fdfd3b51 100644 --- a/test/dao/network-fee-change.ts +++ b/test/dao/network-fee-change.ts @@ -23,9 +23,9 @@ describe('Network Fee Tests', () => { expect(await ssvNetworkContract.getNetworkFee()).to.equal(0); }); - it('Change the network fee to a number below the minimum fee reverts "Precision is over the maximum defined"', async () => { + it('Change the network fee to a number below the minimum fee reverts "Max precision exceeded"', async () => { await expect(ssvNetworkContract.updateNetworkFee(networkFee - 1 - )).to.be.revertedWith('Precision is over the maximum defined'); + )).to.be.revertedWith('Max precision exceeded'); }); it('Change network fee from an address thats not the DAO reverts "caller is not the owner"', async () => { From b43dd3ab5c0e4c14f3c4234ff31cd0916b36d266 Mon Sep 17 00:00:00 2001 From: Wadym Date: Wed, 4 Jan 2023 11:50:29 +0100 Subject: [PATCH 111/149] list of gas optz changes IO1-1433 (#160) Small gas improvement & best practices fixs --- contracts/SSVNetwork.sol | 104 +++++++++++++++++++++++---------------- 1 file changed, 61 insertions(+), 43 deletions(-) diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index ca76c36e..04a5b477 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -187,14 +187,12 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } function declareOperatorFee(uint64 operatorId, uint256 fee) onlyOperatorOwnerOrContractOwner(operatorId) external override { - Operator memory operator = _operators[operatorId]; - if (fee < MINIMAL_OPERATOR_FEE) revert FeeTooLow(); uint64 shrunkFee = fee.shrink(); // @dev 100% = 10000, 10% = 1000 - using 10000 to represent 2 digit precision - uint64 maxAllowedFee = operator.fee * (10000 + _operatorMaxFeeIncrease) / 10000; + uint64 maxAllowedFee = _operators[operatorId].fee * (10000 + _operatorMaxFeeIncrease) / 10000; if (shrunkFee > maxAllowedFee) revert FeeExceedsIncreaseLimit(); @@ -221,9 +219,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } function cancelDeclaredOperatorFee(uint64 operatorId) onlyOperatorOwnerOrContractOwner(operatorId) external override { - OperatorFeeChangeRequest memory feeChangeRequest = _operatorFeeChangeRequests[operatorId]; - - if(feeChangeRequest.fee == 0) revert NoPendingFeeChangeRequest(); + if(_operatorFeeChangeRequests[operatorId].fee == 0) revert NoPendingFeeChangeRequest(); delete _operatorFeeChangeRequests[operatorId]; @@ -244,8 +240,10 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { uint256 amount, Pod memory pod ) external override { + uint operatorsLength = operatorIds.length; + { - _validateOperatorIds(operatorIds); + _validateOperatorIds(operatorsLength); _validatePublicKey(publicKey); } @@ -260,18 +258,22 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { uint64 burnRate; { if (!pod.disabled) { - for (uint8 i = 0; i < operatorIds.length; ++i) { + for (uint i; i < operatorsLength;) { + if (i+1 < operatorsLength) { + if (operatorIds[i] > operatorIds[i+1]) { + revert OperatorsListDoesNotSorted(); + } + } Operator memory operator = _operators[operatorIds[i]]; if (operator.snapshot.block == 0) { revert OperatorDoesNotExist(); - } else if (i+1 < operatorIds.length && operatorIds[i] > operatorIds[i+1]) { - revert OperatorsListDoesNotSorted(); } operator.snapshot = _getSnapshot(operator, uint64(block.number)); ++operator.validatorCount; podIndex += operator.snapshot.index; burnRate += operator.fee; _operators[operatorIds[i]] = operator; + unchecked { ++i; } } } } @@ -286,11 +288,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } } - if (amount > 0) { - _deposit(msg.sender, operatorIds, amount.shrink()); - pod.balance += amount.shrink(); - } - + pod.balance += amount.shrink(); pod = _updatePodData(pod, podIndex, 1); if (_liquidatable(_podBalance(pod, podIndex), pod.validatorCount, burnRate)) { @@ -308,6 +306,10 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _pods[hashedPod] = keccak256(abi.encodePacked(pod.validatorCount, pod.networkFee, pod.networkFeeIndex, pod.index, pod.balance, pod.disabled )); + if (amount > 0) { + _deposit(msg.sender, operatorIds, amount.shrink()); + } + emit ValidatorAdded(msg.sender, operatorIds, publicKey, shares, pod); } @@ -316,8 +318,10 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { uint64[] memory operatorIds, Pod memory pod ) external override { + uint operatorsLength = operatorIds.length; + { - _validateOperatorIds(operatorIds); + _validateOperatorIds(operatorsLength); _validatePublicKey(publicKey); } @@ -329,7 +333,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { uint64 podIndex; { if (!pod.disabled) { - for (uint8 i = 0; i < operatorIds.length; ++i) { + for (uint i; i < operatorsLength;) { Operator memory operator = _operators[operatorIds[i]]; if (operator.snapshot.block != 0) { operator.snapshot = _getSnapshot(operator, uint64(block.number)); @@ -338,6 +342,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } podIndex += operator.snapshot.index; + unchecked { ++i; } } } } @@ -373,7 +378,8 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { uint64 podIndex; uint64 burnRate; { - for (uint8 i = 0; i < operatorIds.length; ++i) { + uint operatorsLength = operatorIds.length; + for (uint i; i < operatorsLength;) { Operator memory operator = _operators[operatorIds[i]]; uint64 currentBlock = uint64(block.number); if (operator.snapshot.block != 0) { @@ -384,15 +390,17 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } podIndex += operator.snapshot.index; + unchecked { ++i; } } } { - if (!_liquidatable(_podBalance(pod, podIndex), pod.validatorCount, burnRate)) { + uint64 podBalance = _podBalance(pod, podIndex); + if (!_liquidatable(podBalance, pod.validatorCount, burnRate)) { revert PodNotLiquidatable(); } - _token.transfer(msg.sender, _podBalance(pod, podIndex).expand()); + _token.transfer(msg.sender, podBalance.expand()); pod.disabled = true; pod.balance = 0; @@ -424,7 +432,8 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { uint64 podIndex; uint64 burnRate; { - for (uint8 i = 0; i < operatorIds.length; ++i) { + uint operatorsLength = operatorIds.length; + for (uint i; i < operatorsLength;) { Operator memory operator = _operators[operatorIds[i]]; if (operator.snapshot.block != 0) { operator.snapshot = _getSnapshot(operator, uint64(block.number)); @@ -434,16 +443,13 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } podIndex += operator.snapshot.index; + unchecked { ++i; } } } bytes32 hashedPod = _validateHashedPod(msg.sender, operatorIds, pod); - if (amount > 0) { - _deposit(msg.sender, operatorIds, amount.shrink()); - pod.balance += amount.shrink(); - } - + pod.balance += amount.shrink(); pod.disabled = false; pod.index = podIndex; @@ -462,6 +468,10 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _pods[hashedPod] = keccak256(abi.encodePacked(pod.validatorCount, pod.networkFee, pod.networkFeeIndex, pod.index, pod.balance, pod.disabled )); + if (amount > 0) { + _deposit(msg.sender, operatorIds, amount.shrink()); + } + emit PodEnabled(msg.sender, operatorIds, pod); } @@ -471,7 +481,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { function deposit( address owner, - uint64[] memory operatorIds, + uint64[] calldata operatorIds, uint256 amount, Pod memory pod ) external override { @@ -483,15 +493,15 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { pod.balance += shrunkAmount; - _deposit(owner, operatorIds, shrunkAmount); - _pods[hashedPod] = keccak256(abi.encodePacked(pod.validatorCount, pod.networkFee, pod.networkFeeIndex, pod.index, pod.balance, pod.disabled )); + _deposit(owner, operatorIds, shrunkAmount); + emit PodDeposited(owner, operatorIds, pod); } function deposit( - uint64[] memory operatorIds, + uint64[] calldata operatorIds, uint256 amount, Pod memory pod ) external override { @@ -562,10 +572,12 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { uint64 podIndex; uint64 burnRate; { - for (uint8 i = 0; i < operatorIds.length; ++i) { + uint operatorsLength = operatorIds.length; + for (uint i; i < operatorsLength;) { Operator memory operator = _operators[operatorIds[i]]; podIndex += operator.snapshot.index + (uint64(block.number) - operator.snapshot.block) * operator.fee; burnRate += operator.fee; + unchecked { ++i; } } } @@ -573,16 +585,16 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { uint64 podBalance = _podBalance(pod, podIndex); - if (podBalance < shrunkAmount || _liquidatable(_podBalance(pod, podIndex), pod.validatorCount, burnRate)) { + if (podBalance < shrunkAmount || _liquidatable(podBalance, pod.validatorCount, burnRate)) { revert NotEnoughBalance(); } pod.balance -= shrunkAmount; - _token.transfer(msg.sender, amount); - _pods[hashedPod] = keccak256(abi.encodePacked(pod.validatorCount, pod.networkFee, pod.networkFeeIndex, pod.index, pod.balance, pod.disabled )); + _token.transfer(msg.sender, amount); + emit PodFundsWithdrawal(msg.sender, operatorIds, amount, pod); } @@ -675,15 +687,17 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { function isLiquidatable( address owner, - uint64[] memory operatorIds, + uint64[] calldata operatorIds, Pod memory pod ) external view override returns (bool) { uint64 podIndex; uint64 burnRate; - for (uint8 i = 0; i < operatorIds.length; ++i) { + uint operatorsLength = operatorIds.length; + for (uint i; i < operatorsLength;) { Operator memory operator = _operators[operatorIds[i]]; podIndex += operator.snapshot.index + (uint64(block.number) - operator.snapshot.block) * operator.fee; burnRate += operator.fee; + unchecked { ++i; } } _validateHashedPod(owner, operatorIds, pod); @@ -701,13 +715,15 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { return pod.disabled; } - function getPodBurnRate(uint64[] memory operatorIds) external view override returns (uint256) { + function getPodBurnRate(uint64[] calldata operatorIds) external view override returns (uint256) { uint64 burnRate; - for (uint8 i = 0; i < operatorIds.length; ++i) { + uint operatorsLength = operatorIds.length; + for (uint i; i < operatorsLength;) { Operator memory operator = _operators[operatorIds[i]]; if (operator.owner != address(0)) { burnRate += operator.fee; } + unchecked { ++i; } } return burnRate.expand(); } @@ -723,16 +739,18 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { function podBalanceOf( address owner, - uint64[] memory operatorIds, + uint64[] calldata operatorIds, Pod memory pod ) external view override returns (uint256) { _validatePodIsNotLiquidated(pod); uint64 podIndex; { - for (uint8 i = 0; i < operatorIds.length; ++i) { + uint operatorsLength = operatorIds.length; + for (uint i; i < operatorsLength;) { Operator memory operator = _operators[operatorIds[i]]; podIndex += operator.snapshot.index + (uint64(block.number) - operator.snapshot.block) * operator.fee; + unchecked { ++i; } } } @@ -786,14 +804,14 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } } - function _validatePublicKey(bytes memory publicKey) private pure { + function _validatePublicKey(bytes calldata publicKey) private pure { if (publicKey.length != 48) { revert InvalidPublicKeyLength(); } } - function _validateOperatorIds(uint64[] memory operatorIds) private pure { - if (operatorIds.length < 4 || operatorIds.length > 13 || operatorIds.length % 3 != 1) { + function _validateOperatorIds(uint operatorsLength) private pure { + if (operatorsLength < 4 || operatorsLength > 13 || operatorsLength % 3 != 1) { revert OperatorIdsStructureInvalid(); } } From ebcc4d0447d761ab2ce94c2ebafb475640cb6f5b Mon Sep 17 00:00:00 2001 From: Wadym Date: Tue, 10 Jan 2023 15:31:20 +0100 Subject: [PATCH 112/149] Extra names (#163) * extra func logic * wip * change all names * Fix misspelling * fix code issues * fix naming NoValidatorOwnership * extra deploy param * minor naming fixes * fix deposit params which are not used --- contracts/ISSVNetwork.sol | 163 ++++---- contracts/SSVNetwork.sol | 626 ++++++++++-------------------- scripts/deploy.ts | 3 +- test/account/deposit.ts | 30 +- test/account/withdraw.ts | 50 +-- test/dao/liquidation-threshold.ts | 8 +- test/dao/network-fee-change.ts | 8 +- test/dao/network-fee-withdraw.ts | 8 +- test/helpers/contract-helpers.ts | 28 +- test/liquidate/liquidate.ts | 118 +++--- test/liquidate/reactivate.ts | 46 +-- test/operators/others.ts | 6 +- test/operators/register.ts | 4 +- test/operators/remove.ts | 6 +- test/operators/update-fee.ts | 54 +-- test/sanity/balances.ts | 54 +-- test/validators/register.ts | 64 +-- test/validators/remove.ts | 66 ++-- 18 files changed, 557 insertions(+), 785 deletions(-) diff --git a/contracts/ISSVNetwork.sol b/contracts/ISSVNetwork.sol index b4ce4fa0..1e312055 100644 --- a/contracts/ISSVNetwork.sol +++ b/contracts/ISSVNetwork.sol @@ -4,7 +4,8 @@ pragma solidity ^0.8.2; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; interface ISSVNetwork { - struct Pod { + + struct Cluster { uint32 validatorCount; uint64 networkFee; uint64 networkFeeIndex; @@ -42,31 +43,31 @@ interface ISSVNetwork { * @param publicKey The public key of a validator. * @param operatorIds The operator ids list. * @param shares snappy compressed shares(a set of encrypted and public shares). - * @param pod All the pod data. + * @param cluster All the cluster data. */ event ValidatorAdded( - address ownerAddress, + address owner, uint64[] operatorIds, bytes publicKey, bytes shares, - Pod pod + Cluster cluster ); /** * @dev Emitted when the validator is removed. * @param publicKey The public key of a validator. * @param operatorIds The operator ids list. - * @param pod All the pod data. + * @param cluster All the cluster data. */ event ValidatorRemoved( - address ownerAddress, + address owner, uint64[] operatorIds, bytes publicKey, - Pod pod + Cluster cluster ); event OperatorFeeDeclaration( - address indexed ownerAddress, + address indexed owner, uint64 operatorId, uint256 blockNumber, uint256 fee @@ -79,68 +80,59 @@ interface ISSVNetwork { */ event OperatorFeeSet(uint64 id, uint64 fee); - event DeclaredOperatorFeeCancelation( - address indexed ownerAddress, - uint64 operatorId - ); + event OperatorFeeCancelationDeclared(address indexed owner, uint64 operatorId); /** * @dev Emitted when an operator's fee is updated. - * @param ownerAddress Operator's owner. + * @param owner Operator's owner. * @param blockNumber from which block number. * @param fee updated fee value. */ - event OperatorFeeExecution( - address indexed ownerAddress, + event OperatorFeeExecuted( + address indexed owner, uint64 operatorId, uint256 blockNumber, uint256 fee ); - event PodLiquidated(address ownerAddress, uint64[] operatorIds, Pod pod); + event ClusterLiquidated(address owner, uint64[] operatorIds, Cluster cluster); - event PodEnabled(address ownerAddress, uint64[] operatorIds, Pod pod); + event ClusterReactivated(address owner, uint64[] operatorIds, Cluster cluster); - event OperatorFeeIncreaseLimitUpdate(uint64 value); + event OperatorFeeIncreaseLimitUpdated(uint64 value); - event DeclareOperatorFeePeriodUpdate(uint64 value); + event DeclareOperatorFeePeriodUpdated(uint64 value); - event ExecuteOperatorFeePeriodUpdate(uint64 value); + event ExecuteOperatorFeePeriodUpdated(uint64 value); - event LiquidationThresholdPeriodUpdate(uint64 value); + event LiquidationThresholdPeriodUpdated(uint64 value); /** * @dev Emitted when the network fee is updated. * @param oldFee The old fee * @param newFee The new fee */ - event NetworkFeeUpdate(uint256 oldFee, uint256 newFee); + event NetworkFeeUpdated(uint256 oldFee, uint256 newFee); /** * @dev Emitted when transfer fees are withdrawn. * @param value The amount of tokens withdrawn. * @param recipient The recipient address. */ - event NetworkEarningsWithdrawal(uint256 value, address recipient); + event NetworkEarningsWithdrawn(uint256 value, address recipient); + + event ClusterWithdrawn(address owner, uint64[] operatorIds, uint256 value, Cluster cluster); + event OperatorWithdrawn(uint256 value, uint64 operatorId, address owner); - event PodFundsWithdrawal( - address ownerAddress, + event ClusterDeposit( + address owner, uint64[] operatorIds, uint256 value, - Pod pod - ); - event OperatorFundsWithdrawal( - uint256 value, - uint64 operatorId, - address ownerAddress + Cluster cluster ); - event FundsDeposit(uint256 value, uint64[] operatorIds, address owner); - - event PodDeposited(address ownerAddress, uint64[] operatorIds, Pod pod); - - event FeeRecipientAddressAdded( - address ownerAddress, + event FeeRecipientAddressUpdated( + address owner, address recipientAddress ); @@ -151,27 +143,26 @@ interface ISSVNetwork { error CallerNotOwner(); error FeeTooLow(); error FeeExceedsIncreaseLimit(); - error NoPendingFeeChangeRequest(); + error NoFeeDelcared(); error ApprovalNotWithinTimeframe(); - error OperatorWithPublicKeyNotExist(); - error OperatorNotFound(); error OperatorDoesNotExist(); - error NotEnoughBalance(); + error InsufficientBalance(); error ValidatorAlreadyExists(); - error PodLiquidatable(); - error PodNotLiquidatable(); + error ClusterLiquidatable(); + error ClusterNotLiquidatable(); error InvalidPublicKeyLength(); - error OperatorIdsStructureInvalid(); - error ValidatorNotOwned(); + error InvalidOperatorIdsLength(); + error NoValidatorOwnership(); error ParametersMismatch(); - error NegativeBalance(); - error PodAlreadyEnabled(); - error PodIsLiquidated(); - error PodNotExists(); + error InsufficientFunds(); + error ClusterAlreadyEnabled(); + error ClusterIsLiquidated(); + error ClusterDoesNotExists(); error BurnRatePositive(); - error PodDataIsBroken(); - error OperatorsListDoesNotSorted(); - error BelowMinimumBlockPeriod(); + error IncorrectClusterState(); + error UnsortedOperatorsList(); + error NewBlockPeriodIsBelowMinimum(); + error ExceedValidatorLimit(); /****************/ /* Initializers */ @@ -218,7 +209,7 @@ interface ISSVNetwork { function cancelDeclaredOperatorFee(uint64 operatorId) external; - function feeRecipientAddress(address feeRecipientAddress) external; + function setFeeRecipientAddress(address feeRecipientAddress) external; /********************************/ /* Validator External Functions */ @@ -227,31 +218,31 @@ interface ISSVNetwork { function registerValidator( bytes calldata publicKey, uint64[] memory operatorIds, - bytes calldata shares, + bytes calldata sharesEncrypted, uint256 amount, - Pod memory pod + Cluster memory cluster ) external; function removeValidator( bytes calldata publicKey, uint64[] memory operatorIds, - Pod memory pod + Cluster memory cluster ) external; /**************************/ - /* Pod External Functions */ + /* Cluster External Functions */ /**************************/ - function liquidatePod( - address ownerAddress, + function liquidate( + address owner, uint64[] memory operatorIds, - Pod memory pod + Cluster memory cluster ) external; - function reactivatePod( + function reactivate( uint64[] memory operatorIds, uint256 amount, - Pod memory pod + Cluster memory cluster ) external; /******************************/ @@ -262,26 +253,23 @@ interface ISSVNetwork { address owner, uint64[] memory operatorIds, uint256 amount, - Pod memory pod + Cluster memory cluster ) external; function deposit( uint64[] memory operatorIds, uint256 amount, - Pod memory pod + Cluster memory cluster ) external; - function withdrawOperatorBalance( - uint64 operatorId, - uint256 tokenAmount - ) external; + function withdrawOperatorEarnings(uint64 operatorId, uint256 tokenAmount) external; - function withdrawOperatorBalance(uint64 operatorId) external; + function withdrawOperatorEarnings(uint64 operatorId) external; - function withdrawPodBalance( + function withdraw( uint64[] memory operatorIds, uint256 tokenAmount, - Pod memory pod + Cluster memory cluster ) external; /**************************/ @@ -321,24 +309,22 @@ interface ISSVNetwork { ) external view returns (address owner, uint256 fee, uint32 validatorCount); /*******************************/ - /* Pod External View Functions */ + /* Cluster External View Functions */ /*******************************/ function isLiquidatable( - address ownerAddress, + address owner, uint64[] memory operatorIds, - Pod memory pod - ) external view returns (bool); + Cluster memory cluster + ) external view returns(bool); function isLiquidated( - address ownerAddress, + address owner, uint64[] memory operatorIds, - Pod memory pod - ) external view returns (bool); + Cluster memory cluster + ) external view returns(bool); - function getPodBurnRate( - uint64[] memory operatorIds - ) external view returns (uint256); + function getClusterBurnRate(uint64[] memory operatorIds) external view returns (uint256); /***********************************/ /* Balance External View Functions */ @@ -351,17 +337,12 @@ interface ISSVNetwork { * @return index the index of the operator. * @return balance the current balance of the operator. */ - function operatorSnapshot( - uint64 id - ) - external - view - returns (uint64 currentBlock, uint64 index, uint256 balance); - - function podBalanceOf( - address ownerAddress, + function getOperatorEarnings(uint64 id) external view returns (uint64 currentBlock, uint64 index, uint256 balance); + + function getBalance( + address owner, uint64[] memory operatorIds, - Pod memory pod + Cluster memory cluster ) external view returns (uint256); /*******************************/ diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index ad1f2680..7fdd0887 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -67,8 +67,9 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { /* Constants */ /*************/ - uint64 private constant MINIMAL_LIQUIDATION_THRESHOLD = 6570; - uint64 private constant MINIMAL_OPERATOR_FEE = 100000000; + uint64 constant MINIMAL_LIQUIDATION_THRESHOLD = 6570; + uint64 constant MINIMAL_OPERATOR_FEE = 100000000; + uint32 constant VALIDATORS_PER_OPERATOR_LIMIT = 2000; /********************/ /* Global Variables */ @@ -84,8 +85,8 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { mapping(uint64 => OperatorFeeChangeRequest) private _operatorFeeChangeRequests; // mapping(bytes32 => Cluster) private _clusters; - mapping(bytes32 => bytes32) private _pods; - mapping(bytes32 => Validator) private _validatorPKs; + mapping(bytes32 => bytes32) private _clusters; + mapping(bytes32 => Validator) _validatorPKs; uint64 private _networkFee; uint64 private _networkFeeIndex; @@ -133,7 +134,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { /*******************************/ function registerOperator( - bytes calldata encryptionPK, + bytes calldata publicKey, uint256 fee ) external override returns (uint64 id) { if (fee < MINIMAL_OPERATOR_FEE) { @@ -142,30 +143,18 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { lastOperatorId.increment(); id = uint64(lastOperatorId.current()); - _operators[id] = Operator({ - owner: msg.sender, - snapshot: Snapshot({ - block: uint64(block.number), - index: 0, - balance: 0 - }), - validatorCount: 0, - fee: fee.shrink() - }); - emit OperatorAdded(id, msg.sender, encryptionPK, fee); - } - - function removeOperator(uint64 operatorId) external override { - Operator memory operator = _operators[operatorId]; + _operators[id] = Operator({ owner: msg.sender, snapshot: Snapshot({ block: uint64(block.number), index: 0, balance: 0}), validatorCount: 0, fee: fee.shrink()}); + emit OperatorAdded(id, msg.sender, publicKey, fee); + } + + function removeOperator(uint64 id) external override { + Operator memory operator = _operators[id]; if (operator.owner != msg.sender) revert CallerNotOwner(); operator.snapshot = _getSnapshot(operator, uint64(block.number)); if (operator.snapshot.balance > 0) { - _transferOperatorBalanceUnsafe( - operatorId, - operator.snapshot.balance.expand() - ); + _transferOperatorBalanceUnsafe(id, operator.snapshot.balance.expand()); } operator.snapshot.block = 0; @@ -173,8 +162,8 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { operator.validatorCount = 0; operator.fee = 0; - _operators[operatorId] = operator; - emit OperatorRemoved(operatorId); + _operators[id] = operator; + emit OperatorRemoved(id); } function declareOperatorFee( @@ -207,7 +196,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { OperatorFeeChangeRequest memory feeChangeRequest = _operatorFeeChangeRequests[operatorId]; - if (feeChangeRequest.fee == 0) revert NoPendingFeeChangeRequest(); + if(feeChangeRequest.fee == 0) revert NoFeeDelcared(); if ( block.timestamp < feeChangeRequest.approvalBeginTime || @@ -221,19 +210,16 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { delete _operatorFeeChangeRequests[operatorId]; } - function cancelDeclaredOperatorFee( - uint64 operatorId - ) external override onlyOperatorOwnerOrContractOwner(operatorId) { - if (_operatorFeeChangeRequests[operatorId].fee == 0) - revert NoPendingFeeChangeRequest(); + function cancelDeclaredOperatorFee(uint64 operatorId) onlyOperatorOwnerOrContractOwner(operatorId) external override { + if(_operatorFeeChangeRequests[operatorId].fee == 0) revert NoFeeDelcared(); delete _operatorFeeChangeRequests[operatorId]; - emit DeclaredOperatorFeeCancelation(msg.sender, operatorId); + emit OperatorFeeCancelationDeclared(msg.sender, operatorId); } - function feeRecipientAddress(address recipientAddress) external override { - emit FeeRecipientAddressAdded(msg.sender, recipientAddress); + function setFeeRecipientAddress(address recipientAddress) external override { + emit FeeRecipientAddressUpdated(msg.sender, recipientAddress); } /********************************/ @@ -242,9 +228,9 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { function registerValidator( bytes calldata publicKey, uint64[] memory operatorIds, - bytes calldata shares, + bytes calldata sharesEncrypted, uint256 amount, - Pod memory pod + Cluster memory cluster ) external override { uint operatorsLength = operatorIds.length; @@ -263,26 +249,25 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { }); } - uint64 podIndex; + uint64 clusterIndex; uint64 burnRate; { - if (!pod.disabled) { - for (uint i; i < operatorsLength; ) { - if (i + 1 < operatorsLength) { - if (operatorIds[i] > operatorIds[i + 1]) { - revert OperatorsListDoesNotSorted(); + if (!cluster.disabled) { + for (uint i; i < operatorsLength;) { + if (i+1 < operatorsLength) { + if (operatorIds[i] > operatorIds[i+1]) { + revert UnsortedOperatorsList(); } } Operator memory operator = _operators[operatorIds[i]]; if (operator.snapshot.block == 0) { revert OperatorDoesNotExist(); } - operator.snapshot = _getSnapshot( - operator, - uint64(block.number) - ); - ++operator.validatorCount; - podIndex += operator.snapshot.index; + operator.snapshot = _getSnapshot(operator, uint64(block.number)); + if (++operator.validatorCount > VALIDATORS_PER_OPERATOR_LIMIT) { + revert ExceedValidatorLimit(); + } + clusterIndex += operator.snapshot.index; burnRate += operator.fee; _operators[operatorIds[i]] = operator; unchecked { @@ -292,49 +277,25 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } } - bytes32 hashedPod = keccak256( - abi.encodePacked(msg.sender, operatorIds) - ); + bytes32 hashedCluster = keccak256(abi.encodePacked(msg.sender, operatorIds)); { - bytes32 hashedPodData = keccak256( - abi.encodePacked( - pod.validatorCount, - pod.networkFee, - pod.networkFeeIndex, - pod.index, - pod.balance, - pod.disabled - ) - ); - if (_pods[hashedPod] == bytes32(0)) { - pod = Pod({ - validatorCount: 0, - networkFee: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - disabled: false - }); - } else if (_pods[hashedPod] != hashedPodData) { - revert PodDataIsBroken(); + bytes32 hashedClusterData = keccak256(abi.encodePacked(cluster.validatorCount, cluster.networkFee, cluster.networkFeeIndex, cluster.index, cluster.balance, cluster.disabled )); + if (_clusters[hashedCluster] == bytes32(0)) { + cluster = Cluster({ validatorCount: 0, networkFee: 0, networkFeeIndex: 0, index: 0, balance: 0, disabled: false }); + } else if (_clusters[hashedCluster] != hashedClusterData) { + revert IncorrectClusterState(); } } - pod.balance += amount.shrink(); - pod = _updatePodData(pod, podIndex, 1); + cluster.balance += amount.shrink(); + cluster = _updateClusterData(cluster, clusterIndex, 1); - if ( - _liquidatable( - _podBalance(pod, podIndex), - pod.validatorCount, - burnRate - ) - ) { - revert NotEnoughBalance(); + if (_liquidatable(_clusterBalance(cluster, clusterIndex), cluster.validatorCount, burnRate)) { + revert InsufficientBalance(); } { - if (!pod.disabled) { + if (!cluster.disabled) { DAO memory dao = _dao; dao = _updateDAOEarnings(dao); ++dao.validatorCount; @@ -342,28 +303,19 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } } - _pods[hashedPod] = keccak256( - abi.encodePacked( - pod.validatorCount, - pod.networkFee, - pod.networkFeeIndex, - pod.index, - pod.balance, - pod.disabled - ) - ); + _clusters[hashedCluster] = keccak256(abi.encodePacked(cluster.validatorCount, cluster.networkFee, cluster.networkFeeIndex, cluster.index, cluster.balance, cluster.disabled )); if (amount > 0) { - _deposit(msg.sender, operatorIds, amount.shrink()); + _deposit(amount.shrink()); } - emit ValidatorAdded(msg.sender, operatorIds, publicKey, shares, pod); + emit ValidatorAdded(msg.sender, operatorIds, publicKey, sharesEncrypted, cluster); } function removeValidator( bytes calldata publicKey, uint64[] memory operatorIds, - Pod memory pod + Cluster memory cluster ) external override { uint operatorsLength = operatorIds.length; @@ -374,13 +326,13 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { bytes32 hashedValidator = keccak256(publicKey); if (_validatorPKs[hashedValidator].owner != msg.sender) { - revert ValidatorNotOwned(); + revert NoValidatorOwnership(); } - uint64 podIndex; + uint64 clusterIndex; { - if (!pod.disabled) { - for (uint i; i < operatorsLength; ) { + if (!cluster.disabled) { + for (uint i; i < operatorsLength;) { Operator memory operator = _operators[operatorIds[i]]; if (operator.snapshot.block != 0) { operator.snapshot = _getSnapshot( @@ -390,21 +342,19 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { --operator.validatorCount; _operators[operatorIds[i]] = operator; } - - podIndex += operator.snapshot.index; - unchecked { - ++i; - } + + clusterIndex += operator.snapshot.index; + unchecked { ++i; } } } } - bytes32 hashedPod = _validateHashedPod(msg.sender, operatorIds, pod); + bytes32 hashedCluster = _validateHashedCluster(msg.sender, operatorIds, cluster); - pod = _updatePodData(pod, podIndex, -1); + cluster = _updateClusterData(cluster, clusterIndex, -1); { - if (!pod.disabled) { + if (!cluster.disabled) { DAO memory dao = _dao; dao = _updateDAOEarnings(dao); --dao.validatorCount; @@ -413,30 +363,21 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } delete _validatorPKs[hashedValidator]; - _pods[hashedPod] = keccak256( - abi.encodePacked( - pod.validatorCount, - pod.networkFee, - pod.networkFeeIndex, - pod.index, - pod.balance, - pod.disabled - ) - ); + _clusters[hashedCluster] = keccak256(abi.encodePacked(cluster.validatorCount, cluster.networkFee, cluster.networkFeeIndex, cluster.index, cluster.balance, cluster.disabled )); - emit ValidatorRemoved(msg.sender, operatorIds, publicKey, pod); + emit ValidatorRemoved(msg.sender, operatorIds, publicKey, cluster); } - function liquidatePod( + function liquidate( address owner, uint64[] memory operatorIds, - Pod memory pod + Cluster memory cluster ) external override { - _validatePodIsNotLiquidated(pod); + _validateClusterIsNotLiquidated(cluster); - bytes32 hashedPod = _validateHashedPod(owner, operatorIds, pod); + bytes32 hashedCluster = _validateHashedCluster(owner, operatorIds, cluster); - uint64 podIndex; + uint64 clusterIndex; uint64 burnRate; { uint operatorsLength = operatorIds.length; @@ -445,125 +386,95 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { uint64 currentBlock = uint64(block.number); if (operator.snapshot.block != 0) { operator.snapshot = _getSnapshot(operator, currentBlock); - operator.validatorCount -= pod.validatorCount; + operator.validatorCount -= cluster.validatorCount; burnRate += operator.fee; _operators[operatorIds[i]] = operator; } - - podIndex += operator.snapshot.index; - unchecked { - ++i; - } + + clusterIndex += operator.snapshot.index; + unchecked { ++i; } } } { - uint64 podBalance = _podBalance(pod, podIndex); - if (!_liquidatable(podBalance, pod.validatorCount, burnRate)) { - revert PodNotLiquidatable(); + uint64 clusterBalance = _clusterBalance(cluster, clusterIndex); + if (!_liquidatable(clusterBalance, cluster.validatorCount, burnRate)) { + revert ClusterNotLiquidatable(); } - _token.transfer(msg.sender, podBalance.expand()); + _token.transfer(msg.sender, clusterBalance.expand()); - pod.disabled = true; - pod.balance = 0; - pod.index = 0; + cluster.disabled = true; + cluster.balance = 0; + cluster.index = 0; } { DAO memory dao = _dao; dao = _updateDAOEarnings(dao); - dao.validatorCount -= pod.validatorCount; + dao.validatorCount -= cluster.validatorCount; _dao = dao; } - _pods[hashedPod] = keccak256( - abi.encodePacked( - pod.validatorCount, - pod.networkFee, - pod.networkFeeIndex, - pod.index, - pod.balance, - pod.disabled - ) - ); + _clusters[hashedCluster] = keccak256(abi.encodePacked(cluster.validatorCount, cluster.networkFee, cluster.networkFeeIndex, cluster.index, cluster.balance, cluster.disabled )); - emit PodLiquidated(owner, operatorIds, pod); + emit ClusterLiquidated(owner, operatorIds, cluster); } - function reactivatePod( + function reactivate( uint64[] memory operatorIds, uint256 amount, - Pod memory pod + Cluster memory cluster ) external override { - if (!pod.disabled) { - revert PodAlreadyEnabled(); + + if (!cluster.disabled) { + revert ClusterAlreadyEnabled(); } - uint64 podIndex; + uint64 clusterIndex; uint64 burnRate; { uint operatorsLength = operatorIds.length; for (uint i; i < operatorsLength; ) { Operator memory operator = _operators[operatorIds[i]]; if (operator.snapshot.block != 0) { - operator.snapshot = _getSnapshot( - operator, - uint64(block.number) - ); - operator.validatorCount += pod.validatorCount; + operator.snapshot = _getSnapshot(operator, uint64(block.number)); + operator.validatorCount += cluster.validatorCount; burnRate += operator.fee; _operators[operatorIds[i]] = operator; } - podIndex += operator.snapshot.index; - unchecked { - ++i; - } + clusterIndex += operator.snapshot.index; + unchecked { ++i; } } } - bytes32 hashedPod = _validateHashedPod(msg.sender, operatorIds, pod); + bytes32 hashedCluster = _validateHashedCluster(msg.sender, operatorIds, cluster); - pod.balance += amount.shrink(); - pod.disabled = false; - pod.index = podIndex; + cluster.balance += amount.shrink(); + cluster.disabled = false; + cluster.index = clusterIndex; - pod = _updatePodData(pod, podIndex, 0); + cluster = _updateClusterData(cluster, clusterIndex, 0); { DAO memory dao = _dao; dao = _updateDAOEarnings(dao); - dao.validatorCount += pod.validatorCount; + dao.validatorCount += cluster.validatorCount; _dao = dao; } - if ( - _liquidatable( - _podBalance(pod, podIndex), - pod.validatorCount, - burnRate - ) - ) { - revert NotEnoughBalance(); + if (_liquidatable(_clusterBalance(cluster, clusterIndex), cluster.validatorCount, burnRate)) { + revert InsufficientBalance(); } - _pods[hashedPod] = keccak256( - abi.encodePacked( - pod.validatorCount, - pod.networkFee, - pod.networkFeeIndex, - pod.index, - pod.balance, - pod.disabled - ) - ); + _clusters[hashedCluster] = keccak256(abi.encodePacked(cluster.validatorCount, cluster.networkFee, cluster.networkFeeIndex, cluster.index, cluster.balance, cluster.disabled )); if (amount > 0) { - _deposit(msg.sender, operatorIds, amount.shrink()); + _deposit(amount.shrink()); } - emit PodEnabled(msg.sender, operatorIds, pod); + emit ClusterReactivated(msg.sender, operatorIds, cluster); } /******************************/ @@ -574,65 +485,44 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { address owner, uint64[] calldata operatorIds, uint256 amount, - Pod memory pod + Cluster memory cluster ) external override { - _validatePodIsNotLiquidated(pod); + _validateClusterIsNotLiquidated(cluster); uint64 shrunkAmount = amount.shrink(); - bytes32 hashedPod = _validateHashedPod(owner, operatorIds, pod); + bytes32 hashedCluster = _validateHashedCluster(owner, operatorIds, cluster); - pod.balance += shrunkAmount; + cluster.balance += shrunkAmount; - _pods[hashedPod] = keccak256( - abi.encodePacked( - pod.validatorCount, - pod.networkFee, - pod.networkFeeIndex, - pod.index, - pod.balance, - pod.disabled - ) - ); + _clusters[hashedCluster] = keccak256(abi.encodePacked(cluster.validatorCount, cluster.networkFee, cluster.networkFeeIndex, cluster.index, cluster.balance, cluster.disabled )); - _deposit(owner, operatorIds, shrunkAmount); + _deposit(shrunkAmount); - emit PodDeposited(owner, operatorIds, pod); + emit ClusterDeposit(owner, operatorIds, amount, cluster); } function deposit( uint64[] calldata operatorIds, uint256 amount, - Pod memory pod + Cluster memory cluster ) external override { - _validatePodIsNotLiquidated(pod); + _validateClusterIsNotLiquidated(cluster); uint64 shrunkAmount = amount.shrink(); - bytes32 hashedPod = _validateHashedPod(msg.sender, operatorIds, pod); + bytes32 hashedCluster = _validateHashedCluster(msg.sender, operatorIds, cluster); - pod.balance += shrunkAmount; + cluster.balance += shrunkAmount; - _deposit(msg.sender, operatorIds, shrunkAmount); + _deposit(shrunkAmount); - _pods[hashedPod] = keccak256( - abi.encodePacked( - pod.validatorCount, - pod.networkFee, - pod.networkFeeIndex, - pod.index, - pod.balance, - pod.disabled - ) - ); + _clusters[hashedCluster] = keccak256(abi.encodePacked(cluster.validatorCount, cluster.networkFee, cluster.networkFeeIndex, cluster.index, cluster.balance, cluster.disabled )); - emit PodDeposited(msg.sender, operatorIds, pod); + emit ClusterDeposit(msg.sender, operatorIds, amount, cluster); } - function withdrawOperatorBalance( - uint64 operatorId, - uint256 amount - ) external override { + function withdrawOperatorEarnings(uint64 operatorId, uint256 amount) external override { Operator memory operator = _operators[operatorId]; if (operator.owner != msg.sender) revert CallerNotOwner(); @@ -642,7 +532,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { uint64 shrunkAmount = amount.shrink(); if (operator.snapshot.balance < shrunkAmount) { - revert NotEnoughBalance(); + revert InsufficientBalance(); } operator.snapshot.balance -= shrunkAmount; @@ -652,7 +542,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _transferOperatorBalanceUnsafe(operatorId, amount); } - function withdrawOperatorBalance(uint64 operatorId) external override { + function withdrawOperatorEarnings(uint64 operatorId) external override { Operator memory operator = _operators[operatorId]; if (operator.owner != msg.sender) revert CallerNotOwner(); @@ -662,7 +552,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { uint64 operatorBalance = operator.snapshot.balance; if (operatorBalance <= 0) { - revert NotEnoughBalance(); + revert InsufficientBalance(); } operator.snapshot.balance -= operatorBalance; @@ -672,25 +562,22 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _transferOperatorBalanceUnsafe(operatorId, operatorBalance.expand()); } - function withdrawPodBalance( + function withdraw( uint64[] memory operatorIds, uint256 amount, - Pod memory pod + Cluster memory cluster ) external override { - _validatePodIsNotLiquidated(pod); + _validateClusterIsNotLiquidated(cluster); uint64 shrunkAmount = amount.shrink(); - uint64 podIndex; + uint64 clusterIndex; uint64 burnRate; { uint operatorsLength = operatorIds.length; for (uint i; i < operatorsLength; ) { Operator memory operator = _operators[operatorIds[i]]; - podIndex += - operator.snapshot.index + - (uint64(block.number) - operator.snapshot.block) * - operator.fee; + clusterIndex += operator.snapshot.index + (uint64(block.number) - operator.snapshot.block) * operator.fee; burnRate += operator.fee; unchecked { ++i; @@ -698,37 +585,21 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } } - bytes32 hashedPod = _validateHashedPod(msg.sender, operatorIds, pod); + bytes32 hashedCluster = _validateHashedCluster(msg.sender, operatorIds, cluster); - uint64 podBalance = _podBalance(pod, podIndex); + uint64 clusterBalance = _clusterBalance(cluster, clusterIndex); - if ( - podBalance < shrunkAmount || - _liquidatable( - _podBalance(pod, podIndex), - pod.validatorCount, - burnRate - ) - ) { - revert NotEnoughBalance(); + if (clusterBalance < shrunkAmount || _liquidatable(clusterBalance, cluster.validatorCount, burnRate)) { + revert InsufficientBalance(); } - pod.balance -= shrunkAmount; - - _pods[hashedPod] = keccak256( - abi.encodePacked( - pod.validatorCount, - pod.networkFee, - pod.networkFeeIndex, - pod.index, - pod.balance, - pod.disabled - ) - ); + cluster.balance -= shrunkAmount; + + _clusters[hashedCluster] = keccak256(abi.encodePacked(cluster.validatorCount, cluster.networkFee, cluster.networkFeeIndex, cluster.index, cluster.balance, cluster.disabled )); _token.transfer(msg.sender, amount); - emit PodFundsWithdrawal(msg.sender, operatorIds, amount, pod); + emit ClusterWithdrawn(msg.sender, operatorIds, amount, cluster); } /**************************/ @@ -742,7 +613,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _updateNetworkFeeIndex(); - emit NetworkFeeUpdate(_networkFee.expand(), fee); + emit NetworkFeeUpdated(_networkFee.expand(), fee); _networkFee = fee.shrink(); } @@ -754,8 +625,8 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { uint64 shrunkAmount = amount.shrink(); - if (shrunkAmount > _networkBalance(dao)) { - revert NotEnoughBalance(); + if(shrunkAmount > _networkBalance(dao)) { + revert InsufficientBalance(); } dao.withdrawn += shrunkAmount; @@ -763,50 +634,45 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _token.transfer(msg.sender, amount); - emit NetworkEarningsWithdrawal(amount, msg.sender); + emit NetworkEarningsWithdrawn(amount, msg.sender); } function updateOperatorFeeIncreaseLimit( uint64 newOperatorMaxFeeIncrease ) external override onlyOwner { _operatorMaxFeeIncrease = newOperatorMaxFeeIncrease; - emit OperatorFeeIncreaseLimitUpdate(_operatorMaxFeeIncrease); + emit OperatorFeeIncreaseLimitUpdated(_operatorMaxFeeIncrease); } function updateDeclareOperatorFeePeriod( uint64 newDeclareOperatorFeePeriod ) external override onlyOwner { _declareOperatorFeePeriod = newDeclareOperatorFeePeriod; - emit DeclareOperatorFeePeriodUpdate(newDeclareOperatorFeePeriod); + emit DeclareOperatorFeePeriodUpdated(newDeclareOperatorFeePeriod); } function updateExecuteOperatorFeePeriod( uint64 newExecuteOperatorFeePeriod ) external override onlyOwner { _executeOperatorFeePeriod = newExecuteOperatorFeePeriod; - emit ExecuteOperatorFeePeriodUpdate(newExecuteOperatorFeePeriod); + emit ExecuteOperatorFeePeriodUpdated(newExecuteOperatorFeePeriod); } - function updateLiquidationThresholdPeriod( - uint64 blocks - ) external override onlyOwner { - if (blocks < MINIMAL_LIQUIDATION_THRESHOLD) { - revert BelowMinimumBlockPeriod(); + function updateLiquidationThresholdPeriod(uint64 blocks) external onlyOwner override { + if(blocks < MINIMAL_LIQUIDATION_THRESHOLD) { + revert NewBlockPeriodIsBelowMinimum(); } _minimumBlocksBeforeLiquidation = blocks; - emit LiquidationThresholdPeriodUpdate(blocks); + emit LiquidationThresholdPeriodUpdated(blocks); } /************************************/ /* Operator External View Functions */ /************************************/ - function getOperatorFee( - uint64 operatorId - ) external view override returns (uint256) { - if (_operators[operatorId].snapshot.block == 0) - revert OperatorNotFound(); + function getOperatorFee(uint64 operatorId) external view override returns (uint256) { + if (_operators[operatorId].snapshot.block == 0) revert OperatorDoesNotExist(); return _operators[operatorId].fee.expand(); } @@ -817,8 +683,8 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { OperatorFeeChangeRequest memory feeChangeRequest = _operatorFeeChangeRequests[operatorId]; - if (feeChangeRequest.fee == 0) { - revert NoPendingFeeChangeRequest(); + if(feeChangeRequest.fee == 0) { + revert NoFeeDelcared(); } return ( @@ -828,16 +694,8 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { ); } - function getOperatorById( - uint64 operatorId - ) - external - view - override - returns (address owner, uint256 fee, uint32 validatorCount) - { - if (_operators[operatorId].owner == address(0)) - revert OperatorNotFound(); + function getOperatorById(uint64 operatorId) external view override returns (address owner, uint256 fee, uint32 validatorCount) { + if (_operators[operatorId].owner == address(0)) revert OperatorDoesNotExist(); return ( _operators[operatorId].owner, @@ -846,53 +704,43 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { ); } - /*******************************/ - /* Pod External View Functions */ - /*******************************/ + /***********************************/ + /* Cluster External View Functions */ + /***********************************/ function isLiquidatable( address owner, uint64[] calldata operatorIds, - Pod memory pod + Cluster memory cluster ) external view override returns (bool) { - uint64 podIndex; + uint64 clusterIndex; uint64 burnRate; uint operatorsLength = operatorIds.length; for (uint i; i < operatorsLength; ) { Operator memory operator = _operators[operatorIds[i]]; - podIndex += - operator.snapshot.index + - (uint64(block.number) - operator.snapshot.block) * - operator.fee; + clusterIndex += operator.snapshot.index + (uint64(block.number) - operator.snapshot.block) * operator.fee; burnRate += operator.fee; unchecked { ++i; } } - _validateHashedPod(owner, operatorIds, pod); + _validateHashedCluster(owner, operatorIds, cluster); - return - _liquidatable( - _podBalance(pod, podIndex), - pod.validatorCount, - burnRate - ); + return _liquidatable(_clusterBalance(cluster, clusterIndex), cluster.validatorCount, burnRate); } function isLiquidated( address owner, uint64[] calldata operatorIds, - Pod memory pod + Cluster memory cluster ) external view override returns (bool) { - _validateHashedPod(owner, operatorIds, pod); + _validateHashedCluster(owner, operatorIds, cluster); - return pod.disabled; + return cluster.disabled; } - function getPodBurnRate( - uint64[] memory operatorIds - ) external view override returns (uint256) { + function getClusterBurnRate(uint64[] calldata operatorIds) external view override returns (uint256) { uint64 burnRate; uint operatorsLength = operatorIds.length; for (uint i; i < operatorsLength; ) { @@ -911,43 +759,31 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { /* Balance External View Functions */ /***********************************/ - function operatorSnapshot( - uint64 id - ) - external - view - override - returns (uint64 currentBlock, uint64 index, uint256 balance) - { + function getOperatorEarnings(uint64 id) external view override returns (uint64 currentBlock, uint64 index, uint256 balance) { Snapshot memory s = _getSnapshot(_operators[id], uint64(block.number)); return (s.block, s.index, s.balance.expand()); } - function podBalanceOf( + function getBalance( address owner, uint64[] calldata operatorIds, - Pod memory pod + Cluster memory cluster ) external view override returns (uint256) { - _validatePodIsNotLiquidated(pod); + _validateClusterIsNotLiquidated(cluster); - uint64 podIndex; + uint64 clusterIndex; { uint operatorsLength = operatorIds.length; for (uint i; i < operatorsLength; ) { Operator memory operator = _operators[operatorIds[i]]; - podIndex += - operator.snapshot.index + - (uint64(block.number) - operator.snapshot.block) * - operator.fee; - unchecked { - ++i; - } + clusterIndex += operator.snapshot.index + (uint64(block.number) - operator.snapshot.block) * operator.fee; + unchecked { ++i; } } } - _validateHashedPod(owner, operatorIds, pod); + _validateHashedCluster(owner, operatorIds, cluster); - return _podBalance(pod, podIndex).expand(); + return _clusterBalance(cluster, clusterIndex).expand(); } /*******************************/ @@ -1043,8 +879,8 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { function _onlyOperatorOwnerOrContractOwner(uint64 operatorId) private view { Operator memory operator = _operators[operatorId]; - if (operator.snapshot.block == 0) { - revert OperatorWithPublicKeyNotExist(); + if(operator.snapshot.block == 0) { + revert OperatorDoesNotExist(); } if (msg.sender != operator.owner && msg.sender != owner()) { @@ -1059,18 +895,14 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } function _validateOperatorIds(uint operatorsLength) private pure { - if ( - operatorsLength < 4 || - operatorsLength > 13 || - operatorsLength % 3 != 1 - ) { - revert OperatorIdsStructureInvalid(); + if (operatorsLength < 4 || operatorsLength > 13 || operatorsLength % 3 != 1) { + revert InvalidOperatorIdsLength(); } } - function _validatePodIsNotLiquidated(Pod memory pod) private pure { - if (pod.disabled) { - revert PodIsLiquidated(); + function _validateClusterIsNotLiquidated(Cluster memory cluster) private pure { + if (cluster.disabled) { + revert ClusterIsLiquidated(); } } @@ -1093,7 +925,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _operators[operatorId] = _setFee(operator, fee); - emit OperatorFeeExecution( + emit OperatorFeeExecuted( msg.sender, operatorId, block.number, @@ -1120,64 +952,43 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { uint256 amount ) private { _token.transfer(msg.sender, amount); - emit OperatorFundsWithdrawal(amount, operatorId, msg.sender); + emit OperatorWithdrawn(amount, operatorId, msg.sender); } - /*************************/ - /* Pod Private Functions */ - /*************************/ + /*****************************/ + /* Cluster Private Functions */ + /*****************************/ - function _validateHashedPod( - address owner, - uint64[] memory operatorIds, - Pod memory pod - ) private view returns (bytes32) { - bytes32 hashedPod = keccak256(abi.encodePacked(owner, operatorIds)); + function _validateHashedCluster(address owner, uint64[] memory operatorIds, Cluster memory cluster) private view returns (bytes32) { + bytes32 hashedCluster = keccak256(abi.encodePacked(owner, operatorIds)); { - bytes32 hashedPodData = keccak256( - abi.encodePacked( - pod.validatorCount, - pod.networkFee, - pod.networkFeeIndex, - pod.index, - pod.balance, - pod.disabled - ) - ); - if (_pods[hashedPod] == bytes32(0)) { - revert PodNotExists(); - } else if (_pods[hashedPod] != hashedPodData) { - revert PodDataIsBroken(); + bytes32 hashedClusterData = keccak256(abi.encodePacked(cluster.validatorCount, cluster.networkFee, cluster.networkFeeIndex, cluster.index, cluster.balance, cluster.disabled )); + if (_clusters[hashedCluster] == bytes32(0)) { + revert ClusterDoesNotExists(); + } else if (_clusters[hashedCluster] != hashedClusterData) { + revert IncorrectClusterState(); } } - return hashedPod; + return hashedCluster; } - function _updatePodData( - Pod memory pod, - uint64 podIndex, - int8 changedTo - ) private view returns (Pod memory) { - if (!pod.disabled) { - pod.balance = _podBalance(pod, podIndex); - pod.index = podIndex; + function _updateClusterData(Cluster memory cluster, uint64 clusterIndex, int8 changedTo) private view returns (Cluster memory) { + if (!cluster.disabled) { + cluster.balance = _clusterBalance(cluster, clusterIndex); + cluster.index = clusterIndex; - pod.networkFee = _podNetworkFee( - pod.networkFee, - pod.networkFeeIndex, - pod.validatorCount - ); - pod.networkFeeIndex = _currentNetworkFeeIndex(); + cluster.networkFee = _clusterNetworkFee(cluster.networkFee, cluster.networkFeeIndex, cluster.validatorCount); + cluster.networkFeeIndex = _currentNetworkFeeIndex(); } if (changedTo == 1) { - ++pod.validatorCount; + ++cluster.validatorCount; } else if (changedTo == -1) { - --pod.validatorCount; + --cluster.validatorCount; } - return pod; + return cluster; } function _liquidatable( @@ -1196,13 +1007,8 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { /* Balance Private Functions */ /*****************************/ - function _deposit( - address owner, - uint64[] memory operatorIds, - uint64 amount - ) private { + function _deposit(uint64 amount) private { _token.transferFrom(msg.sender, address(this), amount.expand()); - emit FundsDeposit(amount.expand(), operatorIds, owner); } function _updateNetworkFeeIndex() private { @@ -1240,33 +1046,17 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { return _networkTotalEarnings(dao) - dao.withdrawn; } - function _podBalance( - Pod memory pod, - uint64 newIndex - ) private view returns (uint64) { - uint64 usage = (newIndex - pod.index) * - pod.validatorCount + - _podNetworkFee( - pod.networkFee, - pod.networkFeeIndex, - pod.validatorCount - ); - - if (usage > pod.balance) { - revert NegativeBalance(); + function _clusterBalance(Cluster memory cluster, uint64 newIndex) private view returns (uint64) { + uint64 usage = (newIndex - cluster.index) * cluster.validatorCount + _clusterNetworkFee(cluster.networkFee, cluster.networkFeeIndex, cluster.validatorCount); + + if (usage > cluster.balance) { + revert InsufficientFunds(); } - return pod.balance - usage; + return cluster.balance - usage; } - function _podNetworkFee( - uint64 networkFee, - uint64 networkFeeIndex, - uint32 validatorCount - ) private view returns (uint64) { - return - networkFee + - uint64(_currentNetworkFeeIndex() - networkFeeIndex) * - validatorCount; + function _clusterNetworkFee(uint64 networkFee, uint64 networkFeeIndex, uint32 validatorCount) private view returns (uint64) { + return networkFee + uint64(_currentNetworkFeeIndex() - networkFeeIndex) * validatorCount; } } diff --git a/scripts/deploy.ts b/scripts/deploy.ts index 24f33a46..4b2a2ffb 100644 --- a/scripts/deploy.ts +++ b/scripts/deploy.ts @@ -8,7 +8,8 @@ async function main() { ssvTokenAddress, process.env.OPERATOR_MAX_FEE_INCREASE, process.env.DECLARE_OPERATOR_FEE_PERIOD, - process.env.EXECUTE_OPERATOR_FEE_PERIOD + process.env.EXECUTE_OPERATOR_FEE_PERIOD, + process.env.MINIMAL_BLOCKS_BEFORE_LIQUIDATION, ]); await contract.deployed(); console.log(`SSVNetwork deployed to: ${contract.address}`); diff --git a/test/account/deposit.ts b/test/account/deposit.ts index 1d47e6d1..0dde686a 100644 --- a/test/account/deposit.ts +++ b/test/account/deposit.ts @@ -4,7 +4,7 @@ import { expect } from 'chai'; import { trackGas, GasGroup } from '../helpers/gas-usage'; // Declare globals -let ssvNetworkContract: any, pod1: any, minDepositAmount: any; +let ssvNetworkContract: any, cluster1: any, minDepositAmount: any; describe('Deposit Tests', () => { beforeEach(async () => { @@ -34,34 +34,34 @@ describe('Deposit Tests', () => { ); // Register validators - pod1 = 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]); }); - it('Deposit to a pod I own emits "FundsDeposit', async () => { + it('Deposit to a cluster I own emits "ClusterDeposit', async () => { await helpers.DB.ssvToken.connect(helpers.DB.owners[4]).approve(ssvNetworkContract.address, minDepositAmount); - await expect(ssvNetworkContract.connect(helpers.DB.owners[4])['deposit(uint64[],uint256,(uint32,uint64,uint64,uint64,uint64,bool))'](pod1.args.operatorIds, minDepositAmount, pod1.args.pod)).to.emit(ssvNetworkContract, 'FundsDeposit'); + await expect(ssvNetworkContract.connect(helpers.DB.owners[4])['deposit(uint64[],uint256,(uint32,uint64,uint64,uint64,uint64,bool))'](cluster1.args.operatorIds, minDepositAmount, cluster1.args.cluster)).to.emit(ssvNetworkContract, 'ClusterDeposit'); }); - it('Deposit to a pod I own gas limits', async () => { + 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(uint64[],uint256,(uint32,uint64,uint64,uint64,uint64,bool))'](pod1.args.operatorIds, minDepositAmount, pod1.args.pod), [GasGroup.DEPOSIT]); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4])['deposit(uint64[],uint256,(uint32,uint64,uint64,uint64,uint64,bool))'](cluster1.args.operatorIds, minDepositAmount, cluster1.args.cluster), [GasGroup.DEPOSIT]); }); - it('Deposit to a pod I do not own emits "FundsDeposit"', async () => { + it('Deposit to a cluster I do not own emits "ClusterDeposit"', async () => { await helpers.DB.ssvToken.connect(helpers.DB.owners[0]).approve(ssvNetworkContract.address, minDepositAmount); - await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['deposit(address,uint64[],uint256,(uint32,uint64,uint64,uint64,uint64,bool))'](helpers.DB.owners[4].address, pod1.args.operatorIds, minDepositAmount, pod1.args.pod)).to.emit(ssvNetworkContract, 'FundsDeposit'); + await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['deposit(address,uint64[],uint256,(uint32,uint64,uint64,uint64,uint64,bool))'](helpers.DB.owners[4].address, cluster1.args.operatorIds, minDepositAmount, cluster1.args.cluster)).to.emit(ssvNetworkContract, 'ClusterDeposit'); }); - it('Deposit to a pod I do not own gas limits', async () => { + 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(address,uint64[],uint256,(uint32,uint64,uint64,uint64,uint64,bool))'](helpers.DB.owners[4].address, pod1.args.operatorIds, minDepositAmount, pod1.args.pod), [GasGroup.DEPOSIT]); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[0])['deposit(address,uint64[],uint256,(uint32,uint64,uint64,uint64,uint64,bool))'](helpers.DB.owners[4].address, cluster1.args.operatorIds, minDepositAmount, cluster1.args.cluster), [GasGroup.DEPOSIT]); }); - it('Deposit to a pod I do own with a pod that does not exist reverts "PodNotExists"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[1])['deposit(uint64[],uint256,(uint32,uint64,uint64,uint64,uint64,bool))'](pod1.args.operatorIds, minDepositAmount, pod1.args.pod)).to.be.revertedWith('PodNotExists'); + 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(uint64[],uint256,(uint32,uint64,uint64,uint64,uint64,bool))'](cluster1.args.operatorIds, minDepositAmount, cluster1.args.cluster)).to.be.revertedWith('ClusterDoesNotExists'); }); - it('Deposit to a pod I do not own with a pod that does not exist reverts "PodNotExists"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[4])['deposit(uint64[],uint256,(uint32,uint64,uint64,uint64,uint64,bool))']([1,2,4,5], minDepositAmount, pod1.args.pod)).to.be.revertedWith('PodNotExists'); + 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(uint64[],uint256,(uint32,uint64,uint64,uint64,uint64,bool))']([1,2,4,5], minDepositAmount, cluster1.args.cluster)).to.be.revertedWith('ClusterDoesNotExists'); }); -}); \ No newline at end of file +}); diff --git a/test/account/withdraw.ts b/test/account/withdraw.ts index 0004f719..24c14d52 100644 --- a/test/account/withdraw.ts +++ b/test/account/withdraw.ts @@ -5,7 +5,7 @@ import { expect } from 'chai'; import { trackGas, GasGroup } from '../helpers/gas-usage'; // Declare globals -let ssvNetworkContract: any, pod1: any, minDepositAmount: any; +let ssvNetworkContract: any, cluster1: any, minDepositAmount: any; describe('Withdraw Tests', () => { beforeEach(async () => { @@ -35,61 +35,61 @@ describe('Withdraw Tests', () => { } ); - pod1 = 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]); }); - it('Withdraw from pod emits "PodFundsWithdrawal"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).withdrawPodBalance(pod1.args.operatorIds, helpers.CONFIG.minimalOperatorFee, pod1.args.pod)).to.emit(ssvNetworkContract, 'PodFundsWithdrawal'); + it('Withdraw from cluster emits "ClusterWithdrawn"', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).withdraw(cluster1.args.operatorIds, helpers.CONFIG.minimalOperatorFee, cluster1.args.cluster)).to.emit(ssvNetworkContract, 'ClusterWithdrawn'); }); - it('Withdraw from pod gas limits', async () => { - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).withdrawPodBalance(pod1.args.operatorIds, helpers.CONFIG.minimalOperatorFee, pod1.args.pod), [GasGroup.WITHDRAW_POD_BALANCE]); + it('Withdraw from cluster gas limits', async () => { + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4]).withdraw(cluster1.args.operatorIds, helpers.CONFIG.minimalOperatorFee, cluster1.args.cluster), [GasGroup.WITHDRAW_POD_BALANCE]); }); - it('Withdraw from operator balance emits "OperatorFundsWithdrawal"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorBalance(uint64,uint256)'](1, helpers.CONFIG.minimalOperatorFee)).to.emit(ssvNetworkContract, 'OperatorFundsWithdrawal'); + it('Withdraw from operator balance emits "OperatorWithdrawn"', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorEarnings(uint64,uint256)'](1, helpers.CONFIG.minimalOperatorFee)).to.emit(ssvNetworkContract, 'OperatorWithdrawn'); }); it('Withdraw from operator balance gas limits', async () => { - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorBalance(uint64,uint256)'](1, helpers.CONFIG.minimalOperatorFee), [GasGroup.WITHDRAW_OPERATOR_BALANCE]); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorEarnings(uint64,uint256)'](1, helpers.CONFIG.minimalOperatorFee), [GasGroup.WITHDRAW_OPERATOR_BALANCE]); }); - it('Withdraw the total operator balance emits "OperatorFundsWithdrawal"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorBalance(uint64)'](1)).to.emit(ssvNetworkContract, 'OperatorFundsWithdrawal'); + it('Withdraw the total operator balance emits "OperatorWithdrawn"', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorEarnings(uint64)'](1)).to.emit(ssvNetworkContract, 'OperatorWithdrawn'); }); it('Withdraw the total operator balance gas limits', async () => { - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorBalance(uint64)'](1), [GasGroup.WITHDRAW_OPERATOR_BALANCE]); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorEarnings(uint64)'](1), [GasGroup.WITHDRAW_OPERATOR_BALANCE]); }); - it('Withdraw from a pod that has a removed operator emits "PodFundsWithdrawal"', async () => { + 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]).withdrawPodBalance(pod1.args.operatorIds, helpers.CONFIG.minimalOperatorFee, pod1.args.pod)).to.emit(ssvNetworkContract, 'PodFundsWithdrawal'); + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).withdraw(cluster1.args.operatorIds, helpers.CONFIG.minimalOperatorFee, cluster1.args.cluster)).to.emit(ssvNetworkContract, 'ClusterWithdrawn'); }); - it('Withdraw more than the pod balance reverts "NotEnoughBalance"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).withdrawPodBalance(pod1.args.operatorIds, minDepositAmount, pod1.args.pod)).to.be.revertedWith('NotEnoughBalance'); + it('Withdraw more than the cluster balance reverts "InsufficientBalance"', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).withdraw(cluster1.args.operatorIds, minDepositAmount, cluster1.args.cluster)).to.be.revertedWith('InsufficientBalance'); }); - it('Withdraw from a liquidatable pod reverts "NotEnoughBalance"', async () => { + it('Withdraw from a liquidatable cluster reverts "InsufficientBalance"', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).withdrawPodBalance(pod1.args.operatorIds, helpers.CONFIG.minimalOperatorFee, pod1.args.pod)).to.be.revertedWith('NotEnoughBalance'); + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).withdraw(cluster1.args.operatorIds, helpers.CONFIG.minimalOperatorFee, cluster1.args.cluster)).to.be.revertedWith('InsufficientBalance'); }); it('Withdraw balance from an operator I do not own reverts "CallerNotOwner"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[2])['withdrawOperatorBalance(uint64,uint256)'](1, minDepositAmount)).to.be.revertedWith('CallerNotOwner'); + await expect(ssvNetworkContract.connect(helpers.DB.owners[2])['withdrawOperatorEarnings(uint64,uint256)'](1, minDepositAmount)).to.be.revertedWith('CallerNotOwner'); }); - it('Withdraw more than the operator balance reverts "NotEnoughBalance"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorBalance(uint64,uint256)'](1, minDepositAmount - )).to.be.revertedWith('NotEnoughBalance'); + it('Withdraw more than the operator balance reverts "InsufficientBalance"', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorEarnings(uint64,uint256)'](1, minDepositAmount + )).to.be.revertedWith('InsufficientBalance'); }); it('Withdraw the total balance from an operator I do not own reverts "CallerNotOwner"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[2])['withdrawOperatorBalance(uint64)'](12)).to.be.revertedWith('CallerNotOwner'); + await expect(ssvNetworkContract.connect(helpers.DB.owners[2])['withdrawOperatorEarnings(uint64)'](12)).to.be.revertedWith('CallerNotOwner'); }); - it('Withdraw more than the operator total balance reverts "NotEnoughBalance"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorBalance(uint64)'](12)).to.be.revertedWith('NotEnoughBalance'); + it('Withdraw more than the operator total balance reverts "InsufficientBalance"', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorEarnings(uint64)'](12)).to.be.revertedWith('InsufficientBalance'); }); }); diff --git a/test/dao/liquidation-threshold.ts b/test/dao/liquidation-threshold.ts index 7047d61b..b03f6bc5 100644 --- a/test/dao/liquidation-threshold.ts +++ b/test/dao/liquidation-threshold.ts @@ -14,16 +14,16 @@ describe('Liquidation Threshold Tests', () => { networkFee = helpers.CONFIG.minimalOperatorFee / 10; }); - it('Change liquidation threshold period emits "LiquidationThresholdPeriodUpdate"', async () => { - await expect(ssvNetworkContract.updateLiquidationThresholdPeriod(helpers.CONFIG.minimalBlocksBeforeLiquidation + 10)).to.emit(ssvNetworkContract, 'LiquidationThresholdPeriodUpdate').withArgs(helpers.CONFIG.minimalBlocksBeforeLiquidation + 10); + it('Change liquidation threshold period emits "LiquidationThresholdPeriodUpdated"', async () => { + await expect(ssvNetworkContract.updateLiquidationThresholdPeriod(helpers.CONFIG.minimalBlocksBeforeLiquidation + 10)).to.emit(ssvNetworkContract, 'LiquidationThresholdPeriodUpdated').withArgs(helpers.CONFIG.minimalBlocksBeforeLiquidation + 10); }); it('Get liquidation threshold period', async () => { expect(await ssvNetworkContract.getLiquidationThresholdPeriod()).to.equal(helpers.CONFIG.minimalBlocksBeforeLiquidation); }); - it('Change liquidation threshold period reverts "BelowMinimumBlockPeriod"', async () => { - await expect(ssvNetworkContract.updateLiquidationThresholdPeriod(helpers.CONFIG.minimalBlocksBeforeLiquidation - 10)).to.be.revertedWith('BelowMinimumBlockPeriod'); + it('Change liquidation threshold period reverts "NewBlockPeriodIsBelowMinimum"', async () => { + await expect(ssvNetworkContract.updateLiquidationThresholdPeriod(helpers.CONFIG.minimalBlocksBeforeLiquidation - 10)).to.be.revertedWith('NewBlockPeriodIsBelowMinimum'); }); it('Change liquidation threshold period reverts "caller is not the owner"', async () => { diff --git a/test/dao/network-fee-change.ts b/test/dao/network-fee-change.ts index fdfd3b51..4606ea80 100644 --- a/test/dao/network-fee-change.ts +++ b/test/dao/network-fee-change.ts @@ -13,10 +13,10 @@ describe('Network Fee Tests', () => { // Define minumum allowed network fee to pass shrinkable validation networkFee = helpers.CONFIG.minimalOperatorFee / 10; }); - - it('Change network fee emits "NetworkFeeUpdate"', async () => { + + it('Change network fee emits "NetworkFeeUpdated"', async () => { await expect(ssvNetworkContract.updateNetworkFee(networkFee - )).to.emit(ssvNetworkContract, 'NetworkFeeUpdate').withArgs(0, networkFee); + )).to.emit(ssvNetworkContract, 'NetworkFeeUpdated').withArgs(0, networkFee); }); it('Get network fee', async () => { @@ -32,4 +32,4 @@ describe('Network Fee Tests', () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[3]).updateNetworkFee(networkFee )).to.be.revertedWith('caller is not the owner'); }); -}); \ No newline at end of file +}); diff --git a/test/dao/network-fee-withdraw.ts b/test/dao/network-fee-withdraw.ts index 91ac7e75..8d38b8c9 100644 --- a/test/dao/network-fee-withdraw.ts +++ b/test/dao/network-fee-withdraw.ts @@ -53,10 +53,10 @@ describe('DAO Network Fee Withdraw Tests', () => { await helpers.DB.ssvToken.mint(ssvNetworkContract.address, minDepositAmount); }); - it('Withdraw network earnings emits "NetworkEarningsWithdrawal"', async () => { + it('Withdraw network earnings emits "NetworkEarningsWithdrawn"', async () => { const amount = await ssvNetworkContract.getNetworkEarnings(); await expect(ssvNetworkContract.withdrawNetworkEarnings(amount - )).to.emit(ssvNetworkContract, 'NetworkEarningsWithdrawal').withArgs(amount, helpers.DB.owners[0].address); + )).to.emit(ssvNetworkContract, 'NetworkEarningsWithdrawn').withArgs(amount, helpers.DB.owners[0].address); }); it('Get withdrawable network earnings', async () => { @@ -67,10 +67,10 @@ describe('DAO Network Fee Withdraw Tests', () => { await ssvNetworkContract.connect(helpers.DB.owners[3]).getNetworkEarnings(); }); - it('Withdraw network earnings with not enough balance reverts "NotEnoughBalance"', async () => { + it('Withdraw network earnings with not enough balance reverts "InsufficientBalance"', async () => { const amount = await ssvNetworkContract.getNetworkEarnings() * 2; await expect(ssvNetworkContract.withdrawNetworkEarnings(amount - )).to.be.revertedWith('NotEnoughBalance'); + )).to.be.revertedWith('InsufficientBalance'); }); it('Withdraw network earnings from an address thats not the DAO reverts "caller is not the owner"', async () => { diff --git a/test/helpers/contract-helpers.ts b/test/helpers/contract-helpers.ts index 29c24d1a..df8720d0 100644 --- a/test/helpers/contract-helpers.ts +++ b/test/helpers/contract-helpers.ts @@ -139,37 +139,37 @@ export const registerValidators = async (ownerId: number, numberOfValidators: nu return { validators, args }; }; -export const getPod = (payload: any) => ethers.utils.AbiCoder.prototype.encode( - ['tuple(uint32 validatorCount, uint64 networkFee, uint64 networkFeeIndex, uint64 index, uint64 balance, bool disabled) pod'], +export const getCluster = (payload: any) => ethers.utils.AbiCoder.prototype.encode( + ['tuple(uint32 validatorCount, uint64 networkFee, uint64 networkFeeIndex, uint64 index, uint64 balance, bool disabled) cluster'], [ payload ] ); /* export const transferValidator = async (ownerId: number, publicKey: string, operatorIds: number[], amount: string, gasGroups?: GasGroup[]) => { - // let podId: any; + // let clusterId: any; const shares = DataGenerator.shares(DB.validators.length); // Transfer validator await trackGas(DB.ssvNetwork.contract.connect(DB.owners[ownerId]).transferValidator( publicKey, - (await registerPodAndDeposit(ownerId, operatorIds, amount)).clusterId, + (await registerClusterAndDeposit(ownerId, operatorIds, amount)).clusterId, shares, ), gasGroups); // FOR ADAM TO UPDATE - // podId = eventsByName.ValidatorTransferred[0].args.podId; - // DB.clusters[podId] = ({ id: podId, operatorIds }); - // DB.validators[publicKey].podId = podId; + // clusterId = eventsByName.ValidatorTransferred[0].args.clusterId; + // DB.clusters[clusterId] = ({ id: clusterId, operatorIds }); + // DB.validators[publicKey].clusterId = clusterId; // DB.validators[publicKey].shares = shares; - // return { podId }; + // return { clusterId }; }; export const bulkTransferValidator = async (ownerId: number, publicKey: string[], fromCluster: string, toCluster: string, amount: string, gasGroups?: GasGroup[]) => { const shares = Array(publicKey.length).fill(DataGenerator.shares(0)); - await registerPodAndDeposit(ownerId, DataGenerator.cluster.byId(toCluster), amount); + await registerClusterAndDeposit(ownerId, DataGenerator.cluster.byId(toCluster), amount); // Bulk transfer validators await trackGas(DB.ssvNetwork.contract.connect(DB.owners[ownerId]).bulkTransferValidators( @@ -180,18 +180,18 @@ export const bulkTransferValidator = async (ownerId: number, publicKey: string[] ), gasGroups); // FOR ADAM TO UPDATE - // podId = eventsByName.ValidatorTransferred[0].args.podId; - // DB.clusters[podId] = ({ id: podId, operatorIds }); - // DB.validators[publicKey].podId = podId; + // clusterId = eventsByName.ValidatorTransferred[0].args.clusterId; + // DB.clusters[clusterId] = ({ id: clusterId, operatorIds }); + // DB.validators[publicKey].clusterId = clusterId; // DB.validators[publicKey].shares = shares; - // return { podId }; + // return { clusterId }; }; export const liquidate = async (executorOwnerId: number, liquidatedOwnerId: number, operatorIds: number[], gasGroups?: GasGroup[]) => { const { eventsByName } = await trackGas(DB.ssvNetwork.contract.connect(DB.owners[executorOwnerId]).liquidate( DB.owners[liquidatedOwnerId].address, - await DB.ssvNetwork.contract.getPod(operatorIds), + await DB.ssvNetwork.contract.getCluster(operatorIds), ), gasGroups); const clusterId = eventsByName.AccountLiquidated[0].args.clusterId; diff --git a/test/liquidate/liquidate.ts b/test/liquidate/liquidate.ts index e5be36f1..be746e35 100644 --- a/test/liquidate/liquidate.ts +++ b/test/liquidate/liquidate.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, minDepositAmount: any, firstPod: any; +let ssvNetworkContract: any, minDepositAmount: any, firstCluster: any; describe('Liquidate Tests', () => { beforeEach(async () => { @@ -49,71 +49,71 @@ describe('Liquidate Tests', () => { disabled: false } ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); - firstPod = register.eventsByName.ValidatorAdded[0].args; + firstCluster = register.eventsByName.ValidatorAdded[0].args; }); - it('Get if the pod is liquidatable', async () => { + it('Get if the cluster is liquidatable', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - expect(await ssvNetworkContract.isLiquidatable(firstPod.ownerAddress, firstPod.operatorIds, firstPod.pod)).to.equal(true); + expect(await ssvNetworkContract.isLiquidatable(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster)).to.equal(true); }); it('Liquidatable with removed operator', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); await ssvNetworkContract.removeOperator(1); - expect(await ssvNetworkContract.isLiquidatable(firstPod.ownerAddress, firstPod.operatorIds, firstPod.pod)).to.equal(true); + expect(await ssvNetworkContract.isLiquidatable(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster)).to.equal(true); }); - it('Liquidate emits PodLiquidated event', async () => { + it('Liquidate emits ClusterLiquidated event', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - await expect(ssvNetworkContract.liquidatePod( - firstPod.ownerAddress, - firstPod.operatorIds, - firstPod.pod - )).to.emit(ssvNetworkContract, 'PodLiquidated'); + await expect(ssvNetworkContract.liquidate( + firstCluster.owner, + firstCluster.operatorIds, + firstCluster.cluster + )).to.emit(ssvNetworkContract, 'ClusterLiquidated'); }); - it('Liquidate validator with removed operator in a pod', async () => { + it('Liquidate validator with removed operator in a cluster', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); await ssvNetworkContract.removeOperator(1); - await trackGas(ssvNetworkContract.liquidatePod( - firstPod.ownerAddress, - firstPod.operatorIds, - firstPod.pod + await trackGas(ssvNetworkContract.liquidate( + firstCluster.owner, + firstCluster.operatorIds, + firstCluster.cluster ), [GasGroup.LIQUIDATE_POD]); }); - it('Liquidate and register validator in disabled pod', async () => { + it('Liquidate and register validator in disabled cluster', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - const liquidatedPod = await trackGas(ssvNetworkContract.liquidatePod( - firstPod.ownerAddress, - firstPod.operatorIds, - firstPod.pod + const liquidatedCluster = await trackGas(ssvNetworkContract.liquidate( + firstCluster.owner, + firstCluster.operatorIds, + firstCluster.cluster ), [GasGroup.LIQUIDATE_POD]); - const updatedPod = liquidatedPod.eventsByName.PodLiquidated[0].args; + 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 trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( helpers.DataGenerator.publicKey(2), - updatedPod.operatorIds, + updatedCluster.operatorIds, helpers.DataGenerator.shares(0), `${minDepositAmount*2}`, - updatedPod.pod + updatedCluster.cluster ), [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]); }); - it('Liquidate a pod that is not liquidatable reverts "PodNotLiquidatable"', async () => { - await expect(ssvNetworkContract.liquidatePod( - firstPod.ownerAddress, - firstPod.operatorIds, - firstPod.pod - )).to.be.revertedWith('PodNotLiquidatable'); + it('Liquidate a cluster that is not liquidatable reverts "ClusterNotLiquidatable"', async () => { + await expect(ssvNetworkContract.liquidate( + firstCluster.owner, + firstCluster.operatorIds, + firstCluster.cluster + )).to.be.revertedWith('ClusterNotLiquidatable'); }); - it('Liquidate a pod that is not liquidatable reverts "PodDataIsBroken"', async () => { - await expect(ssvNetworkContract.liquidatePod( - firstPod.ownerAddress, - firstPod.operatorIds, + it('Liquidate a cluster that is not liquidatable reverts "IncorrectClusterState"', async () => { + await expect(ssvNetworkContract.liquidate( + firstCluster.owner, + firstCluster.operatorIds, { validatorCount: 0, networkFee: 0, @@ -122,47 +122,47 @@ describe('Liquidate Tests', () => { balance: 0, disabled: false } - )).to.be.revertedWith('PodDataIsBroken'); + )).to.be.revertedWith('IncorrectClusterState'); }); - it('Liquidate second time a pod that is liquidated already reverts "PodIsLiquidated"', async () => { + it('Liquidate second time a cluster that is liquidated already reverts "ClusterIsLiquidated"', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - const liquidatedPod = await trackGas(ssvNetworkContract.liquidatePod( - firstPod.ownerAddress, - firstPod.operatorIds, - firstPod.pod + const liquidatedCluster = await trackGas(ssvNetworkContract.liquidate( + firstCluster.owner, + firstCluster.operatorIds, + firstCluster.cluster ), [GasGroup.LIQUIDATE_POD]); - const updatedPod = liquidatedPod.eventsByName.PodLiquidated[0].args; + const updatedCluster = liquidatedCluster.eventsByName.ClusterLiquidated[0].args; - await expect(ssvNetworkContract.liquidatePod( - firstPod.ownerAddress, - updatedPod.operatorIds, - updatedPod.pod - )).to.be.revertedWith('PodIsLiquidated'); + await expect(ssvNetworkContract.liquidate( + firstCluster.owner, + updatedCluster.operatorIds, + updatedCluster.cluster + )).to.be.revertedWith('ClusterIsLiquidated'); }); it('Is liquidated', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - const liquidatedPod = await trackGas(ssvNetworkContract.liquidatePod( - firstPod.ownerAddress, - firstPod.operatorIds, - firstPod.pod + const liquidatedCluster = await trackGas(ssvNetworkContract.liquidate( + firstCluster.owner, + firstCluster.operatorIds, + firstCluster.cluster ), [GasGroup.LIQUIDATE_POD]); - const updatedPod = liquidatedPod.eventsByName.PodLiquidated[0].args; + const updatedCluster = liquidatedCluster.eventsByName.ClusterLiquidated[0].args; - expect(await ssvNetworkContract.isLiquidated(firstPod.ownerAddress, firstPod.operatorIds, updatedPod.pod)).to.equal(true); + expect(await ssvNetworkContract.isLiquidated(firstCluster.owner, firstCluster.operatorIds, updatedCluster.cluster)).to.equal(true); }); - it('Is liquidated reverts "PodNotExists"', async () => { + it('Is liquidated reverts "ClusterDoesNotExists"', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - const liquidatedPod = await trackGas(ssvNetworkContract.liquidatePod( - firstPod.ownerAddress, - firstPod.operatorIds, - firstPod.pod + const liquidatedCluster = await trackGas(ssvNetworkContract.liquidate( + firstCluster.owner, + firstCluster.operatorIds, + firstCluster.cluster ), [GasGroup.LIQUIDATE_POD]); - const updatedPod = liquidatedPod.eventsByName.PodLiquidated[0].args; + const updatedCluster = liquidatedCluster.eventsByName.ClusterLiquidated[0].args; - await expect(ssvNetworkContract.isLiquidated(helpers.DB.owners[0].address, firstPod.operatorIds, updatedPod.pod)).to.be.revertedWith('PodNotExists'); + await expect(ssvNetworkContract.isLiquidated(helpers.DB.owners[0].address, firstCluster.operatorIds, updatedCluster.cluster)).to.be.revertedWith('ClusterDoesNotExists'); }); }); diff --git a/test/liquidate/reactivate.ts b/test/liquidate/reactivate.ts index c9d79f8b..12e30b89 100644 --- a/test/liquidate/reactivate.ts +++ b/test/liquidate/reactivate.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, minDepositAmount: any, firstPod: any; +let ssvNetworkContract: any, minDepositAmount: any, firstCluster: any; describe('Reactivate Tests', () => { beforeEach(async () => { @@ -50,53 +50,53 @@ describe('Reactivate Tests', () => { disabled: false } ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); - firstPod = register.eventsByName.ValidatorAdded[0].args; + firstCluster = register.eventsByName.ValidatorAdded[0].args; }); - it('Reactivate a disabled pod emits "PodEnabled"', async () => { + it('Reactivate a disabled cluster emits "ClusterReactivated"', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - const liquidatedPod = await trackGas(ssvNetworkContract.liquidatePod(firstPod.ownerAddress, firstPod.operatorIds, firstPod.pod), [GasGroup.LIQUIDATE_POD]); - const updatedPod = liquidatedPod.eventsByName.PodLiquidated[0].args; + const liquidatedCluster = await trackGas(ssvNetworkContract.liquidate(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster), [GasGroup.LIQUIDATE_POD]); + 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]).reactivatePod(updatedPod.operatorIds, minDepositAmount, updatedPod.pod)).to.emit(ssvNetworkContract, 'PodEnabled'); + await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).reactivate(updatedCluster.operatorIds, minDepositAmount, updatedCluster.cluster)).to.emit(ssvNetworkContract, 'ClusterReactivated'); }); - it('Reactivate with 0 deposit and no validators emits PodEnabled', async () => { + it('Reactivate with 0 deposit and no validators emits ClusterReactivated', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - const liquidatedPod = await trackGas(ssvNetworkContract.liquidatePod(firstPod.ownerAddress, firstPod.operatorIds, firstPod.pod), [GasGroup.LIQUIDATE_POD]); - const updatedPod = liquidatedPod.eventsByName.PodLiquidated[0].args; + const liquidatedCluster = await trackGas(ssvNetworkContract.liquidate(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster), [GasGroup.LIQUIDATE_POD]); + const updatedCluster = liquidatedCluster.eventsByName.ClusterLiquidated[0].args; const remove = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).removeValidator( helpers.DataGenerator.publicKey(1), - firstPod.operatorIds, - updatedPod.pod + firstCluster.operatorIds, + updatedCluster.cluster ), [GasGroup.REMOVE_VALIDATOR]); - const updatedPodAfrerRemove = remove.eventsByName.ValidatorRemoved[0].args; + const updatedClusterAfrerRemove = remove.eventsByName.ValidatorRemoved[0].args; - await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).reactivatePod(updatedPodAfrerRemove.operatorIds, 0, updatedPodAfrerRemove.pod)).to.emit(ssvNetworkContract, 'PodEnabled'); + await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).reactivate(updatedClusterAfrerRemove.operatorIds, 0, updatedClusterAfrerRemove.cluster)).to.emit(ssvNetworkContract, 'ClusterReactivated'); }); - it('Reactivate an enabled pod reverts "PodAlreadyEnabled"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).reactivatePod(firstPod.operatorIds, minDepositAmount, firstPod.pod)).to.be.revertedWith('PodAlreadyEnabled'); + it('Reactivate an enabled cluster reverts "ClusterAlreadyEnabled"', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).reactivate(firstCluster.operatorIds, minDepositAmount, firstCluster.cluster)).to.be.revertedWith('ClusterAlreadyEnabled'); }); - it('Reactivate a pod when the amount is not enough reverts "NegativeBalance"', async () => { + it('Reactivate a cluster when the amount is not enough reverts "InsufficientFunds"', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - const liquidatedPod = await trackGas(ssvNetworkContract.liquidatePod(firstPod.ownerAddress, firstPod.operatorIds, firstPod.pod), [GasGroup.LIQUIDATE_POD]); - const updatedPod = liquidatedPod.eventsByName.PodLiquidated[0].args; + const liquidatedCluster = await trackGas(ssvNetworkContract.liquidate(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster), [GasGroup.LIQUIDATE_POD]); + 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]).reactivatePod(updatedPod.operatorIds, helpers.CONFIG.minimalOperatorFee, updatedPod.pod)).to.be.revertedWith('NotEnoughBalance'); + await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).reactivate(updatedCluster.operatorIds, helpers.CONFIG.minimalOperatorFee, updatedCluster.cluster)).to.be.revertedWith('InsufficientBalance'); }); - it('Reactivate a pod with a removed operator in the cluster', async () => { + it('Reactivate a cluster with a removed operator in the cluster', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - const liquidatedPod = await trackGas(ssvNetworkContract.liquidatePod(firstPod.ownerAddress, firstPod.operatorIds, firstPod.pod), [GasGroup.LIQUIDATE_POD]); - const updatedPod = liquidatedPod.eventsByName.PodLiquidated[0].args; + const liquidatedCluster = await trackGas(ssvNetworkContract.liquidate(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster), [GasGroup.LIQUIDATE_POD]); + 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]).reactivatePod(updatedPod.operatorIds, minDepositAmount, updatedPod.pod), [GasGroup.REACTIVATE_POD]); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).reactivate(updatedCluster.operatorIds, minDepositAmount, updatedCluster.cluster), [GasGroup.REACTIVATE_POD]); }); }); diff --git a/test/operators/others.ts b/test/operators/others.ts index 0e75a72a..cb589183 100644 --- a/test/operators/others.ts +++ b/test/operators/others.ts @@ -10,11 +10,11 @@ describe('Others Operator Tests', () => { ssvNetworkContract = (await helpers.initializeContract()).contract; }); - it('Add fee recipient address emits "FeeRecipientAddressAdded"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).feeRecipientAddress( + it('Add fee recipient address emits "FeeRecipientAddressUpdated"', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).setFeeRecipientAddress( helpers.DB.owners[2].address )) - .to.emit(ssvNetworkContract, 'FeeRecipientAddressAdded') + .to.emit(ssvNetworkContract, 'FeeRecipientAddressUpdated') .withArgs(helpers.DB.owners[1].address, helpers.DB.owners[2].address); }); }); diff --git a/test/operators/register.ts b/test/operators/register.ts index 7f3423a0..feb648f8 100644 --- a/test/operators/register.ts +++ b/test/operators/register.ts @@ -44,12 +44,12 @@ describe('Register Operator Tests', () => { expect((await ssvNetworkContract.getOperatorById(1)).validatorCount).to.equal(0); }); - it('Get operator by id reverts "OperatorNotFound"', async () => { + it('Get operator by id reverts "OperatorDoesNotExist"', async () => { await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerOperator( helpers.DataGenerator.publicKey(0), helpers.CONFIG.minimalOperatorFee, ), [GasGroup.REGISTER_OPERATOR]); - await expect(ssvNetworkContract.getOperatorById(3)).to.be.revertedWith('OperatorNotFound'); + await expect(ssvNetworkContract.getOperatorById(3)).to.be.revertedWith('OperatorDoesNotExist'); }); }); diff --git a/test/operators/remove.ts b/test/operators/remove.ts index e6788da1..e18d1c1c 100644 --- a/test/operators/remove.ts +++ b/test/operators/remove.ts @@ -46,12 +46,12 @@ describe('Remove Operator Tests', () => { }); it('Remove operator with 0 balance', async () => { - await expect(ssvNetworkContract.removeOperator(5)).not.to.emit(ssvNetworkContract, 'OperatorFundsWithdrawal'); + await expect(ssvNetworkContract.removeOperator(5)).not.to.emit(ssvNetworkContract, 'OperatorWithdrawn'); }); - it('Remove operator with a balance emits "OperatorFundsWithdrawal"', async () => { + 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 expect(ssvNetworkContract.removeOperator(1)).to.emit(ssvNetworkContract, 'OperatorFundsWithdrawal'); + await expect(ssvNetworkContract.removeOperator(1)).to.emit(ssvNetworkContract, 'OperatorWithdrawn'); }); it('Remove operator with a balance gas limits', async () => { diff --git a/test/operators/update-fee.ts b/test/operators/update-fee.ts index 02f62e27..161ba78b 100644 --- a/test/operators/update-fee.ts +++ b/test/operators/update-fee.ts @@ -26,11 +26,11 @@ describe('Operator Fee Tests', () => { it('Declare a higher fee gas limit', async () => { await trackGas(ssvNetworkContract.declareOperatorFee(1, initialFee - initialFee / 20), [GasGroup.REGISTER_OPERATOR]); }); - - it('Cancel declared fee emits "DeclaredOperatorFeeCancelation"', async () => { + + it('Cancel declared fee emits "OperatorFeeCancelationDeclared"', async () => { await ssvNetworkContract.declareOperatorFee(1, initialFee + initialFee / 10); await expect(ssvNetworkContract.connect(helpers.DB.owners[2]).cancelDeclaredOperatorFee(1 - )).to.emit(ssvNetworkContract, 'DeclaredOperatorFeeCancelation'); + )).to.emit(ssvNetworkContract, 'OperatorFeeCancelationDeclared'); }); it('Cancel declared fee gas limits', async () => { @@ -38,11 +38,11 @@ describe('Operator Fee Tests', () => { await trackGas(ssvNetworkContract.cancelDeclaredOperatorFee(1), [GasGroup.REGISTER_OPERATOR]); }); - it('Execute declared fee emits "OperatorFeeExecution"', async () => { + it('Execute declared fee emits "OperatorFeeExecuted"', async () => { await ssvNetworkContract.declareOperatorFee(1, initialFee + initialFee / 10); await progressTime(helpers.CONFIG.declareOperatorFeePeriod); await expect(ssvNetworkContract.connect(helpers.DB.owners[2]).executeOperatorFee(1 - )).to.emit(ssvNetworkContract, 'OperatorFeeExecution'); + )).to.emit(ssvNetworkContract, 'OperatorFeeExecuted'); }); it('Execute declared fee gas limits', async () => { @@ -54,22 +54,22 @@ describe('Operator Fee Tests', () => { it('Get operator fee', async () => { expect(await ssvNetworkContract.getOperatorFee(1)).to.equal(initialFee); }); - - it('Get fee from operator that does not exist reverts "OperatorNotFound"', async () => { + + it('Get fee from operator that does not exist reverts "OperatorDoesNotExist"', async () => { await expect(ssvNetworkContract.getOperatorFee(12 - )).to.be.revertedWith('OperatorNotFound'); + )).to.be.revertedWith('OperatorDoesNotExist'); }); it('Declare fee of operator I do not own reverts "CallerNotOwner"', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).declareOperatorFee(1, initialFee + initialFee / 10 )).to.be.revertedWith('CallerNotOwner'); }); - - it('Declare fee with a wrong Publickey reverts "OperatorWithPublicKeyNotExist"', async () => { + + it('Declare fee with a wrong Publickey reverts "OperatorDoesNotExist"', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).declareOperatorFee(12, initialFee + initialFee / 10 - )).to.be.revertedWith('OperatorWithPublicKeyNotExist'); + )).to.be.revertedWith('OperatorDoesNotExist'); }); - + it('Declare fee with too low of a fee reverts "FeeTooLow"', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[2]).declareOperatorFee(1, helpers.CONFIG.minimalOperatorFee - 1 )).to.be.revertedWith('FeeTooLow'); @@ -80,9 +80,9 @@ describe('Operator Fee Tests', () => { )).to.be.revertedWith('FeeExceedsIncreaseLimit'); }); - it('Cancel declared fee without a pending request reverts "NoPendingFeeChangeRequest"', async () => { + it('Cancel declared fee without a pending request reverts "NoFeeDelcared"', async () => { await expect(ssvNetworkContract.cancelDeclaredOperatorFee(1 - )).to.be.revertedWith('NoPendingFeeChangeRequest'); + )).to.be.revertedWith('NoFeeDelcared'); }); it('Cancel declared fee of an operator I do not own reverts "CallerNotOwner"', async () => { @@ -97,9 +97,9 @@ describe('Operator Fee Tests', () => { )).to.be.revertedWith('CallerNotOwner'); }); - it('Execute declared fee without a pending request reverts "NoPendingFeeChangeRequest"', async () => { + it('Execute declared fee without a pending request reverts "NoFeeDelcared"', async () => { await expect(ssvNetworkContract.executeOperatorFee(1 - )).to.be.revertedWith('NoPendingFeeChangeRequest'); + )).to.be.revertedWith('NoFeeDelcared'); }); it('Execute declared fee too early reverts "ApprovalNotWithinTimeframe"', async () => { @@ -117,21 +117,21 @@ describe('Operator Fee Tests', () => { }); //Dao - it('DAO increase the fee emits "OperatorFeeIncreaseLimitUpdate"', async () => { + it('DAO increase the fee emits "OperatorFeeIncreaseLimitUpdated"', async () => { await expect(ssvNetworkContract.updateOperatorFeeIncreaseLimit(1000 - )).to.emit(ssvNetworkContract, 'OperatorFeeIncreaseLimitUpdate'); + )).to.emit(ssvNetworkContract, 'OperatorFeeIncreaseLimitUpdated'); }); - it('DAO update the declare fee period emits "DeclareOperatorFeePeriodUpdate"', async () => { + it('DAO update the declare fee period emits "DeclareOperatorFeePeriodUpdated"', async () => { await expect(ssvNetworkContract.updateDeclareOperatorFeePeriod(1200 - )).to.emit(ssvNetworkContract, 'DeclareOperatorFeePeriodUpdate'); + )).to.emit(ssvNetworkContract, 'DeclareOperatorFeePeriodUpdated'); }); - it('DAO update the execute fee period emits "ExecuteOperatorFeePeriodUpdate"', async () => { + it('DAO update the execute fee period emits "ExecuteOperatorFeePeriodUpdated"', async () => { await expect(ssvNetworkContract.updateExecuteOperatorFeePeriod(1200 - )).to.emit(ssvNetworkContract, 'ExecuteOperatorFeePeriodUpdate'); + )).to.emit(ssvNetworkContract, 'ExecuteOperatorFeePeriodUpdated'); }); - + it('DAO get fee increase limit', async () => { expect(await ssvNetworkContract.getOperatorFeeIncreaseLimit()).to.equal(helpers.CONFIG.operatorMaxFeeIncrease); }); @@ -150,7 +150,7 @@ describe('Operator Fee Tests', () => { it('DAO get execute fee period', async () => { expect(await ssvNetworkContract.getExecuteOperatorFeePeriod()).to.equal(helpers.CONFIG.executeOperatorFeePeriod); }); - + it('Increase fee from an address thats not the DAO reverts "caller is not the owner"', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).updateOperatorFeeIncreaseLimit(1000 )).to.be.revertedWith('caller is not the owner'); @@ -166,9 +166,9 @@ describe('Operator Fee Tests', () => { .to.be.revertedWith('caller is not the owner'); }); - it('DAO declared fee without a pending request reverts "NoPendingFeeChangeRequest"', async () => { + it('DAO declared fee without a pending request reverts "NoFeeDelcared"', async () => { await trackGas(ssvNetworkContract.declareOperatorFee(1, initialFee + initialFee / 10), [GasGroup.REGISTER_OPERATOR]); await expect(ssvNetworkContract.getOperatorDeclaredFee(2 - )).to.be.revertedWith('NoPendingFeeChangeRequest'); + )).to.be.revertedWith('NoFeeDelcared'); }); -}); \ No newline at end of file +}); diff --git a/test/sanity/balances.ts b/test/sanity/balances.ts index 4d7396ac..cdc5476c 100644 --- a/test/sanity/balances.ts +++ b/test/sanity/balances.ts @@ -4,7 +4,7 @@ import * as utils from '../helpers/utils'; import { expect } from 'chai'; import { GasGroup } from '../helpers/gas-usage'; -let ssvNetworkContract: any, pod1: any, minDepositAmount: any, burnPerBlock: any, networkFee: any, initNetworkFeeBalance: any; +let ssvNetworkContract: any, cluster1: any, minDepositAmount: any, burnPerBlock: any, networkFee: any, initNetworkFeeBalance: any; describe('Balance Tests', () => { beforeEach(async () => { @@ -42,30 +42,30 @@ describe('Balance Tests', () => { } ); - pod1 = 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 ssvNetworkContract.getNetworkEarnings(); }); - it('Check pod balance in three blocks, one after the other', async () => { + it('Check cluster balance in three blocks, one after the other', async () => { await utils.progressBlocks(1); - expect(await ssvNetworkContract.podBalanceOf(helpers.DB.owners[4].address, pod1.args.operatorIds, pod1.args.pod)).to.equal(minDepositAmount - burnPerBlock); + expect(await ssvNetworkContract.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster)).to.equal(minDepositAmount - burnPerBlock); await utils.progressBlocks(1); - expect(await ssvNetworkContract.podBalanceOf(helpers.DB.owners[4].address, pod1.args.operatorIds, pod1.args.pod)).to.equal(minDepositAmount - burnPerBlock * 2); + expect(await ssvNetworkContract.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster)).to.equal(minDepositAmount - burnPerBlock * 2); await utils.progressBlocks(1); - expect(await ssvNetworkContract.podBalanceOf(helpers.DB.owners[4].address, pod1.args.operatorIds, pod1.args.pod)).to.equal(minDepositAmount - burnPerBlock * 3); + expect(await ssvNetworkContract.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster)).to.equal(minDepositAmount - burnPerBlock * 3); }); - it('Check pod balance in two and twelve blocks, after network fee updates', async () => { + it('Check cluster balance in two and twelve blocks, after network fee updates', async () => { await utils.progressBlocks(1); - expect(await ssvNetworkContract.podBalanceOf(helpers.DB.owners[4].address, pod1.args.operatorIds, pod1.args.pod)).to.equal(minDepositAmount - burnPerBlock); + expect(await ssvNetworkContract.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 ssvNetworkContract.podBalanceOf(helpers.DB.owners[4].address, pod1.args.operatorIds, pod1.args.pod)).to.equal(minDepositAmount - burnPerBlock * 2 - newBurnPerBlock); + expect(await ssvNetworkContract.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster)).to.equal(minDepositAmount - burnPerBlock * 2 - newBurnPerBlock); await utils.progressBlocks(1); - expect(await ssvNetworkContract.podBalanceOf(helpers.DB.owners[4].address, pod1.args.operatorIds, pod1.args.pod)).to.equal(minDepositAmount - burnPerBlock * 2 - newBurnPerBlock * 2); + expect(await ssvNetworkContract.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 ssvNetworkContract.podBalanceOf(helpers.DB.owners[4].address, pod1.args.operatorIds, pod1.args.pod)).to.equal(minDepositAmount - burnPerBlock * 2 - newBurnPerBlock * 12); + expect(await ssvNetworkContract.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 () => { @@ -92,30 +92,30 @@ describe('Balance Tests', () => { it('Check operators earnings in three blocks, one after the other', async () => { await utils.progressBlocks(1); - expect((await ssvNetworkContract.operatorSnapshot(1)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 2 + helpers.CONFIG.minimalOperatorFee * 2); - expect((await ssvNetworkContract.operatorSnapshot(2)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 2 + helpers.CONFIG.minimalOperatorFee * 2); - expect((await ssvNetworkContract.operatorSnapshot(3)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 2 + helpers.CONFIG.minimalOperatorFee * 2); - expect((await ssvNetworkContract.operatorSnapshot(4)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 2 + helpers.CONFIG.minimalOperatorFee * 2); + expect((await ssvNetworkContract.getOperatorEarnings(1)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 2 + helpers.CONFIG.minimalOperatorFee * 2); + expect((await ssvNetworkContract.getOperatorEarnings(2)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 2 + helpers.CONFIG.minimalOperatorFee * 2); + expect((await ssvNetworkContract.getOperatorEarnings(3)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 2 + helpers.CONFIG.minimalOperatorFee * 2); + expect((await ssvNetworkContract.getOperatorEarnings(4)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 2 + helpers.CONFIG.minimalOperatorFee * 2); await utils.progressBlocks(1); - expect((await ssvNetworkContract.operatorSnapshot(1)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 4 + helpers.CONFIG.minimalOperatorFee * 2); - expect((await ssvNetworkContract.operatorSnapshot(2)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 4 + helpers.CONFIG.minimalOperatorFee * 2); - expect((await ssvNetworkContract.operatorSnapshot(3)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 4 + helpers.CONFIG.minimalOperatorFee * 2); - expect((await ssvNetworkContract.operatorSnapshot(4)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 4 + helpers.CONFIG.minimalOperatorFee * 2); + expect((await ssvNetworkContract.getOperatorEarnings(1)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 4 + helpers.CONFIG.minimalOperatorFee * 2); + expect((await ssvNetworkContract.getOperatorEarnings(2)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 4 + helpers.CONFIG.minimalOperatorFee * 2); + expect((await ssvNetworkContract.getOperatorEarnings(3)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 4 + helpers.CONFIG.minimalOperatorFee * 2); + expect((await ssvNetworkContract.getOperatorEarnings(4)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 4 + helpers.CONFIG.minimalOperatorFee * 2); await utils.progressBlocks(1); - expect((await ssvNetworkContract.operatorSnapshot(1)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 6 + helpers.CONFIG.minimalOperatorFee * 2); - expect((await ssvNetworkContract.operatorSnapshot(2)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 6 + helpers.CONFIG.minimalOperatorFee * 2); - expect((await ssvNetworkContract.operatorSnapshot(3)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 6 + helpers.CONFIG.minimalOperatorFee * 2); - expect((await ssvNetworkContract.operatorSnapshot(4)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 6 + helpers.CONFIG.minimalOperatorFee * 2); + expect((await ssvNetworkContract.getOperatorEarnings(1)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 6 + helpers.CONFIG.minimalOperatorFee * 2); + expect((await ssvNetworkContract.getOperatorEarnings(2)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 6 + helpers.CONFIG.minimalOperatorFee * 2); + expect((await ssvNetworkContract.getOperatorEarnings(3)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 6 + helpers.CONFIG.minimalOperatorFee * 2); + expect((await ssvNetworkContract.getOperatorEarnings(4)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 6 + helpers.CONFIG.minimalOperatorFee * 2); }); - it('Check pod balance returns error - NegativeBalance', async () => { + it('Check cluster balance returns error - InsufficientFunds', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation + 10); - await expect(ssvNetworkContract.podBalanceOf(helpers.DB.owners[4].address, pod1.args.operatorIds, pod1.args.pod)).to.be.revertedWith('NegativeBalance'); + await expect(ssvNetworkContract.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster)).to.be.revertedWith('InsufficientFunds'); }); - it('Check pod balance with removed operator', async () => { + it('Check cluster balance with removed operator', async () => { await ssvNetworkContract.removeOperator(1); - expect(await ssvNetworkContract.podBalanceOf(helpers.DB.owners[4].address, pod1.args.operatorIds, pod1.args.pod)).not.equals(0); + expect(await ssvNetworkContract.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster)).not.equals(0); }); }); diff --git a/test/validators/register.ts b/test/validators/register.ts index 7db82ab9..0b0c1e80 100644 --- a/test/validators/register.ts +++ b/test/validators/register.ts @@ -52,7 +52,7 @@ describe('Register Validator Tests', () => { ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); }); - it('4 operators: Register 2 validators in same pod gas usage', async () => { + it('4 operators: Register 2 validators in same cluster gas usage', 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), @@ -77,11 +77,11 @@ describe('Register Validator Tests', () => { [1,2,3,4], helpers.DataGenerator.shares(0), minDepositAmount, - args.pod + args.cluster ), [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]); }); - it('4 operators: Register 2 validators in same pod and 1 validator in new pod gas usage', async () => { + it('4 operators: Register 2 validators in same cluster and 1 validator in new cluster gas usage', 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), @@ -106,7 +106,7 @@ describe('Register Validator Tests', () => { [1,2,3,4], helpers.DataGenerator.shares(0), minDepositAmount, - args.pod + args.cluster ), [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]); await helpers.DB.ssvToken.connect(helpers.DB.owners[2]).approve(ssvNetworkContract.address, minDepositAmount); @@ -126,7 +126,7 @@ describe('Register Validator Tests', () => { ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); }); - it('4 operators: Register 2 validators in same pod with one time deposit gas usage', async () => { + it('4 operators: Register 2 validators in same cluster with one time deposit gas usage', 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), @@ -149,7 +149,7 @@ describe('Register Validator Tests', () => { [1,2,3,4], helpers.DataGenerator.shares(0), 0, - args.pod + args.cluster ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT]); }); @@ -173,7 +173,7 @@ describe('Register Validator Tests', () => { ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]); }); - it('7 operators: Register 2 validators in same pod gas usage', async () => { + it('7 operators: Register 2 validators in same cluster gas usage', 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), @@ -198,11 +198,11 @@ describe('Register Validator Tests', () => { [1,2,3,4,5,6,7], helpers.DataGenerator.shares(0), minDepositAmount, - args.pod + args.cluster ), [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_7]); }); - it('7 operators: Register 2 validators in same pod and 1 validator in new pod gas usage', async () => { + it('7 operators: Register 2 validators in same cluster and 1 validator in new cluster gas usage', 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), @@ -227,7 +227,7 @@ describe('Register Validator Tests', () => { [1,2,3,4,5,6,7], helpers.DataGenerator.shares(0), minDepositAmount, - args.pod + args.cluster ), [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_7]); await helpers.DB.ssvToken.connect(helpers.DB.owners[2]).approve(ssvNetworkContract.address, minDepositAmount); @@ -247,7 +247,7 @@ describe('Register Validator Tests', () => { ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]); }); - it('7 operators: Register 2 validators in same pod with one time deposit gas usage', async () => { + it('7 operators: Register 2 validators in same cluster with one time deposit gas usage', 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), @@ -270,7 +270,7 @@ describe('Register Validator Tests', () => { [1,2,3,4,5,6,7], helpers.DataGenerator.shares(0), 0, - args.pod + args.cluster ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_7]); }); @@ -294,7 +294,7 @@ describe('Register Validator Tests', () => { ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]); }); - it('13 operators: Register 2 validators in same pod gas usage', async () => { + it('13 operators: Register 2 validators in same cluster gas usage', 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), @@ -319,11 +319,11 @@ describe('Register Validator Tests', () => { [1,2,3,4,5,6,7,8,9,10,11,12,13], helpers.DataGenerator.shares(0), minDepositAmount, - args.pod + args.cluster ), [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_13]); }); - it('13 operators: Register 2 validators in same pod and 1 validator in new pod gas usage', async () => { + it('13 operators: Register 2 validators in same cluster and 1 validator in new cluster gas usage', 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), @@ -348,7 +348,7 @@ describe('Register Validator Tests', () => { [1,2,3,4,5,6,7,8,9,10,11,12,13], helpers.DataGenerator.shares(0), minDepositAmount, - args.pod + args.cluster ), [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_13]); await helpers.DB.ssvToken.connect(helpers.DB.owners[2]).approve(ssvNetworkContract.address, minDepositAmount); @@ -368,7 +368,7 @@ describe('Register Validator Tests', () => { ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]); }); - it('13 operators: Register 2 validators in same pod with one time deposit gas usage', async () => { + it('13 operators: Register 2 validators in same cluster with one time deposit gas usage', 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), @@ -391,11 +391,11 @@ describe('Register Validator Tests', () => { [1,2,3,4,5,6,7,8,9,10,11,12,13], helpers.DataGenerator.shares(0), 0, - args.pod + args.cluster ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_13]); }); - it('Register validator returns an error - PodDataIsBroken', async () => { + it('Register validator returns an error - 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), @@ -425,7 +425,7 @@ describe('Register Validator Tests', () => { balance: 0, disabled: false } - )).to.be.revertedWith('PodDataIsBroken'); + )).to.be.revertedWith('IncorrectClusterState'); }); it('Register validator returns an error - OperatorDoesNotExist', async () => { @@ -481,19 +481,19 @@ describe('Register Validator Tests', () => { )).to.emit(ssvNetworkContract, 'ValidatorAdded'); }); - it('Register pod returns an error - The operators list should be in ascending order', async () => { - await expect(helpers.registerValidators(2, 1, minDepositAmount, [3, 2, 1, 4])).to.be.revertedWith('OperatorsListDoesNotSorted'); + it('Register cluster returns an error - The operators list should be in ascending order', async () => { + await expect(helpers.registerValidators(2, 1, minDepositAmount, [3, 2, 1, 4])).to.be.revertedWith('UnsortedOperatorsList'); }); - it('Invalid operator amount reverts "OperatorIdsStructureInvalid"', async () => { + it('Invalid operator amount reverts "InvalidOperatorIdsLength"', async () => { // 2 Operators - await expect(helpers.registerValidators(2, 1, minDepositAmount, [1, 2])).to.be.revertedWith('OperatorIdsStructureInvalid'); + await expect(helpers.registerValidators(2, 1, minDepositAmount, [1, 2])).to.be.revertedWith('InvalidOperatorIdsLength'); // 6 Operators - await expect(helpers.registerValidators(2, 1, minDepositAmount, [1, 2, 3, 4, 5, 6])).to.be.revertedWith('OperatorIdsStructureInvalid'); + await expect(helpers.registerValidators(2, 1, minDepositAmount, [1, 2, 3, 4, 5, 6])).to.be.revertedWith('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.revertedWith('OperatorIdsStructureInvalid'); + await expect(helpers.registerValidators(2, 1, minDepositAmount, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])).to.be.revertedWith('InvalidOperatorIdsLength'); }); it('Register validator with an invalild public key reverts "InvalidPublicKeyLength"', async () => { @@ -513,7 +513,7 @@ describe('Register Validator Tests', () => { )).to.be.revertedWith('InvalidPublicKeyLength'); }); - it('Register validator returns an error - NotEnoughBalance', async () => { + it('Register validator returns an error - InsufficientBalance', async () => { await helpers.DB.ssvToken.approve(ssvNetworkContract.address, helpers.CONFIG.minimalOperatorFee); await expect(ssvNetworkContract.registerValidator( helpers.DataGenerator.publicKey(1), @@ -528,7 +528,7 @@ describe('Register Validator Tests', () => { balance: 0, disabled: false } - )).to.be.revertedWith('NotEnoughBalance'); + )).to.be.revertedWith('InsufficientBalance'); }); it('Register validator returns an error - ValidatorAlreadyExists', async () => { @@ -549,11 +549,11 @@ describe('Register Validator Tests', () => { )).to.be.revertedWith('ValidatorAlreadyExists'); }); - it('Get pod burn rate', async () => { - expect(await ssvNetworkContract.getPodBurnRate([1,2,3,4])).to.equal(helpers.CONFIG.minimalOperatorFee * 4); + it('Get cluster burn rate', async () => { + expect(await ssvNetworkContract.getClusterBurnRate([1,2,3,4])).to.equal(helpers.CONFIG.minimalOperatorFee * 4); }); - it('Get pod burn rate by not existed operator in the list', async () => { - expect(await ssvNetworkContract.getPodBurnRate([1,2,3,41])).to.equal(helpers.CONFIG.minimalOperatorFee * 3); + it('Get cluster burn rate by not existed operator in the list', async () => { + expect(await ssvNetworkContract.getClusterBurnRate([1,2,3,41])).to.equal(helpers.CONFIG.minimalOperatorFee * 3); }); }); diff --git a/test/validators/remove.ts b/test/validators/remove.ts index 1dde9828..ab3db684 100644 --- a/test/validators/remove.ts +++ b/test/validators/remove.ts @@ -5,7 +5,7 @@ import * as utils from '../helpers/utils'; import { expect } from 'chai'; import { trackGas, GasGroup } from '../helpers/gas-usage'; -let ssvNetworkContract: any, minDepositAmount: any, firstPod: any; +let ssvNetworkContract: any, minDepositAmount: any, firstCluster: any; describe('Remove Validator Tests', () => { beforeEach(async () => { @@ -51,98 +51,98 @@ describe('Remove Validator Tests', () => { disabled: false } ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); - firstPod = register.eventsByName.ValidatorAdded[0].args; + firstCluster = register.eventsByName.ValidatorAdded[0].args; }); it('Remove validator emits ValidatorRemoved event', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).removeValidator( helpers.DataGenerator.publicKey(1), - firstPod.operatorIds, - firstPod.pod + firstCluster.operatorIds, + firstCluster.cluster )).to.emit(ssvNetworkContract, 'ValidatorRemoved'); }); it('Remove validator track gas', async () => { await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).removeValidator( helpers.DataGenerator.publicKey(1), - firstPod.operatorIds, - firstPod.pod + firstCluster.operatorIds, + firstCluster.cluster ), [GasGroup.REMOVE_VALIDATOR]); }); - it('Remove validator with removed operator in a pod', async () => { + it('Remove validator with removed operator in a 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), - firstPod.operatorIds, - firstPod.pod + firstCluster.operatorIds, + firstCluster.cluster ), [GasGroup.REMOVE_VALIDATOR]); }); it('Remove validator with an invalid owner', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[3]).removeValidator( helpers.DataGenerator.publicKey(1), - firstPod.operatorIds, - firstPod.pod - )).to.be.revertedWith('ValidatorNotOwned'); + firstCluster.operatorIds, + firstCluster.cluster + )).to.be.revertedWith('NoValidatorOwnership'); }); it('Remove validator twice', async () => { // Remove validator await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).removeValidator( helpers.DataGenerator.publicKey(1), - firstPod.operatorIds, - firstPod.pod + firstCluster.operatorIds, + firstCluster.cluster ), [GasGroup.REMOVE_VALIDATOR]); // Remove validator again await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).removeValidator( helpers.DataGenerator.publicKey(1), - firstPod.operatorIds, - firstPod.pod - )).to.be.revertedWith('ValidatorNotOwned'); + firstCluster.operatorIds, + firstCluster.cluster + )).to.be.revertedWith('NoValidatorOwnership'); }); it('Register / remove validator twice', async () => { // Remove validator const remove = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).removeValidator( helpers.DataGenerator.publicKey(1), - firstPod.operatorIds, - firstPod.pod + firstCluster.operatorIds, + firstCluster.cluster ), [GasGroup.REMOVE_VALIDATOR]); - const updatedPod = remove.eventsByName.ValidatorRemoved[0].args; + 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), - updatedPod.operatorIds, + updatedCluster.operatorIds, helpers.DataGenerator.shares(0), 0, - updatedPod.pod + updatedCluster.cluster ), [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]); - const afterRegisterPod = newRegister.eventsByName.ValidatorAdded[0].args; + const afterRegisterCluster = newRegister.eventsByName.ValidatorAdded[0].args; // Remove the validator again await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).removeValidator( helpers.DataGenerator.publicKey(1), - afterRegisterPod.operatorIds, - afterRegisterPod.pod + afterRegisterCluster.operatorIds, + afterRegisterCluster.cluster ), [GasGroup.REMOVE_VALIDATOR]); }); - it('Remove validator from a liquidated pod', async () => { + it('Remove validator from a liquidated cluster', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - const liquidatedPod = await trackGas(ssvNetworkContract.liquidatePod( - firstPod.ownerAddress, - firstPod.operatorIds, - firstPod.pod + const liquidatedCluster = await trackGas(ssvNetworkContract.liquidate( + firstCluster.owner, + firstCluster.operatorIds, + firstCluster.cluster ), [GasGroup.LIQUIDATE_POD]); - const updatedPod = liquidatedPod.eventsByName.PodLiquidated[0].args; + const updatedCluster = liquidatedCluster.eventsByName.ClusterLiquidated[0].args; await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).removeValidator( helpers.DataGenerator.publicKey(1), - updatedPod.operatorIds, - updatedPod.pod + updatedCluster.operatorIds, + updatedCluster.cluster ), [GasGroup.REMOVE_VALIDATOR]); }); }); From 187b3f22f40f4988c195d2b234b9f7fbaab00eaa Mon Sep 17 00:00:00 2001 From: mtabasco Date: Thu, 12 Jan 2023 12:33:12 +0100 Subject: [PATCH 113/149] add OperatorFeeDeclared, ValidatorDoesNotExist (#166) --- contracts/ISSVNetwork.sol | 10 ++-------- contracts/SSVNetwork.sol | 16 ++++++++++------ test/operators/update-fee.ts | 4 ++-- test/validators/remove.ts | 2 +- 4 files changed, 15 insertions(+), 17 deletions(-) diff --git a/contracts/ISSVNetwork.sol b/contracts/ISSVNetwork.sol index 1e312055..f43f5782 100644 --- a/contracts/ISSVNetwork.sol +++ b/contracts/ISSVNetwork.sol @@ -66,20 +66,13 @@ interface ISSVNetwork { Cluster cluster ); - event OperatorFeeDeclaration( + event OperatorFeeDeclared( address indexed owner, uint64 operatorId, uint256 blockNumber, uint256 fee ); - /** - * @dev Emitted when operator changed fee. - * @param id operator's ID. - * @param fee operator's new fee. - */ - event OperatorFeeSet(uint64 id, uint64 fee); - event OperatorFeeCancelationDeclared(address indexed owner, uint64 operatorId); /** @@ -148,6 +141,7 @@ interface ISSVNetwork { error OperatorDoesNotExist(); error InsufficientBalance(); error ValidatorAlreadyExists(); + error ValidatorDoesNotExist(); error ClusterLiquidatable(); error ClusterNotLiquidatable(); error InvalidPublicKeyLength(); diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index 7fdd0887..0a5b6ccd 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -187,7 +187,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _declareOperatorFeePeriod + _executeOperatorFeePeriod ); - emit OperatorFeeDeclaration(msg.sender, operatorId, block.number, fee); + emit OperatorFeeDeclared(msg.sender, operatorId, block.number, fee); } function executeOperatorFee( @@ -319,16 +319,20 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { ) external override { uint operatorsLength = operatorIds.length; + bytes32 hashedValidator = keccak256(publicKey); + address owner = _validatorPKs[hashedValidator].owner; + if (owner == address(0)) { + revert ValidatorDoesNotExist(); + } + if (owner != msg.sender) { + revert NoValidatorOwnership(); + } + { _validateOperatorIds(operatorsLength); _validatePublicKey(publicKey); } - bytes32 hashedValidator = keccak256(publicKey); - if (_validatorPKs[hashedValidator].owner != msg.sender) { - revert NoValidatorOwnership(); - } - uint64 clusterIndex; { if (!cluster.disabled) { diff --git a/test/operators/update-fee.ts b/test/operators/update-fee.ts index 161ba78b..66095fa6 100644 --- a/test/operators/update-fee.ts +++ b/test/operators/update-fee.ts @@ -14,9 +14,9 @@ describe('Operator Fee Tests', () => { await helpers.registerOperators(2, 1, initialFee); }); - it('Declare fee emits "OperatorFeeDeclaration"', async () => { + it('Declare fee emits "OperatorFeeDeclared"', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[2]).declareOperatorFee(1, initialFee + initialFee / 10 - )).to.emit(ssvNetworkContract, 'OperatorFeeDeclaration'); + )).to.emit(ssvNetworkContract, 'OperatorFeeDeclared'); }); it('Declare a lower fee gas limits', async () => { diff --git a/test/validators/remove.ts b/test/validators/remove.ts index ab3db684..03ec1eba 100644 --- a/test/validators/remove.ts +++ b/test/validators/remove.ts @@ -100,7 +100,7 @@ describe('Remove Validator Tests', () => { helpers.DataGenerator.publicKey(1), firstCluster.operatorIds, firstCluster.cluster - )).to.be.revertedWith('NoValidatorOwnership'); + )).to.be.revertedWith('ValidatorDoesNotExist'); }); it('Register / remove validator twice', async () => { From bdb60f627a2d6fe8296581da103d19683f19d04e Mon Sep 17 00:00:00 2001 From: mtabasco Date: Thu, 12 Jan 2023 23:36:23 +0100 Subject: [PATCH 114/149] UUPS proxy implementation (#167) * add UUPS proxy support * add lock file * update README, script names * slither fixes --- .env.example | 1 + README.md | 96 +- contracts/ISSVNetwork.sol | 2 +- contracts/SSVNetwork.sol | 113 +- contracts/mocks/SSVTokenMock.sol | 2 +- contracts/utils/Types.sol | 2 +- hardhat.config.ts | 12 +- package-lock.json | 36278 +++++------------ package.json | 31 +- scripts/{deploy.ts => ssv-network-deploy.ts} | 7 +- scripts/ssv-network-upgrade.ts | 19 + scripts/ssv-network-validate-upgrade.ts | 16 + test/account/deposit.ts | 4 +- test/account/withdraw.ts | 12 +- test/dao/liquidation-threshold.ts | 4 +- test/dao/network-fee-change.ts | 2 +- test/dao/network-fee-withdraw.ts | 4 +- test/helpers/contract-helpers.ts | 5 +- test/liquidate/liquidate.ts | 8 +- test/liquidate/reactivate.ts | 4 +- test/operators/register.ts | 4 +- test/operators/remove.ts | 2 +- test/operators/update-fee.ts | 30 +- test/sanity/balances.ts | 2 +- test/validators/register.ts | 20 +- test/validators/remove.ts | 4 +- 26 files changed, 9629 insertions(+), 27055 deletions(-) rename scripts/{deploy.ts => ssv-network-deploy.ts} (88%) create mode 100644 scripts/ssv-network-upgrade.ts create mode 100644 scripts/ssv-network-validate-upgrade.ts diff --git a/.env.example b/.env.example index 97432e61..31b8e6a0 100644 --- a/.env.example +++ b/.env.example @@ -12,3 +12,4 @@ SET_OPERATOR_FEE_PERIOD=259200 # 3 days APPROVE_OPERATOR_FEE_PERIOD=345600 # 4 days VALIDATORS_PER_OPERATOR_LIMIT=2000 REGISTERED_OPERATORS_PER_ACCOUNT_LIMIT=10 +PROXY_ADDRESS= diff --git a/README.md b/README.md index bd801722..25636870 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # SSV Network Project -This repository contains a SSVRegistry and SSVNetwork smart contacts project. +This repository contains a SSVNetwork smart contacts project. ## Quick start @@ -23,7 +23,7 @@ npx hardhat node For more details about it and how to use MainNet forking you can find [here](https://hardhat.org/hardhat-network/). ### Compile contracts -Take a look at `contracts/` folder, you should be able to find `SSVNetwork.sol`, `SSVNetworkV2.sol` as simple contract example. +Take a look at `contracts/` folder, you should be able to find `SSVNetwork.sol`. To compile it, simply run: ```sh @@ -34,7 +34,7 @@ npx hardhat compile ### Step 1: Test contracts Take a look at `test/` folder, you should be able to find tests related to specific actions. -It comes with tests that use [Waffle](https://getwaffle.io/) and [Ethers.js](https://github.com/ethers-io/ethers.js/). +It comes with tests that use [Ethers.js](https://github.com/ethers-io/ethers.js/). To run tests, run: ```sh @@ -42,27 +42,31 @@ npx hardhat test ``` ### Step 2: Deploy new contracts -We use [Proxy Upgrade pattern](https://docs.openzeppelin.com/upgrades-plugins/1.x/proxies) for smart contracts to have an ability to upgrade them later. -To deploy the contract we will use a Hardhat script. Inside `scripts/` you will find `ssv-registry-deploy.ts` and `ssv-network-deploy.ts` files. -As general rule, you can target any network configured in the `hardhat.config.ts` - -#### Deploy SSV Registry - -```sh -npx hardhat run --network scripts/ssv-registry-deploy.ts -``` -Output of this action will be smart SSV Registry contract proxy address. +We use [UUPS Proxy Upgrade pattern](https://docs.openzeppelin.com/contracts/4.x/api/proxy) for smart contracts to have an ability to upgrade them later. +To deploy the contract we will use a Hardhat script. Inside `scripts/` you will find `ssv-network-deploy.ts` and `ssv-network-upgrade.ts` files. +As general rule, you can target any network configured in the `hardhat.config.ts`, +specifying the right [network]_ETH_NODE_URL and [network]_OWNER_PRIVATE_KEY in `.env` file. #### Deploy SSV Network + Before run the cli command, in `.env` need to add the following seetings: ```sh -SSVREGISTRY_ADDRESS=#SSV Registry contract address +[NETWORK]_ETH_NODE_URL=# RPC URL of the node +[NETWORK]_OWNER_PRIVATE_KEY=# Private key of the deployer account, without 0x prefix +GAS_PRICE=# example 30000000000 +GAS=# example 8000000 +ETHERSCAN_KEY=# etherescan API key SSVTOKEN_ADDRESS=#SSV Token contract address +MINIMUM_BLOCKS_BEFORE_LIQUIDATION=# custom param +OPERATOR_MAX_FEE_INCREASE=# custom param +DECLARE_OPERATOR_FEE_PERIOD=# custom param +EXECUTE_OPERATOR_FEE_PERIOD=# custom param +VALIDATORS_PER_OPERATOR_LIMIT=# custom param +REGISTERED_OPERATORS_PER_ACCOUNT_LIMIT=# custom param +PROXY_ADDRESS=# Proxy address, set it when runnning ssv-network-upgrade.ts script ``` -After that: - ```sh npx hardhat run --network scripts/ssv-network-deploy.ts ``` @@ -70,8 +74,8 @@ Output of this action will be smart SSV Network contract proxy address. ### Step 3: Verify implementation contract on etherscan (each time after upgrade) Open `.openzeppelin/.json` file and find `[impls..address]` value which is implementation smart contract address. -We use [Proxy Upgrade pattern](https://docs.openzeppelin.com/upgrades-plugins/1.x/proxies) for smart contracts to have an ability to upgrade them later. -To deploy the contract we will use a Hardhat script. Inside `scripts/` you will find `deploy.ts` file. +We use [UUPS Proxy Upgrade pattern](https://docs.openzeppelin.com/contracts/4.x/api/proxy) for smart contracts to have an ability to upgrade them later. +To deploy the contract we will use a Hardhat script. Inside `scripts/` you will find `ssv-network-deploy.ts` file. Run this: ```sh npx hardhat verify --network @@ -87,18 +91,34 @@ The proxy\'s ( scripts/ssv-registry-upgrade.ts +npx hardhat run --network scripts/ssv-network-validate-upgrade.ts ``` - -#### Upgrade SSV Network contract: +To fire the upgrade process: ```sh -PROXY_ADDRESS=0x... npx hardhat run --network scripts/ssv-network-upgrade.ts +npx hardhat run --network scripts/ssv-network-upgrade.ts ``` + +If you get the error: +` +Error: invalid hex string ... +reason: 'invalid hex string', +code: 'INVALID_ARGUMENT', +` +Set or change the parameters `GAS_PRICE` and `GAS` in `.env` file. + ### dApp UI to interact with smart contract ```sh @@ -106,29 +126,3 @@ https://eth95.dev/?network=1&address=0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0 ``` UI dApp [direct link](https://eth95.dev/?network=1&address=0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0) - -## User Guide - -You can find detailed instructions on using this repository and many tips in [its documentation](https://hardhat.org/tutorial). -For a complete introduction to Hardhat, refer to [this guide](https://hardhat.org/getting-started/#overview). - -## What’s Included? - -Your environment will have everything you need to build a Dapp powered by Hardhat and React. - -- [Hardhat](https://hardhat.org/): An Ethereum development task runner and testing network. -- [Mocha](https://mochajs.org/): A JavaScript test runner. -- [Chai](https://www.chaijs.com/): A JavaScript assertion library. -- [ethers.js](https://docs.ethers.io/ethers.js/html/): A JavaScript library for interacting with Ethereum. -- [Waffle](https://github.com/EthWorks/Waffle/): To have Ethereum-specific Chai assertions/mathers. - -## Security Audit [OLD Version] - -Full audit report [CoinFabrik Report](./docs/SSV_Token_Dex&Vesting_audit.pdf) - -## Troubleshooting - -- `Invalid nonce` errors: if you are seeing this error on the `npx hardhat node` - console, try resetting your Metamask account. This will reset the account's - transaction history and also the nonce. Open Metamask, click on your account - followed by `Settings > Advanced > Reset Account`. diff --git a/contracts/ISSVNetwork.sol b/contracts/ISSVNetwork.sol index f43f5782..59963789 100644 --- a/contracts/ISSVNetwork.sol +++ b/contracts/ISSVNetwork.sol @@ -1,6 +1,6 @@ // File: contracts/ISSVNetwork.sol // SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity ^0.8.2; +pragma solidity 0.8.16; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; interface ISSVNetwork { diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index 0a5b6ccd..c03e4a5e 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -1,17 +1,16 @@ // File: contracts/SSVRegistry.sol // SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity ^0.8.2; +pragma solidity 0.8.16; import "./ISSVNetwork.sol"; import "@openzeppelin/contracts/utils/Counters.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import "./utils/Types.sol"; -// import "hardhat/console.sol"; - -contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { +contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { /*************/ /* Libraries */ /*************/ @@ -68,7 +67,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { /*************/ uint64 constant MINIMAL_LIQUIDATION_THRESHOLD = 6570; - uint64 constant MINIMAL_OPERATOR_FEE = 100000000; + uint64 constant MINIMAL_OPERATOR_FEE = 1e8; uint32 constant VALIDATORS_PER_OPERATOR_LIMIT = 2000; /********************/ @@ -100,6 +99,9 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { DAO private _dao; IERC20 private _token; + // @dev reserve storage space for future new state variables in base contract + uint256[50] __gap; + /*************/ /* Modifiers */ /*************/ @@ -119,16 +121,32 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { uint64 declareOperatorFeePeriod_, uint64 executeOperatorFeePeriod_, uint64 minimumBlocksBeforeLiquidation_ - ) external override { - __SSVNetwork_init( - token_, - operatorMaxFeeIncrease_, - declareOperatorFeePeriod_, - executeOperatorFeePeriod_, - minimumBlocksBeforeLiquidation_ - ); + ) external override initializer onlyProxy { + __UUPSUpgradeable_init(); + __Ownable_init_unchained(); + __SSVNetwork_init_unchained(token_, operatorMaxFeeIncrease_, declareOperatorFeePeriod_, executeOperatorFeePeriod_, minimumBlocksBeforeLiquidation_); + } + + function __SSVNetwork_init_unchained( + IERC20 token_, + uint64 operatorMaxFeeIncrease_, + uint64 declareOperatorFeePeriod_, + uint64 executeOperatorFeePeriod_, + uint64 minimumBlocksBeforeLiquidation_ + ) internal onlyInitializing { + _token = token_; + _operatorMaxFeeIncrease = operatorMaxFeeIncrease_; + _declareOperatorFeePeriod = declareOperatorFeePeriod_; + _executeOperatorFeePeriod = executeOperatorFeePeriod_; + _minimumBlocksBeforeLiquidation = minimumBlocksBeforeLiquidation_; } + /*****************/ + /* UUPS required */ + /*****************/ + + function _authorizeUpgrade(address) internal override onlyOwner {} + /*******************************/ /* Operator External Functions */ /*******************************/ @@ -152,10 +170,7 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { if (operator.owner != msg.sender) revert CallerNotOwner(); operator.snapshot = _getSnapshot(operator, uint64(block.number)); - - if (operator.snapshot.balance > 0) { - _transferOperatorBalanceUnsafe(id, operator.snapshot.balance.expand()); - } + uint64 currentBalance = operator.snapshot.balance; operator.snapshot.block = 0; operator.snapshot.balance = 0; @@ -163,6 +178,10 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { operator.fee = 0; _operators[id] = operator; + + if (currentBalance > 0) { + _transferOperatorBalanceUnsafe(id, currentBalance.expand()); + } emit OperatorRemoved(id); } @@ -400,18 +419,15 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { } } - { - uint64 clusterBalance = _clusterBalance(cluster, clusterIndex); - if (!_liquidatable(clusterBalance, cluster.validatorCount, burnRate)) { - revert ClusterNotLiquidatable(); - } + uint64 clusterBalance = _clusterBalance(cluster, clusterIndex); + if (!_liquidatable(clusterBalance, cluster.validatorCount, burnRate)) { + revert ClusterNotLiquidatable(); + } - _token.transfer(msg.sender, clusterBalance.expand()); + cluster.disabled = true; + cluster.balance = 0; + cluster.index = 0; - cluster.disabled = true; - cluster.balance = 0; - cluster.index = 0; - } { DAO memory dao = _dao; @@ -422,6 +438,8 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { _clusters[hashedCluster] = keccak256(abi.encodePacked(cluster.validatorCount, cluster.networkFee, cluster.networkFeeIndex, cluster.index, cluster.balance, cluster.disabled )); + _token.transfer(msg.sender, clusterBalance.expand()); + emit ClusterLiquidated(owner, operatorIds, cluster); } @@ -519,10 +537,10 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { cluster.balance += shrunkAmount; - _deposit(shrunkAmount); - _clusters[hashedCluster] = keccak256(abi.encodePacked(cluster.validatorCount, cluster.networkFee, cluster.networkFeeIndex, cluster.index, cluster.balance, cluster.disabled )); + _deposit(shrunkAmount); + emit ClusterDeposit(msg.sender, operatorIds, amount, cluster); } @@ -839,43 +857,6 @@ contract SSVNetwork is OwnableUpgradeable, ISSVNetwork { return _minimumBlocksBeforeLiquidation; } - /**********************/ - /* Internal Functions */ - /**********************/ - - // solhint-disable-next-line func-name-mixedcase - function __SSVNetwork_init( - IERC20 token_, - uint64 operatorMaxFeeIncrease_, - uint64 declareOperatorFeePeriod_, - uint64 executeOperatorFeePeriod_, - uint64 minimumBlocksBeforeLiquidation_ - ) internal initializer { - __Ownable_init_unchained(); - __SSVNetwork_init_unchained( - token_, - operatorMaxFeeIncrease_, - declareOperatorFeePeriod_, - executeOperatorFeePeriod_, - minimumBlocksBeforeLiquidation_ - ); - } - - // solhint-disable-next-line func-name-mixedcase - function __SSVNetwork_init_unchained( - IERC20 token_, - uint64 operatorMaxFeeIncrease_, - uint64 declareOperatorFeePeriod_, - uint64 executeOperatorFeePeriod_, - uint64 minimumBlocksBeforeLiquidation_ - ) internal onlyInitializing { - _token = token_; - _operatorMaxFeeIncrease = operatorMaxFeeIncrease_; - _declareOperatorFeePeriod = declareOperatorFeePeriod_; - _executeOperatorFeePeriod = executeOperatorFeePeriod_; - _minimumBlocksBeforeLiquidation = minimumBlocksBeforeLiquidation_; - } - /********************************/ /* Validation Private Functions */ /********************************/ diff --git a/contracts/mocks/SSVTokenMock.sol b/contracts/mocks/SSVTokenMock.sol index e5284799..adea872a 100644 --- a/contracts/mocks/SSVTokenMock.sol +++ b/contracts/mocks/SSVTokenMock.sol @@ -1,5 +1,5 @@ //SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity ^0.8.13; +pragma solidity 0.8.16; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; diff --git a/contracts/utils/Types.sol b/contracts/utils/Types.sol index 6899e167..ae6fe43f 100644 --- a/contracts/utils/Types.sol +++ b/contracts/utils/Types.sol @@ -1,6 +1,6 @@ // File: contracts/SSVNetwork.sol // SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity ^0.8.2; +pragma solidity 0.8.16; uint256 constant DEDUCTED_DIGITS = 10000000; diff --git a/hardhat.config.ts b/hardhat.config.ts index cedb7866..b884b317 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -1,14 +1,11 @@ import 'dotenv/config'; import { HardhatUserConfig, task } from 'hardhat/config'; -import '@nomiclabs/hardhat-waffle'; -import '@nomiclabs/hardhat-ethers'; -import '@nomiclabs/hardhat-etherscan'; +import '@nomicfoundation/hardhat-toolbox'; import '@openzeppelin/hardhat-upgrades'; -import 'hardhat-gas-reporter'; import 'hardhat-tracer'; -import 'solidity-coverage'; import '@nomiclabs/hardhat-solhint'; +import 'hardhat-contract-sizer'; const config: HardhatUserConfig = { // Your type-safe config goes here @@ -18,11 +15,11 @@ const config: HardhatUserConfig = { solidity: { compilers: [ { - version: '0.8.13', + version: '0.8.16', settings: { optimizer: { enabled: true, - runs: 10000 + runs: 600 } } } @@ -39,6 +36,7 @@ const config: HardhatUserConfig = { apiKey: process.env.ETHERSCAN_KEY }, gasReporter: { + enabled: true, currency: 'USD', gasPrice: 0.3 } diff --git a/package-lock.json b/package-lock.json index 74dd6a57..ac8d21df 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,36 +6,28 @@ "": { "name": "ssv-network", "devDependencies": { - "@nomiclabs/hardhat-ethers": "^2.0.5", - "@nomiclabs/hardhat-etherscan": "^3.0.3", + "@nomicfoundation/hardhat-toolbox": "^2.0.0", "@nomiclabs/hardhat-solhint": "^2.0.0", - "@nomiclabs/hardhat-waffle": "^2.0.3", - "@openzeppelin/contracts": "4.6.0", - "@openzeppelin/contracts-upgradeable": "4.6.0", - "@openzeppelin/hardhat-upgrades": "^1.17.0", + "@openzeppelin/contracts": "^4.8.0", + "@openzeppelin/contracts-upgradeable": "^4.8.0", + "@openzeppelin/hardhat-upgrades": "^1.22.0", "@types/chai": "^4.3.0", "@types/chai-as-promised": "^7.1.5", "@types/cli-table": "^0.3.0", "@types/mocha": "^9.1.0", "@types/node": "^17.0.23", "@typescript-eslint/eslint-plugin": "^5.36.0", - "chai": "^4.3.6", "chai-as-promised": "^7.1.1", "cli-table": "^0.3.11", "dotenv": "^16.0.0", "eslint": "^8.23.0", - "ethereum-public-key-to-address": "0.0.5", - "ethereum-waffle": "^3.4.4", - "ethers": "^5.6.2", "gh-pages": "^3.2.3", - "hardhat": "^2.12.2", - "hardhat-gas-reporter": "^1.0.9", - "hardhat-tracer": "^1.1.1", + "hardhat": "^2.12.5", + "hardhat-contract-sizer": "^2.6.1", + "hardhat-tracer": "^1.2.1", "prompts": "^2.4.2", "simple-git": "^3.10.0", - "solidity-coverage": "^0.8.2", "ts-node": "^10.7.0", - "typechain": "^3.0.0", "typescript": "^4.6.3" } }, @@ -145,6 +137,16 @@ "node": ">=4" } }, + "node_modules/@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, + "engines": { + "node": ">=0.1.90" + } + }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", @@ -157,344 +159,16 @@ "node": ">=12" } }, - "node_modules/@ensdomains/ens": { - "version": "0.4.5", - "resolved": "https://registry.npmjs.org/@ensdomains/ens/-/ens-0.4.5.tgz", - "integrity": "sha512-JSvpj1iNMFjK6K+uVl4unqMoa9rf5jopb8cya5UGBWz23Nw8hSNT7efgUx4BTlAPAgpNlEioUfeTyQ6J9ZvTVw==", - "deprecated": "Please use @ensdomains/ens-contracts", - "dev": true, - "dependencies": { - "bluebird": "^3.5.2", - "eth-ens-namehash": "^2.0.8", - "solc": "^0.4.20", - "testrpc": "0.0.1", - "web3-utils": "^1.0.0-beta.31" - } - }, - "node_modules/@ensdomains/ens/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@ensdomains/ens/node_modules/camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@ensdomains/ens/node_modules/cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w==", - "dev": true, - "dependencies": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - } - }, - "node_modules/@ensdomains/ens/node_modules/find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==", - "dev": true, - "dependencies": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@ensdomains/ens/node_modules/fs-extra": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", - "integrity": "sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0", - "path-is-absolute": "^1.0.0", - "rimraf": "^2.2.8" - } - }, - "node_modules/@ensdomains/ens/node_modules/get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "node_modules/@ensdomains/ens/node_modules/is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", - "dev": true, - "dependencies": { - "number-is-nan": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@ensdomains/ens/node_modules/jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==", - "dev": true, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/@ensdomains/ens/node_modules/load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@ensdomains/ens/node_modules/parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==", - "dev": true, - "dependencies": { - "error-ex": "^1.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@ensdomains/ens/node_modules/path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==", - "dev": true, - "dependencies": { - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@ensdomains/ens/node_modules/path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@ensdomains/ens/node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@ensdomains/ens/node_modules/read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ==", - "dev": true, - "dependencies": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@ensdomains/ens/node_modules/read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A==", - "dev": true, - "dependencies": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@ensdomains/ens/node_modules/require-from-string": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-1.2.1.tgz", - "integrity": "sha512-H7AkJWMobeskkttHyhTVtS0fxpFLjxhbfMa6Bk3wimP7sdPRGL3EyCg3sAQenFfAe+xQ+oAc85Nmtvq0ROM83Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@ensdomains/ens/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/@ensdomains/ens/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/@ensdomains/ens/node_modules/solc": { - "version": "0.4.26", - "resolved": "https://registry.npmjs.org/solc/-/solc-0.4.26.tgz", - "integrity": "sha512-o+c6FpkiHd+HPjmjEVpQgH7fqZ14tJpXhho+/bQXlXbliLIS/xjXb42Vxh+qQY1WCSTMQ0+a5vR9vi0MfhU6mA==", - "dev": true, - "dependencies": { - "fs-extra": "^0.30.0", - "memorystream": "^0.3.1", - "require-from-string": "^1.1.0", - "semver": "^5.3.0", - "yargs": "^4.7.1" - }, - "bin": { - "solcjs": "solcjs" - } - }, - "node_modules/@ensdomains/ens/node_modules/string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", - "dev": true, - "dependencies": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@ensdomains/ens/node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", - "dev": true, - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@ensdomains/ens/node_modules/strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==", - "dev": true, - "dependencies": { - "is-utf8": "^0.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@ensdomains/ens/node_modules/wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==", - "dev": true, - "dependencies": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@ensdomains/ens/node_modules/y18n": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", - "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==", - "dev": true - }, - "node_modules/@ensdomains/ens/node_modules/yargs": { - "version": "4.8.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz", - "integrity": "sha512-LqodLrnIDM3IFT+Hf/5sxBnEGECrfdC1uIbgZeJmESCSo4HoCAaKEus8MylXHAkdacGc0ye+Qa+dpkuom8uVYA==", - "dev": true, - "dependencies": { - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "lodash.assign": "^4.0.3", - "os-locale": "^1.4.0", - "read-pkg-up": "^1.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^1.0.1", - "which-module": "^1.0.0", - "window-size": "^0.2.0", - "y18n": "^3.2.1", - "yargs-parser": "^2.4.1" - } - }, - "node_modules/@ensdomains/ens/node_modules/yargs-parser": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz", - "integrity": "sha512-9pIKIJhnI5tonzG6OnCFlz/yln8xHYcGl+pn3xR0Vzff0vzN1PbNRaelgfgRUwZ3s4i3jvxT9WhmUGL4whnasA==", - "dev": true, - "dependencies": { - "camelcase": "^3.0.0", - "lodash.assign": "^4.0.6" - } - }, - "node_modules/@ensdomains/resolver": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/@ensdomains/resolver/-/resolver-0.2.4.tgz", - "integrity": "sha512-bvaTH34PMCbv6anRa9I/0zjLJgY4EuznbEMgbV77JBCQ9KNC46rzi0avuxpOfu+xDjPEtSFGqVEOr5GlUSGudA==", - "deprecated": "Please use @ensdomains/ens-contracts", - "dev": true - }, "node_modules/@eslint/eslintrc": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", - "integrity": "sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz", + "integrity": "sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^9.4.0", - "globals": "^13.15.0", + "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -508,84 +182,6 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/@ethereum-waffle/chai": { - "version": "3.4.4", - "resolved": "https://registry.npmjs.org/@ethereum-waffle/chai/-/chai-3.4.4.tgz", - "integrity": "sha512-/K8czydBtXXkcM9X6q29EqEkc5dN3oYenyH2a9hF7rGAApAJUpH8QBtojxOY/xQ2up5W332jqgxwp0yPiYug1g==", - "dev": true, - "dependencies": { - "@ethereum-waffle/provider": "^3.4.4", - "ethers": "^5.5.2" - }, - "engines": { - "node": ">=10.0" - } - }, - "node_modules/@ethereum-waffle/compiler": { - "version": "3.4.4", - "resolved": "https://registry.npmjs.org/@ethereum-waffle/compiler/-/compiler-3.4.4.tgz", - "integrity": "sha512-RUK3axJ8IkD5xpWjWoJgyHclOeEzDLQFga6gKpeGxiS/zBu+HB0W2FvsrrLalTFIaPw/CGYACRBSIxqiCqwqTQ==", - "dev": true, - "dependencies": { - "@resolver-engine/imports": "^0.3.3", - "@resolver-engine/imports-fs": "^0.3.3", - "@typechain/ethers-v5": "^2.0.0", - "@types/mkdirp": "^0.5.2", - "@types/node-fetch": "^2.5.5", - "ethers": "^5.0.1", - "mkdirp": "^0.5.1", - "node-fetch": "^2.6.1", - "solc": "^0.6.3", - "ts-generator": "^0.1.1", - "typechain": "^3.0.0" - }, - "engines": { - "node": ">=10.0" - } - }, - "node_modules/@ethereum-waffle/ens": { - "version": "3.4.4", - "resolved": "https://registry.npmjs.org/@ethereum-waffle/ens/-/ens-3.4.4.tgz", - "integrity": "sha512-0m4NdwWxliy3heBYva1Wr4WbJKLnwXizmy5FfSSr5PMbjI7SIGCdCB59U7/ZzY773/hY3bLnzLwvG5mggVjJWg==", - "dev": true, - "dependencies": { - "@ensdomains/ens": "^0.4.4", - "@ensdomains/resolver": "^0.2.4", - "ethers": "^5.5.2" - }, - "engines": { - "node": ">=10.0" - } - }, - "node_modules/@ethereum-waffle/mock-contract": { - "version": "3.4.4", - "resolved": "https://registry.npmjs.org/@ethereum-waffle/mock-contract/-/mock-contract-3.4.4.tgz", - "integrity": "sha512-Mp0iB2YNWYGUV+VMl5tjPsaXKbKo8MDH9wSJ702l9EBjdxFf/vBvnMBAC1Fub1lLtmD0JHtp1pq+mWzg/xlLnA==", - "dev": true, - "dependencies": { - "@ethersproject/abi": "^5.5.0", - "ethers": "^5.5.2" - }, - "engines": { - "node": ">=10.0" - } - }, - "node_modules/@ethereum-waffle/provider": { - "version": "3.4.4", - "resolved": "https://registry.npmjs.org/@ethereum-waffle/provider/-/provider-3.4.4.tgz", - "integrity": "sha512-GK8oKJAM8+PKy2nK08yDgl4A80mFuI8zBkE0C9GqTRYQqvuxIyXoLmJ5NZU9lIwyWVv5/KsoA11BgAv2jXE82g==", - "dev": true, - "dependencies": { - "@ethereum-waffle/ens": "^3.4.4", - "ethers": "^5.5.2", - "ganache-core": "^2.13.2", - "patch-package": "^6.2.2", - "postinstall-postinstall": "^2.1.0" - }, - "engines": { - "node": ">=10.0" - } - }, "node_modules/@ethersproject/abi": { "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz", @@ -1288,9 +884,9 @@ } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.7", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.7.tgz", - "integrity": "sha512-kBbPWzN8oVMLb0hOUYXhmxggL/1cJE6ydvjDIGi9EnAGUyA7cLVKQg+d/Dsm+KZwx2czGHrCmMVLiyg8s5JPKw==", + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", + "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", "dev": true, "dependencies": { "@humanwhocodes/object-schema": "^1.2.1", @@ -1648,13 +1244,152 @@ "node": ">=14" } }, - "node_modules/@nomicfoundation/solidity-analyzer": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.0.tgz", - "integrity": "sha512-xGWAiVCGOycvGiP/qrlf9f9eOn7fpNbyJygcB0P21a1MDuVPlKt0Srp7rvtBEutYQ48ouYnRXm33zlRnlTOPHg==", + "node_modules/@nomicfoundation/hardhat-chai-matchers": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-chai-matchers/-/hardhat-chai-matchers-1.0.5.tgz", + "integrity": "sha512-+W5C/+5FHI2xBajUN9THSNc1UP6FUsA7LeLmfnaC9VMi/50/DEjjxd8OmizEXgV1Bjck7my4NVQLL1Ti39FkpA==", "dev": true, - "engines": { - "node": ">= 12" + "peer": true, + "dependencies": { + "@ethersproject/abi": "^5.1.2", + "@types/chai-as-promised": "^7.1.3", + "chai-as-promised": "^7.1.1", + "chalk": "^2.4.2", + "deep-eql": "^4.0.1", + "ordinal": "^1.0.3" + }, + "peerDependencies": { + "@nomiclabs/hardhat-ethers": "^2.0.0", + "chai": "^4.2.0", + "ethers": "^5.0.0", + "hardhat": "^2.9.4" + } + }, + "node_modules/@nomicfoundation/hardhat-chai-matchers/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/@nomicfoundation/hardhat-chai-matchers/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, + "peer": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@nomicfoundation/hardhat-chai-matchers/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" + } + }, + "node_modules/@nomicfoundation/hardhat-chai-matchers/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/@nomicfoundation/hardhat-chai-matchers/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/@nomicfoundation/hardhat-chai-matchers/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, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@nomicfoundation/hardhat-chai-matchers/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/@nomicfoundation/hardhat-network-helpers": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-network-helpers/-/hardhat-network-helpers-1.0.7.tgz", + "integrity": "sha512-X+3mNvn8B7BY5hpIaLO+TrfzWq12bpux+ajGGdmdcfC78NXmYmOZkAtiz1QZx1YIZGMS1LaXzPXyBExxKFpCaw==", + "dev": true, + "peer": true, + "dependencies": { + "ethereumjs-util": "^7.1.4" + }, + "peerDependencies": { + "hardhat": "^2.9.5" + } + }, + "node_modules/@nomicfoundation/hardhat-toolbox": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-toolbox/-/hardhat-toolbox-2.0.1.tgz", + "integrity": "sha512-/pr8m9xlqiNlq6fXv4hEPNwdNwUhysoB2qbDCKqERfPpq34EydUQTC3Vis4aIea8RLwSrU8sDXFdv4TQxYstKw==", + "dev": true, + "peerDependencies": { + "@ethersproject/abi": "^5.4.7", + "@ethersproject/providers": "^5.4.7", + "@nomicfoundation/hardhat-chai-matchers": "^1.0.0", + "@nomicfoundation/hardhat-network-helpers": "^1.0.0", + "@nomiclabs/hardhat-ethers": "^2.0.0", + "@nomiclabs/hardhat-etherscan": "^3.0.0", + "@typechain/ethers-v5": "^10.1.0", + "@typechain/hardhat": "^6.1.2", + "@types/chai": "^4.2.0", + "@types/mocha": ">=9.1.0", + "@types/node": ">=12.0.0", + "chai": "^4.2.0", + "ethers": "^5.4.7", + "hardhat": "^2.11.0", + "hardhat-gas-reporter": "^1.0.8", + "solidity-coverage": "^0.8.1", + "ts-node": ">=8.0.0", + "typechain": "^8.1.0", + "typescript": ">=4.5.0" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.0.tgz", + "integrity": "sha512-xGWAiVCGOycvGiP/qrlf9f9eOn7fpNbyJygcB0P21a1MDuVPlKt0Srp7rvtBEutYQ48ouYnRXm33zlRnlTOPHg==", + "dev": true, + "engines": { + "node": ">= 12" }, "optionalDependencies": { "@nomicfoundation/solidity-analyzer-darwin-arm64": "0.1.0", @@ -1830,31 +1565,33 @@ } }, "node_modules/@nomiclabs/hardhat-ethers": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.2.1.tgz", - "integrity": "sha512-RHWYwnxryWR8hzRmU4Jm/q4gzvXpetUOJ4OPlwH2YARcDB+j79+yAYCwO0lN1SUOb4++oOTJEe6AWLEc42LIvg==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.2.2.tgz", + "integrity": "sha512-NLDlDFL2us07C0jB/9wzvR0kuLivChJWCXTKcj3yqjZqMoYp7g7wwS157F70VHx/+9gHIBGzak5pKDwG8gEefA==", "dev": true, + "peer": true, "peerDependencies": { "ethers": "^5.0.0", "hardhat": "^2.0.0" } }, "node_modules/@nomiclabs/hardhat-etherscan": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-3.1.2.tgz", - "integrity": "sha512-IEikeOVq0C/7CY6aD74d8L4BpGoc/FNiN6ldiPVg0QIFIUSu4FSGA1dmtJZJKk1tjpwgrfTLQNWnigtEaN9REg==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-3.1.5.tgz", + "integrity": "sha512-PxPX28AGBAlxgXLU27NB3oiMsklxbNhM75SDC4v1QPCyPeAxGm4xV0WpYbR10W7sxY2WF3Ek7u7GhjbQWa2Fcg==", "dev": true, + "peer": true, "dependencies": { "@ethersproject/abi": "^5.1.2", "@ethersproject/address": "^5.0.2", - "cbor": "^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.4.0" + "undici": "^5.14.0" }, "peerDependencies": { "hardhat": "^2.0.4" @@ -1865,6 +1602,7 @@ "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" }, @@ -1877,6 +1615,7 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, + "peer": true, "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -1891,6 +1630,7 @@ "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" } @@ -1899,13 +1639,15 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true + "dev": true, + "peer": true }, "node_modules/@nomiclabs/hardhat-etherscan/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" } @@ -1915,6 +1657,7 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, + "peer": true, "engines": { "node": ">=4" } @@ -1924,6 +1667,7 @@ "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" }, @@ -1943,38 +1687,22 @@ "hardhat": "^2.0.0" } }, - "node_modules/@nomiclabs/hardhat-waffle": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-waffle/-/hardhat-waffle-2.0.3.tgz", - "integrity": "sha512-049PHSnI1CZq6+XTbrMbMv5NaL7cednTfPenx02k3cEh8wBMLa6ys++dBETJa6JjfwgA9nBhhHQ173LJv6k2Pg==", - "dev": true, - "dependencies": { - "@types/sinon-chai": "^3.2.3", - "@types/web3": "1.0.19" - }, - "peerDependencies": { - "@nomiclabs/hardhat-ethers": "^2.0.0", - "ethereum-waffle": "^3.2.0", - "ethers": "^5.0.0", - "hardhat": "^2.0.0" - } - }, "node_modules/@openzeppelin/contracts": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.6.0.tgz", - "integrity": "sha512-8vi4d50NNya/bQqCmaVzvHNmwHvS0OBKb7HNtuNwEE3scXWrP31fKQoGxNMT+KbzmrNZzatE3QK5p2gFONI/hg==", + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.8.0.tgz", + "integrity": "sha512-AGuwhRRL+NaKx73WKRNzeCxOCOCxpaqF+kp8TJ89QzAipSwZy/NoflkWaL9bywXFRhIzXt8j38sfF7KBKCPWLw==", "dev": true }, "node_modules/@openzeppelin/contracts-upgradeable": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.6.0.tgz", - "integrity": "sha512-5OnVuO4HlkjSCJO165a4i2Pu1zQGzMs//o54LPrwUgxvEO2P3ax1QuaSI0cEHHTveA77guS0PnNugpR2JMsPfA==", + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.8.0.tgz", + "integrity": "sha512-5GeFgqMiDlqGT8EdORadp1ntGF0qzWZLmEY7Wbp/yVhN7/B3NNzCxujuI77ktlyG81N3CUZP8cZe3ZAQ/cW10w==", "dev": true }, "node_modules/@openzeppelin/hardhat-upgrades": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/@openzeppelin/hardhat-upgrades/-/hardhat-upgrades-1.21.0.tgz", - "integrity": "sha512-Kwl7IN0Hlhj4HluMTTl0DrtU90OI/Q6rG3sAyd2pv3fababe9EuZqs9DydOlkWM45JwTzC+eBzX3TgHsqI13eA==", + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/@openzeppelin/hardhat-upgrades/-/hardhat-upgrades-1.22.0.tgz", + "integrity": "sha512-1qyZnDaxl0C8tne7ykNRa/fxw3FrNCY2M3fGuCiQW5DDkJoXhLgm3JVsXwl6X7q9mQSrik4vgBbI3ErmxmZTYg==", "dev": true, "dependencies": { "@openzeppelin/upgrades-core": "^1.20.0", @@ -1998,9 +1726,9 @@ } }, "node_modules/@openzeppelin/upgrades-core": { - "version": "1.20.4", - "resolved": "https://registry.npmjs.org/@openzeppelin/upgrades-core/-/upgrades-core-1.20.4.tgz", - "integrity": "sha512-Y4/+BPIbnopfE6ZhPOE2CD0V5fnvDxKKm7+kryx5+WrcRCTW3B5DjbXL9xyyoviG8Rn5EXUh5Fk1GLbiYDfu0g==", + "version": "1.20.6", + "resolved": "https://registry.npmjs.org/@openzeppelin/upgrades-core/-/upgrades-core-1.20.6.tgz", + "integrity": "sha512-KWdtlahm+iunlAlzLsdpBueanwEx0LLPfAkDL1p0C4SPjMiUqHHFlyGtmmWwdiqDpJ//605vfwkd5RqfnFrHSg==", "dev": true, "dependencies": { "cbor": "^8.0.0", @@ -2012,108 +1740,6 @@ "solidity-ast": "^0.4.15" } }, - "node_modules/@openzeppelin/upgrades-core/node_modules/cbor": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/cbor/-/cbor-8.1.0.tgz", - "integrity": "sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg==", - "dev": true, - "dependencies": { - "nofilter": "^3.1.0" - }, - "engines": { - "node": ">=12.19" - } - }, - "node_modules/@openzeppelin/upgrades-core/node_modules/nofilter": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-3.1.0.tgz", - "integrity": "sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==", - "dev": true, - "engines": { - "node": ">=12.19" - } - }, - "node_modules/@resolver-engine/core": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@resolver-engine/core/-/core-0.3.3.tgz", - "integrity": "sha512-eB8nEbKDJJBi5p5SrvrvILn4a0h42bKtbCTri3ZxCGt6UvoQyp7HnGOfki944bUjBSHKK3RvgfViHn+kqdXtnQ==", - "dev": true, - "dependencies": { - "debug": "^3.1.0", - "is-url": "^1.2.4", - "request": "^2.85.0" - } - }, - "node_modules/@resolver-engine/core/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/@resolver-engine/fs": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@resolver-engine/fs/-/fs-0.3.3.tgz", - "integrity": "sha512-wQ9RhPUcny02Wm0IuJwYMyAG8fXVeKdmhm8xizNByD4ryZlx6PP6kRen+t/haF43cMfmaV7T3Cx6ChOdHEhFUQ==", - "dev": true, - "dependencies": { - "@resolver-engine/core": "^0.3.3", - "debug": "^3.1.0" - } - }, - "node_modules/@resolver-engine/fs/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/@resolver-engine/imports": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@resolver-engine/imports/-/imports-0.3.3.tgz", - "integrity": "sha512-anHpS4wN4sRMwsAbMXhMfOD/y4a4Oo0Cw/5+rue7hSwGWsDOQaAU1ClK1OxjUC35/peazxEl8JaSRRS+Xb8t3Q==", - "dev": true, - "dependencies": { - "@resolver-engine/core": "^0.3.3", - "debug": "^3.1.0", - "hosted-git-info": "^2.6.0", - "path-browserify": "^1.0.0", - "url": "^0.11.0" - } - }, - "node_modules/@resolver-engine/imports-fs": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@resolver-engine/imports-fs/-/imports-fs-0.3.3.tgz", - "integrity": "sha512-7Pjg/ZAZtxpeyCFlZR5zqYkz+Wdo84ugB5LApwriT8XFeQoLwGUj4tZFFvvCuxaNCcqZzCYbonJgmGObYBzyCA==", - "dev": true, - "dependencies": { - "@resolver-engine/fs": "^0.3.3", - "@resolver-engine/imports": "^0.3.3", - "debug": "^3.1.0" - } - }, - "node_modules/@resolver-engine/imports-fs/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/@resolver-engine/imports/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, "node_modules/@scure/base": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.1.tgz", @@ -2266,6 +1892,7 @@ "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.14.5.tgz", "integrity": "sha512-6dKnHZn7fg/iQATVEzqyUOyEidbn05q7YA2mQ9hC0MMXhhV3/JrsxmFSYZAcr7j1yUP700LLhTruvJ3MiQmjJg==", "dev": true, + "peer": true, "dependencies": { "antlr4ts": "^0.5.0-alpha.4" } @@ -2295,16 +1922,79 @@ "dev": true }, "node_modules/@typechain/ethers-v5": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@typechain/ethers-v5/-/ethers-v5-2.0.0.tgz", - "integrity": "sha512-0xdCkyGOzdqh4h5JSf+zoWx85IusEjDcPIwNEHP8mrWSnCae4rvrqB+/gtpdNfX7zjlFlZiMeePn2r63EI3Lrw==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/@typechain/ethers-v5/-/ethers-v5-10.2.0.tgz", + "integrity": "sha512-ikaq0N/w9fABM+G01OFmU3U3dNnyRwEahkdvi9mqy1a3XwKiPZaF/lu54OcNaEWnpvEYyhhS0N7buCtLQqC92w==", "dev": true, + "peer": true, "dependencies": { - "ethers": "^5.0.2" + "lodash": "^4.17.15", + "ts-essentials": "^7.0.1" }, "peerDependencies": { - "ethers": "^5.0.0", - "typechain": "^3.0.0" + "@ethersproject/abi": "^5.0.0", + "@ethersproject/bytes": "^5.0.0", + "@ethersproject/providers": "^5.0.0", + "ethers": "^5.1.3", + "typechain": "^8.1.1", + "typescript": ">=4.3.0" + } + }, + "node_modules/@typechain/hardhat": { + "version": "6.1.5", + "resolved": "https://registry.npmjs.org/@typechain/hardhat/-/hardhat-6.1.5.tgz", + "integrity": "sha512-lg7LW4qDZpxFMknp3Xool61Fg6Lays8F8TXdFGBG+MxyYcYU5795P1U2XdStuzGq9S2Dzdgh+1jGww9wvZ6r4Q==", + "dev": true, + "peer": true, + "dependencies": { + "fs-extra": "^9.1.0" + }, + "peerDependencies": { + "@ethersproject/abi": "^5.4.7", + "@ethersproject/providers": "^5.4.7", + "@typechain/ethers-v5": "^10.2.0", + "ethers": "^5.4.7", + "hardhat": "^2.9.9", + "typechain": "^8.1.1" + } + }, + "node_modules/@typechain/hardhat/node_modules/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, + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typechain/hardhat/node_modules/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, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "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==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 10.0.0" } }, "node_modules/@types/async-eventemitter": { @@ -2348,6 +2038,7 @@ "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.1.tgz", "integrity": "sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==", "dev": true, + "peer": true, "dependencies": { "@types/node": "*" } @@ -2357,6 +2048,7 @@ "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz", "integrity": "sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==", "dev": true, + "peer": true, "dependencies": { "@types/node": "*" } @@ -2366,6 +2058,7 @@ "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", "dev": true, + "peer": true, "dependencies": { "@types/minimatch": "*", "@types/node": "*" @@ -2387,16 +2080,8 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", - "dev": true - }, - "node_modules/@types/mkdirp": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@types/mkdirp/-/mkdirp-0.5.2.tgz", - "integrity": "sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg==", "dev": true, - "dependencies": { - "@types/node": "*" - } + "peer": true }, "node_modules/@types/mocha": { "version": "9.1.1", @@ -2410,16 +2095,6 @@ "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==", "dev": true }, - "node_modules/@types/node-fetch": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.2.tgz", - "integrity": "sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A==", - "dev": true, - "dependencies": { - "@types/node": "*", - "form-data": "^3.0.0" - } - }, "node_modules/@types/pbkdf2": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz", @@ -2430,25 +2105,18 @@ } }, "node_modules/@types/prettier": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.1.tgz", - "integrity": "sha512-ri0UmynRRvZiiUJdiz38MmIblKK+oH30MztdBVR95dv/Ubw6neWSb8u1XpRb72L4qsZOhz+L+z9JD40SJmfWow==", - "dev": true + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.2.tgz", + "integrity": "sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==", + "dev": true, + "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==", - "dev": true - }, - "node_modules/@types/resolve": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz", - "integrity": "sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==", "dev": true, - "dependencies": { - "@types/node": "*" - } + "peer": true }, "node_modules/@types/secp256k1": { "version": "4.0.3", @@ -2465,56 +2133,15 @@ "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==", "dev": true }, - "node_modules/@types/sinon": { - "version": "10.0.13", - "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.13.tgz", - "integrity": "sha512-UVjDqJblVNQYvVNUsj0PuYYw0ELRmgt1Nt5Vk0pT5f16ROGfcKJY8o1HVuMOJOpD727RrGB9EGvoaTQE5tgxZQ==", - "dev": true, - "dependencies": { - "@types/sinonjs__fake-timers": "*" - } - }, - "node_modules/@types/sinon-chai": { - "version": "3.2.9", - "resolved": "https://registry.npmjs.org/@types/sinon-chai/-/sinon-chai-3.2.9.tgz", - "integrity": "sha512-/19t63pFYU0ikrdbXKBWj9PCdnKyTd0Qkz0X91Ta081cYsq90OxYdcWwK/dwEoDa6dtXgj2HJfmzgq+QZTHdmQ==", + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "5.48.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.48.1.tgz", + "integrity": "sha512-9nY5K1Rp2ppmpb9s9S2aBiF3xo5uExCehMDmYmmFqqyxgenbHJ3qbarcLt4ITgaD6r/2ypdlcFRdcuVPnks+fQ==", "dev": true, "dependencies": { - "@types/chai": "*", - "@types/sinon": "*" - } - }, - "node_modules/@types/sinonjs__fake-timers": { - "version": "8.1.2", - "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.2.tgz", - "integrity": "sha512-9GcLXF0/v3t80caGs5p2rRfkB+a8VBGLJZVih6CNFkx8IZ994wiKKLSRs9nuFwk1HevWs/1mnUmkApGrSGsShA==", - "dev": true - }, - "node_modules/@types/underscore": { - "version": "1.11.4", - "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.11.4.tgz", - "integrity": "sha512-uO4CD2ELOjw8tasUrAhvnn2W4A0ZECOvMjCivJr4gA9pGgjv+qxKWY9GLTMVEK8ej85BxQOocUyE7hImmSQYcg==", - "dev": true - }, - "node_modules/@types/web3": { - "version": "1.0.19", - "resolved": "https://registry.npmjs.org/@types/web3/-/web3-1.0.19.tgz", - "integrity": "sha512-fhZ9DyvDYDwHZUp5/STa9XW2re0E8GxoioYJ4pEUZ13YHpApSagixj7IAdoYH5uAK+UalGq6Ml8LYzmgRA/q+A==", - "dev": true, - "dependencies": { - "@types/bn.js": "*", - "@types/underscore": "*" - } - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.42.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.42.1.tgz", - "integrity": "sha512-LyR6x784JCiJ1j6sH5Y0K6cdExqCCm8DJUTcwG5ThNXJj/G8o5E56u5EdG4SLy+bZAwZBswC+GYn3eGdttBVCg==", - "dev": true, - "dependencies": { - "@typescript-eslint/scope-manager": "5.42.1", - "@typescript-eslint/type-utils": "5.42.1", - "@typescript-eslint/utils": "5.42.1", + "@typescript-eslint/scope-manager": "5.48.1", + "@typescript-eslint/type-utils": "5.48.1", + "@typescript-eslint/utils": "5.48.1", "debug": "^4.3.4", "ignore": "^5.2.0", "natural-compare-lite": "^1.4.0", @@ -2573,15 +2200,15 @@ "dev": true }, "node_modules/@typescript-eslint/parser": { - "version": "5.42.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.42.1.tgz", - "integrity": "sha512-kAV+NiNBWVQDY9gDJDToTE/NO8BHi4f6b7zTsVAJoTkmB/zlfOpiEVBzHOKtlgTndCKe8vj9F/PuolemZSh50Q==", + "version": "5.48.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.48.1.tgz", + "integrity": "sha512-4yg+FJR/V1M9Xoq56SF9Iygqm+r5LMXvheo6DQ7/yUWynQ4YfCRnsKuRgqH4EQ5Ya76rVwlEpw4Xu+TgWQUcdA==", "dev": true, "peer": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.42.1", - "@typescript-eslint/types": "5.42.1", - "@typescript-eslint/typescript-estree": "5.42.1", + "@typescript-eslint/scope-manager": "5.48.1", + "@typescript-eslint/types": "5.48.1", + "@typescript-eslint/typescript-estree": "5.48.1", "debug": "^4.3.4" }, "engines": { @@ -2601,13 +2228,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.42.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.42.1.tgz", - "integrity": "sha512-QAZY/CBP1Emx4rzxurgqj3rUinfsh/6mvuKbLNMfJMMKYLRBfweus8brgXF8f64ABkIZ3zdj2/rYYtF8eiuksQ==", + "version": "5.48.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.48.1.tgz", + "integrity": "sha512-S035ueRrbxRMKvSTv9vJKIWgr86BD8s3RqoRZmsSh/s8HhIs90g6UlK8ZabUSjUZQkhVxt7nmZ63VJ9dcZhtDQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.42.1", - "@typescript-eslint/visitor-keys": "5.42.1" + "@typescript-eslint/types": "5.48.1", + "@typescript-eslint/visitor-keys": "5.48.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -2618,13 +2245,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.42.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.42.1.tgz", - "integrity": "sha512-WWiMChneex5w4xPIX56SSnQQo0tEOy5ZV2dqmj8Z371LJ0E+aymWD25JQ/l4FOuuX+Q49A7pzh/CGIQflxMVXg==", + "version": "5.48.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.48.1.tgz", + "integrity": "sha512-Hyr8HU8Alcuva1ppmqSYtM/Gp0q4JOp1F+/JH5D1IZm/bUBrV0edoewQZiEc1r6I8L4JL21broddxK8HAcZiqQ==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "5.42.1", - "@typescript-eslint/utils": "5.42.1", + "@typescript-eslint/typescript-estree": "5.48.1", + "@typescript-eslint/utils": "5.48.1", "debug": "^4.3.4", "tsutils": "^3.21.0" }, @@ -2645,9 +2272,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.42.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.42.1.tgz", - "integrity": "sha512-Qrco9dsFF5lhalz+lLFtxs3ui1/YfC6NdXu+RAGBa8uSfn01cjO7ssCsjIsUs484vny9Xm699FSKwpkCcqwWwA==", + "version": "5.48.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.48.1.tgz", + "integrity": "sha512-xHyDLU6MSuEEdIlzrrAerCGS3T7AA/L8Hggd0RCYBi0w3JMvGYxlLlXHeg50JI9Tfg5MrtsfuNxbS/3zF1/ATg==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -2658,13 +2285,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.42.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.42.1.tgz", - "integrity": "sha512-qElc0bDOuO0B8wDhhW4mYVgi/LZL+igPwXtV87n69/kYC/7NG3MES0jHxJNCr4EP7kY1XVsRy8C/u3DYeTKQmw==", + "version": "5.48.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.48.1.tgz", + "integrity": "sha512-Hut+Osk5FYr+sgFh8J/FHjqX6HFcDzTlWLrFqGoK5kVUN3VBHF/QzZmAsIXCQ8T/W9nQNBTqalxi1P3LSqWnRA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.42.1", - "@typescript-eslint/visitor-keys": "5.42.1", + "@typescript-eslint/types": "5.48.1", + "@typescript-eslint/visitor-keys": "5.48.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -2718,16 +2345,16 @@ "dev": true }, "node_modules/@typescript-eslint/utils": { - "version": "5.42.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.42.1.tgz", - "integrity": "sha512-Gxvf12xSp3iYZd/fLqiQRD4uKZjDNR01bQ+j8zvhPjpsZ4HmvEFL/tC4amGNyxN9Rq+iqvpHLhlqx6KTxz9ZyQ==", + "version": "5.48.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.48.1.tgz", + "integrity": "sha512-SmQuSrCGUOdmGMwivW14Z0Lj8dxG1mOFZ7soeJ0TQZEJcs3n5Ndgkg0A4bcMFzBELqLJ6GTHnEU+iIoaD6hFGA==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.42.1", - "@typescript-eslint/types": "5.42.1", - "@typescript-eslint/typescript-estree": "5.42.1", + "@typescript-eslint/scope-manager": "5.48.1", + "@typescript-eslint/types": "5.48.1", + "@typescript-eslint/typescript-estree": "5.48.1", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0", "semver": "^7.3.7" @@ -2777,12 +2404,12 @@ "dev": true }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.42.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.42.1.tgz", - "integrity": "sha512-LOQtSF4z+hejmpUvitPlc4hA7ERGoj2BVkesOcG91HCn8edLGUXbTrErmutmPbl8Bo9HjAvOO/zBKQHExXNA2A==", + "version": "5.48.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.48.1.tgz", + "integrity": "sha512-Ns0XBwmfuX7ZknznfXozgnydyR8F6ev/KEGePP4i74uL3ArsKbEhJ7raeKr1JSa997DBDwol/4a0Y+At82c9dA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.42.1", + "@typescript-eslint/types": "5.48.1", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -2793,17 +2420,12 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@yarnpkg/lockfile": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", - "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", - "dev": true - }, "node_modules/abbrev": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", "integrity": "sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q==", - "dev": true + "dev": true, + "peer": true }, "node_modules/abort-controller": { "version": "3.0.0", @@ -2866,10 +2488,11 @@ } }, "node_modules/address": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/address/-/address-1.2.1.tgz", - "integrity": "sha512-B+6bi5D34+fDYENiH5qOlA0cV2rAGKuWZ9LeyUUehbXy8e0VS9e498yO0Jeeh+iM+6KbfudHTFjXw2MmJD4QRA==", + "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, "engines": { "node": ">= 10.0.0" } @@ -2936,6 +2559,7 @@ "integrity": "sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==", "dev": true, "optional": true, + "peer": true, "engines": { "node": ">=0.4.2" } @@ -3010,12 +2634,13 @@ "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 + "dev": true, + "peer": true }, "node_modules/anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, "dependencies": { "normalize-path": "^3.0.0", @@ -3038,24 +2663,13 @@ "dev": true }, "node_modules/array-back": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz", - "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==", - "dev": true, - "dependencies": { - "typical": "^2.6.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/array-find-index": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", - "integrity": "sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==", + "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, "engines": { - "node": ">=0.10.0" + "node": ">=6" } }, "node_modules/array-union": { @@ -3081,6 +2695,7 @@ "resolved": "https://registry.npmjs.org/array.prototype.reduce/-/array.prototype.reduce-1.0.5.tgz", "integrity": "sha512-kDdugMl7id9COE8R7MHF5jWk7Dqt/fs4Pv+JXoICnYwqpjjjbUurz6w5fT5IG6brLdJhv6/VoHB0H7oyIBXd+Q==", "dev": true, + "peer": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", @@ -3095,26 +2710,19 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/asap": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", - "dev": true + "dev": true, + "peer": true }, "node_modules/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, + "peer": true, "dependencies": { "safer-buffer": "~2.1.0" } @@ -3124,6 +2732,7 @@ "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" } @@ -3133,6 +2742,7 @@ "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", "dev": true, + "peer": true, "engines": { "node": "*" } @@ -3142,6 +2752,7 @@ "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true, + "peer": true, "engines": { "node": ">=8" } @@ -3168,22 +2779,48 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true + "dev": true, + "peer": true + }, + "node_modules/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, + "engines": { + "node": ">= 4.0.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" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/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, + "peer": true, "engines": { "node": "*" } }, "node_modules/aws4": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", - "dev": true + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz", + "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==", + "dev": true, + "peer": true }, "node_modules/balanced-match": { "version": "1.0.2", @@ -3225,6 +2862,7 @@ "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" } @@ -3233,7 +2871,8 @@ "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", - "dev": true + "dev": true, + "peer": true }, "node_modules/bech32": { "version": "1.1.4", @@ -3242,9 +2881,9 @@ "dev": true }, "node_modules/bigint-crypto-utils": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/bigint-crypto-utils/-/bigint-crypto-utils-3.1.7.tgz", - "integrity": "sha512-zpCQpIE2Oy5WIQpjC9iYZf8Uh9QqoS51ZCooAcNvzv1AQ3VWdT52D0ksr1+/faeK8HVIej1bxXcP75YcqH3KPA==", + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/bigint-crypto-utils/-/bigint-crypto-utils-3.1.8.tgz", + "integrity": "sha512-+VMV9Laq8pXLBKKKK49nOoq9bfR3j7NNQAtbA617a4nw9bVLo8rsqkKMBgM2AJWlNX9fEIyYaYX+d0laqYV4tw==", "dev": true, "dependencies": { "bigint-mod-arith": "^3.1.0" @@ -3262,15 +2901,6 @@ "node": ">=10.4.0" } }, - "node_modules/bignumber.js": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.0.tgz", - "integrity": "sha512-4LwHK4nfDOraBCtst+wOWIHbu1vhvAPJK8g8nROd4iuc3PSEjWif/qwbkh8jwCJz6yDBvtU4KPynETgrfh7y3A==", - "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", @@ -3286,12 +2916,6 @@ "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==", "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", @@ -3491,33 +3115,23 @@ } }, "node_modules/camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha512-FxAv7HpHrXbh3aPo4o2qxHay2lkLY3x5Mw3KeE4KQE8ysVfziWeRZDwcjauvwBSGEC/nXUPzZy8zeh4HokqOnw==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true, "engines": { - "node": ">=4" - } - }, - "node_modules/camelcase-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz", - "integrity": "sha512-Ej37YKYbFUI8QiYlvj9YHb6/Z60dZyPJW0Cs8sFilMbd2lP0bw3ylAq9yJkK4lcTA2dID5fG8LjmJYbO7kWb7Q==", - "dev": true, - "dependencies": { - "camelcase": "^4.1.0", - "map-obj": "^2.0.0", - "quick-lru": "^1.0.0" + "node": ">=10" }, - "engines": { - "node": ">=4" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", - "dev": true + "dev": true, + "peer": true }, "node_modules/catering": { "version": "2.1.1", @@ -3529,16 +3143,15 @@ } }, "node_modules/cbor": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/cbor/-/cbor-5.2.0.tgz", - "integrity": "sha512-5IMhi9e1QU76ppa5/ajP1BmMWZ2FHkhAhjeVKQ/EFCgYSEaeVaoGtL7cxJskf9oCCk+XjzaIdc3IuU/dbA/o2A==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/cbor/-/cbor-8.1.0.tgz", + "integrity": "sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg==", "dev": true, "dependencies": { - "bignumber.js": "^9.0.1", - "nofilter": "^1.0.4" + "nofilter": "^3.1.0" }, "engines": { - "node": ">=6.0.0" + "node": ">=12.19" } }, "node_modules/chai": { @@ -3546,6 +3159,7 @@ "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.7.tgz", "integrity": "sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==", "dev": true, + "peer": true, "dependencies": { "assertion-error": "^1.1.0", "check-error": "^1.0.2", @@ -3598,6 +3212,7 @@ "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", "dev": true, + "peer": true, "engines": { "node": "*" } @@ -3717,29 +3332,18 @@ } }, "node_modules/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==", + "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, "dependencies": { - "object-assign": "^4.1.0", - "string-width": "^2.1.1" + "string-width": "^4.2.0" }, "engines": { - "node": ">=6" + "node": "10.* || >= 12.*" }, "optionalDependencies": { - "colors": "^1.1.2" - } - }, - "node_modules/cli-table3/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, - "optional": true, - "engines": { - "node": ">=0.1.90" + "@colors/colors": "1.5.0" } }, "node_modules/cli-width": { @@ -3759,38 +3363,6 @@ "wrap-ansi": "^7.0.0" } }, - "node_modules/cliui/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/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, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -3823,6 +3395,7 @@ "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" }, @@ -3837,17 +3410,133 @@ "dev": true }, "node_modules/command-line-args": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-4.0.7.tgz", - "integrity": "sha512-aUdPvQRAyBvQd2n7jXcsMDz68ckBJELXNzBybCHOibUWEg0mWTnaYCSRU8h9R+aNRSvDihJtssSRCiDRpLaezA==", + "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, "dependencies": { - "array-back": "^2.0.0", - "find-replace": "^1.0.3", - "typical": "^2.6.1" + "array-back": "^3.1.0", + "find-replace": "^3.0.0", + "lodash.camelcase": "^4.3.0", + "typical": "^4.0.0" }, - "bin": { - "command-line-args": "bin/cli.js" + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/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, + "dependencies": { + "array-back": "^4.0.2", + "chalk": "^2.4.2", + "table-layout": "^1.0.2", + "typical": "^5.2.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/command-line-usage/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/command-line-usage/node_modules/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/command-line-usage/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, + "peer": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/command-line-usage/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" + } + }, + "node_modules/command-line-usage/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/command-line-usage/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/command-line-usage/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, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/command-line-usage/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/command-line-usage/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, + "peer": true, + "engines": { + "node": ">=8" } }, "node_modules/commander": { @@ -3863,9 +3552,9 @@ "dev": true }, "node_modules/compare-versions": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-5.0.1.tgz", - "integrity": "sha512-v8Au3l0b+Nwkp4G142JcgJFh1/TUhdxut7wzD1Nq1dyp5oa3tXaqb03EXOAB6jS4gMlalkjAUPZBMiAfKUixHQ==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-5.0.3.tgz", + "integrity": "sha512-4UZlZP8Z99MGEY+Ovg/uJxJuvoXuN4M6B3hKaiackiHrgzQFEe3diJi1mf1PNHbFujM7FvLrK2bpgIaImbtZ1A==", "dev": true }, "node_modules/concat-map": { @@ -3882,6 +3571,7 @@ "engines": [ "node >= 0.8" ], + "peer": true, "dependencies": { "buffer-from": "^1.0.0", "inherits": "^2.0.3", @@ -3894,6 +3584,7 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", "dev": true, + "peer": true, "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -3908,13 +3599,15 @@ "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 + "dev": true, + "peer": true }, "node_modules/concat-stream/node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, + "peer": true, "dependencies": { "safe-buffer": "~5.1.0" } @@ -3932,7 +3625,8 @@ "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 + "dev": true, + "peer": true }, "node_modules/cosmiconfig": { "version": "5.2.1", @@ -4070,27 +3764,17 @@ "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", "dev": true, + "peer": true, "engines": { "node": "*" } }, - "node_modules/currently-unhandled": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", - "integrity": "sha512-/fITjgjGU50vjQ4FH6eUoYu+iUoUKIXws2hL15JJpIR+BbTxaXQsMuuyjtNh2WqsSBS5nsaZHFsFecyw5CCAng==", - "dev": true, - "dependencies": { - "array-find-index": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "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" }, @@ -4102,7 +3786,8 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/death/-/death-1.1.0.tgz", "integrity": "sha512-vsV6S4KVHvTGxbEcij7hkWRv0It+sGGWVOM67dQde/o5Xjnr+KmLjxWJii2uEObIrt1CcM9w0Yaovx+iOlIL+w==", - "dev": true + "dev": true, + "peer": true }, "node_modules/debug": { "version": "4.3.4", @@ -4122,44 +3807,23 @@ } }, "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, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/decamelize-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", - "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", "dev": true, - "dependencies": { - "decamelize": "^1.1.0", - "map-obj": "^1.0.0" - }, "engines": { - "node": ">=0.10.0" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/decamelize-keys/node_modules/map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/deep-eql": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.2.tgz", - "integrity": "sha512-gT18+YW4CcW/DBNTwAmqTtkJh7f9qqScu2qFVlx7kCoeY9tlBu9cUcr7+I+Z/noG8INehS3xQgLpTtd/QUTn4w==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", + "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", "dev": true, + "peer": true, "dependencies": { "type-detect": "^4.0.0" }, @@ -4167,6 +3831,16 @@ "node": ">=6" } }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -4178,6 +3852,7 @@ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", "dev": true, + "peer": true, "dependencies": { "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" @@ -4194,6 +3869,7 @@ "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" } @@ -4212,6 +3888,7 @@ "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.5.1.tgz", "integrity": "sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ==", "dev": true, + "peer": true, "dependencies": { "address": "^1.0.1", "debug": "4" @@ -4235,6 +3912,7 @@ "resolved": "https://registry.npmjs.org/difflib/-/difflib-0.2.4.tgz", "integrity": "sha512-9YVwmMb0wQHQNr5J9m6BSj6fk4pfGITGQOOs+D9Fl+INODWFOfvhIU1hNv6GgR1RBoC/9NJcwu77zShxV0kT7w==", "dev": true, + "peer": true, "dependencies": { "heap": ">= 0.2.0" }, @@ -4280,6 +3958,7 @@ "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" @@ -4349,35 +4028,45 @@ } }, "node_modules/es-abstract": { - "version": "1.20.4", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.4.tgz", - "integrity": "sha512-0UtvRN79eMe2L+UNEF1BwRe364sj/DXhQ/k5FmivgoSdpM90b8Jc0mDzKMGo7QS0BVbOP/bTwBKNnDc9rNzaPA==", + "version": "1.21.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.1.tgz", + "integrity": "sha512-QudMsPOz86xYz/1dG1OuGBKOELjCh99IIWHLzy5znUB6j8xG2yMA7bfTV86VSqKF+Y/H08vQPR+9jyXpuC6hfg==", "dev": true, + "peer": true, "dependencies": { + "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.2", + "es-set-tostringtag": "^2.0.1", "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", "function.prototype.name": "^1.1.5", "get-intrinsic": "^1.1.3", "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.3", + "internal-slot": "^1.0.4", + "is-array-buffer": "^3.0.1", "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.2", "object-keys": "^1.1.1", "object.assign": "^4.1.4", "regexp.prototype.flags": "^1.4.3", "safe-regex-test": "^1.0.0", - "string.prototype.trimend": "^1.0.5", - "string.prototype.trimstart": "^1.0.5", - "unbox-primitive": "^1.0.2" + "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" }, "engines": { "node": ">= 0.4" @@ -4391,6 +4080,7 @@ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", "dev": true, + "peer": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", @@ -4408,13 +4098,30 @@ "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 + "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==", + "dev": true, + "peer": true, + "dependencies": { + "get-intrinsic": "^1.1.3", + "has": "^1.0.3", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } }, "node_modules/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, "dependencies": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", @@ -4453,6 +4160,7 @@ "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", "integrity": "sha512-yhi5S+mNTOuRvyW4gWlg5W1byMaQGWWSYHXsuFZ7GBo7tpyOwi2EdzMP/QWxh9hwkD2m+wDVHJsxhRIj+v/b/A==", "dev": true, + "peer": true, "dependencies": { "esprima": "^2.7.1", "estraverse": "^1.9.1", @@ -4475,6 +4183,7 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", "integrity": "sha512-25w1fMXQrGdoquWnScXZGckOv+Wes+JDnuN/+7ex3SauFRS72r2lFDec0EKPt2YD1wUJ/IrfEex+9yp4hfSOJA==", "dev": true, + "peer": true, "engines": { "node": ">=0.10.0" } @@ -4484,6 +4193,7 @@ "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", "dev": true, + "peer": true, "dependencies": { "prelude-ls": "~1.1.2", "type-check": "~0.3.2" @@ -4497,6 +4207,7 @@ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", "dev": true, + "peer": true, "dependencies": { "deep-is": "~0.1.3", "fast-levenshtein": "~2.0.6", @@ -4514,6 +4225,7 @@ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", "dev": true, + "peer": true, "engines": { "node": ">= 0.8.0" } @@ -4523,6 +4235,7 @@ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", "dev": true, + "peer": true, "dependencies": { "prelude-ls": "~1.1.2" }, @@ -4531,13 +4244,13 @@ } }, "node_modules/eslint": { - "version": "8.27.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.27.0.tgz", - "integrity": "sha512-0y1bfG2ho7mty+SiILVf9PfuRA49ek4Nc60Wmmu62QlobNR+CeXa4xXIJgcuwSQgZiWaPH+5BDsctpIW0PR/wQ==", + "version": "8.31.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.31.0.tgz", + "integrity": "sha512-0tQQEVdmPZ1UtUKXjX7EMm9BlgJ08G90IhWh0PKDCb3ZLsgAOHI8fYSIzYVZej92zsgq+ft0FGsxhJ3xo2tbuA==", "dev": true, "dependencies": { - "@eslint/eslintrc": "^1.3.3", - "@humanwhocodes/config-array": "^0.11.6", + "@eslint/eslintrc": "^1.4.1", + "@humanwhocodes/config-array": "^0.11.8", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "ajv": "^6.10.0", @@ -4556,7 +4269,7 @@ "file-entry-cache": "^6.0.1", "find-up": "^5.0.0", "glob-parent": "^6.0.2", - "globals": "^13.15.0", + "globals": "^13.19.0", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", "import-fresh": "^3.0.0", @@ -4679,6 +4392,7 @@ "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", "integrity": "sha512-OarPfz0lFCiW4/AV2Oy1Rp9qu0iusTKqykwTspGCZtPxmF81JR4MmIebvF1F9+UOKth2ZubLQ4XGGaU+hSn99A==", "dev": true, + "peer": true, "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" @@ -4747,27 +4461,12 @@ "node": ">=0.10.0" } }, - "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, - "dependencies": { - "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.25", "resolved": "https://registry.npmjs.org/eth-gas-reporter/-/eth-gas-reporter-0.2.25.tgz", "integrity": "sha512-1fRgyE4xUB8SoqLgN3eDfpDfwEfRxh2Sz1b7wzFbyQA+9TekMmvSjjoRu9SKcSVyK+vLkLIsVbJDsTWjw195OQ==", "dev": true, + "peer": true, "dependencies": { "@ethersproject/abi": "^5.0.0-beta.146", "@solidity-parser/parser": "^0.14.0", @@ -4799,17 +4498,19 @@ "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": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "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": ">=6" + "node": ">=4" } }, "node_modules/eth-gas-reporter/node_modules/ansi-styles": { @@ -4817,6 +4518,7 @@ "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" }, @@ -4829,6 +4531,7 @@ "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" } @@ -4837,13 +4540,15 @@ "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 + "dev": true, + "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" } @@ -4853,6 +4558,7 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, + "peer": true, "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -4867,6 +4573,7 @@ "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" }, @@ -4879,6 +4586,7 @@ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", "dev": true, + "peer": true, "dependencies": { "anymatch": "~3.1.1", "braces": "~3.0.2", @@ -4895,22 +4603,79 @@ "fsevents": "~2.1.1" } }, + "node_modules/eth-gas-reporter/node_modules/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, + "dependencies": { + "object-assign": "^4.1.0", + "string-width": "^2.1.1" + }, + "engines": { + "node": ">=6" + }, + "optionalDependencies": { + "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==", "dev": true, + "peer": true, "dependencies": { "string-width": "^3.1.0", "strip-ansi": "^5.2.0", "wrap-ansi": "^5.1.0" } }, + "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==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "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==", + "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/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==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, "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==", "dev": true, + "peer": true, "dependencies": { "color-name": "1.1.3" } @@ -4919,13 +4684,15 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true + "dev": true, + "peer": 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==", "dev": true, + "peer": true, "engines": { "node": ">=0.1.90" } @@ -4936,15 +4703,27 @@ "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/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==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.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==", "dev": true, + "peer": true, "engines": { "node": ">=0.3.1" } @@ -4953,13 +4732,15 @@ "version": "7.0.3", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true + "dev": true, + "peer": true }, "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" } @@ -4969,6 +4750,7 @@ "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" @@ -4982,6 +4764,7 @@ "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.1.2.tgz", "integrity": "sha512-XDSJlg4BD+hq9N2FjvotwUET9Tfxpxc3kWGE2AqUG5vcbeunnbImVk3cj6e/xT3phdW21mE8R5IugU4fspQDcQ==", "dev": true, + "peer": true, "dependencies": { "@noble/hashes": "1.1.2", "@noble/secp256k1": "1.6.3", @@ -4994,6 +4777,7 @@ "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.49.tgz", "integrity": "sha512-kPltTvWiyu+OktYy1IStSO16i2e7cS9D9OxZ81q2UUaiNPVrm/RTcbxamCXF9VUSKzJIdJV68EAIhTEVBalRWg==", "dev": true, + "peer": true, "dependencies": { "aes-js": "3.0.0", "bn.js": "^4.11.9", @@ -5011,6 +4795,7 @@ "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" }, @@ -5023,6 +4808,7 @@ "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" }, @@ -5041,6 +4827,7 @@ "os": [ "darwin" ], + "peer": true, "engines": { "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } @@ -5050,6 +4837,7 @@ "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", @@ -5067,6 +4855,7 @@ "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" }, @@ -5079,6 +4868,7 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, + "peer": true, "engines": { "node": ">=4" } @@ -5088,22 +4878,35 @@ "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", "dev": true, + "peer": true, "dependencies": { "inherits": "^2.0.3", "minimalistic-assert": "^1.0.0" } }, + "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": ">=4" + } + }, "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 + "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==", "dev": true, + "peer": true, "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -5117,6 +4920,7 @@ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", "dev": true, + "peer": true, "dependencies": { "p-locate": "^3.0.0", "path-exists": "^3.0.0" @@ -5130,6 +4934,7 @@ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", "dev": true, + "peer": true, "dependencies": { "chalk": "^2.4.2" }, @@ -5142,6 +4947,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, + "peer": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -5154,6 +4960,7 @@ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", "dev": true, + "peer": true, "dependencies": { "minimist": "^1.2.5" }, @@ -5166,6 +4973,7 @@ "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", "dev": true, + "peer": true, "dependencies": { "ansi-colors": "3.2.3", "browser-stdout": "1.3.1", @@ -5208,13 +5016,15 @@ "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 + "dev": true, + "peer": 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==", "dev": true, + "peer": true, "dependencies": { "p-try": "^2.0.0" }, @@ -5230,6 +5040,7 @@ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", "dev": true, + "peer": true, "dependencies": { "p-limit": "^2.0.0" }, @@ -5242,6 +5053,7 @@ "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" } @@ -5251,6 +5063,7 @@ "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" }, @@ -5258,48 +5071,45 @@ "node": ">= 8" } }, - "node_modules/eth-gas-reporter/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 - }, "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 + "dev": true, + "peer": 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 + "dev": true, + "peer": true }, "node_modules/eth-gas-reporter/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==", + "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/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "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/strip-json-comments": { @@ -5307,6 +5117,7 @@ "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" } @@ -5316,6 +5127,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", "dev": true, + "peer": true, "dependencies": { "has-flag": "^3.0.0" }, @@ -5328,13 +5140,15 @@ "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 + "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==", "dev": true, + "peer": true, "dependencies": { "isexe": "^2.0.0" }, @@ -5342,17 +5156,12 @@ "which": "bin/which" } }, - "node_modules/eth-gas-reporter/node_modules/which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", - "dev": true - }, "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==", "dev": true, + "peer": true, "dependencies": { "ansi-styles": "^3.2.0", "string-width": "^3.0.0", @@ -5362,17 +5171,57 @@ "node": ">=6" } }, - "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 - }, + "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==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "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==", + "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/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==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "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/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==", "dev": true, + "peer": true, "dependencies": { "cliui": "^5.0.0", "find-up": "^3.0.0", @@ -5391,6 +5240,7 @@ "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" @@ -5401,6 +5251,7 @@ "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", @@ -5410,26 +5261,52 @@ "node": ">=6" } }, - "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/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==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "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==", "dev": true, + "peer": true, "dependencies": { - "js-sha3": "^0.8.0" + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" } }, - "node_modules/ethereum-checksum-address": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/ethereum-checksum-address/-/ethereum-checksum-address-0.0.2.tgz", - "integrity": "sha512-GAb7mPvGgcfi1j+Bsnwm9af9Z7dLUKp+5cFm88+kMrKACfh9gLatGLVVK5pSGEG2pOGfrmqCRcuh3RtMjIg8GQ==", + "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==", "dev": true, + "peer": true, "dependencies": { - "keccak256": "^1.0.0", - "meow": "^5.0.0" + "ansi-regex": "^4.1.0" }, - "bin": { - "ethereum_checksum_address": "bin/ethereum_checksum_address" + "engines": { + "node": ">=6" + } + }, + "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, + "dependencies": { + "js-sha3": "^0.8.0" } }, "node_modules/ethereum-cryptography": { @@ -5455,41 +5332,6 @@ "setimmediate": "^1.0.5" } }, - "node_modules/ethereum-public-key-to-address": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/ethereum-public-key-to-address/-/ethereum-public-key-to-address-0.0.5.tgz", - "integrity": "sha512-j7k9dP49JuK50PtygiTfqjrZLsk0Hc3Vh5jjqCH8pl4mPfwcQwA9Ds+ie7BXr2JdpFDB3cYR8H/1Rwp0jU5Nxg==", - "dev": true, - "dependencies": { - "ethereum-checksum-address": "0.0.2", - "keccak": "^3.0.1", - "meow": "^5.0.0", - "secp256k1": "^4.0.2" - }, - "bin": { - "ethereum_public_key_to_address": "bin/ethereum_public_key_to_address", - "ethereum-public-key-to-address": "bin/ethereum_public_key_to_address" - } - }, - "node_modules/ethereum-waffle": { - "version": "3.4.4", - "resolved": "https://registry.npmjs.org/ethereum-waffle/-/ethereum-waffle-3.4.4.tgz", - "integrity": "sha512-PA9+jCjw4WC3Oc5ocSMBj5sXvueWQeAbvCA+hUlb6oFgwwKyq5ka3bWQ7QZcjzIX+TdFkxP4IbFmoY2D8Dkj9Q==", - "dev": true, - "dependencies": { - "@ethereum-waffle/chai": "^3.4.4", - "@ethereum-waffle/compiler": "^3.4.4", - "@ethereum-waffle/mock-contract": "^3.4.4", - "@ethereum-waffle/provider": "^3.4.4", - "ethers": "^5.0.1" - }, - "bin": { - "waffle": "bin/waffle" - }, - "engines": { - "node": ">=10.0" - } - }, "node_modules/ethereumjs-abi": { "version": "0.6.8", "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz", @@ -5599,6 +5441,7 @@ "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", "integrity": "sha512-/Sn9Y0oKl0uqQuvgFk/zQgR7aw1g36qX/jzSQ5lSwlO0GigPymk4eGQfeNTD03w1dPOqfz8V77Cy43jH56pagw==", "dev": true, + "peer": true, "dependencies": { "bn.js": "4.11.6", "number-to-bn": "1.7.0" @@ -5612,7 +5455,8 @@ "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 + "dev": true, + "peer": true }, "node_modules/ethjs-util": { "version": "0.1.6", @@ -5651,7 +5495,8 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true + "dev": true, + "peer": true }, "node_modules/external-editor": { "version": "3.1.0", @@ -5674,7 +5519,8 @@ "dev": true, "engines": [ "node >=0.6.0" - ] + ], + "peer": true }, "node_modules/fast-deep-equal": { "version": "3.1.3", @@ -5729,9 +5575,9 @@ "dev": true }, "node_modules/fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", "dev": true, "dependencies": { "reusify": "^1.0.4" @@ -5826,30 +5672,18 @@ } }, "node_modules/find-replace": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-1.0.3.tgz", - "integrity": "sha512-KrUnjzDCD9426YnCP56zGYy/eieTnhtK6Vn++j+JJzmlsWWwEkDnsyVF575spT6HJ6Ow9tlbT3TQTDsa+O4UWA==", + "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": { - "array-back": "^1.0.4", - "test-value": "^2.1.0" + "array-back": "^3.0.1" }, "engines": { "node": ">=4.0.0" } }, - "node_modules/find-replace/node_modules/array-back": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", - "integrity": "sha512-1WxbZvrmyhkNoeYcizokbmh5oiOCIfyvGtcqbK3Ls1v1fKcquzxnQSceOx6tzq7jmai2kFLWIpGND2cLhH6TPw==", - "dev": true, - "dependencies": { - "typical": "^2.6.0" - }, - "engines": { - "node": ">=0.12.0" - } - }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -5866,15 +5700,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/find-yarn-workspace-root": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz", - "integrity": "sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==", - "dev": true, - "dependencies": { - "micromatch": "^4.0.2" - } - }, "node_modules/flat": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", @@ -5923,27 +5748,39 @@ } } }, + "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": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "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.8", + "combined-stream": "^1.0.6", "mime-types": "^2.1.12" }, "engines": { - "node": ">= 6" + "node": ">= 0.12" } }, "node_modules/fp-ts": { @@ -5970,7 +5807,8 @@ "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 + "dev": true, + "peer": true }, "node_modules/fs.realpath": { "version": "1.0.0", @@ -6003,6 +5841,7 @@ "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", @@ -6027,1435 +5866,1317 @@ "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/ganache-core": { - "version": "2.13.2", - "resolved": "https://registry.npmjs.org/ganache-core/-/ganache-core-2.13.2.tgz", - "integrity": "sha512-tIF5cR+ANQz0+3pHWxHjIwHqFXcVo0Mb+kcsNhglNFALcYo49aQpnS9dqHartqPfMFjiHh/qFoD3mYK0d/qGgw==", - "bundleDependencies": [ - "keccak" - ], - "deprecated": "ganache-core is now ganache; visit https://trfl.io/g7 for details", + "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, - "hasShrinkwrap": true, - "dependencies": { - "abstract-leveldown": "3.0.0", - "async": "2.6.2", - "bip39": "2.5.0", - "cachedown": "1.0.0", - "clone": "2.1.2", - "debug": "3.2.6", - "encoding-down": "5.0.4", - "eth-sig-util": "3.0.0", - "ethereumjs-abi": "0.6.8", - "ethereumjs-account": "3.0.0", - "ethereumjs-block": "2.2.2", - "ethereumjs-common": "1.5.0", - "ethereumjs-tx": "2.1.2", - "ethereumjs-util": "6.2.1", - "ethereumjs-vm": "4.2.0", - "heap": "0.2.6", - "keccak": "3.0.1", - "level-sublevel": "6.6.4", - "levelup": "3.1.1", - "lodash": "4.17.20", - "lru-cache": "5.1.1", - "merkle-patricia-tree": "3.0.0", - "patch-package": "6.2.2", - "seedrandom": "3.0.1", - "source-map-support": "0.5.12", - "tmp": "0.1.0", - "web3-provider-engine": "14.2.1", - "websocket": "1.0.32" - }, "engines": { - "node": ">=8.9.0" - }, - "optionalDependencies": { - "ethereumjs-wallet": "0.6.5", - "web3": "1.2.11" + "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/ganache-core/node_modules/@ethersproject/abi": { - "version": "5.0.0-beta.153", + "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, - "license": "MIT", - "optional": true, - "dependencies": { - "@ethersproject/address": ">=5.0.0-beta.128", - "@ethersproject/bignumber": ">=5.0.0-beta.130", - "@ethersproject/bytes": ">=5.0.0-beta.129", - "@ethersproject/constants": ">=5.0.0-beta.128", - "@ethersproject/hash": ">=5.0.0-beta.128", - "@ethersproject/keccak256": ">=5.0.0-beta.127", - "@ethersproject/logger": ">=5.0.0-beta.129", - "@ethersproject/properties": ">=5.0.0-beta.131", - "@ethersproject/strings": ">=5.0.0-beta.130" + "peer": true, + "engines": { + "node": "*" } }, - "node_modules/ganache-core/node_modules/@ethersproject/abstract-provider": { - "version": "5.0.8", + "node_modules/get-intrinsic": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", + "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", "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" - } - ], - "license": "MIT", - "optional": true, "dependencies": { - "@ethersproject/bignumber": "^5.0.13", - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/logger": "^5.0.8", - "@ethersproject/networks": "^5.0.7", - "@ethersproject/properties": "^5.0.7", - "@ethersproject/transactions": "^5.0.9", - "@ethersproject/web": "^5.0.12" + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ganache-core/node_modules/@ethersproject/abstract-signer": { - "version": "5.0.10", + "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, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@ethersproject/abstract-provider": "^5.0.8", - "@ethersproject/bignumber": "^5.0.13", - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/logger": "^5.0.8", - "@ethersproject/properties": "^5.0.7" + "peer": true, + "engines": { + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/@ethersproject/address": { - "version": "5.0.9", + "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, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "optional": true, + "peer": true, "dependencies": { - "@ethersproject/bignumber": "^5.0.13", - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/keccak256": "^5.0.7", - "@ethersproject/logger": "^5.0.8", - "@ethersproject/rlp": "^5.0.7" + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ganache-core/node_modules/@ethersproject/base64": { - "version": "5.0.7", + "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, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "optional": true, + "peer": true, "dependencies": { - "@ethersproject/bytes": "^5.0.9" + "assert-plus": "^1.0.0" } }, - "node_modules/ganache-core/node_modules/@ethersproject/bignumber": { - "version": "5.0.13", + "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, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "optional": true, "dependencies": { - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/logger": "^5.0.8", - "bn.js": "^4.4.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" } }, - "node_modules/ganache-core/node_modules/@ethersproject/bytes": { - "version": "5.0.9", + "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, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "optional": true, "dependencies": { - "@ethersproject/logger": "^5.0.8" + "array-uniq": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/ganache-core/node_modules/@ethersproject/constants": { - "version": "5.0.8", + "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, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "optional": true, "dependencies": { - "@ethersproject/bignumber": "^5.0.13" + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" } }, - "node_modules/ganache-core/node_modules/@ethersproject/hash": { - "version": "5.0.10", + "node_modules/gh-pages/node_modules/globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw==", "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" - } - ], - "license": "MIT", - "optional": true, "dependencies": { - "@ethersproject/abstract-signer": "^5.0.10", - "@ethersproject/address": "^5.0.9", - "@ethersproject/bignumber": "^5.0.13", - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/keccak256": "^5.0.7", - "@ethersproject/logger": "^5.0.8", - "@ethersproject/properties": "^5.0.7", - "@ethersproject/strings": "^5.0.8" + "array-union": "^1.0.1", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/ganache-core/node_modules/@ethersproject/keccak256": { - "version": "5.0.7", + "node_modules/gh-pages/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", "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" - } - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@ethersproject/bytes": "^5.0.9", - "js-sha3": "0.5.7" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/ganache-core/node_modules/@ethersproject/logger": { - "version": "5.0.8", + "node_modules/ghost-testrpc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/ghost-testrpc/-/ghost-testrpc-0.0.2.tgz", + "integrity": "sha512-i08dAEgJ2g8z5buJIrCTduwPIhih3DP+hOCTyyryikfV8T0bNvHnGXO67i0DD1H4GBDETTclPy9njZbfluQYrQ==", "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" - } - ], - "license": "MIT", - "optional": true + "peer": true, + "dependencies": { + "chalk": "^2.4.2", + "node-emoji": "^1.10.0" + }, + "bin": { + "testrpc-sc": "index.js" + } }, - "node_modules/ganache-core/node_modules/@ethersproject/networks": { - "version": "5.0.7", + "node_modules/ghost-testrpc/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, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "optional": true, + "peer": true, "dependencies": { - "@ethersproject/logger": "^5.0.8" + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/@ethersproject/properties": { - "version": "5.0.7", + "node_modules/ghost-testrpc/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, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "optional": true, + "peer": true, "dependencies": { - "@ethersproject/logger": "^5.0.8" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/@ethersproject/rlp": { - "version": "5.0.7", + "node_modules/ghost-testrpc/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, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "optional": true, + "peer": true, "dependencies": { - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/logger": "^5.0.8" + "color-name": "1.1.3" } }, - "node_modules/ganache-core/node_modules/@ethersproject/signing-key": { - "version": "5.0.8", + "node_modules/ghost-testrpc/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, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/logger": "^5.0.8", - "@ethersproject/properties": "^5.0.7", - "elliptic": "6.5.3" + "peer": true + }, + "node_modules/ghost-testrpc/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/ganache-core/node_modules/@ethersproject/strings": { - "version": "5.0.8", + "node_modules/ghost-testrpc/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, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/constants": "^5.0.8", - "@ethersproject/logger": "^5.0.8" + "peer": true, + "engines": { + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/@ethersproject/transactions": { - "version": "5.0.9", + "node_modules/ghost-testrpc/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, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "optional": true, + "peer": true, "dependencies": { - "@ethersproject/address": "^5.0.9", - "@ethersproject/bignumber": "^5.0.13", - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/constants": "^5.0.8", - "@ethersproject/keccak256": "^5.0.7", - "@ethersproject/logger": "^5.0.8", - "@ethersproject/properties": "^5.0.7", - "@ethersproject/rlp": "^5.0.7", - "@ethersproject/signing-key": "^5.0.8" + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/@ethersproject/web": { - "version": "5.0.12", + "node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", "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" - } - ], - "license": "MIT", - "optional": true, "dependencies": { - "@ethersproject/base64": "^5.0.7", - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/logger": "^5.0.8", - "@ethersproject/properties": "^5.0.7", - "@ethersproject/strings": "^5.0.8" - } - }, - "node_modules/ganache-core/node_modules/@sindresorhus/is": { - "version": "0.14.0", - "dev": true, - "license": "MIT", - "optional": true, + "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": ">=6" + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/ganache-core/node_modules/@szmarczak/http-timer": { - "version": "1.1.2", + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, - "license": "MIT", - "optional": true, "dependencies": { - "defer-to-connect": "^1.0.1" + "is-glob": "^4.0.3" }, "engines": { - "node": ">=6" - } - }, - "node_modules/ganache-core/node_modules/@types/bn.js": { - "version": "4.11.6", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/ganache-core/node_modules/@types/node": { - "version": "14.14.20", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/@types/pbkdf2": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" + "node": ">=10.13.0" } }, - "node_modules/ganache-core/node_modules/@types/secp256k1": { - "version": "4.0.1", + "node_modules/global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "@types/node": "*" + "global-prefix": "^3.0.0" + }, + "engines": { + "node": ">=6" } }, - "node_modules/ganache-core/node_modules/@yarnpkg/lockfile": { - "version": "1.1.0", - "dev": true, - "license": "BSD-2-Clause" - }, - "node_modules/ganache-core/node_modules/abstract-leveldown": { + "node_modules/global-prefix": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "xtend": "~4.0.0" + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" }, "engines": { - "node": ">=4" + "node": ">=6" } }, - "node_modules/ganache-core/node_modules/accepts": { - "version": "1.3.7", + "node_modules/global-prefix/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, - "license": "MIT", - "optional": true, + "peer": true, "dependencies": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" + "isexe": "^2.0.0" }, - "engines": { - "node": ">= 0.6" + "bin": { + "which": "bin/which" } }, - "node_modules/ganache-core/node_modules/aes-js": { - "version": "3.1.2", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/ajv": { - "version": "6.12.6", + "node_modules/globals": { + "version": "13.19.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", + "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", "dev": true, - "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ganache-core/node_modules/ansi-styles": { - "version": "3.2.1", + "node_modules/globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "color-convert": "^1.9.0" + "define-properties": "^1.1.3" }, "engines": { - "node": ">=4" - } - }, - "node_modules/ganache-core/node_modules/arr-diff": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/arr-flatten": { - "version": "1.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/arr-union": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ganache-core/node_modules/array-flatten": { - "version": "1.1.1", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/array-unique": { - "version": "0.3.2", + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, - "license": "MIT", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ganache-core/node_modules/asn1": { - "version": "0.2.4", + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "safer-buffer": "~2.1.0" + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ganache-core/node_modules/asn1.js": { - "version": "5.4.1", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "safer-buffer": "^2.1.0" - } + "node_modules/graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "dev": true }, - "node_modules/ganache-core/node_modules/assert-plus": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8" - } + "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==", + "dev": true }, - "node_modules/ganache-core/node_modules/assign-symbols": { - "version": "1.0.0", + "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, - "license": "MIT", + "peer": true, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/async": { - "version": "2.6.2", - "dev": true, - "license": "MIT", - "dependencies": { - "lodash": "^4.17.11" + "node": ">=4.x" } }, - "node_modules/ganache-core/node_modules/async-eventemitter": { - "version": "0.2.4", + "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==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "async": "^2.4.0" - } - }, - "node_modules/ganache-core/node_modules/async-limiter": { - "version": "1.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/asynckit": { - "version": "0.4.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/atob": { - "version": "2.1.2", - "dev": true, - "license": "(MIT OR Apache-2.0)", + "minimist": "^1.2.5", + "neo-async": "^2.6.0", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, "bin": { - "atob": "bin/atob.js" + "handlebars": "bin/handlebars" }, "engines": { - "node": ">= 4.5.0" - } - }, - "node_modules/ganache-core/node_modules/aws-sign2": { - "version": "0.7.0", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "*" - } - }, - "node_modules/ganache-core/node_modules/aws4": { - "version": "1.11.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/babel-code-frame": { - "version": "6.26.0", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" } }, - "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/ansi-regex": { - "version": "2.1.1", + "node_modules/handlebars/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, - "license": "MIT", + "peer": true, "engines": { "node": ">=0.10.0" } }, - "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/ansi-styles": { - "version": "2.2.1", + "node_modules/har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", "dev": true, - "license": "MIT", + "peer": true, "engines": { - "node": ">=0.10.0" + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/chalk": { - "version": "1.1.3", + "node_modules/har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "deprecated": "this library is no longer supported", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" + "ajv": "^6.12.3", + "har-schema": "^2.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=6" } }, - "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/js-tokens": { - "version": "3.0.2", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/strip-ansi": { - "version": "3.0.1", + "node_modules/hardhat": { + "version": "2.12.6", + "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.12.6.tgz", + "integrity": "sha512-0Ent1O5DsPgvaVb5sxEgsQ3bJRt/Ex92tsoO+xjoNH2Qc4bFmhI5/CHVlFikulalxOPjNmw5XQ2vJFuVQFESAA==", "dev": true, - "license": "MIT", "dependencies": { - "ansi-regex": "^2.0.0" + "@ethersproject/abi": "^5.1.2", + "@metamask/eth-sig-util": "^4.0.0", + "@nomicfoundation/ethereumjs-block": "^4.0.0", + "@nomicfoundation/ethereumjs-blockchain": "^6.0.0", + "@nomicfoundation/ethereumjs-common": "^3.0.0", + "@nomicfoundation/ethereumjs-evm": "^1.0.0", + "@nomicfoundation/ethereumjs-rlp": "^4.0.0", + "@nomicfoundation/ethereumjs-statemanager": "^1.0.0", + "@nomicfoundation/ethereumjs-trie": "^5.0.0", + "@nomicfoundation/ethereumjs-tx": "^4.0.0", + "@nomicfoundation/ethereumjs-util": "^8.0.0", + "@nomicfoundation/ethereumjs-vm": "^6.0.0", + "@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", + "chalk": "^2.4.2", + "chokidar": "^3.4.0", + "ci-info": "^2.0.0", + "debug": "^4.1.1", + "enquirer": "^2.3.0", + "env-paths": "^2.2.0", + "ethereum-cryptography": "^1.0.3", + "ethereumjs-abi": "^0.6.8", + "find-up": "^2.1.0", + "fp-ts": "1.19.3", + "fs-extra": "^7.0.1", + "glob": "7.2.0", + "immutable": "^4.0.0-rc.12", + "io-ts": "1.10.4", + "keccak": "^3.0.2", + "lodash": "^4.17.11", + "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", + "solc": "0.7.3", + "source-map-support": "^0.5.13", + "stacktrace-parser": "^0.1.10", + "tsort": "0.0.1", + "undici": "^5.14.0", + "uuid": "^8.3.2", + "ws": "^7.4.6" + }, + "bin": { + "hardhat": "internal/cli/cli.js" }, "engines": { - "node": ">=0.10.0" + "node": "^14.0.0 || ^16.0.0 || ^18.0.0" + }, + "peerDependencies": { + "ts-node": "*", + "typescript": "*" + }, + "peerDependenciesMeta": { + "ts-node": { + "optional": true + }, + "typescript": { + "optional": true + } } }, - "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/supports-color": { - "version": "2.0.0", + "node_modules/hardhat-contract-sizer": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/hardhat-contract-sizer/-/hardhat-contract-sizer-2.6.1.tgz", + "integrity": "sha512-b8wS7DBvyo22kmVwpzstAQTdDCThpl/ySBqZh5ga9Yxjf61/uTL12TEg5nl7lDeWy73ntEUzxMwY6XxbQEc2wA==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/ganache-core/node_modules/babel-core": { - "version": "6.26.3", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-code-frame": "^6.26.0", - "babel-generator": "^6.26.0", - "babel-helpers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-register": "^6.26.0", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "convert-source-map": "^1.5.1", - "debug": "^2.6.9", - "json5": "^0.5.1", - "lodash": "^4.17.4", - "minimatch": "^3.0.4", - "path-is-absolute": "^1.0.1", - "private": "^0.1.8", - "slash": "^1.0.0", - "source-map": "^0.5.7" + "dependencies": { + "chalk": "^4.0.0", + "cli-table3": "^0.6.0" + }, + "peerDependencies": { + "hardhat": "^2.0.0" } }, - "node_modules/ganache-core/node_modules/babel-core/node_modules/debug": { - "version": "2.6.9", + "node_modules/hardhat-gas-reporter": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.9.tgz", + "integrity": "sha512-INN26G3EW43adGKBNzYWOlI3+rlLnasXTwW79YNnUhXPDa+yHESgt639dJEs37gCjhkbNKcRRJnomXEuMFBXJg==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "ms": "2.0.0" + "array-uniq": "1.0.3", + "eth-gas-reporter": "^0.2.25", + "sha1": "^1.1.1" + }, + "peerDependencies": { + "hardhat": "^2.0.2" } }, - "node_modules/ganache-core/node_modules/babel-core/node_modules/json5": { - "version": "0.5.1", + "node_modules/hardhat-tracer": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/hardhat-tracer/-/hardhat-tracer-1.2.1.tgz", + "integrity": "sha512-ZZVXZfWfRzPkjGdkLoxC4v3Dqja7cpG1mOOr+3+m9xGmqfw9P6cKMDo+wYtGPNM6KttwsJ226Gqt5AwBjMxgTg==", "dev": true, - "license": "MIT", - "bin": { - "json5": "lib/cli.js" + "dependencies": { + "ethers": "^5.6.1" + }, + "peerDependencies": { + "chalk": "4.x", + "ethers": "5.x", + "hardhat": "2.x" } }, - "node_modules/ganache-core/node_modules/babel-core/node_modules/ms": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/babel-core/node_modules/slash": { - "version": "1.0.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", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, - "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/babel-generator": { - "version": "6.26.1", + "node_modules/hardhat/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, - "license": "MIT", "dependencies": { - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "detect-indent": "^4.0.0", - "jsesc": "^1.3.0", - "lodash": "^4.17.4", - "source-map": "^0.5.7", - "trim-right": "^1.0.1" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/babel-generator/node_modules/jsesc": { - "version": "1.3.0", + "node_modules/hardhat/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, - "license": "MIT", - "bin": { - "jsesc": "bin/jsesc" + "dependencies": { + "color-name": "1.1.3" } }, - "node_modules/ganache-core/node_modules/babel-helper-builder-binary-assignment-operator-visitor": { - "version": "6.24.1", + "node_modules/hardhat/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/hardhat/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, - "license": "MIT", - "dependencies": { - "babel-helper-explode-assignable-expression": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "engines": { + "node": ">=0.8.0" } }, - "node_modules/ganache-core/node_modules/babel-helper-call-delegate": { - "version": "6.24.1", + "node_modules/hardhat/node_modules/ethereum-cryptography": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.1.2.tgz", + "integrity": "sha512-XDSJlg4BD+hq9N2FjvotwUET9Tfxpxc3kWGE2AqUG5vcbeunnbImVk3cj6e/xT3phdW21mE8R5IugU4fspQDcQ==", "dev": true, - "license": "MIT", "dependencies": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "@noble/hashes": "1.1.2", + "@noble/secp256k1": "1.6.3", + "@scure/bip32": "1.1.0", + "@scure/bip39": "1.1.0" } }, - "node_modules/ganache-core/node_modules/babel-helper-define-map": { - "version": "6.26.0", + "node_modules/hardhat/node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", "dev": true, - "license": "MIT", "dependencies": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/babel-helper-explode-assignable-expression": { - "version": "6.24.1", + "node_modules/hardhat/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, - "license": "MIT", - "dependencies": { - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "engines": { + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/babel-helper-function-name": { - "version": "6.24.1", + "node_modules/hardhat/node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", "dev": true, - "license": "MIT", "dependencies": { - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/babel-helper-get-function-arity": { - "version": "6.24.1", + "node_modules/hardhat/node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", "dev": true, - "license": "MIT", "dependencies": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/babel-helper-hoist-variables": { - "version": "6.24.1", + "node_modules/hardhat/node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", "dev": true, - "license": "MIT", "dependencies": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/babel-helper-optimise-call-expression": { - "version": "6.24.1", + "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, - "license": "MIT", - "dependencies": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "engines": { + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/babel-helper-regex": { - "version": "6.26.0", + "node_modules/hardhat/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, - "license": "MIT", - "dependencies": { - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" + "engines": { + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/babel-helper-remap-async-to-generator": { - "version": "6.24.1", + "node_modules/hardhat/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, - "license": "MIT", "dependencies": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/babel-helper-replace-supers": { - "version": "6.24.1", + "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, - "license": "MIT", "dependencies": { - "babel-helper-optimise-call-expression": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" } }, - "node_modules/ganache-core/node_modules/babel-helpers": { - "version": "6.24.1", + "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, - "license": "MIT", - "dependencies": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "peer": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ganache-core/node_modules/babel-messages": { - "version": "6.23.0", + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, - "license": "MIT", - "dependencies": { - "babel-runtime": "^6.22.0" + "engines": { + "node": ">=8" } }, - "node_modules/ganache-core/node_modules/babel-plugin-check-es2015-constants": { - "version": "6.22.0", + "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==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "babel-runtime": "^6.22.0" + "get-intrinsic": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ganache-core/node_modules/babel-plugin-syntax-async-functions": { - "version": "6.13.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/babel-plugin-syntax-exponentiation-operator": { - "version": "6.13.0", + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/babel-plugin-syntax-trailing-function-commas": { - "version": "6.22.0", - "dev": true, - "license": "MIT" + "peer": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-async-to-generator": { - "version": "6.24.1", + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", "dev": true, - "license": "MIT", - "dependencies": { - "babel-helper-remap-async-to-generator": "^6.24.1", - "babel-plugin-syntax-async-functions": "^6.8.0", - "babel-runtime": "^6.22.0" + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-arrow-functions": { - "version": "6.22.0", + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "babel-runtime": "^6.22.0" + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-block-scoped-functions": { - "version": "6.22.0", + "node_modules/hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", "dev": true, - "license": "MIT", "dependencies": { - "babel-runtime": "^6.22.0" + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "engines": { + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-block-scoping": { - "version": "6.26.0", + "node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", "dev": true, - "license": "MIT", "dependencies": { - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" } }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-classes": { - "version": "6.24.1", + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true, - "license": "MIT", - "dependencies": { - "babel-helper-define-map": "^6.24.1", - "babel-helper-function-name": "^6.24.1", - "babel-helper-optimise-call-expression": "^6.24.1", - "babel-helper-replace-supers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "bin": { + "he": "bin/he" } }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-computed-properties": { - "version": "6.24.1", + "node_modules/heap": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.7.tgz", + "integrity": "sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==", "dev": true, - "license": "MIT", - "dependencies": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } + "peer": true }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-destructuring": { - "version": "6.23.0", + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", "dev": true, - "license": "MIT", "dependencies": { - "babel-runtime": "^6.22.0" + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" } }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-duplicate-keys": { - "version": "6.24.1", + "node_modules/http-basic": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz", + "integrity": "sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "caseless": "^0.12.0", + "concat-stream": "^1.6.2", + "http-response-object": "^3.0.1", + "parse-cache-control": "^1.0.1" + }, + "engines": { + "node": ">=6.0.0" } }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-for-of": { - "version": "6.23.0", + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", "dev": true, - "license": "MIT", "dependencies": { - "babel-runtime": "^6.22.0" + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" } }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-function-name": { - "version": "6.24.1", + "node_modules/http-response-object": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz", + "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "@types/node": "^10.0.3" } }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-literals": { - "version": "6.22.0", + "node_modules/http-response-object/node_modules/@types/node": { + "version": "10.17.60", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", + "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==", "dev": true, - "license": "MIT", - "dependencies": { - "babel-runtime": "^6.22.0" - } + "peer": true }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-modules-amd": { - "version": "6.24.1", + "node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" } }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-modules-commonjs": { - "version": "6.26.2", + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", "dev": true, - "license": "MIT", "dependencies": { - "babel-plugin-transform-strict-mode": "^6.24.1", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-types": "^6.26.0" + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" } }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-modules-systemjs": { - "version": "6.24.1", + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dev": true, - "license": "MIT", "dependencies": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-modules-umd": { - "version": "6.24.1", + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", "dev": true, - "license": "MIT", - "dependencies": { - "babel-plugin-transform-es2015-modules-amd": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.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" + } + ] }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-object-super": { - "version": "6.24.1", + "node_modules/ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", "dev": true, - "license": "MIT", - "dependencies": { - "babel-helper-replace-supers": "^6.24.1", - "babel-runtime": "^6.22.0" + "engines": { + "node": ">= 4" } }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-parameters": { - "version": "6.24.1", + "node_modules/immutable": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.2.2.tgz", + "integrity": "sha512-fTMKDwtbvO5tldky9QZ2fMX7slR0mYpY5nbnFWYp0fOzDhHqhgIw9KoYgxLWsoNTS9ZHGauHj18DTyEw6BK3Og==", + "dev": true + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, - "license": "MIT", "dependencies": { - "babel-helper-call-delegate": "^6.24.1", - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-shorthand-properties": { - "version": "6.24.1", + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, - "license": "MIT", - "dependencies": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "engines": { + "node": ">=0.8.19" } }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-spread": { - "version": "6.22.0", + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "dev": true, - "license": "MIT", - "dependencies": { - "babel-runtime": "^6.22.0" + "engines": { + "node": ">=8" } }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-sticky-regex": { - "version": "6.24.1", + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dev": true, - "license": "MIT", "dependencies": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "once": "^1.3.0", + "wrappy": "1" } }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-template-literals": { - "version": "6.22.0", + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", "dev": true, - "license": "MIT", - "dependencies": { - "babel-runtime": "^6.22.0" - } + "peer": true }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-typeof-symbol": { - "version": "6.23.0", + "node_modules/inquirer": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", + "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", "dev": true, - "license": "MIT", "dependencies": { - "babel-runtime": "^6.22.0" + "ansi-escapes": "^3.2.0", + "chalk": "^2.4.2", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^2.0.0", + "lodash": "^4.17.12", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rxjs": "^6.4.0", + "string-width": "^2.1.0", + "strip-ansi": "^5.1.0", + "through": "^2.3.6" + }, + "engines": { + "node": ">=6.0.0" } }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-unicode-regex": { - "version": "6.24.1", + "node_modules/inquirer/node_modules/ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", "dev": true, - "license": "MIT", - "dependencies": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "regexpu-core": "^2.0.0" + "engines": { + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-exponentiation-operator": { - "version": "6.24.1", + "node_modules/inquirer/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==", "dev": true, - "license": "MIT", - "dependencies": { - "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1", - "babel-plugin-syntax-exponentiation-operator": "^6.8.0", - "babel-runtime": "^6.22.0" + "engines": { + "node": ">=6" } }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-regenerator": { - "version": "6.26.0", + "node_modules/inquirer/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, - "license": "MIT", "dependencies": { - "regenerator-transform": "^0.10.0" + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-strict-mode": { - "version": "6.24.1", + "node_modules/inquirer/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, - "license": "MIT", "dependencies": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/babel-preset-env": { - "version": "1.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-plugin-check-es2015-constants": "^6.22.0", - "babel-plugin-syntax-trailing-function-commas": "^6.22.0", - "babel-plugin-transform-async-to-generator": "^6.22.0", - "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoping": "^6.23.0", - "babel-plugin-transform-es2015-classes": "^6.23.0", - "babel-plugin-transform-es2015-computed-properties": "^6.22.0", - "babel-plugin-transform-es2015-destructuring": "^6.23.0", - "babel-plugin-transform-es2015-duplicate-keys": "^6.22.0", - "babel-plugin-transform-es2015-for-of": "^6.23.0", - "babel-plugin-transform-es2015-function-name": "^6.22.0", - "babel-plugin-transform-es2015-literals": "^6.22.0", - "babel-plugin-transform-es2015-modules-amd": "^6.22.0", - "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0", - "babel-plugin-transform-es2015-modules-systemjs": "^6.23.0", - "babel-plugin-transform-es2015-modules-umd": "^6.23.0", - "babel-plugin-transform-es2015-object-super": "^6.22.0", - "babel-plugin-transform-es2015-parameters": "^6.23.0", - "babel-plugin-transform-es2015-shorthand-properties": "^6.22.0", - "babel-plugin-transform-es2015-spread": "^6.22.0", - "babel-plugin-transform-es2015-sticky-regex": "^6.22.0", - "babel-plugin-transform-es2015-template-literals": "^6.22.0", - "babel-plugin-transform-es2015-typeof-symbol": "^6.23.0", - "babel-plugin-transform-es2015-unicode-regex": "^6.22.0", - "babel-plugin-transform-exponentiation-operator": "^6.22.0", - "babel-plugin-transform-regenerator": "^6.22.0", - "browserslist": "^3.2.6", - "invariant": "^2.2.2", - "semver": "^5.3.0" - } - }, - "node_modules/ganache-core/node_modules/babel-preset-env/node_modules/semver": { - "version": "5.7.1", + "node_modules/inquirer/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, - "license": "ISC", - "bin": { - "semver": "bin/semver" + "dependencies": { + "color-name": "1.1.3" } }, - "node_modules/ganache-core/node_modules/babel-register": { - "version": "6.26.0", + "node_modules/inquirer/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/inquirer/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, - "license": "MIT", - "dependencies": { - "babel-core": "^6.26.0", - "babel-runtime": "^6.26.0", - "core-js": "^2.5.0", - "home-or-tmp": "^2.0.0", - "lodash": "^4.17.4", - "mkdirp": "^0.5.1", - "source-map-support": "^0.4.15" + "engines": { + "node": ">=0.8.0" } }, - "node_modules/ganache-core/node_modules/babel-register/node_modules/source-map-support": { - "version": "0.4.18", + "node_modules/inquirer/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, - "license": "MIT", - "dependencies": { - "source-map": "^0.5.6" + "engines": { + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/babel-runtime": { - "version": "6.26.0", + "node_modules/inquirer/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, - "license": "MIT", - "dependencies": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" + "engines": { + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/babel-template": { - "version": "6.26.0", + "node_modules/inquirer/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, - "license": "MIT", "dependencies": { - "babel-runtime": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "lodash": "^4.17.4" + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/babel-traverse": { - "version": "6.26.0", + "node_modules/inquirer/node_modules/string-width/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, - "license": "MIT", - "dependencies": { - "babel-code-frame": "^6.26.0", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "debug": "^2.6.8", - "globals": "^9.18.0", - "invariant": "^2.2.2", - "lodash": "^4.17.4" + "engines": { + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/babel-traverse/node_modules/debug": { - "version": "2.6.9", + "node_modules/inquirer/node_modules/string-width/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, - "license": "MIT", "dependencies": { - "ms": "2.0.0" + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/babel-traverse/node_modules/globals": { - "version": "9.18.0", + "node_modules/inquirer/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, - "license": "MIT", + "dependencies": { + "ansi-regex": "^4.1.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=6" } }, - "node_modules/ganache-core/node_modules/babel-traverse/node_modules/ms": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/babel-types": { - "version": "6.26.0", + "node_modules/inquirer/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, - "license": "MIT", "dependencies": { - "babel-runtime": "^6.26.0", - "esutils": "^2.0.2", - "lodash": "^4.17.4", - "to-fast-properties": "^1.0.3" + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/babel-types/node_modules/to-fast-properties": { - "version": "1.0.3", + "node_modules/internal-slot": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.4.tgz", + "integrity": "sha512-tA8URYccNzMo94s5MQZgH8NB/XTa6HsOo0MLfXTKKEnHVVdegzaQoFZ7Jp44bdvLvY2waT5dc+j5ICEswhi7UQ==", "dev": true, - "license": "MIT", + "peer": true, + "dependencies": { + "get-intrinsic": "^1.1.3", + "has": "^1.0.3", + "side-channel": "^1.0.4" + }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" } }, - "node_modules/ganache-core/node_modules/babelify": { - "version": "7.3.0", + "node_modules/interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", "dev": true, - "license": "MIT", - "dependencies": { - "babel-core": "^6.0.14", - "object-assign": "^4.0.0" + "peer": true, + "engines": { + "node": ">= 0.10" } }, - "node_modules/ganache-core/node_modules/babylon": { - "version": "6.18.0", + "node_modules/io-ts": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/io-ts/-/io-ts-1.10.4.tgz", + "integrity": "sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g==", "dev": true, - "license": "MIT", - "bin": { - "babylon": "bin/babylon.js" + "dependencies": { + "fp-ts": "^1.0.0" } }, - "node_modules/ganache-core/node_modules/backoff": { - "version": "2.5.0", + "node_modules/is-array-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.1.tgz", + "integrity": "sha512-ASfLknmY8Xa2XtB4wmbz13Wu202baeA18cJBCeCy0wXUHZF0IPyVEXqKEcd+t2fNSLLL1vC6k7lxZEojNbISXQ==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "precond": "0.2" + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-typed-array": "^1.1.10" }, - "engines": { - "node": ">= 0.6" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ganache-core/node_modules/balanced-match": { - "version": "1.0.0", - "dev": true, - "license": "MIT" + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true }, - "node_modules/ganache-core/node_modules/base": { - "version": "0.11.2", + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" + "has-bigints": "^1.0.1" }, - "engines": { - "node": ">=0.10.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ganache-core/node_modules/base-x": { - "version": "3.0.8", + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, - "license": "MIT", "dependencies": { - "safe-buffer": "^5.0.1" + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/ganache-core/node_modules/base/node_modules/define-property": { - "version": "1.0.0", + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "is-descriptor": "^1.0.0" + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ganache-core/node_modules/base64-js": { - "version": "1.5.1", + "node_modules/is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", "dev": true, "funding": [ { @@ -7471,26006 +7192,9227 @@ "url": "https://feross.org/support" } ], - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/bcrypt-pbkdf": { - "version": "1.0.2", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "tweetnacl": "^0.14.3" + "engines": { + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/bcrypt-pbkdf/node_modules/tweetnacl": { - "version": "0.14.5", - "dev": true, - "license": "Unlicense" - }, - "node_modules/ganache-core/node_modules/bignumber.js": { - "version": "9.0.1", + "node_modules/is-callable": { + "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, - "license": "MIT", - "optional": true, + "peer": true, "engines": { - "node": "*" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ganache-core/node_modules/bip39": { - "version": "2.5.0", + "node_modules/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, - "license": "ISC", + "peer": true, "dependencies": { - "create-hash": "^1.1.0", - "pbkdf2": "^3.0.9", - "randombytes": "^2.0.1", - "safe-buffer": "^5.0.1", - "unorm": "^1.3.3" + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ganache-core/node_modules/blakejs": { - "version": "1.1.0", + "node_modules/is-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw==", "dev": true, - "license": "CC0-1.0" + "engines": { + "node": ">=0.10.0" + } }, - "node_modules/ganache-core/node_modules/bluebird": { - "version": "3.7.2", + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, - "license": "MIT", - "optional": true + "engines": { + "node": ">=0.10.0" + } }, - "node_modules/ganache-core/node_modules/bn.js": { - "version": "4.11.9", + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, - "license": "MIT" + "engines": { + "node": ">=8" + } }, - "node_modules/ganache-core/node_modules/body-parser": { - "version": "1.19.0", + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, - "license": "MIT", - "optional": true, "dependencies": { - "bytes": "3.1.0", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" + "is-extglob": "^2.1.1" }, "engines": { - "node": ">= 0.8" + "node": ">=0.10.0" } }, - "node_modules/ganache-core/node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", + "node_modules/is-hex-prefixed": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", + "integrity": "sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==", "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "ms": "2.0.0" + "engines": { + "node": ">=6.5.0", + "npm": ">=3" } }, - "node_modules/ganache-core/node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", + "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, - "license": "MIT", - "optional": true + "peer": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "node_modules/ganache-core/node_modules/body-parser/node_modules/qs": { - "version": "6.7.0", + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, - "license": "BSD-3-Clause", - "optional": true, "engines": { - "node": ">=0.6" + "node": ">=0.12.0" } }, - "node_modules/ganache-core/node_modules/brace-expansion": { - "version": "1.1.11", + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ganache-core/node_modules/brorand": { - "version": "1.1.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/browserify-aes": { - "version": "1.2.0", + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true, - "license": "MIT", - "dependencies": { - "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" + "engines": { + "node": ">=8" } }, - "node_modules/ganache-core/node_modules/browserify-cipher": { - "version": "1.0.1", + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" + "engines": { + "node": ">=8" } }, - "node_modules/ganache-core/node_modules/browserify-des": { - "version": "1.0.2", + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", "dev": true, - "license": "MIT", - "optional": true, + "peer": true, "dependencies": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ganache-core/node_modules/browserify-rsa": { - "version": "4.1.0", + "node_modules/is-shared-array-buffer": { + "version": "1.0.2", + "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, - "license": "MIT", - "optional": true, + "peer": true, "dependencies": { - "bn.js": "^5.0.0", - "randombytes": "^2.0.1" + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ganache-core/node_modules/browserify-rsa/node_modules/bn.js": { - "version": "5.1.3", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/browserify-sign": { - "version": "4.2.1", + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", "dev": true, - "license": "ISC", - "optional": true, + "peer": true, "dependencies": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.3", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ganache-core/node_modules/browserify-sign/node_modules/bn.js": { - "version": "5.1.3", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/browserify-sign/node_modules/readable-stream": { - "version": "3.6.0", + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", "dev": true, - "license": "MIT", - "optional": true, + "peer": true, "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "has-symbols": "^1.0.2" }, "engines": { - "node": ">= 6" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ganache-core/node_modules/browserslist": { - "version": "3.2.8", + "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==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "caniuse-lite": "^1.0.30000844", - "electron-to-chromium": "^1.3.47" + "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" }, - "bin": { - "browserslist": "cli.js" + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ganache-core/node_modules/bs58": { - "version": "4.0.1", + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", "dev": true, - "license": "MIT", - "dependencies": { - "base-x": "^3.0.2" - } + "peer": true }, - "node_modules/ganache-core/node_modules/bs58check": { - "version": "2.1.2", + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", "dev": true, - "license": "MIT", - "dependencies": { - "bs58": "^4.0.0", - "create-hash": "^1.1.0", - "safe-buffer": "^5.1.2" + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ganache-core/node_modules/buffer": { - "version": "5.7.1", + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", "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" - } - ], - "license": "MIT", + "peer": true, "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ganache-core/node_modules/buffer-from": { - "version": "1.1.1", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/buffer-to-arraybuffer": { - "version": "0.0.5", + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", "dev": true, - "license": "MIT", - "optional": true + "peer": true }, - "node_modules/ganache-core/node_modules/buffer-xor": { - "version": "1.0.3", - "dev": true, - "license": "MIT" + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true }, - "node_modules/ganache-core/node_modules/bufferutil": { - "version": "4.0.3", + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", "dev": true, - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "node-gyp-build": "^4.2.0" - } + "peer": true }, - "node_modules/ganache-core/node_modules/bytes": { - "version": "3.1.0", + "node_modules/js-sdsl": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.2.0.tgz", + "integrity": "sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ==", "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 0.8" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" } }, - "node_modules/ganache-core/node_modules/bytewise": { - "version": "1.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "bytewise-core": "^1.2.2", - "typewise": "^1.0.3" - } + "node_modules/js-sha3": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", + "dev": true }, - "node_modules/ganache-core/node_modules/bytewise-core": { - "version": "1.2.3", - "dev": true, - "license": "MIT", - "dependencies": { - "typewise-core": "^1.2" - } + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true }, - "node_modules/ganache-core/node_modules/cache-base": { - "version": "1.0.1", + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, - "license": "MIT", "dependencies": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" + "argparse": "^2.0.1" }, - "engines": { - "node": ">=0.10.0" + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/ganache-core/node_modules/cacheable-request": { - "version": "6.1.0", + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", "dev": true, - "license": "MIT", - "optional": 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" - } + "peer": true }, - "node_modules/ganache-core/node_modules/cacheable-request/node_modules/lowercase-keys": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=8" - } + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true }, - "node_modules/ganache-core/node_modules/cachedown": { - "version": "1.0.0", + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", "dev": true, - "license": "MIT", - "dependencies": { - "abstract-leveldown": "^2.4.1", - "lru-cache": "^3.2.0" - } + "peer": true }, - "node_modules/ganache-core/node_modules/cachedown/node_modules/abstract-leveldown": { - "version": "2.7.2", - "dev": true, - "license": "MIT", - "dependencies": { - "xtend": "~4.0.0" - } - }, - "node_modules/ganache-core/node_modules/cachedown/node_modules/lru-cache": { - "version": "3.2.0", - "dev": true, - "license": "ISC", - "dependencies": { - "pseudomap": "^1.0.1" - } + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true }, - "node_modules/ganache-core/node_modules/call-bind": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true }, - "node_modules/ganache-core/node_modules/caniuse-lite": { - "version": "1.0.30001174", + "node_modules/json-stringify-safe": { + "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, - "license": "CC-BY-4.0" + "peer": true }, - "node_modules/ganache-core/node_modules/caseless": { - "version": "0.12.0", + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", "dev": true, - "license": "Apache-2.0" + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } }, - "node_modules/ganache-core/node_modules/chalk": { - "version": "2.4.2", + "node_modules/jsonschema": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.1.tgz", + "integrity": "sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ==", "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, + "peer": true, "engines": { - "node": ">=4" + "node": "*" } }, - "node_modules/ganache-core/node_modules/checkpoint-store": { - "version": "1.1.0", + "node_modules/jsprim": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", "dev": true, - "license": "ISC", + "peer": true, "dependencies": { - "functional-red-black-tree": "^1.0.1" + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + }, + "engines": { + "node": ">=0.6.0" } }, - "node_modules/ganache-core/node_modules/chownr": { - "version": "1.1.4", - "dev": true, - "license": "ISC", - "optional": true - }, - "node_modules/ganache-core/node_modules/ci-info": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/cids": { - "version": "0.7.5", + "node_modules/keccak": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.3.tgz", + "integrity": "sha512-JZrLIAJWuZxKbCilMpNz5Vj7Vtb4scDG3dMXLOsbzBmQGyjwE61BbW7bJkfKKCShXiQZt3T6sBgALRtmd+nZaQ==", "dev": true, - "license": "MIT", - "optional": true, + "hasInstallScript": true, "dependencies": { - "buffer": "^5.5.0", - "class-is": "^1.1.0", - "multibase": "~0.6.0", - "multicodec": "^1.0.0", - "multihashes": "~0.4.15" + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0", + "readable-stream": "^3.6.0" }, "engines": { - "node": ">=4.0.0", - "npm": ">=3.0.0" + "node": ">=10.0.0" } }, - "node_modules/ganache-core/node_modules/cids/node_modules/multicodec": { - "version": "1.0.4", + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "buffer": "^5.6.0", - "varint": "^5.0.0" + "peer": true, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/ganache-core/node_modules/cipher-base": { - "version": "1.0.4", + "node_modules/klaw": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", + "integrity": "sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw==", "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "optionalDependencies": { + "graceful-fs": "^4.1.9" } }, - "node_modules/ganache-core/node_modules/class-is": { - "version": "1.1.0", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/class-utils": { - "version": "0.3.6", + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", "dev": true, - "license": "MIT", - "dependencies": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, "engines": { - "node": ">=0.10.0" + "node": ">=6" } }, - "node_modules/ganache-core/node_modules/class-utils/node_modules/define-property": { - "version": "0.2.5", + "node_modules/level": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/level/-/level-8.0.0.tgz", + "integrity": "sha512-ypf0jjAk2BWI33yzEaaotpq7fkOPALKAgDBxggO6Q9HGX2MRXn0wbP1Jn/tJv1gtL867+YOjOB49WaUF3UoJNQ==", "dev": true, - "license": "MIT", "dependencies": { - "is-descriptor": "^0.1.0" + "browser-level": "^1.0.1", + "classic-level": "^1.2.0" }, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/class-utils/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^3.0.2" + "node": ">=12" }, - "engines": { - "node": ">=0.10.0" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/level" } }, - "node_modules/ganache-core/node_modules/class-utils/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", + "node_modules/level-supports": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/level-supports/-/level-supports-4.0.1.tgz", + "integrity": "sha512-PbXpve8rKeNcZ9C1mUicC9auIYFyGpkV9/i6g76tLgANwWhtG2v7I4xNBUlkn3lE2/dZF3Pi0ygYGtLc4RXXdA==", "dev": true, - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, "engines": { - "node": ">=0.10.0" + "node": ">=12" } }, - "node_modules/ganache-core/node_modules/class-utils/node_modules/is-buffer": { - "version": "1.1.6", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/class-utils/node_modules/is-data-descriptor": { - "version": "0.1.4", + "node_modules/level-transcoder": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/level-transcoder/-/level-transcoder-1.0.1.tgz", + "integrity": "sha512-t7bFwFtsQeD8cl8NIoQ2iwxA0CL/9IFw7/9gAjOonH0PWTTiRfY7Hq+Ejbsxh86tXobDQ6IOiddjNYIfOBs06w==", "dev": true, - "license": "MIT", "dependencies": { - "kind-of": "^3.0.2" + "buffer": "^6.0.3", + "module-error": "^1.0.1" }, "engines": { - "node": ">=0.10.0" + "node": ">=12" } }, - "node_modules/ganache-core/node_modules/class-utils/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, - "license": "MIT", "dependencies": { - "is-buffer": "^1.1.5" + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.8.0" } }, - "node_modules/ganache-core/node_modules/class-utils/node_modules/is-descriptor": { - "version": "0.1.6", + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, - "license": "MIT", "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" + "p-locate": "^5.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ganache-core/node_modules/class-utils/node_modules/kind-of": { - "version": "5.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true }, - "node_modules/ganache-core/node_modules/clone": { - "version": "2.1.2", + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8" - } + "peer": true }, - "node_modules/ganache-core/node_modules/clone-response": { - "version": "1.0.2", + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "mimic-response": "^1.0.0" - } + "peer": true }, - "node_modules/ganache-core/node_modules/collection-visit": { - "version": "1.0.0", + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", "dev": true, - "license": "MIT", "dependencies": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ganache-core/node_modules/color-convert": { - "version": "1.9.3", + "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==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "color-name": "1.1.3" + "get-func-name": "^2.0.0" } }, - "node_modules/ganache-core/node_modules/color-name": { - "version": "1.1.3", + "node_modules/lru_map": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz", + "integrity": "sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==", + "dev": true + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, - "license": "MIT" + "dependencies": { + "yallist": "^3.0.2" + } }, - "node_modules/ganache-core/node_modules/combined-stream": { - "version": "1.0.8", + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", "dev": true, - "license": "MIT", "dependencies": { - "delayed-stream": "~1.0.0" + "semver": "^6.0.0" }, "engines": { - "node": ">= 0.8" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ganache-core/node_modules/component-emitter": { - "version": "1.3.0", - "dev": true, - "license": "MIT" + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true }, - "node_modules/ganache-core/node_modules/concat-map": { - "version": "0.0.1", + "node_modules/markdown-table": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.3.tgz", + "integrity": "sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==", "dev": true, - "license": "MIT" + "peer": true }, - "node_modules/ganache-core/node_modules/concat-stream": { - "version": "1.6.2", - "dev": true, - "engines": [ - "node >= 0.8" - ], - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "node_modules/ganache-core/node_modules/content-disposition": { - "version": "0.5.3", + "node_modules/mcl-wasm": { + "version": "0.7.9", + "resolved": "https://registry.npmjs.org/mcl-wasm/-/mcl-wasm-0.7.9.tgz", + "integrity": "sha512-iJIUcQWA88IJB/5L15GnJVnSQJmf/YaxxV6zRavv83HILHaJQb6y0iFyDMdDO0gN8X37tdxmAOrH/P8B6RB8sQ==", "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "safe-buffer": "5.1.2" - }, "engines": { - "node": ">= 0.6" + "node": ">=8.9.0" } }, - "node_modules/ganache-core/node_modules/content-disposition/node_modules/safe-buffer": { - "version": "5.1.2", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/content-hash": { - "version": "2.5.2", + "node_modules/md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", "dev": true, - "license": "ISC", - "optional": true, "dependencies": { - "cids": "^0.7.1", - "multicodec": "^0.5.5", - "multihashes": "^0.4.15" + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" } }, - "node_modules/ganache-core/node_modules/content-type": { - "version": "1.0.4", + "node_modules/memory-level": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/memory-level/-/memory-level-1.0.0.tgz", + "integrity": "sha512-UXzwewuWeHBz5krr7EvehKcmLFNoXxGcvuYhC41tRnkrTbJohtS7kVn9akmgirtRygg+f7Yjsfi8Uu5SGSQ4Og==", "dev": true, - "license": "MIT", - "optional": true, + "dependencies": { + "abstract-level": "^1.0.0", + "functional-red-black-tree": "^1.0.1", + "module-error": "^1.0.1" + }, "engines": { - "node": ">= 0.6" + "node": ">=12" } }, - "node_modules/ganache-core/node_modules/convert-source-map": { - "version": "1.7.0", + "node_modules/memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.1.1" + "engines": { + "node": ">= 0.10.0" } }, - "node_modules/ganache-core/node_modules/convert-source-map/node_modules/safe-buffer": { - "version": "5.1.2", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/cookie": { - "version": "0.4.0", + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, - "license": "MIT", - "optional": true, "engines": { - "node": ">= 0.6" + "node": ">= 8" } }, - "node_modules/ganache-core/node_modules/cookie-signature": { - "version": "1.0.6", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/cookiejar": { - "version": "2.1.2", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/copy-descriptor": { - "version": "0.1.1", + "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, - "license": "MIT", + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, "engines": { - "node": ">=0.10.0" + "node": ">=8.6" } }, - "node_modules/ganache-core/node_modules/core-js": { - "version": "2.6.12", - "dev": true, - "hasInstallScript": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/core-js-pure": { - "version": "3.8.2", + "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, - "hasInstallScript": true, - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" + "peer": true, + "engines": { + "node": ">= 0.6" } }, - "node_modules/ganache-core/node_modules/core-util-is": { - "version": "1.0.2", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/cors": { - "version": "2.8.5", + "node_modules/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, - "license": "MIT", - "optional": true, + "peer": true, "dependencies": { - "object-assign": "^4", - "vary": "^1" + "mime-db": "1.52.0" }, "engines": { - "node": ">= 0.10" - } - }, - "node_modules/ganache-core/node_modules/create-ecdh": { - "version": "4.0.4", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" + "node": ">= 0.6" } }, - "node_modules/ganache-core/node_modules/create-hash": { + "node_modules/mimic-fn": { "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", "dev": true, - "license": "MIT", - "dependencies": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" + "engines": { + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/create-hmac": { - "version": "1.1.7", - "dev": true, - "license": "MIT", - "dependencies": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true }, - "node_modules/ganache-core/node_modules/cross-fetch": { - "version": "2.2.3", - "dev": true, - "license": "MIT", - "dependencies": { - "node-fetch": "2.1.2", - "whatwg-fetch": "2.0.4" - } + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", + "dev": true }, - "node_modules/ganache-core/node_modules/crypto-browserify": { - "version": "3.12.0", + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, - "license": "MIT", - "optional": 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" + "brace-expansion": "^1.1.7" }, "engines": { "node": "*" } }, - "node_modules/ganache-core/node_modules/d": { - "version": "1.0.1", + "node_modules/minimist": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", + "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", "dev": true, - "license": "ISC", - "dependencies": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ganache-core/node_modules/dashdash": { - "version": "1.14.1", + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", "dev": true, - "license": "MIT", "dependencies": { - "assert-plus": "^1.0.0" + "minimist": "^1.2.6" }, - "engines": { - "node": ">=0.10" + "bin": { + "mkdirp": "bin/cmd.js" } }, - "node_modules/ganache-core/node_modules/debug": { - "version": "3.2.6", + "node_modules/mnemonist": { + "version": "0.38.5", + "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.38.5.tgz", + "integrity": "sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg==", "dev": true, - "license": "MIT", "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/ganache-core/node_modules/decode-uri-component": { - "version": "0.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10" + "obliterator": "^2.0.0" } }, - "node_modules/ganache-core/node_modules/decompress-response": { - "version": "3.3.0", + "node_modules/mocha": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", + "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==", "dev": true, - "license": "MIT", - "optional": true, "dependencies": { - "mimic-response": "^1.0.0" + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.3", + "debug": "4.3.4", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.2.0", + "he": "1.2.0", + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", + "minimatch": "5.0.1", + "ms": "2.1.3", + "nanoid": "3.3.3", + "serialize-javascript": "6.0.0", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "workerpool": "6.2.1", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha.js" }, "engines": { - "node": ">=4" - } - }, - "node_modules/ganache-core/node_modules/deep-equal": { - "version": "1.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "is-arguments": "^1.0.4", - "is-date-object": "^1.0.1", - "is-regex": "^1.0.4", - "object-is": "^1.0.1", - "object-keys": "^1.1.1", - "regexp.prototype.flags": "^1.2.0" + "node": ">= 14.0.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/mochajs" } }, - "node_modules/ganache-core/node_modules/defer-to-connect": { - "version": "1.1.3", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/deferred-leveldown": { - "version": "4.0.2", + "node_modules/mocha/node_modules/ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", "dev": true, - "license": "MIT", - "dependencies": { - "abstract-leveldown": "~5.0.0", - "inherits": "^2.0.3" - }, "engines": { "node": ">=6" } }, - "node_modules/ganache-core/node_modules/deferred-leveldown/node_modules/abstract-leveldown": { - "version": "5.0.0", + "node_modules/mocha/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, - "license": "MIT", "dependencies": { - "xtend": "~4.0.0" - }, - "engines": { - "node": ">=6" + "balanced-match": "^1.0.0" } }, - "node_modules/ganache-core/node_modules/define-properties": { - "version": "1.1.3", + "node_modules/mocha/node_modules/minimatch": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", + "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", "dev": true, - "license": "MIT", "dependencies": { - "object-keys": "^1.0.12" + "brace-expansion": "^2.0.1" }, "engines": { - "node": ">= 0.4" + "node": ">=10" } }, - "node_modules/ganache-core/node_modules/define-property": { - "version": "2.0.2", + "node_modules/mocha/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/mocha/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, - "license": "MIT", "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" + "has-flag": "^4.0.0" }, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/defined": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/delayed-stream": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.4.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/ganache-core/node_modules/depd": { - "version": "1.1.2", + "node_modules/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, - "license": "MIT", - "optional": true, "engines": { - "node": ">= 0.6" + "node": ">=10" } }, - "node_modules/ganache-core/node_modules/des.js": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } + "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/ganache-core/node_modules/destroy": { - "version": "1.0.4", - "dev": true, - "license": "MIT", - "optional": true + "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/ganache-core/node_modules/detect-indent": { - "version": "4.0.0", + "node_modules/nanoid": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", + "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", "dev": true, - "license": "MIT", - "dependencies": { - "repeating": "^2.0.0" + "bin": { + "nanoid": "bin/nanoid.cjs" }, "engines": { - "node": ">=0.10.0" + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/ganache-core/node_modules/diffie-hellman": { - "version": "5.0.3", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - } + "node_modules/napi-macros": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/napi-macros/-/napi-macros-2.0.0.tgz", + "integrity": "sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg==", + "dev": true }, - "node_modules/ganache-core/node_modules/dom-walk": { - "version": "0.1.2", + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, - "node_modules/ganache-core/node_modules/dotignore": { - "version": "0.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "minimatch": "^3.0.4" - }, - "bin": { - "ignored": "bin/ignored" - } + "node_modules/natural-compare-lite": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", + "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", + "dev": true }, - "node_modules/ganache-core/node_modules/duplexer3": { - "version": "0.1.4", + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "dev": true, - "license": "BSD-3-Clause", - "optional": true + "peer": true }, - "node_modules/ganache-core/node_modules/ecc-jsbn": { - "version": "0.1.2", + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node_modules/node-addon-api": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", + "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==", + "dev": true + }, + "node_modules/node-emoji": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", + "integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" + "lodash": "^4.17.21" } }, - "node_modules/ganache-core/node_modules/ee-first": { - "version": "1.1.1", + "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, - "license": "MIT", - "optional": true + "peer": true, + "dependencies": { + "object.getownpropertydescriptors": "^2.0.3", + "semver": "^5.7.0" + } }, - "node_modules/ganache-core/node_modules/electron-to-chromium": { - "version": "1.3.636", + "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, - "license": "ISC" + "peer": true, + "bin": { + "semver": "bin/semver" + } }, - "node_modules/ganache-core/node_modules/elliptic": { - "version": "6.5.3", + "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==", "dev": true, - "license": "MIT", - "dependencies": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.0" + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" } }, - "node_modules/ganache-core/node_modules/encodeurl": { - "version": "1.0.2", + "node_modules/nofilter": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-3.1.0.tgz", + "integrity": "sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==", "dev": true, - "license": "MIT", - "optional": true, "engines": { - "node": ">= 0.8" + "node": ">=12.19" } }, - "node_modules/ganache-core/node_modules/encoding": { - "version": "0.1.13", + "node_modules/nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "iconv-lite": "^0.6.2" + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" } }, - "node_modules/ganache-core/node_modules/encoding-down": { - "version": "5.0.4", + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true, - "license": "MIT", - "dependencies": { - "abstract-leveldown": "^5.0.0", - "inherits": "^2.0.3", - "level-codec": "^9.0.0", - "level-errors": "^2.0.0", - "xtend": "^4.0.1" - }, "engines": { - "node": ">=6" + "node": ">=0.10.0" } }, - "node_modules/ganache-core/node_modules/encoding-down/node_modules/abstract-leveldown": { - "version": "5.0.0", + "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, - "license": "MIT", + "peer": true, "dependencies": { - "xtend": "~4.0.0" + "bn.js": "4.11.6", + "strip-hex-prefix": "1.0.0" }, "engines": { - "node": ">=6" + "node": ">=6.5.0", + "npm": ">=3" } }, - "node_modules/ganache-core/node_modules/encoding/node_modules/iconv-lite": { - "version": "0.6.2", + "node_modules/number-to-bn/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, + "peer": 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": "*" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "dev": true, - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, "engines": { "node": ">=0.10.0" } }, - "node_modules/ganache-core/node_modules/end-of-stream": { - "version": "1.4.4", + "node_modules/object-inspect": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", + "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", "dev": true, - "license": "MIT", - "dependencies": { - "once": "^1.4.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ganache-core/node_modules/errno": { - "version": "0.1.8", + "node_modules/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, - "license": "MIT", - "dependencies": { - "prr": "~1.0.1" - }, - "bin": { - "errno": "cli.js" + "peer": true, + "engines": { + "node": ">= 0.4" } }, - "node_modules/ganache-core/node_modules/es-abstract": { - "version": "1.18.0-next.1", + "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==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "es-to-primitive": "^1.2.1", + "define-properties": "^1.1.2", "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.2", - "is-negative-zero": "^2.0.0", - "is-regex": "^1.1.1", - "object-inspect": "^1.8.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.1", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ganache-core/node_modules/es-to-primitive": { - "version": "1.2.1", + "node_modules/object.getownpropertydescriptors": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.5.tgz", + "integrity": "sha512-yDNzckpM6ntyQiGTik1fKV1DcVDRS+w8bvpWNCBanvH5LfRX9O8WTHqQzG4RZwRAM4I0oU7TV11Lj5v0g20ibw==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" + "array.prototype.reduce": "^1.0.5", + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" }, "engines": { - "node": ">= 0.4" + "node": ">= 0.8" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ganache-core/node_modules/es5-ext": { - "version": "0.10.53", - "dev": true, - "license": "ISC", - "dependencies": { - "es6-iterator": "~2.0.3", - "es6-symbol": "~3.1.3", - "next-tick": "~1.0.0" + "node_modules/obliterator": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.4.tgz", + "integrity": "sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==", + "dev": true + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" } }, - "node_modules/ganache-core/node_modules/es6-iterator": { - "version": "2.0.3", + "node_modules/onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==", "dev": true, - "license": "MIT", "dependencies": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" + "mimic-fn": "^1.0.0" + }, + "engines": { + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/es6-symbol": { - "version": "3.1.3", + "node_modules/optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", "dev": true, - "license": "ISC", "dependencies": { - "d": "^1.0.1", - "ext": "^1.1.2" + "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" + }, + "engines": { + "node": ">= 0.8.0" } }, - "node_modules/ganache-core/node_modules/escape-html": { + "node_modules/ordinal": { "version": "1.0.3", + "resolved": "https://registry.npmjs.org/ordinal/-/ordinal-1.0.3.tgz", + "integrity": "sha512-cMddMgb2QElm8G7vdaa02jhUNbTSrhsgAGUz1OokD83uJTwSUn+nKoNoKVVaRa08yF6sgfO7Maou1+bgLd9rdQ==", "dev": true, - "license": "MIT", - "optional": true + "peer": true }, - "node_modules/ganache-core/node_modules/escape-string-regexp": { - "version": "1.0.5", + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", "dev": true, - "license": "MIT", "engines": { - "node": ">=0.8.0" + "node": ">=0.10.0" } }, - "node_modules/ganache-core/node_modules/esutils": { - "version": "2.0.3", + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, - "license": "BSD-2-Clause", + "dependencies": { + "yocto-queue": "^0.1.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ganache-core/node_modules/etag": { - "version": "1.8.1", + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, - "license": "MIT", - "optional": true, + "dependencies": { + "p-limit": "^3.0.2" + }, "engines": { - "node": ">= 0.6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ganache-core/node_modules/eth-block-tracker": { - "version": "3.0.1", + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", "dev": true, - "license": "MIT", "dependencies": { - "eth-query": "^2.1.0", - "ethereumjs-tx": "^1.3.3", - "ethereumjs-util": "^5.1.3", - "ethjs-util": "^0.1.3", - "json-rpc-engine": "^3.6.0", - "pify": "^2.3.0", - "tape": "^4.6.3" + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ganache-core/node_modules/eth-block-tracker/node_modules/ethereumjs-tx": { - "version": "1.3.7", + "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, - "license": "MPL-2.0", - "dependencies": { - "ethereum-common": "^0.0.18", - "ethereumjs-util": "^5.0.0" + "engines": { + "node": ">=6" } }, - "node_modules/ganache-core/node_modules/eth-block-tracker/node_modules/ethereumjs-util": { - "version": "5.2.1", + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, - "license": "MPL-2.0", "dependencies": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" } }, - "node_modules/ganache-core/node_modules/eth-block-tracker/node_modules/pify": { - "version": "2.3.0", + "node_modules/parse-cache-control": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", + "integrity": "sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } + "peer": true }, - "node_modules/ganache-core/node_modules/eth-ens-namehash": { - "version": "2.0.8", + "node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", "dev": true, - "license": "ISC", - "optional": true, "dependencies": { - "idna-uts46-hx": "^2.3.1", - "js-sha3": "^0.5.7" + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/eth-json-rpc-infura": { - "version": "3.2.1", + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, - "license": "ISC", - "dependencies": { - "cross-fetch": "^2.1.1", - "eth-json-rpc-middleware": "^1.5.0", - "json-rpc-engine": "^3.4.0", - "json-rpc-error": "^2.0.0" + "engines": { + "node": ">=8" } }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware": { - "version": "1.6.0", + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true, - "license": "ISC", - "dependencies": { - "async": "^2.5.0", - "eth-query": "^2.1.2", - "eth-tx-summary": "^3.1.2", - "ethereumjs-block": "^1.6.0", - "ethereumjs-tx": "^1.3.3", - "ethereumjs-util": "^5.1.2", - "ethereumjs-vm": "^2.1.0", - "fetch-ponyfill": "^4.0.0", - "json-rpc-engine": "^3.6.0", - "json-rpc-error": "^2.0.0", - "json-stable-stringify": "^1.0.1", - "promise-to-callback": "^1.0.0", - "tape": "^4.6.3" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/abstract-leveldown": { - "version": "2.6.3", + "node_modules/path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", + "dev": true + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, - "license": "MIT", - "dependencies": { - "xtend": "~4.0.0" + "engines": { + "node": ">=8" } }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/deferred-leveldown": { - "version": "1.2.2", + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true, - "license": "MIT", - "dependencies": { - "abstract-leveldown": "~2.6.0" + "engines": { + "node": ">=8" } }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-account": { - "version": "2.0.5", + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", "dev": true, - "license": "MPL-2.0", - "dependencies": { - "ethereumjs-util": "^5.0.0", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" + "peer": true, + "engines": { + "node": "*" } }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-block": { - "version": "1.7.1", + "node_modules/pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", "dev": true, - "license": "MPL-2.0", "dependencies": { - "async": "^2.0.1", - "ethereum-common": "0.2.0", - "ethereumjs-tx": "^1.2.2", - "ethereumjs-util": "^5.0.0", - "merkle-patricia-tree": "^2.1.2" + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + }, + "engines": { + "node": ">=0.12" } }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-block/node_modules/ethereum-common": { - "version": "0.2.0", + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", "dev": true, - "license": "MIT" + "peer": true }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-tx": { - "version": "1.3.7", + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, - "license": "MPL-2.0", - "dependencies": { - "ethereum-common": "^0.0.18", - "ethereumjs-util": "^5.0.0" + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-util": { - "version": "5.2.1", + "node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", "dev": true, - "license": "MPL-2.0", - "dependencies": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" + "peer": true, + "engines": { + "node": ">=6" } }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm": { - "version": "2.6.0", + "node_modules/pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", "dev": true, - "license": "MPL-2.0", - "dependencies": { - "async": "^2.1.2", - "async-eventemitter": "^0.2.2", - "ethereumjs-account": "^2.0.3", - "ethereumjs-block": "~2.2.0", - "ethereumjs-common": "^1.1.0", - "ethereumjs-util": "^6.0.0", - "fake-merkle-patricia-tree": "^1.0.1", - "functional-red-black-tree": "^1.0.1", - "merkle-patricia-tree": "^2.3.2", - "rustbn.js": "~0.2.0", - "safe-buffer": "^5.1.1" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm/node_modules/ethereumjs-block": { - "version": "2.2.2", + "node_modules/pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", "dev": true, - "license": "MPL-2.0", "dependencies": { - "async": "^2.0.1", - "ethereumjs-common": "^1.5.0", - "ethereumjs-tx": "^2.1.1", - "ethereumjs-util": "^5.0.0", - "merkle-patricia-tree": "^2.1.2" + "pinkie": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm/node_modules/ethereumjs-block/node_modules/ethereumjs-util": { - "version": "5.2.1", + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, - "license": "MPL-2.0", "dependencies": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm/node_modules/ethereumjs-tx": { - "version": "2.1.2", + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, - "license": "MPL-2.0", "dependencies": { - "ethereumjs-common": "^1.5.0", - "ethereumjs-util": "^6.0.0" - } - }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm/node_modules/ethereumjs-util": { - "version": "6.2.1", - "dev": true, - "license": "MPL-2.0", - "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" - } - }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/isarray": { - "version": "0.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-codec": { - "version": "7.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-errors": { - "version": "1.0.5", - "dev": true, - "license": "MIT", - "dependencies": { - "errno": "~0.1.1" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-iterator-stream": { - "version": "1.3.1", + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, - "license": "MIT", "dependencies": { - "inherits": "^2.0.1", - "level-errors": "^1.0.3", - "readable-stream": "^1.0.33", - "xtend": "^4.0.0" + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-iterator-stream/node_modules/readable-stream": { - "version": "1.1.14", + "node_modules/pkg-dir/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==", "dev": true, - "license": "MIT", "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-ws": { - "version": "0.0.0", + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, - "license": "MIT", "dependencies": { - "readable-stream": "~1.0.15", - "xtend": "~2.1.1" + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-ws/node_modules/readable-stream": { - "version": "1.0.34", + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" + "engines": { + "node": ">= 0.8.0" } }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-ws/node_modules/xtend": { - "version": "2.1.2", + "node_modules/prettier": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", + "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", "dev": true, - "dependencies": { - "object-keys": "~0.4.0" + "optional": true, + "bin": { + "prettier": "bin-prettier.js" }, "engines": { - "node": ">=0.4" + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/levelup": { - "version": "1.3.9", + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true, - "license": "MIT", - "dependencies": { - "deferred-leveldown": "~1.2.1", - "level-codec": "~7.0.0", - "level-errors": "~1.0.3", - "level-iterator-stream": "~1.3.0", - "prr": "~1.0.1", - "semver": "~5.4.1", - "xtend": "~4.0.0" - } + "peer": true }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ltgt": { - "version": "2.2.1", + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true, - "license": "MIT" + "engines": { + "node": ">=0.4.0" + } }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/memdown": { - "version": "1.4.1", + "node_modules/promise": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", + "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "abstract-leveldown": "~2.7.1", - "functional-red-black-tree": "^1.0.1", - "immediate": "^3.2.3", - "inherits": "~2.0.1", - "ltgt": "~2.2.0", - "safe-buffer": "~5.1.1" + "asap": "~2.0.6" } }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/memdown/node_modules/abstract-leveldown": { - "version": "2.7.2", + "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==", "dev": true, - "license": "MIT", "dependencies": { - "xtend": "~4.0.0" + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" } }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/merkle-patricia-tree": { - "version": "2.3.2", + "node_modules/proper-lockfile": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-4.1.2.tgz", + "integrity": "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==", "dev": true, - "license": "MPL-2.0", "dependencies": { - "async": "^1.4.2", - "ethereumjs-util": "^5.0.0", - "level-ws": "0.0.0", - "levelup": "^1.2.1", - "memdown": "^1.0.0", - "readable-stream": "^2.0.0", - "rlp": "^2.0.0", - "semaphore": ">=1.0.1" + "graceful-fs": "^4.2.4", + "retry": "^0.12.0", + "signal-exit": "^3.0.2" } }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/merkle-patricia-tree/node_modules/async": { - "version": "1.5.2", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/object-keys": { - "version": "0.4.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/safe-buffer": { - "version": "5.1.2", + "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, - "license": "MIT" + "peer": true }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/semver": { - "version": "5.4.1", + "node_modules/punycode": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.2.0.tgz", + "integrity": "sha512-LN6QV1IJ9ZhxWTNdktaPClrNfp8xdSAYS0Zk2ddX7XsXZAxckMHPCBcHRo0cTcEIgYPRiGEkmji3Idkh2yFtYw==", "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" + "engines": { + "node": ">=6" } }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/string_decoder": { - "version": "0.10.31", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/eth-lib": { - "version": "0.1.29", + "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, - "license": "MIT", - "optional": true, "dependencies": { - "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" + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ganache-core/node_modules/eth-query": { - "version": "2.1.2", + "node_modules/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, - "license": "ISC", - "dependencies": { - "json-rpc-random-id": "^1.0.0", - "xtend": "^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" + } + ] }, - "node_modules/ganache-core/node_modules/eth-sig-util": { - "version": "3.0.0", + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dev": true, - "license": "ISC", "dependencies": { - "buffer": "^5.2.1", - "elliptic": "^6.4.0", - "ethereumjs-abi": "0.6.5", - "ethereumjs-util": "^5.1.1", - "tweetnacl": "^1.0.0", - "tweetnacl-util": "^0.15.0" + "safe-buffer": "^5.1.0" } }, - "node_modules/ganache-core/node_modules/eth-sig-util/node_modules/ethereumjs-abi": { - "version": "0.6.5", + "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, - "license": "MIT", "dependencies": { - "bn.js": "^4.10.0", - "ethereumjs-util": "^4.3.0" + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" } }, - "node_modules/ganache-core/node_modules/eth-sig-util/node_modules/ethereumjs-abi/node_modules/ethereumjs-util": { - "version": "4.5.1", + "node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "dev": true, - "license": "MPL-2.0", "dependencies": { - "bn.js": "^4.8.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.0.0" + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" } }, - "node_modules/ganache-core/node_modules/eth-sig-util/node_modules/ethereumjs-util": { - "version": "5.2.1", + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, - "license": "MPL-2.0", "dependencies": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" } }, - "node_modules/ganache-core/node_modules/eth-tx-summary": { - "version": "3.2.4", + "node_modules/rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", "dev": true, - "license": "ISC", + "peer": true, "dependencies": { - "async": "^2.1.2", - "clone": "^2.0.0", - "concat-stream": "^1.5.1", - "end-of-stream": "^1.1.0", - "eth-query": "^2.0.2", - "ethereumjs-block": "^1.4.1", - "ethereumjs-tx": "^1.1.1", - "ethereumjs-util": "^5.0.1", - "ethereumjs-vm": "^2.6.0", - "through2": "^2.0.3" + "resolve": "^1.1.6" + }, + "engines": { + "node": ">= 0.10" } }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/abstract-leveldown": { - "version": "2.6.3", + "node_modules/recursive-readdir": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", + "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "xtend": "~4.0.0" + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=6.0.0" } }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/deferred-leveldown": { - "version": "1.2.2", + "node_modules/reduce-flatten": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-2.0.0.tgz", + "integrity": "sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w==", "dev": true, - "license": "MIT", - "dependencies": { - "abstract-leveldown": "~2.6.0" + "peer": true, + "engines": { + "node": ">=6" } }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-account": { - "version": "2.0.5", + "node_modules/regexp.prototype.flags": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", + "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", "dev": true, - "license": "MPL-2.0", + "peer": true, "dependencies": { - "ethereumjs-util": "^5.0.0", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "functions-have-names": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-block": { - "version": "1.7.1", + "node_modules/regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "dev": true, - "license": "MPL-2.0", - "dependencies": { - "async": "^2.0.1", - "ethereum-common": "0.2.0", - "ethereumjs-tx": "^1.2.2", - "ethereumjs-util": "^5.0.0", - "merkle-patricia-tree": "^2.1.2" + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" } }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-block/node_modules/ethereum-common": { - "version": "0.2.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-tx": { - "version": "1.3.7", + "node_modules/req-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/req-cwd/-/req-cwd-2.0.0.tgz", + "integrity": "sha512-ueoIoLo1OfB6b05COxAA9UpeoscNpYyM+BqYlA7H6LVF4hKGPXQQSSaD2YmvDVJMkk4UDpAHIeU1zG53IqjvlQ==", "dev": true, - "license": "MPL-2.0", + "peer": true, "dependencies": { - "ethereum-common": "^0.0.18", - "ethereumjs-util": "^5.0.0" + "req-from": "^2.0.0" + }, + "engines": { + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-util": { - "version": "5.2.1", + "node_modules/req-from": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/req-from/-/req-from-2.0.0.tgz", + "integrity": "sha512-LzTfEVDVQHBRfjOUMgNBA+V6DWsSnoeKzf42J7l0xa/B4jyPOuuF5MlNSmomLNGemWTnV2TIdjSSLnEn95fOQA==", "dev": true, - "license": "MPL-2.0", + "peer": true, "dependencies": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" + "resolve-from": "^3.0.0" + }, + "engines": { + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm": { - "version": "2.6.0", + "node_modules/req-from/node_modules/resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", "dev": true, - "license": "MPL-2.0", - "dependencies": { - "async": "^2.1.2", - "async-eventemitter": "^0.2.2", - "ethereumjs-account": "^2.0.3", - "ethereumjs-block": "~2.2.0", - "ethereumjs-common": "^1.1.0", - "ethereumjs-util": "^6.0.0", - "fake-merkle-patricia-tree": "^1.0.1", - "functional-red-black-tree": "^1.0.1", - "merkle-patricia-tree": "^2.3.2", - "rustbn.js": "~0.2.0", - "safe-buffer": "^5.1.1" + "peer": true, + "engines": { + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm/node_modules/ethereumjs-block": { - "version": "2.2.2", + "node_modules/request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", "dev": true, - "license": "MPL-2.0", + "peer": true, "dependencies": { - "async": "^2.0.1", - "ethereumjs-common": "^1.5.0", - "ethereumjs-tx": "^2.1.1", - "ethereumjs-util": "^5.0.0", - "merkle-patricia-tree": "^2.1.2" + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" } }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm/node_modules/ethereumjs-block/node_modules/ethereumjs-util": { - "version": "5.2.1", + "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, - "license": "MPL-2.0", + "peer": true, "dependencies": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" + "lodash": "^4.17.19" + }, + "engines": { + "node": ">=0.10.0" + }, + "peerDependencies": { + "request": "^2.34" } }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm/node_modules/ethereumjs-tx": { - "version": "2.1.2", + "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", "dev": true, - "license": "MPL-2.0", + "peer": true, "dependencies": { - "ethereumjs-common": "^1.5.0", - "ethereumjs-util": "^6.0.0" + "request-promise-core": "1.1.4", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + }, + "engines": { + "node": ">=0.12.0" + }, + "peerDependencies": { + "request": "^2.34" } }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm/node_modules/ethereumjs-util": { - "version": "6.2.1", + "node_modules/request/node_modules/qs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", "dev": true, - "license": "MPL-2.0", - "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" + "peer": true, + "engines": { + "node": ">=0.6" } }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/isarray": { - "version": "0.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-codec": { - "version": "7.0.1", + "node_modules/request/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "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, - "license": "MIT" + "peer": true, + "bin": { + "uuid": "bin/uuid" + } }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-errors": { - "version": "1.0.5", + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true, - "license": "MIT", - "dependencies": { - "errno": "~0.1.1" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-iterator-stream": { - "version": "1.3.1", + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.1", - "level-errors": "^1.0.3", - "readable-stream": "^1.0.33", - "xtend": "^4.0.0" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-iterator-stream/node_modules/readable-stream": { - "version": "1.1.14", + "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, - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } + "peer": true }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-ws": { - "version": "0.0.0", + "node_modules/resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", "dev": true, - "license": "MIT", "dependencies": { - "readable-stream": "~1.0.15", - "xtend": "~2.1.1" + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-ws/node_modules/readable-stream": { - "version": "1.0.34", + "node_modules/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, - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" + "engines": { + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-ws/node_modules/xtend": { - "version": "2.1.2", + "node_modules/restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==", "dev": true, "dependencies": { - "object-keys": "~0.4.0" + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" }, "engines": { - "node": ">=0.4" + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/levelup": { - "version": "1.3.9", + "node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", "dev": true, - "license": "MIT", - "dependencies": { - "deferred-leveldown": "~1.2.1", - "level-codec": "~7.0.0", - "level-errors": "~1.0.3", - "level-iterator-stream": "~1.3.0", - "prr": "~1.0.1", - "semver": "~5.4.1", - "xtend": "~4.0.0" + "engines": { + "node": ">= 4" } }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ltgt": { - "version": "2.2.1", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/memdown": { - "version": "1.4.1", + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true, - "license": "MIT", - "dependencies": { - "abstract-leveldown": "~2.7.1", - "functional-red-black-tree": "^1.0.1", - "immediate": "^3.2.3", - "inherits": "~2.0.1", - "ltgt": "~2.2.0", - "safe-buffer": "~5.1.1" + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" } }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/memdown/node_modules/abstract-leveldown": { - "version": "2.7.2", + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, - "license": "MIT", "dependencies": { - "xtend": "~4.0.0" + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/merkle-patricia-tree": { - "version": "2.3.2", + "node_modules/ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", "dev": true, - "license": "MPL-2.0", "dependencies": { - "async": "^1.4.2", - "ethereumjs-util": "^5.0.0", - "level-ws": "0.0.0", - "levelup": "^1.2.1", - "memdown": "^1.0.0", - "readable-stream": "^2.0.0", - "rlp": "^2.0.0", - "semaphore": ">=1.0.1" + "hash-base": "^3.0.0", + "inherits": "^2.0.1" } }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/merkle-patricia-tree/node_modules/async": { - "version": "1.5.2", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/object-keys": { - "version": "0.4.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/safe-buffer": { - "version": "5.1.2", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/semver": { - "version": "5.4.1", + "node_modules/rlp": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz", + "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==", "dev": true, - "license": "ISC", + "dependencies": { + "bn.js": "^5.2.0" + }, "bin": { - "semver": "bin/semver" + "rlp": "bin/rlp" } }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/string_decoder": { - "version": "0.10.31", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/ethashjs": { - "version": "0.0.8", + "node_modules/run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", "dev": true, - "license": "MPL-2.0", - "dependencies": { - "async": "^2.1.2", - "buffer-xor": "^2.0.1", - "ethereumjs-util": "^7.0.2", - "miller-rabin": "^4.0.0" + "engines": { + "node": ">=0.12.0" } }, - "node_modules/ganache-core/node_modules/ethashjs/node_modules/bn.js": { - "version": "5.1.3", + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/ethashjs/node_modules/buffer-xor": { - "version": "2.0.2", - "dev": true, - "license": "MIT", + "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": { - "safe-buffer": "^5.1.1" + "queue-microtask": "^1.2.2" } }, - "node_modules/ganache-core/node_modules/ethashjs/node_modules/ethereumjs-util": { - "version": "7.0.7", + "node_modules/run-parallel-limit": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/run-parallel-limit/-/run-parallel-limit-1.1.0.tgz", + "integrity": "sha512-jJA7irRNM91jaKc3Hcl1npHsFLOXOoTkPCUL1JEa1R82O2miplXXRaGdjW/KM/98YQWDhJLiSs793CnXfblJUw==", "dev": true, - "license": "MPL-2.0", + "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": { - "@types/bn.js": "^4.11.3", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "0.1.6", - "rlp": "^2.2.4" - }, - "engines": { - "node": ">=10.0.0" + "queue-microtask": "^1.2.2" } }, - "node_modules/ganache-core/node_modules/ethereum-bloom-filters": { - "version": "1.0.7", + "node_modules/rustbn.js": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/rustbn.js/-/rustbn.js-0.2.0.tgz", + "integrity": "sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA==", + "dev": true + }, + "node_modules/rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", "dev": true, - "license": "MIT", - "optional": true, "dependencies": { - "js-sha3": "^0.8.0" + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" } }, - "node_modules/ganache-core/node_modules/ethereum-bloom-filters/node_modules/js-sha3": { - "version": "0.8.0", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/ethereum-common": { - "version": "0.0.18", + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true, - "license": "MIT" + "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/ganache-core/node_modules/ethereum-cryptography": { - "version": "0.1.3", + "node_modules/safe-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", "dev": true, - "license": "MIT", + "peer": 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" + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ganache-core/node_modules/ethereumjs-abi": { - "version": "0.6.8", + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/sc-istanbul": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/sc-istanbul/-/sc-istanbul-0.4.6.tgz", + "integrity": "sha512-qJFF/8tW/zJsbyfh/iT/ZM5QNHE3CXxtLJbZsL+CzdJLBsPD7SedJZoUA4d8iAcN2IoMp/Dx80shOOd2x96X/g==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "bn.js": "^4.11.8", - "ethereumjs-util": "^6.0.0" + "abbrev": "1.0.x", + "async": "1.x", + "escodegen": "1.8.x", + "esprima": "2.7.x", + "glob": "^5.0.15", + "handlebars": "^4.0.1", + "js-yaml": "3.x", + "mkdirp": "0.5.x", + "nopt": "3.x", + "once": "1.x", + "resolve": "1.1.x", + "supports-color": "^3.1.0", + "which": "^1.1.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "istanbul": "lib/cli.js" } }, - "node_modules/ganache-core/node_modules/ethereumjs-account": { - "version": "3.0.0", + "node_modules/sc-istanbul/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, - "license": "MPL-2.0", + "peer": true, "dependencies": { - "ethereumjs-util": "^6.0.0", - "rlp": "^2.2.1", - "safe-buffer": "^5.1.1" + "sprintf-js": "~1.0.2" } }, - "node_modules/ganache-core/node_modules/ethereumjs-block": { - "version": "2.2.2", + "node_modules/sc-istanbul/node_modules/async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==", "dev": true, - "license": "MPL-2.0", - "dependencies": { - "async": "^2.0.1", - "ethereumjs-common": "^1.5.0", - "ethereumjs-tx": "^2.1.1", - "ethereumjs-util": "^5.0.0", - "merkle-patricia-tree": "^2.1.2" - } + "peer": true }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/abstract-leveldown": { - "version": "2.6.3", + "node_modules/sc-istanbul/node_modules/glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha512-c9IPMazfRITpmAAKi22dK1VKxGDX9ehhqfABDriL/lzO92xcUKEJPQHrVA/2YHSNFB4iFlykVmWvwo48nr3OxA==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "xtend": "~4.0.0" + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" } }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/deferred-leveldown": { - "version": "1.2.2", + "node_modules/sc-istanbul/node_modules/has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA==", "dev": true, - "license": "MIT", - "dependencies": { - "abstract-leveldown": "~2.6.0" + "peer": true, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/ethereumjs-util": { - "version": "5.2.1", + "node_modules/sc-istanbul/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, - "license": "MPL-2.0", + "peer": true, "dependencies": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/isarray": { - "version": "0.0.1", + "node_modules/sc-istanbul/node_modules/js-yaml/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, - "license": "MIT" + "peer": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-codec": { - "version": "7.0.1", + "node_modules/sc-istanbul/node_modules/resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha512-9znBF0vBcaSN3W2j7wKvdERPwqTxSpCq+if5C0WoTCyV9n24rua28jeuQ2pL/HOf+yUe/Mef+H/5p60K0Id3bg==", "dev": true, - "license": "MIT" + "peer": true }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-errors": { - "version": "1.0.5", + "node_modules/sc-istanbul/node_modules/supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha512-Jds2VIYDrlp5ui7t8abHN2bjAu4LV/q4N2KivFPpGH0lrka0BMq/33AmECUXlKPcHigkNaqfXRENFju+rlcy+A==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "errno": "~0.1.1" + "has-flag": "^1.0.0" + }, + "engines": { + "node": ">=0.8.0" } }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-iterator-stream": { + "node_modules/sc-istanbul/node_modules/which": { "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "inherits": "^2.0.1", - "level-errors": "^1.0.3", - "readable-stream": "^1.0.33", - "xtend": "^4.0.0" + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" } }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-iterator-stream/node_modules/readable-stream": { - "version": "1.1.14", - "dev": true, - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } + "node_modules/scrypt-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", + "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==", + "dev": true }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-ws": { - "version": "0.0.0", + "node_modules/secp256k1": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz", + "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==", "dev": true, - "license": "MIT", + "hasInstallScript": true, "dependencies": { - "readable-stream": "~1.0.15", - "xtend": "~2.1.1" + "elliptic": "^6.5.4", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + }, + "engines": { + "node": ">=10.0.0" } }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-ws/node_modules/readable-stream": { - "version": "1.0.34", - "dev": true, - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-ws/node_modules/xtend": { - "version": "2.1.2", + "node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true, - "dependencies": { - "object-keys": "~0.4.0" - }, - "engines": { - "node": ">=0.4" + "bin": { + "semver": "bin/semver.js" } }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/levelup": { - "version": "1.3.9", + "node_modules/serialize-javascript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", "dev": true, - "license": "MIT", "dependencies": { - "deferred-leveldown": "~1.2.1", - "level-codec": "~7.0.0", - "level-errors": "~1.0.3", - "level-iterator-stream": "~1.3.0", - "prr": "~1.0.1", - "semver": "~5.4.1", - "xtend": "~4.0.0" + "randombytes": "^2.1.0" } }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/ltgt": { - "version": "2.2.1", + "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==", "dev": true, - "license": "MIT" + "peer": true }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/memdown": { - "version": "1.4.1", - "dev": true, - "license": "MIT", - "dependencies": { - "abstract-leveldown": "~2.7.1", - "functional-red-black-tree": "^1.0.1", - "immediate": "^3.2.3", - "inherits": "~2.0.1", - "ltgt": "~2.2.0", - "safe-buffer": "~5.1.1" - } + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "dev": true }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/memdown/node_modules/abstract-leveldown": { - "version": "2.7.2", - "dev": true, - "license": "MIT", - "dependencies": { - "xtend": "~4.0.0" - } + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/merkle-patricia-tree": { - "version": "2.3.2", + "node_modules/sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", "dev": true, - "license": "MPL-2.0", "dependencies": { - "async": "^1.4.2", - "ethereumjs-util": "^5.0.0", - "level-ws": "0.0.0", - "levelup": "^1.2.1", - "memdown": "^1.0.0", - "readable-stream": "^2.0.0", - "rlp": "^2.0.0", - "semaphore": ">=1.0.1" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/merkle-patricia-tree/node_modules/async": { - "version": "1.5.2", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/object-keys": { - "version": "0.4.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/safe-buffer": { - "version": "5.1.2", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/semver": { - "version": "5.4.1", - "dev": true, - "license": "ISC", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, "bin": { - "semver": "bin/semver" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/string_decoder": { - "version": "0.10.31", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/ethereumjs-blockchain": { - "version": "4.0.4", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "async": "^2.6.1", - "ethashjs": "~0.0.7", - "ethereumjs-block": "~2.2.2", - "ethereumjs-common": "^1.5.0", - "ethereumjs-util": "^6.1.0", - "flow-stoplight": "^1.0.0", - "level-mem": "^3.0.1", - "lru-cache": "^5.1.1", - "rlp": "^2.2.2", - "semaphore": "^1.1.0" + "sha.js": "bin.js" } }, - "node_modules/ganache-core/node_modules/ethereumjs-common": { - "version": "1.5.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/ethereumjs-tx": { - "version": "2.1.2", + "node_modules/sha1": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/sha1/-/sha1-1.1.1.tgz", + "integrity": "sha512-dZBS6OrMjtgVkopB1Gmo4RQCDKiZsqcpAQpkV/aaj+FCrCg8r4I4qMkDPQjBgLIxlmu9k4nUbWq6ohXahOneYA==", "dev": true, - "license": "MPL-2.0", + "peer": true, "dependencies": { - "ethereumjs-common": "^1.5.0", - "ethereumjs-util": "^6.0.0" + "charenc": ">= 0.0.1", + "crypt": ">= 0.0.1" + }, + "engines": { + "node": "*" } }, - "node_modules/ganache-core/node_modules/ethereumjs-util": { - "version": "6.2.1", + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, - "license": "MPL-2.0", "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" + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/ganache-core/node_modules/ethereumjs-vm": { - "version": "4.2.0", + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, - "license": "MPL-2.0", - "dependencies": { - "async": "^2.1.2", - "async-eventemitter": "^0.2.2", - "core-js-pure": "^3.0.1", - "ethereumjs-account": "^3.0.0", - "ethereumjs-block": "^2.2.2", - "ethereumjs-blockchain": "^4.0.3", - "ethereumjs-common": "^1.5.0", - "ethereumjs-tx": "^2.1.2", - "ethereumjs-util": "^6.2.0", - "fake-merkle-patricia-tree": "^1.0.1", - "functional-red-black-tree": "^1.0.1", - "merkle-patricia-tree": "^2.3.2", - "rustbn.js": "~0.2.0", - "safe-buffer": "^5.1.1", - "util.promisify": "^1.0.0" + "engines": { + "node": ">=8" } }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/abstract-leveldown": { - "version": "2.6.3", + "node_modules/shelljs": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", + "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "xtend": "~4.0.0" + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + }, + "bin": { + "shjs": "bin/shjs" + }, + "engines": { + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/deferred-leveldown": { - "version": "1.2.2", + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", "dev": true, - "license": "MIT", "dependencies": { - "abstract-leveldown": "~2.6.0" + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/isarray": { - "version": "0.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-codec": { - "version": "7.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-errors": { - "version": "1.0.5", - "dev": true, - "license": "MIT", - "dependencies": { - "errno": "~0.1.1" - } + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-iterator-stream": { - "version": "1.3.1", + "node_modules/simple-git": { + "version": "3.15.1", + "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.15.1.tgz", + "integrity": "sha512-73MVa5984t/JP4JcQt0oZlKGr42ROYWC3BcUZfuHtT3IHKPspIvL0cZBnvPXF7LL3S/qVeVHVdYYmJ3LOTw4Rg==", "dev": true, - "license": "MIT", "dependencies": { - "inherits": "^2.0.1", - "level-errors": "^1.0.3", - "readable-stream": "^1.0.33", - "xtend": "^4.0.0" + "@kwsites/file-exists": "^1.1.1", + "@kwsites/promise-deferred": "^1.1.1", + "debug": "^4.3.4" + }, + "funding": { + "type": "github", + "url": "https://github.com/steveukx/git-js?sponsor=1" } }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-iterator-stream/node_modules/readable-stream": { - "version": "1.1.14", - "dev": true, - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-ws": { - "version": "0.0.0", + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, - "license": "MIT", - "dependencies": { - "readable-stream": "~1.0.15", - "xtend": "~2.1.1" + "engines": { + "node": ">=8" } }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-ws/node_modules/readable-stream": { - "version": "1.0.34", + "node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-ws/node_modules/xtend": { - "version": "2.1.2", + "node_modules/solc": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/solc/-/solc-0.7.3.tgz", + "integrity": "sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA==", "dev": true, "dependencies": { - "object-keys": "~0.4.0" + "command-exists": "^1.2.8", + "commander": "3.0.2", + "follow-redirects": "^1.12.1", + "fs-extra": "^0.30.0", + "js-sha3": "0.8.0", + "memorystream": "^0.3.1", + "require-from-string": "^2.0.0", + "semver": "^5.5.0", + "tmp": "0.0.33" + }, + "bin": { + "solcjs": "solcjs" }, "engines": { - "node": ">=0.4" + "node": ">=8.0.0" } }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/levelup": { - "version": "1.3.9", + "node_modules/solc/node_modules/commander": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz", + "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==", + "dev": true + }, + "node_modules/solc/node_modules/fs-extra": { + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", + "integrity": "sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==", "dev": true, - "license": "MIT", "dependencies": { - "deferred-leveldown": "~1.2.1", - "level-codec": "~7.0.0", - "level-errors": "~1.0.3", - "level-iterator-stream": "~1.3.0", - "prr": "~1.0.1", - "semver": "~5.4.1", - "xtend": "~4.0.0" + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0", + "path-is-absolute": "^1.0.0", + "rimraf": "^2.2.8" } }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/ltgt": { - "version": "2.2.1", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/memdown": { - "version": "1.4.1", + "node_modules/solc/node_modules/jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==", "dev": true, - "license": "MIT", - "dependencies": { - "abstract-leveldown": "~2.7.1", - "functional-red-black-tree": "^1.0.1", - "immediate": "^3.2.3", - "inherits": "~2.0.1", - "ltgt": "~2.2.0", - "safe-buffer": "~5.1.1" + "optionalDependencies": { + "graceful-fs": "^4.1.6" } }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/memdown/node_modules/abstract-leveldown": { - "version": "2.7.2", + "node_modules/solc/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "dev": true, - "license": "MIT", "dependencies": { - "xtend": "~4.0.0" + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" } }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/merkle-patricia-tree": { - "version": "2.3.2", + "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==", "dev": true, - "license": "MPL-2.0", - "dependencies": { - "async": "^1.4.2", - "ethereumjs-util": "^5.0.0", - "level-ws": "0.0.0", - "levelup": "^1.2.1", - "memdown": "^1.0.0", - "readable-stream": "^2.0.0", - "rlp": "^2.0.0", - "semaphore": ">=1.0.1" + "bin": { + "semver": "bin/semver" } }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/merkle-patricia-tree/node_modules/async": { - "version": "1.5.2", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/merkle-patricia-tree/node_modules/ethereumjs-util": { - "version": "5.2.1", + "node_modules/solhint": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/solhint/-/solhint-2.3.1.tgz", + "integrity": "sha512-wP/G+Dqj8LNWlCI9Mt6XiQRWQfZwv1rkZe/V+HKtip5SAZJVvp144PdH28KE45ZvR99Hhrp/Mujt74fSmXsFiw==", "dev": true, - "license": "MPL-2.0", "dependencies": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" + "ajv": "^6.6.1", + "antlr4": "4.7.1", + "chalk": "^2.4.2", + "commander": "2.18.0", + "cosmiconfig": "^5.0.7", + "eslint": "^5.6.0", + "fast-diff": "^1.1.2", + "glob": "^7.1.3", + "ignore": "^4.0.6", + "js-yaml": "^3.12.0", + "lodash": "^4.17.11", + "semver": "^6.3.0" + }, + "bin": { + "solhint": "solhint.js" + }, + "optionalDependencies": { + "prettier": "^1.14.3" } }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/object-keys": { - "version": "0.4.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/safe-buffer": { - "version": "5.1.2", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/semver": { - "version": "5.4.1", + "node_modules/solhint/node_modules/acorn": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", + "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", "dev": true, - "license": "ISC", "bin": { - "semver": "bin/semver" + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" } }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/string_decoder": { - "version": "0.10.31", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/ethereumjs-wallet": { - "version": "0.6.5", + "node_modules/solhint/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, - "license": "MIT", - "optional": true, - "dependencies": { - "aes-js": "^3.1.1", - "bs58check": "^2.1.2", - "ethereum-cryptography": "^0.1.3", - "ethereumjs-util": "^6.0.0", - "randombytes": "^2.0.6", - "safe-buffer": "^5.1.2", - "scryptsy": "^1.2.1", - "utf8": "^3.0.0", - "uuid": "^3.3.2" + "engines": { + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/ethjs-unit": { - "version": "0.1.6", + "node_modules/solhint/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, - "license": "MIT", - "optional": true, "dependencies": { - "bn.js": "4.11.6", - "number-to-bn": "1.7.0" + "color-convert": "^1.9.0" }, "engines": { - "node": ">=6.5.0", - "npm": ">=3" + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/ethjs-unit/node_modules/bn.js": { - "version": "4.11.6", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/ethjs-util": { - "version": "0.1.6", + "node_modules/solhint/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, - "license": "MIT", "dependencies": { - "is-hex-prefixed": "1.0.0", - "strip-hex-prefix": "1.0.0" - }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" + "sprintf-js": "~1.0.2" } }, - "node_modules/ganache-core/node_modules/eventemitter3": { - "version": "4.0.4", + "node_modules/solhint/node_modules/astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", "dev": true, - "license": "MIT", - "optional": true + "engines": { + "node": ">=4" + } }, - "node_modules/ganache-core/node_modules/events": { - "version": "3.2.0", + "node_modules/solhint/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, - "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, "engines": { - "node": ">=0.8.x" + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/evp_bytestokey": { - "version": "1.0.3", + "node_modules/solhint/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, - "license": "MIT", "dependencies": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" + "color-name": "1.1.3" } }, - "node_modules/ganache-core/node_modules/expand-brackets": { - "version": "2.1.4", + "node_modules/solhint/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/solhint/node_modules/commander": { + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.18.0.tgz", + "integrity": "sha512-6CYPa+JP2ftfRU2qkDK+UTVeQYosOg/2GbcjIcKPHfinyOLPVGXu/ovN86RP49Re5ndJK1N0kuiidFFuepc4ZQ==", + "dev": true + }, + "node_modules/solhint/node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", "dev": true, - "license": "MIT", "dependencies": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" }, "engines": { - "node": ">=0.10.0" + "node": ">=4.8" } }, - "node_modules/ganache-core/node_modules/expand-brackets/node_modules/debug": { - "version": "2.6.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==", "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" + "bin": { + "semver": "bin/semver" } }, - "node_modules/ganache-core/node_modules/expand-brackets/node_modules/define-property": { - "version": "0.2.5", + "node_modules/solhint/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 + }, + "node_modules/solhint/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, - "license": "MIT", - "dependencies": { - "is-descriptor": "^0.1.0" - }, "engines": { - "node": ">=0.10.0" + "node": ">=0.8.0" } }, - "node_modules/ganache-core/node_modules/expand-brackets/node_modules/extend-shallow": { - "version": "2.0.1", + "node_modules/solhint/node_modules/eslint": { + "version": "5.16.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz", + "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==", "dev": true, - "license": "MIT", "dependencies": { - "is-extendable": "^0.1.0" + "@babel/code-frame": "^7.0.0", + "ajv": "^6.9.1", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "eslint-scope": "^4.0.3", + "eslint-utils": "^1.3.1", + "eslint-visitor-keys": "^1.0.0", + "espree": "^5.0.1", + "esquery": "^1.0.1", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob": "^7.1.2", + "globals": "^11.7.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "inquirer": "^6.2.2", + "js-yaml": "^3.13.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.11", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.2", + "progress": "^2.0.0", + "regexpp": "^2.0.1", + "semver": "^5.5.1", + "strip-ansi": "^4.0.0", + "strip-json-comments": "^2.0.1", + "table": "^5.2.3", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" }, "engines": { - "node": ">=0.10.0" + "node": "^6.14.0 || ^8.10.0 || >=9.10.0" } }, - "node_modules/ganache-core/node_modules/expand-brackets/node_modules/is-accessor-descriptor": { - "version": "0.1.6", + "node_modules/solhint/node_modules/eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", "dev": true, - "license": "MIT", "dependencies": { - "kind-of": "^3.0.2" + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" }, "engines": { - "node": ">=0.10.0" + "node": ">=4.0.0" } }, - "node_modules/ganache-core/node_modules/expand-brackets/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", + "node_modules/solhint/node_modules/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, - "license": "MIT", "dependencies": { - "is-buffer": "^1.1.5" + "eslint-visitor-keys": "^1.1.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=6" } }, - "node_modules/ganache-core/node_modules/expand-brackets/node_modules/is-buffer": { - "version": "1.1.6", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/expand-brackets/node_modules/is-data-descriptor": { - "version": "0.1.4", + "node_modules/solhint/node_modules/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, - "license": "MIT", - "dependencies": { - "kind-of": "^3.0.2" - }, "engines": { - "node": ">=0.10.0" + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/expand-brackets/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", + "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==", "dev": true, - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" + "bin": { + "semver": "bin/semver" } }, - "node_modules/ganache-core/node_modules/expand-brackets/node_modules/is-descriptor": { - "version": "0.1.6", + "node_modules/solhint/node_modules/espree": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz", + "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==", "dev": true, - "license": "MIT", "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" + "acorn": "^6.0.7", + "acorn-jsx": "^5.0.0", + "eslint-visitor-keys": "^1.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=6.0.0" } }, - "node_modules/ganache-core/node_modules/expand-brackets/node_modules/is-extendable": { - "version": "0.1.1", + "node_modules/solhint/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, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/expand-brackets/node_modules/kind-of": { - "version": "5.1.0", - "dev": true, - "license": "MIT", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, "engines": { - "node": ">=0.10.0" + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/expand-brackets/node_modules/ms": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/express": { - "version": "4.17.1", + "node_modules/solhint/node_modules/file-entry-cache": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", "dev": true, - "license": "MIT", - "optional": true, "dependencies": { - "accepts": "~1.3.7", - "array-flatten": "1.1.1", - "body-parser": "1.19.0", - "content-disposition": "0.5.3", - "content-type": "~1.0.4", - "cookie": "0.4.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~1.1.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "~1.1.2", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.5", - "qs": "6.7.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.1.2", - "send": "0.17.1", - "serve-static": "1.14.1", - "setprototypeof": "1.1.1", - "statuses": "~1.5.0", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" + "flat-cache": "^2.0.1" }, "engines": { - "node": ">= 0.10.0" + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/express/node_modules/debug": { - "version": "2.6.9", + "node_modules/solhint/node_modules/flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", "dev": true, - "license": "MIT", - "optional": true, "dependencies": { - "ms": "2.0.0" + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + }, + "engines": { + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/express/node_modules/ms": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "optional": true + "node_modules/solhint/node_modules/flatted": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", + "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", + "dev": true }, - "node_modules/ganache-core/node_modules/express/node_modules/qs": { - "version": "6.7.0", + "node_modules/solhint/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true, - "license": "BSD-3-Clause", - "optional": true, "engines": { - "node": ">=0.6" + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/express/node_modules/safe-buffer": { - "version": "5.1.2", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/ext": { - "version": "1.4.0", + "node_modules/solhint/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, - "license": "ISC", - "dependencies": { - "type": "^2.0.0" + "engines": { + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/ext/node_modules/type": { - "version": "2.1.0", + "node_modules/solhint/node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true, - "license": "ISC" + "engines": { + "node": ">= 4" + } }, - "node_modules/ganache-core/node_modules/extend": { - "version": "3.0.2", + "node_modules/solhint/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, - "license": "MIT" + "engines": { + "node": ">=4" + } }, - "node_modules/ganache-core/node_modules/extend-shallow": { - "version": "3.0.2", + "node_modules/solhint/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, - "license": "MIT", "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" + "argparse": "^1.0.7", + "esprima": "^4.0.0" }, - "engines": { - "node": ">=0.10.0" + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/ganache-core/node_modules/extglob": { - "version": "2.0.4", + "node_modules/solhint/node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", "dev": true, - "license": "MIT", "dependencies": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.8.0" } }, - "node_modules/ganache-core/node_modules/extglob/node_modules/define-property": { - "version": "1.0.0", + "node_modules/solhint/node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", "dev": true, - "license": "MIT", "dependencies": { - "is-descriptor": "^1.0.0" + "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" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.8.0" } }, - "node_modules/ganache-core/node_modules/extglob/node_modules/extend-shallow": { + "node_modules/solhint/node_modules/path-key": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", "dev": true, - "license": "MIT", - "dependencies": { - "is-extendable": "^0.1.0" - }, "engines": { - "node": ">=0.10.0" + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/extglob/node_modules/is-extendable": { - "version": "0.1.1", + "node_modules/solhint/node_modules/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, - "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">= 0.8.0" } }, - "node_modules/ganache-core/node_modules/extsprintf": { - "version": "1.3.0", + "node_modules/solhint/node_modules/regexpp": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", "dev": true, - "engines": [ - "node >=0.6.0" - ], - "license": "MIT" + "engines": { + "node": ">=6.5.0" + } }, - "node_modules/ganache-core/node_modules/fake-merkle-patricia-tree": { - "version": "1.0.1", + "node_modules/solhint/node_modules/rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", "dev": true, - "license": "ISC", "dependencies": { - "checkpoint-store": "^1.1.0" + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" } }, - "node_modules/ganache-core/node_modules/fast-deep-equal": { - "version": "3.1.3", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/fetch-ponyfill": { - "version": "4.1.0", + "node_modules/solhint/node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", "dev": true, - "license": "MIT", "dependencies": { - "node-fetch": "~1.7.1" + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/ganache-core/node_modules/fetch-ponyfill/node_modules/is-stream": { - "version": "1.1.0", + "node_modules/solhint/node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, - "node_modules/ganache-core/node_modules/fetch-ponyfill/node_modules/node-fetch": { - "version": "1.7.3", + "node_modules/solhint/node_modules/slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", "dev": true, - "license": "MIT", "dependencies": { - "encoding": "^0.1.11", - "is-stream": "^1.0.1" + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + }, + "engines": { + "node": ">=6" } }, - "node_modules/ganache-core/node_modules/finalhandler": { - "version": "1.1.2", + "node_modules/solhint/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, - "license": "MIT", - "optional": true, "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" }, "engines": { - "node": ">= 0.8" + "node": ">=6" } }, - "node_modules/ganache-core/node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", + "node_modules/solhint/node_modules/string-width/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==", "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "ms": "2.0.0" + "engines": { + "node": ">=6" } }, - "node_modules/ganache-core/node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/find-yarn-workspace-root": { - "version": "1.2.1", + "node_modules/solhint/node_modules/string-width/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, - "license": "Apache-2.0", "dependencies": { - "fs-extra": "^4.0.3", - "micromatch": "^3.1.4" + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" } }, - "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/braces": { - "version": "2.3.2", + "node_modules/solhint/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, - "license": "MIT", "dependencies": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" + "ansi-regex": "^3.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/braces/node_modules/extend-shallow": { + "node_modules/solhint/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, - "license": "MIT", - "dependencies": { - "is-extendable": "^0.1.0" - }, "engines": { "node": ">=0.10.0" } }, - "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/fill-range": { - "version": "4.0.0", + "node_modules/solhint/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, - "license": "MIT", "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" + "has-flag": "^3.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/fill-range/node_modules/extend-shallow": { - "version": "2.0.1", + "node_modules/solhint/node_modules/table": { + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", "dev": true, - "license": "MIT", "dependencies": { - "is-extendable": "^0.1.0" + "ajv": "^6.10.2", + "lodash": "^4.17.14", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=6.0.0" } }, - "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/fs-extra": { - "version": "4.0.3", + "node_modules/solhint/node_modules/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, - "license": "MIT", "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/is-buffer": { - "version": "1.1.6", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/is-extendable": { - "version": "0.1.1", - "dev": true, - "license": "MIT", + "prelude-ls": "~1.1.2" + }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.8.0" } }, - "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/is-number": { - "version": "3.0.0", + "node_modules/solhint/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, - "license": "MIT", "dependencies": { - "kind-of": "^3.0.2" + "isexe": "^2.0.0" }, - "engines": { - "node": ">=0.10.0" + "bin": { + "which": "bin/which" } }, - "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", + "node_modules/solidity-ast": { + "version": "0.4.40", + "resolved": "https://registry.npmjs.org/solidity-ast/-/solidity-ast-0.4.40.tgz", + "integrity": "sha512-M8uLBT2jgFB7B0iVAC5a2l71J8vim7aEm03AZkaHbDqyrl1pE+i5PriMEw6WlwGfHp3/Ym7cn9BqvVLQgRk+Yw==", + "dev": true + }, + "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==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "is-buffer": "^1.1.5" + "@ethersproject/abi": "^5.0.9", + "@solidity-parser/parser": "^0.14.1", + "chalk": "^2.4.2", + "death": "^1.1.0", + "detect-port": "^1.3.0", + "difflib": "^0.2.4", + "fs-extra": "^8.1.0", + "ghost-testrpc": "^0.0.2", + "global-modules": "^2.0.0", + "globby": "^10.0.1", + "jsonschema": "^1.2.4", + "lodash": "^4.17.15", + "mocha": "7.1.2", + "node-emoji": "^1.10.0", + "pify": "^4.0.1", + "recursive-readdir": "^2.2.2", + "sc-istanbul": "^0.4.5", + "semver": "^7.3.4", + "shelljs": "^0.8.3", + "web3-utils": "^1.3.6" }, - "engines": { - "node": ">=0.10.0" + "bin": { + "solidity-coverage": "plugins/bin.js" + }, + "peerDependencies": { + "hardhat": "^2.11.0" } }, - "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/micromatch": { - "version": "3.1.10", + "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, - "license": "MIT", - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, + "peer": true, "engines": { - "node": ">=0.10.0" + "node": ">=6" } }, - "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/to-regex-range": { - "version": "2.1.1", + "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==", "dev": true, - "license": "MIT", - "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, + "peer": true, "engines": { - "node": ">=0.10.0" + "node": ">=6" } }, - "node_modules/ganache-core/node_modules/flow-stoplight": { - "version": "1.0.0", - "dev": true, - "license": "ISC" - }, - "node_modules/ganache-core/node_modules/for-each": { - "version": "0.3.3", + "node_modules/solidity-coverage/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, - "license": "MIT", + "peer": true, "dependencies": { - "is-callable": "^1.1.3" + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/for-in": { - "version": "1.0.2", + "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, - "license": "MIT", - "engines": { - "node": ">=0.10.0" + "peer": true, + "dependencies": { + "sprintf-js": "~1.0.2" } }, - "node_modules/ganache-core/node_modules/forever-agent": { - "version": "0.6.1", + "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, - "license": "Apache-2.0", + "peer": true, "engines": { - "node": "*" + "node": ">=6" } }, - "node_modules/ganache-core/node_modules/form-data": { - "version": "2.3.3", + "node_modules/solidity-coverage/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, - "license": "MIT", + "peer": true, "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" }, "engines": { - "node": ">= 0.12" - } - }, - "node_modules/ganache-core/node_modules/forwarded": { - "version": "0.1.2", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 0.6" + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/fragment-cache": { - "version": "0.2.1", + "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==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "map-cache": "^0.2.2" + "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": ">=0.10.0" + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.1.1" } }, - "node_modules/ganache-core/node_modules/fresh": { - "version": "0.5.2", + "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, - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 0.6" + "peer": true, + "dependencies": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" } }, - "node_modules/ganache-core/node_modules/fs-extra": { - "version": "7.0.1", + "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, - "license": "MIT", + "peer": true, "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" + "color-name": "1.1.3" } }, - "node_modules/ganache-core/node_modules/fs.realpath": { - "version": "1.0.0", - "dev": true, - "license": "ISC" - }, - "node_modules/ganache-core/node_modules/function-bind": { - "version": "1.1.1", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/functional-red-black-tree": { - "version": "1.0.1", + "node_modules/solidity-coverage/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, - "license": "MIT" + "peer": true }, - "node_modules/ganache-core/node_modules/get-intrinsic": { - "version": "1.0.2", + "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, - "license": "MIT", + "peer": true, "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "ms": "^2.1.1" } }, - "node_modules/ganache-core/node_modules/get-stream": { - "version": "5.2.0", + "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, - "license": "MIT", - "optional": true, - "dependencies": { - "pump": "^3.0.0" - }, + "peer": true, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=0.10.0" } }, - "node_modules/ganache-core/node_modules/get-value": { - "version": "2.0.6", + "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, - "license": "MIT", + "peer": true, "engines": { - "node": ">=0.10.0" + "node": ">=0.3.1" } }, - "node_modules/ganache-core/node_modules/getpass": { - "version": "0.1.7", + "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, - "license": "MIT", - "dependencies": { - "assert-plus": "^1.0.0" - } + "peer": true }, - "node_modules/ganache-core/node_modules/glob": { - "version": "7.1.3", + "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", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, - "license": "ISC", - "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" - }, + "peer": true, "engines": { - "node": "*" - } - }, - "node_modules/ganache-core/node_modules/global": { - "version": "4.4.0", - "dev": true, - "license": "MIT", - "dependencies": { - "min-document": "^2.19.0", - "process": "^0.11.10" + "node": ">=0.8.0" } }, - "node_modules/ganache-core/node_modules/got": { - "version": "9.6.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, - "license": "MIT", - "optional": 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" + "peer": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" }, "engines": { - "node": ">=8.6" + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/got/node_modules/get-stream": { - "version": "4.1.0", + "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, - "license": "MIT", - "optional": true, + "peer": true, "dependencies": { - "pump": "^3.0.0" + "locate-path": "^3.0.0" }, "engines": { "node": ">=6" } }, - "node_modules/ganache-core/node_modules/graceful-fs": { - "version": "4.2.4", - "dev": true, - "license": "ISC" - }, - "node_modules/ganache-core/node_modules/har-schema": { - "version": "2.0.0", + "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, - "license": "ISC", - "engines": { - "node": ">=4" + "peer": true, + "dependencies": { + "is-buffer": "~2.0.3" + }, + "bin": { + "flat": "cli.js" } }, - "node_modules/ganache-core/node_modules/har-validator": { - "version": "5.1.5", + "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", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" }, "engines": { - "node": ">=6" + "node": ">=6 <7 || >=8" } }, - "node_modules/ganache-core/node_modules/has": { - "version": "1.0.3", + "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, - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.1" - }, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "peer": true, "engines": { - "node": ">= 0.4.0" + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/ganache-core/node_modules/has-ansi": { - "version": "2.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, - "license": "MIT", + "peer": true, "dependencies": { - "ansi-regex": "^2.0.0" + "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": ">=0.10.0" + "node": "*" } }, - "node_modules/ganache-core/node_modules/has-ansi/node_modules/ansi-regex": { - "version": "2.1.1", + "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, - "license": "MIT", + "peer": true, + "dependencies": { + "is-glob": "^4.0.1" + }, "engines": { - "node": ">=0.10.0" + "node": ">= 6" } }, - "node_modules/ganache-core/node_modules/has-flag": { - "version": "3.0.0", + "node_modules/solidity-coverage/node_modules/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, - "license": "MIT", + "peer": true, + "dependencies": { + "@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" + }, "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/ganache-core/node_modules/has-symbol-support-x": { - "version": "1.4.2", + "node_modules/solidity-coverage/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, - "license": "MIT", - "optional": true, + "peer": true, "engines": { - "node": "*" + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/has-symbols": { - "version": "1.0.1", + "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==", "dev": true, - "license": "MIT", + "peer": true, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/has-to-string-tag-x": { - "version": "1.4.1", + "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==", "dev": true, - "license": "MIT", - "optional": true, + "peer": true, "dependencies": { - "has-symbol-support-x": "^1.4.1" + "argparse": "^1.0.7", + "esprima": "^4.0.0" }, - "engines": { - "node": "*" + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/ganache-core/node_modules/has-value": { - "version": "1.0.0", + "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==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=6" } }, - "node_modules/ganache-core/node_modules/has-values": { - "version": "1.0.0", + "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==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" + "chalk": "^2.4.2" }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/ganache-core/node_modules/has-values/node_modules/is-buffer": { - "version": "1.1.6", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/has-values/node_modules/is-number": { - "version": "3.0.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==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "kind-of": "^3.0.2" + "yallist": "^4.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=10" } }, - "node_modules/ganache-core/node_modules/has-values/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", + "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==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "is-buffer": "^1.1.5" + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">=0.10.0" + "node": "*" } }, - "node_modules/ganache-core/node_modules/has-values/node_modules/kind-of": { - "version": "4.0.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==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "is-buffer": "^1.1.5" + "minimist": "^1.2.5" }, - "engines": { - "node": ">=0.10.0" + "bin": { + "mkdirp": "bin/cmd.js" } }, - "node_modules/ganache-core/node_modules/hash-base": { - "version": "3.1.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==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" + "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": ">=4" + "node": ">= 8.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mochajs" } }, - "node_modules/ganache-core/node_modules/hash-base/node_modules/readable-stream": { - "version": "3.6.0", + "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==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "has-flag": "^3.0.0" }, "engines": { - "node": ">= 6" + "node": ">=6" } }, - "node_modules/ganache-core/node_modules/hash.js": { - "version": "1.1.7", + "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==", "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "node_modules/ganache-core/node_modules/heap": { - "version": "0.2.6", - "dev": true + "peer": true }, - "node_modules/ganache-core/node_modules/hmac-drbg": { - "version": "1.0.1", + "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==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ganache-core/node_modules/home-or-tmp": { - "version": "2.0.0", + "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==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.1" + "p-limit": "^2.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=6" } }, - "node_modules/ganache-core/node_modules/http-cache-semantics": { - "version": "4.1.0", + "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, - "license": "BSD-2-Clause", - "optional": true + "peer": true, + "engines": { + "node": ">=4" + } }, - "node_modules/ganache-core/node_modules/http-errors": { - "version": "1.7.2", + "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, - "license": "MIT", - "optional": true, + "peer": true, "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" + "picomatch": "^2.0.4" }, "engines": { - "node": ">= 0.6" + "node": ">= 8" } }, - "node_modules/ganache-core/node_modules/http-errors/node_modules/inherits": { - "version": "2.0.3", - "dev": true, - "license": "ISC", - "optional": true - }, - "node_modules/ganache-core/node_modules/http-https": { - "version": "1.0.0", + "node_modules/solidity-coverage/node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, - "license": "ISC", - "optional": true + "peer": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } }, - "node_modules/ganache-core/node_modules/http-signature": { - "version": "1.2.0", + "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, - "license": "MIT", + "peer": true, "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" }, "engines": { - "node": ">=0.8", - "npm": ">=1.3.7" + "node": ">=6" } }, - "node_modules/ganache-core/node_modules/iconv-lite": { - "version": "0.4.24", + "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, - "license": "MIT", - "optional": true, + "peer": true, "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" + "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/ganache-core/node_modules/idna-uts46-hx": { - "version": "2.3.1", + "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, - "license": "MIT", - "optional": true, + "peer": true, "dependencies": { - "punycode": "2.1.0" + "has-flag": "^3.0.0" }, "engines": { - "node": ">=4.0.0" + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/idna-uts46-hx/node_modules/punycode": { - "version": "2.1.0", + "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, - "license": "MIT", - "optional": 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/ganache-core/node_modules/ieee754": { - "version": "1.2.1", + "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, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "BSD-3-Clause" + "peer": true }, - "node_modules/ganache-core/node_modules/immediate": { - "version": "3.2.3", + "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, - "license": "MIT" + "peer": true }, - "node_modules/ganache-core/node_modules/inflight": { - "version": "1.0.6", + "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==", "dev": true, - "license": "ISC", + "peer": true, "dependencies": { - "once": "^1.3.0", - "wrappy": "1" + "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" } }, - "node_modules/ganache-core/node_modules/inherits": { - "version": "2.0.4", - "dev": true, - "license": "ISC" - }, - "node_modules/ganache-core/node_modules/invariant": { - "version": "2.2.4", + "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, - "license": "MIT", + "peer": true, "dependencies": { - "loose-envify": "^1.0.0" + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" } }, - "node_modules/ganache-core/node_modules/ipaddr.js": { - "version": "1.9.1", + "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, - "license": "MIT", - "optional": true, + "peer": true, + "dependencies": { + "flat": "^4.1.0", + "lodash": "^4.17.15", + "yargs": "^13.3.0" + }, "engines": { - "node": ">= 0.10" + "node": ">=6" } }, - "node_modules/ganache-core/node_modules/is-accessor-descriptor": { - "version": "1.0.0", + "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, - "license": "MIT", + "optional": true, + "peer": true, "dependencies": { - "kind-of": "^6.0.0" + "amdefine": ">=0.0.4" }, "engines": { - "node": ">=0.10.0" + "node": ">=0.8.0" } }, - "node_modules/ganache-core/node_modules/is-arguments": { - "version": "1.1.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, - "license": "MIT", "dependencies": { - "call-bind": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" } }, - "node_modules/ganache-core/node_modules/is-callable": { - "version": "1.2.2", + "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, - "license": "MIT", "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=0.10.0" } }, - "node_modules/ganache-core/node_modules/is-ci": { - "version": "2.0.0", + "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==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "ci-info": "^2.0.0" + "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": { - "is-ci": "bin.js" - } - }, - "node_modules/ganache-core/node_modules/is-data-descriptor": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^6.0.0" + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" }, "engines": { "node": ">=0.10.0" } }, - "node_modules/ganache-core/node_modules/is-date-object": { - "version": "1.0.2", + "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, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "peer": true }, - "node_modules/ganache-core/node_modules/is-descriptor": { - "version": "1.0.2", + "node_modules/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, - "license": "MIT", "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" + "type-fest": "^0.7.1" }, "engines": { - "node": ">=0.10.0" + "node": ">=6" } }, - "node_modules/ganache-core/node_modules/is-extendable": { - "version": "1.0.1", + "node_modules/stacktrace-parser/node_modules/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, - "license": "MIT", - "dependencies": { - "is-plain-object": "^2.0.4" - }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/ganache-core/node_modules/is-finite": { - "version": "1.1.0", + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", "dev": true, - "license": "MIT", "engines": { - "node": ">=0.10.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 0.8" } }, - "node_modules/ganache-core/node_modules/is-fn": { - "version": "1.0.0", + "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==", "dev": true, - "license": "MIT", + "peer": true, "engines": { "node": ">=0.10.0" } }, - "node_modules/ganache-core/node_modules/is-function": { - "version": "1.0.2", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/is-hex-prefixed": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/ganache-core/node_modules/is-negative-zero": { - "version": "2.0.1", + "node_modules/streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", "dev": true, - "license": "MIT", "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=10.0.0" } }, - "node_modules/ganache-core/node_modules/is-object": { - "version": "1.0.2", + "node_modules/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, - "license": "MIT", - "optional": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "dependencies": { + "safe-buffer": "~5.2.0" } }, - "node_modules/ganache-core/node_modules/is-plain-obj": { - "version": "1.1.0", + "node_modules/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, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.10.0" - } + "peer": true }, - "node_modules/ganache-core/node_modules/is-plain-object": { - "version": "2.0.4", + "node_modules/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, - "license": "MIT", "dependencies": { - "isobject": "^3.0.1" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/ganache-core/node_modules/is-regex": { - "version": "1.1.1", + "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==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "has-symbols": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ganache-core/node_modules/is-retry-allowed": { - "version": "1.2.0", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/is-symbol": { - "version": "1.0.3", + "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==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "has-symbols": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ganache-core/node_modules/is-typedarray": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/is-windows": { - "version": "1.0.2", + "node_modules/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, - "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/ganache-core/node_modules/isarray": { + "node_modules/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, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/isexe": { - "version": "2.0.0", - "dev": true, - "license": "ISC" - }, - "node_modules/ganache-core/node_modules/isobject": { - "version": "3.0.1", - "dev": true, - "license": "MIT", + "dependencies": { + "is-hex-prefixed": "1.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=6.5.0", + "npm": ">=3" } }, - "node_modules/ganache-core/node_modules/isstream": { - "version": "0.1.2", + "node_modules/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, - "license": "MIT" + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "node_modules/ganache-core/node_modules/isurl": { - "version": "1.0.0", + "node_modules/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, - "license": "MIT", - "optional": true, "dependencies": { - "has-to-string-tag-x": "^1.2.0", - "is-object": "^1.0.1" + "escape-string-regexp": "^1.0.2" }, "engines": { - "node": ">= 4" + "node": ">=0.10.0" } }, - "node_modules/ganache-core/node_modules/js-sha3": { - "version": "0.5.7", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/js-tokens": { - "version": "4.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/jsbn": { - "version": "0.1.1", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/json-buffer": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/json-rpc-engine": { - "version": "3.8.0", + "node_modules/strip-outer/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, - "license": "ISC", - "dependencies": { - "async": "^2.0.1", - "babel-preset-env": "^1.7.0", - "babelify": "^7.3.0", - "json-rpc-error": "^2.0.0", - "promise-to-callback": "^1.0.0", - "safe-event-emitter": "^1.0.1" + "engines": { + "node": ">=0.8.0" } }, - "node_modules/ganache-core/node_modules/json-rpc-error": { - "version": "2.0.0", + "node_modules/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, - "license": "MIT", "dependencies": { - "inherits": "^2.0.1" + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/ganache-core/node_modules/json-rpc-random-id": { - "version": "1.0.1", - "dev": true, - "license": "ISC" - }, - "node_modules/ganache-core/node_modules/json-schema": { - "version": "0.2.3", - "dev": true - }, - "node_modules/ganache-core/node_modules/json-schema-traverse": { - "version": "0.4.1", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/json-stable-stringify": { - "version": "1.0.1", + "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, - "license": "MIT", + "peer": true, "dependencies": { - "jsonify": "~0.0.0" - } - }, - "node_modules/ganache-core/node_modules/json-stringify-safe": { - "version": "5.0.1", - "dev": true, - "license": "ISC" - }, - "node_modules/ganache-core/node_modules/jsonfile": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "optionalDependencies": { - "graceful-fs": "^4.1.6" + "http-response-object": "^3.0.1", + "sync-rpc": "^1.2.1", + "then-request": "^6.0.0" + }, + "engines": { + "node": ">=8.0.0" } }, - "node_modules/ganache-core/node_modules/jsonify": { - "version": "0.0.0", - "dev": true, - "license": "Public Domain" - }, - "node_modules/ganache-core/node_modules/jsprim": { - "version": "1.4.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==", "dev": true, - "engines": [ - "node >=0.6.0" - ], - "license": "MIT", + "peer": true, "dependencies": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" + "get-port": "^3.1.0" } }, - "node_modules/ganache-core/node_modules/keccak": { - "version": "3.0.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==", "dev": true, - "hasInstallScript": true, - "inBundle": true, - "license": "MIT", + "peer": true, "dependencies": { - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" + "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/ganache-core/node_modules/keyv": { - "version": "3.1.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, - "license": "MIT", - "optional": true, + "peer": true, "dependencies": { - "json-buffer": "3.0.0" + "array-back": "^4.0.1", + "deep-extend": "~0.6.0", + "typical": "^5.2.0", + "wordwrapjs": "^4.0.0" + }, + "engines": { + "node": ">=8.0.0" } }, - "node_modules/ganache-core/node_modules/kind-of": { - "version": "6.0.3", + "node_modules/table-layout/node_modules/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, - "license": "MIT", + "peer": true, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/ganache-core/node_modules/klaw-sync": { - "version": "6.0.0", + "node_modules/table-layout/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, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.1.11" - } - }, - "node_modules/ganache-core/node_modules/level-codec": { - "version": "9.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer": "^5.6.0" - }, + "peer": true, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/ganache-core/node_modules/level-errors": { - "version": "2.0.1", + "node_modules/table/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "errno": "~0.1.1" + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" }, - "engines": { - "node": ">=6" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/ganache-core/node_modules/level-iterator-stream": { - "version": "2.0.3", + "node_modules/table/node_modules/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, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.5", - "xtend": "^4.0.0" - }, - "engines": { - "node": ">=4" - } + "peer": true }, - "node_modules/ganache-core/node_modules/level-mem": { - "version": "3.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "level-packager": "~4.0.0", - "memdown": "~3.0.0" - }, - "engines": { - "node": ">=6" - } + "node_modules/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 }, - "node_modules/ganache-core/node_modules/level-mem/node_modules/abstract-leveldown": { - "version": "5.0.0", + "node_modules/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, - "license": "MIT", + "peer": true, "dependencies": { - "xtend": "~4.0.0" + "@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" }, "engines": { - "node": ">=6" + "node": ">=6.0.0" } }, - "node_modules/ganache-core/node_modules/level-mem/node_modules/ltgt": { - "version": "2.2.1", + "node_modules/then-request/node_modules/@types/node": { + "version": "8.10.66", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz", + "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==", "dev": true, - "license": "MIT" + "peer": true }, - "node_modules/ganache-core/node_modules/level-mem/node_modules/memdown": { - "version": "3.0.0", + "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/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", "dev": true, - "license": "MIT", "dependencies": { - "abstract-leveldown": "~5.0.0", - "functional-red-black-tree": "~1.0.1", - "immediate": "~3.2.3", - "inherits": "~2.0.1", - "ltgt": "~2.2.0", - "safe-buffer": "~5.1.1" + "os-tmpdir": "~1.0.2" }, "engines": { - "node": ">=6" + "node": ">=0.6.0" } }, - "node_modules/ganache-core/node_modules/level-mem/node_modules/safe-buffer": { - "version": "5.1.2", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/level-packager": { - "version": "4.0.1", + "node_modules/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, - "license": "MIT", "dependencies": { - "encoding-down": "~5.0.0", - "levelup": "^3.0.0" + "is-number": "^7.0.0" }, "engines": { - "node": ">=6" + "node": ">=8.0" } }, - "node_modules/ganache-core/node_modules/level-post": { - "version": "1.0.7", + "node_modules/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, - "license": "MIT", - "dependencies": { - "ltgt": "^2.1.2" + "engines": { + "node": ">=0.6" } }, - "node_modules/ganache-core/node_modules/level-sublevel": { - "version": "6.6.4", + "node_modules/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, - "license": "MIT", + "peer": true, "dependencies": { - "bytewise": "~1.1.0", - "level-codec": "^9.0.0", - "level-errors": "^2.0.0", - "level-iterator-stream": "^2.0.3", - "ltgt": "~2.1.1", - "pull-defer": "^0.2.2", - "pull-level": "^2.0.3", - "pull-stream": "^3.6.8", - "typewiselite": "~1.0.0", - "xtend": "~4.0.0" + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" } }, - "node_modules/ganache-core/node_modules/level-ws": { + "node_modules/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, - "license": "MIT", "dependencies": { - "inherits": "^2.0.3", - "readable-stream": "^2.2.8", - "xtend": "^4.0.1" + "escape-string-regexp": "^1.0.2" }, "engines": { - "node": ">=6" + "node": ">=0.10.0" } }, - "node_modules/ganache-core/node_modules/levelup": { - "version": "3.1.1", + "node_modules/trim-repeated/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, - "license": "MIT", - "dependencies": { - "deferred-leveldown": "~4.0.0", - "level-errors": "~2.0.0", - "level-iterator-stream": "~3.0.0", - "xtend": "~4.0.0" - }, "engines": { - "node": ">=6" + "node": ">=0.8.0" } }, - "node_modules/ganache-core/node_modules/levelup/node_modules/level-iterator-stream": { - "version": "3.0.1", + "node_modules/ts-command-line-args": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/ts-command-line-args/-/ts-command-line-args-2.3.1.tgz", + "integrity": "sha512-FR3y7pLl/fuUNSmnPhfLArGqRrpojQgIEEOVzYx9DhTmfIN7C9RWSfpkJEF4J+Gk7aVx5pak8I7vWZsaN4N84g==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "xtend": "^4.0.0" + "chalk": "^4.1.0", + "command-line-args": "^5.1.1", + "command-line-usage": "^6.1.0", + "string-format": "^2.0.0" }, - "engines": { - "node": ">=6" + "bin": { + "write-markdown": "dist/write-markdown.js" } }, - "node_modules/ganache-core/node_modules/lodash": { - "version": "4.17.20", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/looper": { - "version": "2.0.0", + "node_modules/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, - "license": "MIT" + "peer": true, + "peerDependencies": { + "typescript": ">=3.7.0" + } }, - "node_modules/ganache-core/node_modules/loose-envify": { - "version": "1.4.0", + "node_modules/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, - "license": "MIT", "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" + "@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" }, "bin": { - "loose-envify": "cli.js" + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } } }, - "node_modules/ganache-core/node_modules/lowercase-keys": { - "version": "1.0.1", + "node_modules/ts-node/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, - "license": "MIT", - "optional": true, "engines": { - "node": ">=0.10.0" + "node": ">=0.3.1" } }, - "node_modules/ganache-core/node_modules/lru-cache": { - "version": "5.1.1", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^3.0.2" - } + "node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true }, - "node_modules/ganache-core/node_modules/ltgt": { - "version": "2.1.3", - "dev": true, - "license": "MIT" + "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/ganache-core/node_modules/map-cache": { - "version": "0.2.2", + "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, - "license": "MIT", + "dependencies": { + "tslib": "^1.8.1" + }, "engines": { - "node": ">=0.10.0" + "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/ganache-core/node_modules/map-visit": { - "version": "1.0.0", + "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, - "license": "MIT", + "peer": true, "dependencies": { - "object-visit": "^1.0.0" + "safe-buffer": "^5.0.1" }, "engines": { - "node": ">=0.10.0" + "node": "*" } }, - "node_modules/ganache-core/node_modules/md5.js": { - "version": "1.3.5", + "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==", "dev": true, - "license": "MIT", "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" } }, - "node_modules/ganache-core/node_modules/media-typer": { - "version": "0.3.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, - "license": "MIT", - "optional": true, + "peer": true, "engines": { - "node": ">= 0.6" + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/merge-descriptors": { - "version": "1.0.1", + "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, - "license": "MIT", - "optional": true + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "node_modules/ganache-core/node_modules/merkle-patricia-tree": { - "version": "3.0.0", + "node_modules/typechain": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/typechain/-/typechain-8.1.1.tgz", + "integrity": "sha512-uF/sUvnXTOVF2FHKhQYnxHk4su4JjZR8vr4mA2mBaRwHTbwh0jIlqARz9XJr1tA0l7afJGvEa1dTSi4zt039LQ==", "dev": true, - "license": "MPL-2.0", + "peer": true, "dependencies": { - "async": "^2.6.1", - "ethereumjs-util": "^5.2.0", - "level-mem": "^3.0.1", - "level-ws": "^1.0.0", - "readable-stream": "^3.0.6", - "rlp": "^2.0.0", - "semaphore": ">=1.0.1" + "@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" + }, + "bin": { + "typechain": "dist/cli/cli.js" + }, + "peerDependencies": { + "typescript": ">=4.3.0" } }, - "node_modules/ganache-core/node_modules/merkle-patricia-tree/node_modules/ethereumjs-util": { - "version": "5.2.1", + "node_modules/typechain/node_modules/glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", "dev": true, - "license": "MPL-2.0", + "peer": true, "dependencies": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" + "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": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/ganache-core/node_modules/merkle-patricia-tree/node_modules/readable-stream": { - "version": "3.6.0", + "node_modules/typechain/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "peer": true, + "bin": { + "mkdirp": "bin/cmd.js" }, "engines": { - "node": ">= 6" + "node": ">=10" } }, - "node_modules/ganache-core/node_modules/methods": { - "version": "1.1.2", + "node_modules/typechain/node_modules/prettier": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.2.tgz", + "integrity": "sha512-BtRV9BcncDyI2tsuS19zzhzoxD8Dh8LiCx7j7tHzrkz8GFXAexeWFdi22mjE1d16dftH2qNaytVxqiRTGlMfpw==", "dev": true, - "license": "MIT", - "optional": true, + "peer": true, + "bin": { + "prettier": "bin-prettier.js" + }, "engines": { - "node": ">= 0.6" + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" } }, - "node_modules/ganache-core/node_modules/miller-rabin": { - "version": "4.0.1", + "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, - "license": "MIT", + "peer": true, "dependencies": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "is-typed-array": "^1.1.9" }, - "bin": { - "miller-rabin": "bin/miller-rabin" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ganache-core/node_modules/mime": { - "version": "1.6.0", + "node_modules/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 + }, + "node_modules/typescript": { + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", + "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", "dev": true, - "license": "MIT", - "optional": true, "bin": { - "mime": "cli.js" + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" }, "engines": { - "node": ">=4" + "node": ">=4.2.0" } }, - "node_modules/ganache-core/node_modules/mime-db": { - "version": "1.45.0", + "node_modules/typical": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", + "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==", "dev": true, - "license": "MIT", + "peer": true, "engines": { - "node": ">= 0.6" + "node": ">=8" } }, - "node_modules/ganache-core/node_modules/mime-types": { - "version": "2.1.28", + "node_modules/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, - "license": "MIT", - "dependencies": { - "mime-db": "1.45.0" + "optional": true, + "peer": true, + "bin": { + "uglifyjs": "bin/uglifyjs" }, "engines": { - "node": ">= 0.6" + "node": ">=0.8.0" } }, - "node_modules/ganache-core/node_modules/mimic-response": { - "version": "1.0.1", + "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, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=4" + "peer": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ganache-core/node_modules/min-document": { - "version": "2.19.0", + "node_modules/undici": { + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.15.0.tgz", + "integrity": "sha512-wCAZJDyjw9Myv+Ay62LAoB+hZLPW9SmKbQkbHIhMw/acKSlpn7WohdMUc/Vd4j1iSMBO0hWwU8mjB7a5p5bl8g==", "dev": true, "dependencies": { - "dom-walk": "^0.1.0" + "busboy": "^1.6.0" + }, + "engines": { + "node": ">=12.18" } }, - "node_modules/ganache-core/node_modules/minimalistic-assert": { - "version": "1.0.1", + "node_modules/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, - "license": "ISC" + "engines": { + "node": ">= 4.0.0" + } }, - "node_modules/ganache-core/node_modules/minimalistic-crypto-utils": { - "version": "1.0.1", + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "dev": true, - "license": "MIT" + "engines": { + "node": ">= 0.8" + } }, - "node_modules/ganache-core/node_modules/minimatch": { - "version": "3.0.4", + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, - "license": "ISC", "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" + "punycode": "^2.1.0" } }, - "node_modules/ganache-core/node_modules/minimist": { - "version": "1.2.5", + "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, - "license": "MIT" + "peer": true + }, + "node_modules/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 }, - "node_modules/ganache-core/node_modules/minizlib": { - "version": "1.3.3", + "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==", "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "minipass": "^2.9.0" + "bin": { + "uuid": "dist/bin/uuid" } }, - "node_modules/ganache-core/node_modules/minizlib/node_modules/minipass": { - "version": "2.9.0", + "node_modules/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 + }, + "node_modules/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, - "license": "ISC", - "optional": true, + "engines": [ + "node >=0.6.0" + ], + "peer": true, "dependencies": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" } }, - "node_modules/ganache-core/node_modules/mixin-deep": { - "version": "1.3.2", + "node_modules/web3-utils": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.8.1.tgz", + "integrity": "sha512-LgnM9p6V7rHHUGfpMZod+NST8cRfGzJ1BTXAyNo7A9cJX9LczBfSRxJp+U/GInYe9mby40t3v22AJdlELibnsQ==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" + "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" }, "engines": { - "node": ">=0.10.0" + "node": ">=8.0.0" } }, - "node_modules/ganache-core/node_modules/mkdirp": { - "version": "0.5.5", + "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, - "license": "MIT", "dependencies": { - "minimist": "^1.2.5" + "isexe": "^2.0.0" }, "bin": { - "mkdirp": "bin/cmd.js" + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" } }, - "node_modules/ganache-core/node_modules/mkdirp-promise": { - "version": "5.0.1", + "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, - "license": "ISC", - "optional": true, + "peer": true, "dependencies": { - "mkdirp": "*" + "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" }, - "engines": { - "node": ">=4" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ganache-core/node_modules/mock-fs": { - "version": "4.13.0", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/ms": { - "version": "2.1.3", + "node_modules/which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", "dev": true, - "license": "MIT" + "peer": true }, - "node_modules/ganache-core/node_modules/multibase": { - "version": "0.6.1", + "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==", "dev": true, - "license": "MIT", - "optional": true, + "peer": true, "dependencies": { - "base-x": "^3.0.8", - "buffer": "^5.5.0" + "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" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ganache-core/node_modules/multicodec": { - "version": "0.5.7", + "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==", "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "varint": "^5.0.0" - } - }, - "node_modules/ganache-core/node_modules/multihashes": { - "version": "0.4.21", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "buffer": "^5.5.0", - "multibase": "^0.7.0", - "varint": "^5.0.0" - } - }, - "node_modules/ganache-core/node_modules/multihashes/node_modules/multibase": { - "version": "0.7.0", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "base-x": "^3.0.8", - "buffer": "^5.5.0" - } - }, - "node_modules/ganache-core/node_modules/nano-json-stream-parser": { - "version": "0.1.2", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/nanomatch": { - "version": "1.2.13", - "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" + "string-width": "^1.0.2 || 2" } }, - "node_modules/ganache-core/node_modules/negotiator": { - "version": "0.6.2", + "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==", "dev": true, - "license": "MIT", - "optional": true, + "peer": true, "engines": { - "node": ">= 0.6" + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/next-tick": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/nice-try": { - "version": "1.0.5", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/node-addon-api": { - "version": "2.0.2", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/node-fetch": { - "version": "2.1.2", + "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==", "dev": true, - "license": "MIT", + "peer": true, "engines": { - "node": "4.x || >=6.0.0" - } - }, - "node_modules/ganache-core/node_modules/node-gyp-build": { - "version": "4.2.3", - "dev": true, - "inBundle": true, - "license": "MIT", - "bin": { - "node-gyp-build": "bin.js", - "node-gyp-build-optional": "optional.js", - "node-gyp-build-test": "build-test.js" + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/normalize-url": { - "version": "4.5.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==", "dev": true, - "license": "MIT", - "optional": true, + "peer": true, + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, "engines": { - "node": ">=8" + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/number-to-bn": { - "version": "1.7.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==", "dev": true, - "license": "MIT", - "optional": true, + "peer": true, "dependencies": { - "bn.js": "4.11.6", - "strip-hex-prefix": "1.0.0" + "ansi-regex": "^3.0.0" }, "engines": { - "node": ">=6.5.0", - "npm": ">=3" + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/number-to-bn/node_modules/bn.js": { - "version": "4.11.6", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/oauth-sign": { - "version": "0.9.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==", "dev": true, - "license": "Apache-2.0", "engines": { - "node": "*" + "node": ">=0.10.0" } }, - "node_modules/ganache-core/node_modules/object-assign": { - "version": "4.1.1", + "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, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } + "peer": true }, - "node_modules/ganache-core/node_modules/object-copy": { - "version": "0.1.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==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" + "reduce-flatten": "^2.0.0", + "typical": "^5.2.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=8.0.0" } }, - "node_modules/ganache-core/node_modules/object-copy/node_modules/define-property": { - "version": "0.2.5", + "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, - "license": "MIT", - "dependencies": { - "is-descriptor": "^0.1.0" - }, + "peer": true, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/ganache-core/node_modules/object-copy/node_modules/is-accessor-descriptor": { - "version": "0.1.6", + "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 + }, + "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, - "license": "MIT", "dependencies": { - "kind-of": "^3.0.2" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/ganache-core/node_modules/object-copy/node_modules/is-buffer": { - "version": "1.1.6", - "dev": true, - "license": "MIT" + "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/ganache-core/node_modules/object-copy/node_modules/is-data-descriptor": { - "version": "0.1.4", + "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, - "license": "MIT", "dependencies": { - "kind-of": "^3.0.2" + "mkdirp": "^0.5.1" }, "engines": { - "node": ">=0.10.0" + "node": ">=4" } }, - "node_modules/ganache-core/node_modules/object-copy/node_modules/is-descriptor": { - "version": "0.1.6", + "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, - "license": "MIT", - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, "engines": { - "node": ">=0.10.0" + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } } }, - "node_modules/ganache-core/node_modules/object-copy/node_modules/is-descriptor/node_modules/kind-of": { - "version": "5.1.0", + "node_modules/xmlhttprequest": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", + "integrity": "sha512-58Im/U0mlVBLM38NdZjHyhuMtCqa61469k2YP/AaPbvCoV9aQGUpbJBj1QRm2ytRiVQBD/fsw7L2bJGDVQswBA==", "dev": true, - "license": "MIT", + "peer": true, "engines": { - "node": ">=0.10.0" + "node": ">=0.4.0" } }, - "node_modules/ganache-core/node_modules/object-copy/node_modules/kind-of": { - "version": "3.2.2", + "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, - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, "engines": { - "node": ">=0.10.0" + "node": ">=10" } }, - "node_modules/ganache-core/node_modules/object-inspect": { - "version": "1.9.0", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true }, - "node_modules/ganache-core/node_modules/object-is": { - "version": "1.1.4", + "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, - "license": "MIT", "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" + "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": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=10" } }, - "node_modules/ganache-core/node_modules/object-keys": { - "version": "1.1.1", + "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, - "license": "MIT", "engines": { - "node": ">= 0.4" + "node": ">=10" } }, - "node_modules/ganache-core/node_modules/object-visit": { - "version": "1.0.1", + "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, - "license": "MIT", "dependencies": { - "isobject": "^3.0.0" + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=10" } }, - "node_modules/ganache-core/node_modules/object.assign": { - "version": "4.1.2", + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=6" } }, - "node_modules/ganache-core/node_modules/object.getownpropertydescriptors": { - "version": "2.1.1", + "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, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1" - }, "engines": { - "node": ">= 0.8" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } - }, - "node_modules/ganache-core/node_modules/object.pick": { - "version": "1.3.0", + } + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", "dev": true, - "license": "MIT", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" + "requires": { + "@babel/highlight": "^7.18.6" } }, - "node_modules/ganache-core/node_modules/oboe": { - "version": "2.1.4", - "dev": true, - "license": "BSD", - "optional": true, - "dependencies": { - "http-https": "^1.0.0" - } + "@babel/helper-validator-identifier": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "dev": true }, - "node_modules/ganache-core/node_modules/on-finished": { - "version": "2.3.0", + "@babel/highlight": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "ee-first": "1.1.1" + "requires": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/ganache-core/node_modules/once": { - "version": "1.4.0", - "dev": true, - "license": "ISC", "dependencies": { - "wrappy": "1" + "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" + } + } } }, - "node_modules/ganache-core/node_modules/os-homedir": { - "version": "1.0.2", + "@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, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } + "optional": true }, - "node_modules/ganache-core/node_modules/os-tmpdir": { - "version": "1.0.2", + "@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, - "license": "MIT", - "engines": { - "node": ">=0.10.0" + "requires": { + "@jridgewell/trace-mapping": "0.3.9" } }, - "node_modules/ganache-core/node_modules/p-cancelable": { - "version": "1.1.0", + "@eslint/eslintrc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz", + "integrity": "sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==", "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=6" + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.4.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" } }, - "node_modules/ganache-core/node_modules/p-timeout": { - "version": "1.2.1", + "@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, - "license": "MIT", - "optional": true, - "dependencies": { - "p-finally": "^1.0.0" - }, - "engines": { - "node": ">=4" + "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" } }, - "node_modules/ganache-core/node_modules/p-timeout/node_modules/p-finally": { - "version": "1.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==", "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=4" + "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" } }, - "node_modules/ganache-core/node_modules/parse-asn1": { - "version": "5.1.6", + "@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, - "license": "ISC", - "optional": 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" + "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" } }, - "node_modules/ganache-core/node_modules/parse-headers": { - "version": "2.0.3", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/parseurl": { - "version": "1.3.3", + "@ethersproject/address": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz", + "integrity": "sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==", "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 0.8" + "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" } }, - "node_modules/ganache-core/node_modules/pascalcase": { - "version": "0.1.1", + "@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, - "license": "MIT", - "engines": { - "node": ">=0.10.0" + "requires": { + "@ethersproject/bytes": "^5.7.0" } }, - "node_modules/ganache-core/node_modules/patch-package": { - "version": "6.2.2", + "@ethersproject/basex": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.7.0.tgz", + "integrity": "sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw==", "dev": true, - "license": "MIT", - "dependencies": { - "@yarnpkg/lockfile": "^1.1.0", - "chalk": "^2.4.2", - "cross-spawn": "^6.0.5", - "find-yarn-workspace-root": "^1.2.1", - "fs-extra": "^7.0.1", - "is-ci": "^2.0.0", - "klaw-sync": "^6.0.0", - "minimist": "^1.2.0", - "rimraf": "^2.6.3", - "semver": "^5.6.0", - "slash": "^2.0.0", - "tmp": "^0.0.33" - }, - "bin": { - "patch-package": "index.js" - }, - "engines": { - "npm": ">5" + "requires": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/properties": "^5.7.0" } }, - "node_modules/ganache-core/node_modules/patch-package/node_modules/cross-spawn": { - "version": "6.0.5", + "@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, - "license": "MIT", - "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "engines": { - "node": ">=4.8" + "requires": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "bn.js": "^5.2.1" } }, - "node_modules/ganache-core/node_modules/patch-package/node_modules/path-key": { - "version": "2.0.1", + "@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, - "license": "MIT", - "engines": { - "node": ">=4" + "requires": { + "@ethersproject/logger": "^5.7.0" } }, - "node_modules/ganache-core/node_modules/patch-package/node_modules/semver": { - "version": "5.7.1", + "@ethersproject/constants": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.7.0.tgz", + "integrity": "sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==", "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" + "requires": { + "@ethersproject/bignumber": "^5.7.0" } }, - "node_modules/ganache-core/node_modules/patch-package/node_modules/shebang-command": { - "version": "1.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/patch-package/node_modules/shebang-regex": { - "version": "1.0.0", + "@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, - "license": "MIT", - "engines": { - "node": ">=0.10.0" + "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/ganache-core/node_modules/patch-package/node_modules/slash": { - "version": "2.0.0", + "@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, - "license": "MIT", - "engines": { - "node": ">=6" + "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" } }, - "node_modules/ganache-core/node_modules/patch-package/node_modules/tmp": { - "version": "0.0.33", + "@ethersproject/hdnode": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.7.0.tgz", + "integrity": "sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==", "dev": true, - "license": "MIT", - "dependencies": { - "os-tmpdir": "~1.0.2" - }, - "engines": { - "node": ">=0.6.0" + "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" } }, - "node_modules/ganache-core/node_modules/patch-package/node_modules/which": { - "version": "1.3.1", + "@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, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" + "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" } }, - "node_modules/ganache-core/node_modules/path-is-absolute": { - "version": "1.0.1", + "@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, - "license": "MIT", - "engines": { - "node": ">=0.10.0" + "requires": { + "@ethersproject/bytes": "^5.7.0", + "js-sha3": "0.8.0" } }, - "node_modules/ganache-core/node_modules/path-parse": { - "version": "1.0.6", - "dev": true, - "license": "MIT" + "@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 }, - "node_modules/ganache-core/node_modules/path-to-regexp": { - "version": "0.1.7", + "@ethersproject/networks": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.1.tgz", + "integrity": "sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==", "dev": true, - "license": "MIT", - "optional": true + "requires": { + "@ethersproject/logger": "^5.7.0" + } }, - "node_modules/ganache-core/node_modules/pbkdf2": { - "version": "3.1.1", + "@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, - "license": "MIT", - "dependencies": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - }, - "engines": { - "node": ">=0.12" + "requires": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/sha2": "^5.7.0" } }, - "node_modules/ganache-core/node_modules/performance-now": { - "version": "2.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==", "dev": true, - "license": "MIT" + "requires": { + "@ethersproject/logger": "^5.7.0" + } }, - "node_modules/ganache-core/node_modules/posix-character-classes": { - "version": "0.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==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" + "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" } }, - "node_modules/ganache-core/node_modules/precond": { - "version": "0.2.3", + "@ethersproject/random": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.7.0.tgz", + "integrity": "sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ==", "dev": true, - "engines": { - "node": ">= 0.6" + "requires": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0" } }, - "node_modules/ganache-core/node_modules/prepend-http": { - "version": "2.0.0", + "@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, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=4" + "requires": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0" } }, - "node_modules/ganache-core/node_modules/private": { - "version": "0.1.8", + "@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, - "license": "MIT", - "engines": { - "node": ">= 0.6" + "requires": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "hash.js": "1.1.7" } }, - "node_modules/ganache-core/node_modules/process": { - "version": "0.11.10", + "@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, - "license": "MIT", - "engines": { - "node": ">= 0.6.0" + "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" } }, - "node_modules/ganache-core/node_modules/process-nextick-args": { - "version": "2.0.1", + "@ethersproject/solidity": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.7.0.tgz", + "integrity": "sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA==", "dev": true, - "license": "MIT" + "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/ganache-core/node_modules/promise-to-callback": { - "version": "1.0.0", + "@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, - "license": "MIT", - "dependencies": { - "is-fn": "^1.0.0", - "set-immediate-shim": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" + "requires": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0" } }, - "node_modules/ganache-core/node_modules/proxy-addr": { - "version": "2.0.6", + "@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, - "license": "MIT", - "optional": true, - "dependencies": { - "forwarded": "~0.1.2", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" + "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" } }, - "node_modules/ganache-core/node_modules/prr": { - "version": "1.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/pseudomap": { - "version": "1.0.2", - "dev": true, - "license": "ISC" - }, - "node_modules/ganache-core/node_modules/psl": { - "version": "1.8.0", + "@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, - "license": "MIT" + "requires": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } }, - "node_modules/ganache-core/node_modules/public-encrypt": { - "version": "4.0.3", + "@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, - "license": "MIT", - "optional": 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" + "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" } }, - "node_modules/ganache-core/node_modules/pull-cat": { - "version": "1.1.11", + "@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, - "license": "MIT" + "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" + } }, - "node_modules/ganache-core/node_modules/pull-defer": { - "version": "0.2.3", + "@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, - "license": "MIT" + "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" + } }, - "node_modules/ganache-core/node_modules/pull-level": { - "version": "2.0.4", + "@humanwhocodes/config-array": { + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", + "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", "dev": true, - "license": "MIT", - "dependencies": { - "level-post": "^1.0.7", - "pull-cat": "^1.1.9", - "pull-live": "^1.0.1", - "pull-pushable": "^2.0.0", - "pull-stream": "^3.4.0", - "pull-window": "^2.1.4", - "stream-to-pull-stream": "^1.7.1" + "requires": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" } }, - "node_modules/ganache-core/node_modules/pull-live": { + "@humanwhocodes/module-importer": { "version": "1.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "pull-cat": "^1.1.9", - "pull-stream": "^3.4.0" - } + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true }, - "node_modules/ganache-core/node_modules/pull-pushable": { - "version": "2.2.0", - "dev": true, - "license": "MIT" + "@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 }, - "node_modules/ganache-core/node_modules/pull-stream": { - "version": "3.6.14", - "dev": true, - "license": "MIT" + "@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true }, - "node_modules/ganache-core/node_modules/pull-window": { - "version": "2.1.4", - "dev": true, - "license": "MIT", - "dependencies": { - "looper": "^2.0.0" - } + "@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true }, - "node_modules/ganache-core/node_modules/pump": { - "version": "3.0.0", + "@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, - "license": "MIT", - "optional": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" } }, - "node_modules/ganache-core/node_modules/punycode": { - "version": "2.1.1", + "@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, - "license": "MIT", - "engines": { - "node": ">=6" + "requires": { + "debug": "^4.1.1" } }, - "node_modules/ganache-core/node_modules/qs": { - "version": "6.5.2", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.6" - } + "@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 }, - "node_modules/ganache-core/node_modules/query-string": { - "version": "5.1.1", + "@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, - "license": "MIT", - "optional": true, - "dependencies": { - "decode-uri-component": "^0.2.0", - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" + "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" }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/randombytes": { - "version": "2.1.0", - "dev": true, - "license": "MIT", "dependencies": { - "safe-buffer": "^5.1.0" + "@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 + }, + "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, + "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" + } + } } }, - "node_modules/ganache-core/node_modules/randomfill": { - "version": "1.0.4", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } + "@noble/hashes": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.1.2.tgz", + "integrity": "sha512-KYRCASVTv6aeUi1tsF8/vpyR7zpfs3FUzy2Jqm+MU+LmUKhQ0y2FpfwqkCcxSg2ua4GALJd8k2R76WxwZGbQpA==", + "dev": true }, - "node_modules/ganache-core/node_modules/range-parser": { - "version": "1.2.1", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 0.6" - } + "@noble/secp256k1": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-1.6.3.tgz", + "integrity": "sha512-T04e4iTurVy7I8Sw4+c5OSN9/RkPlo1uKxAomtxQNLq8j1uPAqnsqG1bqvY3Jv7c13gyr6dui0zmh/I3+f/JaQ==", + "dev": true }, - "node_modules/ganache-core/node_modules/raw-body": { - "version": "2.4.0", + "@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, - "license": "MIT", - "optional": true, - "dependencies": { - "bytes": "3.1.0", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" } }, - "node_modules/ganache-core/node_modules/readable-stream": { - "version": "2.3.7", + "@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 + }, + "@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, - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" } }, - "node_modules/ganache-core/node_modules/readable-stream/node_modules/safe-buffer": { - "version": "5.1.2", + "@nomicfoundation/ethereumjs-block": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-block/-/ethereumjs-block-4.0.0.tgz", + "integrity": "sha512-bk8uP8VuexLgyIZAHExH1QEovqx0Lzhc9Ntm63nCRKLHXIZkobaFaeCVwTESV7YkPKUk7NiK11s8ryed4CS9yA==", "dev": true, - "license": "MIT" + "requires": { + "@nomicfoundation/ethereumjs-common": "^3.0.0", + "@nomicfoundation/ethereumjs-rlp": "^4.0.0", + "@nomicfoundation/ethereumjs-trie": "^5.0.0", + "@nomicfoundation/ethereumjs-tx": "^4.0.0", + "@nomicfoundation/ethereumjs-util": "^8.0.0", + "ethereum-cryptography": "0.1.3" + } }, - "node_modules/ganache-core/node_modules/regenerate": { - "version": "1.4.2", + "@nomicfoundation/ethereumjs-blockchain": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-blockchain/-/ethereumjs-blockchain-6.0.0.tgz", + "integrity": "sha512-pLFEoea6MWd81QQYSReLlLfH7N9v7lH66JC/NMPN848ySPPQA5renWnE7wPByfQFzNrPBuDDRFFULMDmj1C0xw==", "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/regenerator-runtime": { - "version": "0.11.1", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/regenerator-transform": { - "version": "0.10.1", - "dev": true, - "license": "BSD", - "dependencies": { - "babel-runtime": "^6.18.0", - "babel-types": "^6.19.0", - "private": "^0.1.6" + "requires": { + "@nomicfoundation/ethereumjs-block": "^4.0.0", + "@nomicfoundation/ethereumjs-common": "^3.0.0", + "@nomicfoundation/ethereumjs-ethash": "^2.0.0", + "@nomicfoundation/ethereumjs-rlp": "^4.0.0", + "@nomicfoundation/ethereumjs-trie": "^5.0.0", + "@nomicfoundation/ethereumjs-util": "^8.0.0", + "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" } }, - "node_modules/ganache-core/node_modules/regex-not": { - "version": "1.0.2", + "@nomicfoundation/ethereumjs-common": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-3.0.0.tgz", + "integrity": "sha512-WS7qSshQfxoZOpHG/XqlHEGRG1zmyjYrvmATvc4c62+gZXgre1ymYP8ZNgx/3FyZY0TWe9OjFlKOfLqmgOeYwA==", "dev": true, - "license": "MIT", - "dependencies": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" + "requires": { + "@nomicfoundation/ethereumjs-util": "^8.0.0", + "crc-32": "^1.2.0" } }, - "node_modules/ganache-core/node_modules/regexp.prototype.flags": { - "version": "1.3.0", + "@nomicfoundation/ethereumjs-ethash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-ethash/-/ethereumjs-ethash-2.0.0.tgz", + "integrity": "sha512-WpDvnRncfDUuXdsAXlI4lXbqUDOA+adYRQaEezIkxqDkc+LDyYDbd/xairmY98GnQzo1zIqsIL6GB5MoMSJDew==", "dev": true, - "license": "MIT", - "dependencies": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "requires": { + "@nomicfoundation/ethereumjs-block": "^4.0.0", + "@nomicfoundation/ethereumjs-rlp": "^4.0.0", + "@nomicfoundation/ethereumjs-util": "^8.0.0", + "abstract-level": "^1.0.3", + "bigint-crypto-utils": "^3.0.23", + "ethereum-cryptography": "0.1.3" } }, - "node_modules/ganache-core/node_modules/regexp.prototype.flags/node_modules/es-abstract": { - "version": "1.17.7", + "@nomicfoundation/ethereumjs-evm": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-evm/-/ethereumjs-evm-1.0.0.tgz", + "integrity": "sha512-hVS6qRo3V1PLKCO210UfcEQHvlG7GqR8iFzp0yyjTg2TmJQizcChKgWo8KFsdMw6AyoLgLhHGHw4HdlP8a4i+Q==", "dev": true, - "license": "MIT", - "dependencies": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.2", - "is-regex": "^1.1.1", - "object-inspect": "^1.8.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.1", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "requires": { + "@nomicfoundation/ethereumjs-common": "^3.0.0", + "@nomicfoundation/ethereumjs-util": "^8.0.0", + "@types/async-eventemitter": "^0.2.1", + "async-eventemitter": "^0.2.4", + "debug": "^4.3.3", + "ethereum-cryptography": "0.1.3", + "mcl-wasm": "^0.7.1", + "rustbn.js": "~0.2.0" } }, - "node_modules/ganache-core/node_modules/regexpu-core": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "regenerate": "^1.2.1", - "regjsgen": "^0.2.0", - "regjsparser": "^0.1.4" - } + "@nomicfoundation/ethereumjs-rlp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-4.0.0.tgz", + "integrity": "sha512-GaSOGk5QbUk4eBP5qFbpXoZoZUj/NrW7MRa0tKY4Ew4c2HAS0GXArEMAamtFrkazp0BO4K5p2ZCG3b2FmbShmw==", + "dev": true }, - "node_modules/ganache-core/node_modules/regjsgen": { - "version": "0.2.0", + "@nomicfoundation/ethereumjs-statemanager": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-statemanager/-/ethereumjs-statemanager-1.0.0.tgz", + "integrity": "sha512-jCtqFjcd2QejtuAMjQzbil/4NHf5aAWxUc+CvS0JclQpl+7M0bxMofR2AJdtz+P3u0ke2euhYREDiE7iSO31vQ==", "dev": true, - "license": "MIT" + "requires": { + "@nomicfoundation/ethereumjs-common": "^3.0.0", + "@nomicfoundation/ethereumjs-rlp": "^4.0.0", + "@nomicfoundation/ethereumjs-trie": "^5.0.0", + "@nomicfoundation/ethereumjs-util": "^8.0.0", + "debug": "^4.3.3", + "ethereum-cryptography": "0.1.3", + "functional-red-black-tree": "^1.0.1" + } }, - "node_modules/ganache-core/node_modules/regjsparser": { - "version": "0.1.5", + "@nomicfoundation/ethereumjs-trie": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-trie/-/ethereumjs-trie-5.0.0.tgz", + "integrity": "sha512-LIj5XdE+s+t6WSuq/ttegJzZ1vliwg6wlb+Y9f4RlBpuK35B9K02bO7xU+E6Rgg9RGptkWd6TVLdedTI4eNc2A==", "dev": true, - "license": "BSD", - "dependencies": { - "jsesc": "~0.5.0" - }, - "bin": { - "regjsparser": "bin/parser" + "requires": { + "@nomicfoundation/ethereumjs-rlp": "^4.0.0", + "@nomicfoundation/ethereumjs-util": "^8.0.0", + "ethereum-cryptography": "0.1.3", + "readable-stream": "^3.6.0" } }, - "node_modules/ganache-core/node_modules/regjsparser/node_modules/jsesc": { - "version": "0.5.0", + "@nomicfoundation/ethereumjs-tx": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-4.0.0.tgz", + "integrity": "sha512-Gg3Lir2lNUck43Kp/3x6TfBNwcWC9Z1wYue9Nz3v4xjdcv6oDW9QSMJxqsKw9QEGoBBZ+gqwpW7+F05/rs/g1w==", "dev": true, - "bin": { - "jsesc": "bin/jsesc" + "requires": { + "@nomicfoundation/ethereumjs-common": "^3.0.0", + "@nomicfoundation/ethereumjs-rlp": "^4.0.0", + "@nomicfoundation/ethereumjs-util": "^8.0.0", + "ethereum-cryptography": "0.1.3" } }, - "node_modules/ganache-core/node_modules/repeat-element": { - "version": "1.1.3", + "@nomicfoundation/ethereumjs-util": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-8.0.0.tgz", + "integrity": "sha512-2emi0NJ/HmTG+CGY58fa+DQuAoroFeSH9gKu9O6JnwTtlzJtgfTixuoOqLEgyyzZVvwfIpRueuePb8TonL1y+A==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" + "requires": { + "@nomicfoundation/ethereumjs-rlp": "^4.0.0-beta.2", + "ethereum-cryptography": "0.1.3" } }, - "node_modules/ganache-core/node_modules/repeat-string": { - "version": "1.6.1", + "@nomicfoundation/ethereumjs-vm": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-vm/-/ethereumjs-vm-6.0.0.tgz", + "integrity": "sha512-JMPxvPQ3fzD063Sg3Tp+UdwUkVxMoo1uML6KSzFhMH3hoQi/LMuXBoEHAoW83/vyNS9BxEe6jm6LmT5xdeEJ6w==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10" + "requires": { + "@nomicfoundation/ethereumjs-block": "^4.0.0", + "@nomicfoundation/ethereumjs-blockchain": "^6.0.0", + "@nomicfoundation/ethereumjs-common": "^3.0.0", + "@nomicfoundation/ethereumjs-evm": "^1.0.0", + "@nomicfoundation/ethereumjs-rlp": "^4.0.0", + "@nomicfoundation/ethereumjs-statemanager": "^1.0.0", + "@nomicfoundation/ethereumjs-trie": "^5.0.0", + "@nomicfoundation/ethereumjs-tx": "^4.0.0", + "@nomicfoundation/ethereumjs-util": "^8.0.0", + "@types/async-eventemitter": "^0.2.1", + "async-eventemitter": "^0.2.4", + "debug": "^4.3.3", + "ethereum-cryptography": "0.1.3", + "functional-red-black-tree": "^1.0.1", + "mcl-wasm": "^0.7.1", + "rustbn.js": "~0.2.0" } }, - "node_modules/ganache-core/node_modules/repeating": { - "version": "2.0.1", + "@nomicfoundation/hardhat-chai-matchers": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-chai-matchers/-/hardhat-chai-matchers-1.0.5.tgz", + "integrity": "sha512-+W5C/+5FHI2xBajUN9THSNc1UP6FUsA7LeLmfnaC9VMi/50/DEjjxd8OmizEXgV1Bjck7my4NVQLL1Ti39FkpA==", "dev": true, - "license": "MIT", - "dependencies": { - "is-finite": "^1.0.0" + "peer": true, + "requires": { + "@ethersproject/abi": "^5.1.2", + "@types/chai-as-promised": "^7.1.3", + "chai-as-promised": "^7.1.1", + "chalk": "^2.4.2", + "deep-eql": "^4.0.1", + "ordinal": "^1.0.3" }, - "engines": { - "node": ">=0.10.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" + } + } } }, - "node_modules/ganache-core/node_modules/request": { - "version": "2.88.2", + "@nomicfoundation/hardhat-network-helpers": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-network-helpers/-/hardhat-network-helpers-1.0.7.tgz", + "integrity": "sha512-X+3mNvn8B7BY5hpIaLO+TrfzWq12bpux+ajGGdmdcfC78NXmYmOZkAtiz1QZx1YIZGMS1LaXzPXyBExxKFpCaw==", "dev": true, - "license": "Apache-2.0", - "dependencies": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "engines": { - "node": ">= 6" + "peer": true, + "requires": { + "ethereumjs-util": "^7.1.4" } }, - "node_modules/ganache-core/node_modules/resolve-url": { - "version": "0.2.1", + "@nomicfoundation/hardhat-toolbox": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-toolbox/-/hardhat-toolbox-2.0.1.tgz", + "integrity": "sha512-/pr8m9xlqiNlq6fXv4hEPNwdNwUhysoB2qbDCKqERfPpq34EydUQTC3Vis4aIea8RLwSrU8sDXFdv4TQxYstKw==", "dev": true, - "license": "MIT" + "requires": {} }, - "node_modules/ganache-core/node_modules/responselike": { - "version": "1.0.2", + "@nomicfoundation/solidity-analyzer": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.0.tgz", + "integrity": "sha512-xGWAiVCGOycvGiP/qrlf9f9eOn7fpNbyJygcB0P21a1MDuVPlKt0Srp7rvtBEutYQ48ouYnRXm33zlRnlTOPHg==", "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "lowercase-keys": "^1.0.0" + "requires": { + "@nomicfoundation/solidity-analyzer-darwin-arm64": "0.1.0", + "@nomicfoundation/solidity-analyzer-darwin-x64": "0.1.0", + "@nomicfoundation/solidity-analyzer-freebsd-x64": "0.1.0", + "@nomicfoundation/solidity-analyzer-linux-arm64-gnu": "0.1.0", + "@nomicfoundation/solidity-analyzer-linux-arm64-musl": "0.1.0", + "@nomicfoundation/solidity-analyzer-linux-x64-gnu": "0.1.0", + "@nomicfoundation/solidity-analyzer-linux-x64-musl": "0.1.0", + "@nomicfoundation/solidity-analyzer-win32-arm64-msvc": "0.1.0", + "@nomicfoundation/solidity-analyzer-win32-ia32-msvc": "0.1.0", + "@nomicfoundation/solidity-analyzer-win32-x64-msvc": "0.1.0" } }, - "node_modules/ganache-core/node_modules/resumer": { - "version": "0.0.0", + "@nomicfoundation/solidity-analyzer-darwin-arm64": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.0.tgz", + "integrity": "sha512-vEF3yKuuzfMHsZecHQcnkUrqm8mnTWfJeEVFHpg+cO+le96xQA4lAJYdUan8pXZohQxv1fSReQsn4QGNuBNuCw==", "dev": true, - "license": "MIT", - "dependencies": { - "through": "~2.3.4" - } + "optional": true }, - "node_modules/ganache-core/node_modules/ret": { - "version": "0.1.15", + "@nomicfoundation/solidity-analyzer-darwin-x64": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-x64/-/solidity-analyzer-darwin-x64-0.1.0.tgz", + "integrity": "sha512-dlHeIg0pTL4dB1l9JDwbi/JG6dHQaU1xpDK+ugYO8eJ1kxx9Dh2isEUtA4d02cQAl22cjOHTvifAk96A+ItEHA==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.12" - } + "optional": true }, - "node_modules/ganache-core/node_modules/rimraf": { - "version": "2.6.3", + "@nomicfoundation/solidity-analyzer-freebsd-x64": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-freebsd-x64/-/solidity-analyzer-freebsd-x64-0.1.0.tgz", + "integrity": "sha512-WFCZYMv86WowDA4GiJKnebMQRt3kCcFqHeIomW6NMyqiKqhK1kIZCxSLDYsxqlx396kKLPN1713Q1S8tu68GKg==", "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } + "optional": true }, - "node_modules/ganache-core/node_modules/ripemd160": { - "version": "2.0.2", + "@nomicfoundation/solidity-analyzer-linux-arm64-gnu": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-gnu/-/solidity-analyzer-linux-arm64-gnu-0.1.0.tgz", + "integrity": "sha512-DTw6MNQWWlCgc71Pq7CEhEqkb7fZnS7oly13pujs4cMH1sR0JzNk90Mp1zpSCsCs4oKan2ClhMlLKtNat/XRKQ==", "dev": true, - "license": "MIT", - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } + "optional": true }, - "node_modules/ganache-core/node_modules/rlp": { - "version": "2.2.6", + "@nomicfoundation/solidity-analyzer-linux-arm64-musl": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-musl/-/solidity-analyzer-linux-arm64-musl-0.1.0.tgz", + "integrity": "sha512-wUpUnR/3GV5Da88MhrxXh/lhb9kxh9V3Jya2NpBEhKDIRCDmtXMSqPMXHZmOR9DfCwCvG6vLFPr/+YrPCnUN0w==", "dev": true, - "license": "MPL-2.0", - "dependencies": { - "bn.js": "^4.11.1" - }, - "bin": { - "rlp": "bin/rlp" - } + "optional": true }, - "node_modules/ganache-core/node_modules/rustbn.js": { - "version": "0.2.0", + "@nomicfoundation/solidity-analyzer-linux-x64-gnu": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-gnu/-/solidity-analyzer-linux-x64-gnu-0.1.0.tgz", + "integrity": "sha512-lR0AxK1x/MeKQ/3Pt923kPvwigmGX3OxeU5qNtQ9pj9iucgk4PzhbS3ruUeSpYhUxG50jN4RkIGwUMoev5lguw==", "dev": true, - "license": "(MIT OR Apache-2.0)" + "optional": true }, - "node_modules/ganache-core/node_modules/safe-buffer": { - "version": "5.2.1", + "@nomicfoundation/solidity-analyzer-linux-x64-musl": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-musl/-/solidity-analyzer-linux-x64-musl-0.1.0.tgz", + "integrity": "sha512-A1he/8gy/JeBD3FKvmI6WUJrGrI5uWJNr5Xb9WdV+DK0F8msuOqpEByLlnTdLkXMwW7nSl3awvLezOs9xBHJEg==", "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" - } - ], - "license": "MIT" + "optional": true }, - "node_modules/ganache-core/node_modules/safe-event-emitter": { - "version": "1.0.1", + "@nomicfoundation/solidity-analyzer-win32-arm64-msvc": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-arm64-msvc/-/solidity-analyzer-win32-arm64-msvc-0.1.0.tgz", + "integrity": "sha512-7x5SXZ9R9H4SluJZZP8XPN+ju7Mx+XeUMWZw7ZAqkdhP5mK19I4vz3x0zIWygmfE8RT7uQ5xMap0/9NPsO+ykw==", "dev": true, - "license": "ISC", - "dependencies": { - "events": "^3.0.0" - } + "optional": true }, - "node_modules/ganache-core/node_modules/safe-regex": { - "version": "1.1.0", + "@nomicfoundation/solidity-analyzer-win32-ia32-msvc": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-ia32-msvc/-/solidity-analyzer-win32-ia32-msvc-0.1.0.tgz", + "integrity": "sha512-m7w3xf+hnE774YRXu+2mGV7RiF3QJtUoiYU61FascCkQhX3QMQavh7saH/vzb2jN5D24nT/jwvaHYX/MAM9zUw==", "dev": true, - "license": "MIT", - "dependencies": { - "ret": "~0.1.10" - } + "optional": true }, - "node_modules/ganache-core/node_modules/safer-buffer": { - "version": "2.1.2", + "@nomicfoundation/solidity-analyzer-win32-x64-msvc": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-x64-msvc/-/solidity-analyzer-win32-x64-msvc-0.1.0.tgz", + "integrity": "sha512-xCuybjY0sLJQnJhupiFAXaek2EqF0AP0eBjgzaalPXSNvCEN6ZYHvUzdA50ENDVeSYFXcUsYf3+FsD3XKaeptA==", "dev": true, - "license": "MIT" + "optional": true }, - "node_modules/ganache-core/node_modules/scrypt-js": { - "version": "3.0.1", + "@nomiclabs/hardhat-ethers": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.2.2.tgz", + "integrity": "sha512-NLDlDFL2us07C0jB/9wzvR0kuLivChJWCXTKcj3yqjZqMoYp7g7wwS157F70VHx/+9gHIBGzak5pKDwG8gEefA==", "dev": true, - "license": "MIT" + "peer": true, + "requires": {} }, - "node_modules/ganache-core/node_modules/scryptsy": { - "version": "1.2.1", + "@nomiclabs/hardhat-etherscan": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-3.1.5.tgz", + "integrity": "sha512-PxPX28AGBAlxgXLU27NB3oiMsklxbNhM75SDC4v1QPCyPeAxGm4xV0WpYbR10W7sxY2WF3Ek7u7GhjbQWa2Fcg==", "dev": true, - "license": "MIT", - "optional": 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": { - "pbkdf2": "^3.0.3" + "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" + } + } } }, - "node_modules/ganache-core/node_modules/secp256k1": { - "version": "4.0.2", + "@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, - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "elliptic": "^6.5.2", - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" - }, - "engines": { - "node": ">=10.0.0" + "requires": { + "solhint": "^2.0.0" } }, - "node_modules/ganache-core/node_modules/seedrandom": { - "version": "3.0.1", - "dev": true, - "license": "MIT" + "@openzeppelin/contracts": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.8.0.tgz", + "integrity": "sha512-AGuwhRRL+NaKx73WKRNzeCxOCOCxpaqF+kp8TJ89QzAipSwZy/NoflkWaL9bywXFRhIzXt8j38sfF7KBKCPWLw==", + "dev": true }, - "node_modules/ganache-core/node_modules/semaphore": { - "version": "1.1.0", - "dev": true, - "engines": { - "node": ">=0.8.0" - } + "@openzeppelin/contracts-upgradeable": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.8.0.tgz", + "integrity": "sha512-5GeFgqMiDlqGT8EdORadp1ntGF0qzWZLmEY7Wbp/yVhN7/B3NNzCxujuI77ktlyG81N3CUZP8cZe3ZAQ/cW10w==", + "dev": true }, - "node_modules/ganache-core/node_modules/send": { - "version": "0.17.1", + "@openzeppelin/hardhat-upgrades": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/@openzeppelin/hardhat-upgrades/-/hardhat-upgrades-1.22.0.tgz", + "integrity": "sha512-1qyZnDaxl0C8tne7ykNRa/fxw3FrNCY2M3fGuCiQW5DDkJoXhLgm3JVsXwl6X7q9mQSrik4vgBbI3ErmxmZTYg==", "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "~1.7.2", - "mime": "1.6.0", - "ms": "2.1.1", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.0" - }, - "engines": { - "node": ">= 0.8.0" + "requires": { + "@openzeppelin/upgrades-core": "^1.20.0", + "chalk": "^4.1.0", + "debug": "^4.1.1", + "proper-lockfile": "^4.1.1" } }, - "node_modules/ganache-core/node_modules/send/node_modules/debug": { - "version": "2.6.9", + "@openzeppelin/upgrades-core": { + "version": "1.20.6", + "resolved": "https://registry.npmjs.org/@openzeppelin/upgrades-core/-/upgrades-core-1.20.6.tgz", + "integrity": "sha512-KWdtlahm+iunlAlzLsdpBueanwEx0LLPfAkDL1p0C4SPjMiUqHHFlyGtmmWwdiqDpJ//605vfwkd5RqfnFrHSg==", "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "ms": "2.0.0" + "requires": { + "cbor": "^8.0.0", + "chalk": "^4.1.0", + "compare-versions": "^5.0.0", + "debug": "^4.1.1", + "ethereumjs-util": "^7.0.3", + "proper-lockfile": "^4.1.1", + "solidity-ast": "^0.4.15" } }, - "node_modules/ganache-core/node_modules/send/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "optional": true + "@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 }, - "node_modules/ganache-core/node_modules/send/node_modules/ms": { - "version": "2.1.1", + "@scure/bip32": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.0.tgz", + "integrity": "sha512-ftTW3kKX54YXLCxH6BB7oEEoJfoE2pIgw7MINKAs5PsS6nqKPuKk1haTF/EuHmYqG330t5GSrdmtRuHaY1a62Q==", "dev": true, - "license": "MIT", - "optional": true + "requires": { + "@noble/hashes": "~1.1.1", + "@noble/secp256k1": "~1.6.0", + "@scure/base": "~1.1.0" + } }, - "node_modules/ganache-core/node_modules/serve-static": { - "version": "1.14.1", + "@scure/bip39": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.0.tgz", + "integrity": "sha512-pwrPOS16VeTKg98dYXQyIjJEcWfz7/1YJIwxUEPFfQPtc86Ym/1sVgQ2RLoD43AazMk2l/unK4ITySSpW2+82w==", "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.17.1" - }, - "engines": { - "node": ">= 0.8.0" + "requires": { + "@noble/hashes": "~1.1.1", + "@scure/base": "~1.1.0" } }, - "node_modules/ganache-core/node_modules/servify": { - "version": "0.1.12", + "@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, - "license": "MIT", - "optional": 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" + "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" } }, - "node_modules/ganache-core/node_modules/set-immediate-shim": { - "version": "1.0.1", + "@sentry/hub": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-5.30.0.tgz", + "integrity": "sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" + "requires": { + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "tslib": "^1.9.3" } }, - "node_modules/ganache-core/node_modules/set-value": { - "version": "2.0.1", + "@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, - "license": "MIT", - "dependencies": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" + "requires": { + "@sentry/hub": "5.30.0", + "@sentry/types": "5.30.0", + "tslib": "^1.9.3" } }, - "node_modules/ganache-core/node_modules/set-value/node_modules/extend-shallow": { - "version": "2.0.1", + "@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, - "license": "MIT", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" + "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" } }, - "node_modules/ganache-core/node_modules/set-value/node_modules/is-extendable": { - "version": "0.1.1", + "@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, - "license": "MIT", - "engines": { - "node": ">=0.10.0" + "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" } }, - "node_modules/ganache-core/node_modules/setimmediate": { - "version": "1.0.5", - "dev": true, - "license": "MIT" + "@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 }, - "node_modules/ganache-core/node_modules/setprototypeof": { - "version": "1.1.1", + "@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, - "license": "ISC", - "optional": true + "requires": { + "@sentry/types": "5.30.0", + "tslib": "^1.9.3" + } }, - "node_modules/ganache-core/node_modules/sha.js": { - "version": "2.4.11", + "@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, - "license": "(MIT AND BSD-3-Clause)", - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - }, - "bin": { - "sha.js": "bin.js" + "peer": true, + "requires": { + "antlr4ts": "^0.5.0-alpha.4" } }, - "node_modules/ganache-core/node_modules/simple-concat": { - "version": "1.0.1", - "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" - } - ], - "license": "MIT", - "optional": true + "@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "dev": true }, - "node_modules/ganache-core/node_modules/simple-get": { - "version": "2.8.1", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "decompress-response": "^3.3.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } + "@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 }, - "node_modules/ganache-core/node_modules/snapdragon": { - "version": "0.8.2", + "@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 + }, + "@tsconfig/node16": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", + "dev": true + }, + "@typechain/ethers-v5": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/@typechain/ethers-v5/-/ethers-v5-10.2.0.tgz", + "integrity": "sha512-ikaq0N/w9fABM+G01OFmU3U3dNnyRwEahkdvi9mqy1a3XwKiPZaF/lu54OcNaEWnpvEYyhhS0N7buCtLQqC92w==", "dev": true, - "license": "MIT", - "dependencies": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "engines": { - "node": ">=0.10.0" + "peer": true, + "requires": { + "lodash": "^4.17.15", + "ts-essentials": "^7.0.1" } }, - "node_modules/ganache-core/node_modules/snapdragon-node": { - "version": "2.1.1", + "@typechain/hardhat": { + "version": "6.1.5", + "resolved": "https://registry.npmjs.org/@typechain/hardhat/-/hardhat-6.1.5.tgz", + "integrity": "sha512-lg7LW4qDZpxFMknp3Xool61Fg6Lays8F8TXdFGBG+MxyYcYU5795P1U2XdStuzGq9S2Dzdgh+1jGww9wvZ6r4Q==", "dev": true, - "license": "MIT", - "dependencies": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" + "peer": true, + "requires": { + "fs-extra": "^9.1.0" }, - "engines": { - "node": ">=0.10.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.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true, + "peer": true + } } }, - "node_modules/ganache-core/node_modules/snapdragon-node/node_modules/define-property": { - "version": "1.0.0", + "@types/async-eventemitter": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@types/async-eventemitter/-/async-eventemitter-0.2.1.tgz", + "integrity": "sha512-M2P4Ng26QbAeITiH7w1d7OxtldgfAe0wobpyJzVK/XOb0cUGKU2R4pfAhqcJBXAe2ife5ZOhSv4wk7p+ffURtg==", + "dev": 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==", "dev": true, - "license": "MIT", - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" + "requires": { + "@types/node": "*" } }, - "node_modules/ganache-core/node_modules/snapdragon-util": { - "version": "3.0.1", + "@types/chai": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.4.tgz", + "integrity": "sha512-KnRanxnpfpjUTqTCXslZSEdLfXExwgNxYPdiO2WGUj8+HDjFi8R3k5RVKPeSCzLjCcshCAtVO2QBbVuAV4kTnw==", + "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==", "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^3.2.0" - }, - "engines": { - "node": ">=0.10.0" + "requires": { + "@types/chai": "*" } }, - "node_modules/ganache-core/node_modules/snapdragon-util/node_modules/is-buffer": { - "version": "1.1.6", - "dev": true, - "license": "MIT" + "@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==", + "dev": true }, - "node_modules/ganache-core/node_modules/snapdragon-util/node_modules/kind-of": { - "version": "3.2.2", + "@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, - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" + "peer": true, + "requires": { + "@types/node": "*" } }, - "node_modules/ganache-core/node_modules/snapdragon/node_modules/debug": { - "version": "2.6.9", + "@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, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" + "peer": true, + "requires": { + "@types/node": "*" } }, - "node_modules/ganache-core/node_modules/snapdragon/node_modules/define-property": { - "version": "0.2.5", + "@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, - "license": "MIT", - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" + "peer": true, + "requires": { + "@types/minimatch": "*", + "@types/node": "*" } }, - "node_modules/ganache-core/node_modules/snapdragon/node_modules/extend-shallow": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } + "@types/json-schema": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "dev": true }, - "node_modules/ganache-core/node_modules/snapdragon/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } + "@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 }, - "node_modules/ganache-core/node_modules/snapdragon/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", + "@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, - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } + "peer": true }, - "node_modules/ganache-core/node_modules/snapdragon/node_modules/is-buffer": { - "version": "1.1.6", - "dev": true, - "license": "MIT" + "@types/mocha": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.1.tgz", + "integrity": "sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw==", + "dev": true }, - "node_modules/ganache-core/node_modules/snapdragon/node_modules/is-data-descriptor": { - "version": "0.1.4", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } + "@types/node": { + "version": "17.0.45", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", + "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==", + "dev": true }, - "node_modules/ganache-core/node_modules/snapdragon/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", + "@types/pbkdf2": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz", + "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==", "dev": true, - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" + "requires": { + "@types/node": "*" } }, - "node_modules/ganache-core/node_modules/snapdragon/node_modules/is-descriptor": { - "version": "0.1.6", + "@types/prettier": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.2.tgz", + "integrity": "sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==", "dev": true, - "license": "MIT", - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } + "peer": true }, - "node_modules/ganache-core/node_modules/snapdragon/node_modules/is-extendable": { - "version": "0.1.1", + "@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==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } + "peer": true }, - "node_modules/ganache-core/node_modules/snapdragon/node_modules/kind-of": { - "version": "5.1.0", + "@types/secp256k1": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.3.tgz", + "integrity": "sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" + "requires": { + "@types/node": "*" } }, - "node_modules/ganache-core/node_modules/snapdragon/node_modules/ms": { - "version": "2.0.0", - "dev": true, - "license": "MIT" + "@types/semver": { + "version": "7.3.13", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", + "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==", + "dev": true }, - "node_modules/ganache-core/node_modules/source-map": { - "version": "0.5.7", + "@typescript-eslint/eslint-plugin": { + "version": "5.48.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.48.1.tgz", + "integrity": "sha512-9nY5K1Rp2ppmpb9s9S2aBiF3xo5uExCehMDmYmmFqqyxgenbHJ3qbarcLt4ITgaD6r/2ypdlcFRdcuVPnks+fQ==", "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" + "requires": { + "@typescript-eslint/scope-manager": "5.48.1", + "@typescript-eslint/type-utils": "5.48.1", + "@typescript-eslint/utils": "5.48.1", + "debug": "^4.3.4", + "ignore": "^5.2.0", + "natural-compare-lite": "^1.4.0", + "regexpp": "^3.2.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.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "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 + } } }, - "node_modules/ganache-core/node_modules/source-map-resolve": { - "version": "0.5.3", + "@typescript-eslint/parser": { + "version": "5.48.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.48.1.tgz", + "integrity": "sha512-4yg+FJR/V1M9Xoq56SF9Iygqm+r5LMXvheo6DQ7/yUWynQ4YfCRnsKuRgqH4EQ5Ya76rVwlEpw4Xu+TgWQUcdA==", "dev": true, - "license": "MIT", - "dependencies": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" + "peer": true, + "requires": { + "@typescript-eslint/scope-manager": "5.48.1", + "@typescript-eslint/types": "5.48.1", + "@typescript-eslint/typescript-estree": "5.48.1", + "debug": "^4.3.4" } }, - "node_modules/ganache-core/node_modules/source-map-support": { - "version": "0.5.12", + "@typescript-eslint/scope-manager": { + "version": "5.48.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.48.1.tgz", + "integrity": "sha512-S035ueRrbxRMKvSTv9vJKIWgr86BD8s3RqoRZmsSh/s8HhIs90g6UlK8ZabUSjUZQkhVxt7nmZ63VJ9dcZhtDQ==", "dev": true, - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" + "requires": { + "@typescript-eslint/types": "5.48.1", + "@typescript-eslint/visitor-keys": "5.48.1" } }, - "node_modules/ganache-core/node_modules/source-map-support/node_modules/source-map": { - "version": "0.6.1", + "@typescript-eslint/type-utils": { + "version": "5.48.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.48.1.tgz", + "integrity": "sha512-Hyr8HU8Alcuva1ppmqSYtM/Gp0q4JOp1F+/JH5D1IZm/bUBrV0edoewQZiEc1r6I8L4JL21broddxK8HAcZiqQ==", "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" + "requires": { + "@typescript-eslint/typescript-estree": "5.48.1", + "@typescript-eslint/utils": "5.48.1", + "debug": "^4.3.4", + "tsutils": "^3.21.0" } }, - "node_modules/ganache-core/node_modules/source-map-url": { - "version": "0.4.0", - "dev": true, - "license": "MIT" + "@typescript-eslint/types": { + "version": "5.48.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.48.1.tgz", + "integrity": "sha512-xHyDLU6MSuEEdIlzrrAerCGS3T7AA/L8Hggd0RCYBi0w3JMvGYxlLlXHeg50JI9Tfg5MrtsfuNxbS/3zF1/ATg==", + "dev": true }, - "node_modules/ganache-core/node_modules/split-string": { - "version": "3.1.0", + "@typescript-eslint/typescript-estree": { + "version": "5.48.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.48.1.tgz", + "integrity": "sha512-Hut+Osk5FYr+sgFh8J/FHjqX6HFcDzTlWLrFqGoK5kVUN3VBHF/QzZmAsIXCQ8T/W9nQNBTqalxi1P3LSqWnRA==", "dev": true, - "license": "MIT", - "dependencies": { - "extend-shallow": "^3.0.0" + "requires": { + "@typescript-eslint/types": "5.48.1", + "@typescript-eslint/visitor-keys": "5.48.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" }, - "engines": { - "node": ">=0.10.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.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "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 + } } }, - "node_modules/ganache-core/node_modules/sshpk": { - "version": "1.16.1", + "@typescript-eslint/utils": { + "version": "5.48.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.48.1.tgz", + "integrity": "sha512-SmQuSrCGUOdmGMwivW14Z0Lj8dxG1mOFZ7soeJ0TQZEJcs3n5Ndgkg0A4bcMFzBELqLJ6GTHnEU+iIoaD6hFGA==", "dev": true, - "license": "MIT", - "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" + "requires": { + "@types/json-schema": "^7.0.9", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.48.1", + "@typescript-eslint/types": "5.48.1", + "@typescript-eslint/typescript-estree": "5.48.1", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0", + "semver": "^7.3.7" }, - "engines": { - "node": ">=0.10.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.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "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 + } } }, - "node_modules/ganache-core/node_modules/sshpk/node_modules/tweetnacl": { - "version": "0.14.5", + "@typescript-eslint/visitor-keys": { + "version": "5.48.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.48.1.tgz", + "integrity": "sha512-Ns0XBwmfuX7ZknznfXozgnydyR8F6ev/KEGePP4i74uL3ArsKbEhJ7raeKr1JSa997DBDwol/4a0Y+At82c9dA==", "dev": true, - "license": "Unlicense" + "requires": { + "@typescript-eslint/types": "5.48.1", + "eslint-visitor-keys": "^3.3.0" + } }, - "node_modules/ganache-core/node_modules/static-extend": { - "version": "0.1.2", + "abbrev": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", + "integrity": "sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q==", "dev": true, - "license": "MIT", - "dependencies": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } + "peer": true }, - "node_modules/ganache-core/node_modules/static-extend/node_modules/define-property": { - "version": "0.2.5", + "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, - "license": "MIT", - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" + "requires": { + "event-target-shim": "^5.0.0" } }, - "node_modules/ganache-core/node_modules/static-extend/node_modules/is-accessor-descriptor": { - "version": "0.1.6", + "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, - "license": "MIT", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" + "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" } }, - "node_modules/ganache-core/node_modules/static-extend/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "dev": true, - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } + "acorn": { + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", + "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", + "dev": true }, - "node_modules/ganache-core/node_modules/static-extend/node_modules/is-buffer": { - "version": "1.1.6", + "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, - "license": "MIT" + "requires": {} }, - "node_modules/ganache-core/node_modules/static-extend/node_modules/is-data-descriptor": { - "version": "0.1.4", + "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==", + "dev": true + }, + "address": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/address/-/address-1.2.2.tgz", + "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==", "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } + "peer": 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 + }, + "aes-js": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", + "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==", + "dev": true }, - "node_modules/ganache-core/node_modules/static-extend/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", + "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, - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" + "requires": { + "debug": "4" } }, - "node_modules/ganache-core/node_modules/static-extend/node_modules/is-descriptor": { - "version": "0.1.6", + "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, - "license": "MIT", - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" } }, - "node_modules/ganache-core/node_modules/static-extend/node_modules/kind-of": { - "version": "5.1.0", + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" + "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" } }, - "node_modules/ganache-core/node_modules/statuses": { - "version": "1.5.0", + "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, - "license": "MIT", "optional": true, - "engines": { - "node": ">= 0.6" - } + "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 }, - "node_modules/ganache-core/node_modules/stream-to-pull-stream": { - "version": "1.7.3", + "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, - "license": "MIT", + "requires": { + "type-fest": "^0.21.3" + }, "dependencies": { - "looper": "^3.0.0", - "pull-stream": "^3.2.3" + "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 + } } }, - "node_modules/ganache-core/node_modules/stream-to-pull-stream/node_modules/looper": { - "version": "3.0.0", - "dev": true, - "license": "MIT" + "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 }, - "node_modules/ganache-core/node_modules/strict-uri-encode": { - "version": "1.1.0", + "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, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.10.0" + "requires": { + "color-convert": "^2.0.1" } }, - "node_modules/ganache-core/node_modules/string_decoder": { - "version": "1.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.1.0" - } + "antlr4": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/antlr4/-/antlr4-4.7.1.tgz", + "integrity": "sha512-haHyTW7Y9joE5MVs37P2lNYfU2RWBLfcRDD8OWldcdZm5TiCE91B5Xl1oWSwiDUSd4rlExpt2pu1fksYQjRBYQ==", + "dev": true }, - "node_modules/ganache-core/node_modules/string_decoder/node_modules/safe-buffer": { - "version": "5.1.2", + "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, - "license": "MIT" + "peer": true }, - "node_modules/ganache-core/node_modules/string.prototype.trim": { - "version": "1.2.3", + "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, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" } }, - "node_modules/ganache-core/node_modules/string.prototype.trimend": { - "version": "1.0.3", + "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/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, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "peer": true + }, + "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 }, - "node_modules/ganache-core/node_modules/string.prototype.trimstart": { + "array-uniq": { "version": "1.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", + "dev": true }, - "node_modules/ganache-core/node_modules/strip-hex-prefix": { - "version": "1.0.0", + "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==", "dev": true, - "license": "MIT", - "dependencies": { - "is-hex-prefixed": "1.0.0" - }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" + "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" } }, - "node_modules/ganache-core/node_modules/supports-color": { - "version": "5.5.0", + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } + "peer": true }, - "node_modules/ganache-core/node_modules/swarm-js": { - "version": "0.1.40", + "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, - "license": "MIT", - "optional": true, - "dependencies": { - "bluebird": "^3.5.0", - "buffer": "^5.0.5", - "eth-lib": "^0.1.26", - "fs-extra": "^4.0.2", - "got": "^7.1.0", - "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" + "peer": true, + "requires": { + "safer-buffer": "~2.1.0" } }, - "node_modules/ganache-core/node_modules/swarm-js/node_modules/fs-extra": { - "version": "4.0.3", + "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, - "license": "MIT", - "optional": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } + "peer": true }, - "node_modules/ganache-core/node_modules/swarm-js/node_modules/get-stream": { - "version": "3.0.0", + "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, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=4" - } + "peer": true }, - "node_modules/ganache-core/node_modules/swarm-js/node_modules/got": { - "version": "7.1.0", + "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, - "license": "MIT", - "optional": true, - "dependencies": { - "decompress-response": "^3.2.0", - "duplexer3": "^0.1.4", - "get-stream": "^3.0.0", - "is-plain-obj": "^1.1.0", - "is-retry-allowed": "^1.0.0", - "is-stream": "^1.0.0", - "isurl": "^1.0.0-alpha5", - "lowercase-keys": "^1.0.0", - "p-cancelable": "^0.3.0", - "p-timeout": "^1.1.1", - "safe-buffer": "^5.0.1", - "timed-out": "^4.0.0", - "url-parse-lax": "^1.0.0", - "url-to-options": "^1.0.1" - }, - "engines": { - "node": ">=4" - } + "peer": true }, - "node_modules/ganache-core/node_modules/swarm-js/node_modules/is-stream": { - "version": "1.1.0", + "async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.10.0" + "requires": { + "lodash": "^4.17.14" } }, - "node_modules/ganache-core/node_modules/swarm-js/node_modules/p-cancelable": { - "version": "0.3.0", + "async-eventemitter": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/async-eventemitter/-/async-eventemitter-0.2.4.tgz", + "integrity": "sha512-pd20BwL7Yt1zwDFy+8MX8F1+WCT8aQeKj0kQnTrH9WaeRETlRamVhD0JtRPmrV4GfOJ2F9CvdQkZeZhnh2TuHw==", "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=4" + "requires": { + "async": "^2.4.0" } }, - "node_modules/ganache-core/node_modules/swarm-js/node_modules/prepend-http": { - "version": "1.0.4", + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.10.0" - } + "peer": true }, - "node_modules/ganache-core/node_modules/swarm-js/node_modules/url-parse-lax": { + "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, - "license": "MIT", - "optional": true, - "dependencies": { - "prepend-http": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } + "peer": true }, - "node_modules/ganache-core/node_modules/tape": { - "version": "4.13.3", + "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, - "license": "MIT", - "dependencies": { - "deep-equal": "~1.1.1", - "defined": "~1.0.0", - "dotignore": "~0.1.2", - "for-each": "~0.3.3", - "function-bind": "~1.1.1", - "glob": "~7.1.6", - "has": "~1.0.3", - "inherits": "~2.0.4", - "is-regex": "~1.0.5", - "minimist": "~1.2.5", - "object-inspect": "~1.7.0", - "resolve": "~1.17.0", - "resumer": "~0.0.0", - "string.prototype.trim": "~1.2.1", - "through": "~2.3.8" - }, - "bin": { - "tape": "bin/tape" - } + "peer": true }, - "node_modules/ganache-core/node_modules/tape/node_modules/glob": { - "version": "7.1.6", + "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, - "license": "ISC", - "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": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } + "peer": true }, - "node_modules/ganache-core/node_modules/tape/node_modules/is-regex": { - "version": "1.0.5", + "aws4": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz", + "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==", "dev": true, - "license": "MIT", - "dependencies": { - "has": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "peer": true }, - "node_modules/ganache-core/node_modules/tape/node_modules/object-inspect": { - "version": "1.7.0", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "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 }, - "node_modules/ganache-core/node_modules/tape/node_modules/resolve": { - "version": "1.17.0", + "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, - "license": "MIT", - "dependencies": { - "path-parse": "^1.0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "requires": { + "safe-buffer": "^5.0.1" } }, - "node_modules/ganache-core/node_modules/tar": { - "version": "4.4.13", - "dev": true, - "license": "ISC", - "optional": true, - "dependencies": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.8.6", - "minizlib": "^1.2.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.3" - }, - "engines": { - "node": ">=4.5" - } + "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 }, - "node_modules/ganache-core/node_modules/tar/node_modules/fs-minipass": { - "version": "1.2.7", + "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, - "license": "ISC", - "optional": true, + "peer": true, + "requires": { + "tweetnacl": "^0.14.3" + }, "dependencies": { - "minipass": "^2.6.0" + "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/ganache-core/node_modules/tar/node_modules/minipass": { - "version": "2.9.0", + "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.1.8", + "resolved": "https://registry.npmjs.org/bigint-crypto-utils/-/bigint-crypto-utils-3.1.8.tgz", + "integrity": "sha512-+VMV9Laq8pXLBKKKK49nOoq9bfR3j7NNQAtbA617a4nw9bVLo8rsqkKMBgM2AJWlNX9fEIyYaYX+d0laqYV4tw==", "dev": true, - "license": "ISC", - "optional": true, - "dependencies": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" + "requires": { + "bigint-mod-arith": "^3.1.0" } }, - "node_modules/ganache-core/node_modules/through": { - "version": "2.3.8", - "dev": true, - "license": "MIT" + "bigint-mod-arith": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bigint-mod-arith/-/bigint-mod-arith-3.1.2.tgz", + "integrity": "sha512-nx8J8bBeiRR+NlsROFH9jHswW5HO8mgfOSqW0AmjicMMvaONDa8AO+5ViKDUUNytBPWiwfvZP4/Bj4Y3lUfvgQ==", + "dev": true }, - "node_modules/ganache-core/node_modules/through2": { - "version": "2.0.5", - "dev": true, - "license": "MIT", - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } + "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 }, - "node_modules/ganache-core/node_modules/timed-out": { - "version": "4.0.1", + "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 + }, + "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 + }, + "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, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.10.0" + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/ganache-core/node_modules/tmp": { - "version": "0.1.0", + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, - "license": "MIT", - "dependencies": { - "rimraf": "^2.6.3" - }, - "engines": { - "node": ">=6" + "requires": { + "fill-range": "^7.0.1" } }, - "node_modules/ganache-core/node_modules/to-object-path": { - "version": "0.3.0", + "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, - "license": "MIT", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" + "requires": { + "abstract-level": "^1.0.2", + "catering": "^2.1.1", + "module-error": "^1.0.2", + "run-parallel-limit": "^1.1.0" } }, - "node_modules/ganache-core/node_modules/to-object-path/node_modules/is-buffer": { - "version": "1.1.6", - "dev": true, - "license": "MIT" + "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 }, - "node_modules/ganache-core/node_modules/to-object-path/node_modules/kind-of": { - "version": "3.2.2", + "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, - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" + "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" } }, - "node_modules/ganache-core/node_modules/to-readable-stream": { - "version": "1.0.0", + "bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=6" + "requires": { + "base-x": "^3.0.2" } }, - "node_modules/ganache-core/node_modules/to-regex": { - "version": "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, - "license": "MIT", - "dependencies": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" + "requires": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" } }, - "node_modules/ganache-core/node_modules/toidentifier": { - "version": "1.0.0", + "buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.6" + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" } }, - "node_modules/ganache-core/node_modules/tough-cookie": { - "version": "2.5.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==", "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=0.8" + "requires": { + "streamsearch": "^1.1.0" } }, - "node_modules/ganache-core/node_modules/trim-right": { - "version": "1.0.1", + "bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "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==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" } }, - "node_modules/ganache-core/node_modules/tunnel-agent": { - "version": "0.6.0", + "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, - "license": "Apache-2.0", - "dependencies": { - "safe-buffer": "^5.0.1" + "requires": { + "callsites": "^2.0.0" }, - "engines": { - "node": "*" + "dependencies": { + "callsites": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ==", + "dev": true + } } }, - "node_modules/ganache-core/node_modules/tweetnacl": { - "version": "1.0.3", + "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, - "license": "Unlicense" + "requires": { + "caller-callsite": "^2.0.0" + } }, - "node_modules/ganache-core/node_modules/tweetnacl-util": { - "version": "0.15.1", - "dev": true, - "license": "Unlicense" + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true }, - "node_modules/ganache-core/node_modules/type": { - "version": "1.2.0", + "camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", "dev": true, - "license": "ISC" + "peer": true }, - "node_modules/ganache-core/node_modules/type-is": { - "version": "1.6.18", + "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, - "license": "MIT", - "optional": true, - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" + "requires": { + "nofilter": "^3.1.0" } }, - "node_modules/ganache-core/node_modules/typedarray": { - "version": "0.0.6", + "chai": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.7.tgz", + "integrity": "sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==", "dev": true, - "license": "MIT" + "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" + } }, - "node_modules/ganache-core/node_modules/typedarray-to-buffer": { - "version": "3.1.5", + "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, - "license": "MIT", - "dependencies": { - "is-typedarray": "^1.0.0" + "requires": { + "check-error": "^1.0.2" } }, - "node_modules/ganache-core/node_modules/typewise": { - "version": "1.0.3", + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "license": "MIT", - "dependencies": { - "typewise-core": "^1.2.0" + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } }, - "node_modules/ganache-core/node_modules/typewise-core": { - "version": "1.2.0", - "dev": true, - "license": "MIT" + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true }, - "node_modules/ganache-core/node_modules/typewiselite": { - "version": "1.0.0", + "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, - "license": "MIT" + "peer": true }, - "node_modules/ganache-core/node_modules/ultron": { - "version": "1.1.1", - "dev": true, - "license": "MIT", - "optional": 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 }, - "node_modules/ganache-core/node_modules/underscore": { - "version": "1.9.1", + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "dev": true, - "license": "MIT", - "optional": 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" + } + } + } }, - "node_modules/ganache-core/node_modules/union-value": { - "version": "1.0.1", + "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==", "dev": true, - "license": "MIT", - "dependencies": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - }, - "engines": { - "node": ">=0.10.0" + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" } }, - "node_modules/ganache-core/node_modules/union-value/node_modules/is-extendable": { - "version": "0.1.1", + "classic-level": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/classic-level/-/classic-level-1.2.0.tgz", + "integrity": "sha512-qw5B31ANxSluWz9xBzklRWTUAJ1SXIdaVKTVS7HcTGKOAmExx65Wo5BUICW+YGORe2FOUaDghoI9ZDxj82QcFg==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" + "requires": { + "abstract-level": "^1.0.2", + "catering": "^2.1.0", + "module-error": "^1.0.1", + "napi-macros": "~2.0.0", + "node-gyp-build": "^4.3.0" } }, - "node_modules/ganache-core/node_modules/universalify": { - "version": "0.1.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==", "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4.0.0" + "requires": { + "restore-cursor": "^2.0.0" } }, - "node_modules/ganache-core/node_modules/unorm": { - "version": "1.6.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, - "license": "MIT or GPL-2.0", - "engines": { - "node": ">= 0.4.0" + "requires": { + "colors": "1.0.3" } }, - "node_modules/ganache-core/node_modules/unpipe": { - "version": "1.0.0", + "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, - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 0.8" + "requires": { + "@colors/colors": "1.5.0", + "string-width": "^4.2.0" } }, - "node_modules/ganache-core/node_modules/unset-value": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.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 }, - "node_modules/ganache-core/node_modules/unset-value/node_modules/has-value": { - "version": "0.3.1", + "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, - "license": "MIT", - "dependencies": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" } }, - "node_modules/ganache-core/node_modules/unset-value/node_modules/has-value/node_modules/isobject": { - "version": "2.1.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, - "license": "MIT", - "dependencies": { - "isarray": "1.0.0" - }, - "engines": { - "node": ">=0.10.0" + "requires": { + "color-name": "~1.1.4" } }, - "node_modules/ganache-core/node_modules/unset-value/node_modules/has-values": { - "version": "0.1.4", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } + "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 }, - "node_modules/ganache-core/node_modules/uri-js": { - "version": "4.4.1", + "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, - "license": "BSD-2-Clause", - "dependencies": { - "punycode": "^2.1.0" + "peer": true, + "requires": { + "delayed-stream": "~1.0.0" } }, - "node_modules/ganache-core/node_modules/urix": { - "version": "0.1.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, - "license": "MIT" + "peer": true, + "requires": { + "array-back": "^3.1.0", + "find-replace": "^3.0.0", + "lodash.camelcase": "^4.3.0", + "typical": "^4.0.0" + } }, - "node_modules/ganache-core/node_modules/url-parse-lax": { - "version": "3.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, - "license": "MIT", - "optional": true, - "dependencies": { - "prepend-http": "^2.0.0" + "peer": true, + "requires": { + "array-back": "^4.0.2", + "chalk": "^2.4.2", + "table-layout": "^1.0.2", + "typical": "^5.2.0" }, - "engines": { - "node": ">=4" + "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" + } + }, + "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 + }, + "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" + } + }, + "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 + } } }, - "node_modules/ganache-core/node_modules/url-set-query": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "optional": true + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true }, - "node_modules/ganache-core/node_modules/url-to-options": { + "commondir": { "version": "1.0.1", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 4" - } + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true }, - "node_modules/ganache-core/node_modules/use": { - "version": "3.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } + "compare-versions": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-5.0.3.tgz", + "integrity": "sha512-4UZlZP8Z99MGEY+Ovg/uJxJuvoXuN4M6B3hKaiackiHrgzQFEe3diJi1mf1PNHbFujM7FvLrK2bpgIaImbtZ1A==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true }, - "node_modules/ganache-core/node_modules/utf-8-validate": { - "version": "5.0.4", + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", "dev": true, - "hasInstallScript": true, - "license": "MIT", + "peer": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + }, "dependencies": { - "node-gyp-build": "^4.2.0" + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "peer": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "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, + "peer": true + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "peer": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } } }, - "node_modules/ganache-core/node_modules/utf8": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "optional": 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 }, - "node_modules/ganache-core/node_modules/util-deprecate": { + "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, - "license": "MIT" + "peer": true }, - "node_modules/ganache-core/node_modules/util.promisify": { - "version": "1.1.1", + "cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "for-each": "^0.3.3", - "has-symbols": "^1.0.1", - "object.getownpropertydescriptors": "^2.1.1" + "requires": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/ganache-core/node_modules/utils-merge": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 0.4.0" + "dependencies": { + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "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 + }, + "import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==", + "dev": true, + "requires": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + } + }, + "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, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", + "dev": true + } } }, - "node_modules/ganache-core/node_modules/uuid": { - "version": "3.4.0", - "dev": true, - "license": "MIT", - "bin": { - "uuid": "bin/uuid" - } + "crc-32": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "dev": true }, - "node_modules/ganache-core/node_modules/varint": { - "version": "5.0.2", + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", "dev": true, - "license": "MIT", - "optional": true + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } }, - "node_modules/ganache-core/node_modules/vary": { - "version": "1.1.2", + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 0.8" + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" } }, - "node_modules/ganache-core/node_modules/verror": { - "version": "1.10.0", + "create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, - "engines": [ - "node >=0.6.0" - ], - "license": "MIT", - "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" } }, - "node_modules/ganache-core/node_modules/web3": { - "version": "1.2.11", + "crypt": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", + "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", "dev": true, - "hasInstallScript": true, - "license": "LGPL-3.0", - "optional": true, - "dependencies": { - "web3-bzz": "1.2.11", - "web3-core": "1.2.11", - "web3-eth": "1.2.11", - "web3-eth-personal": "1.2.11", - "web3-net": "1.2.11", - "web3-shh": "1.2.11", - "web3-utils": "1.2.11" - }, - "engines": { - "node": ">=8.0.0" - } + "peer": true }, - "node_modules/ganache-core/node_modules/web3-bzz": { - "version": "1.2.11", + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", "dev": true, - "license": "LGPL-3.0", - "optional": true, - "dependencies": { - "@types/node": "^12.12.6", - "got": "9.6.0", - "swarm-js": "^0.1.40", - "underscore": "1.9.1" - }, - "engines": { - "node": ">=8.0.0" + "peer": true, + "requires": { + "assert-plus": "^1.0.0" } }, - "node_modules/ganache-core/node_modules/web3-bzz/node_modules/@types/node": { - "version": "12.19.12", + "death": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/death/-/death-1.1.0.tgz", + "integrity": "sha512-vsV6S4KVHvTGxbEcij7hkWRv0It+sGGWVOM67dQde/o5Xjnr+KmLjxWJii2uEObIrt1CcM9w0Yaovx+iOlIL+w==", "dev": true, - "license": "MIT", - "optional": true + "peer": true }, - "node_modules/ganache-core/node_modules/web3-core": { - "version": "1.2.11", + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, - "license": "LGPL-3.0", - "optional": true, - "dependencies": { - "@types/bn.js": "^4.11.5", - "@types/node": "^12.12.6", - "bignumber.js": "^9.0.0", - "web3-core-helpers": "1.2.11", - "web3-core-method": "1.2.11", - "web3-core-requestmanager": "1.2.11", - "web3-utils": "1.2.11" - }, - "engines": { - "node": ">=8.0.0" + "requires": { + "ms": "2.1.2" } }, - "node_modules/ganache-core/node_modules/web3-core-helpers": { - "version": "1.2.11", + "decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true + }, + "deep-eql": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", + "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", "dev": true, - "license": "LGPL-3.0", - "optional": true, - "dependencies": { - "underscore": "1.9.1", - "web3-eth-iban": "1.2.11", - "web3-utils": "1.2.11" - }, - "engines": { - "node": ">=8.0.0" + "peer": true, + "requires": { + "type-detect": "^4.0.0" } }, - "node_modules/ganache-core/node_modules/web3-core-method": { - "version": "1.2.11", + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", "dev": true, - "license": "LGPL-3.0", - "optional": true, - "dependencies": { - "@ethersproject/transactions": "^5.0.0-beta.135", - "underscore": "1.9.1", - "web3-core-helpers": "1.2.11", - "web3-core-promievent": "1.2.11", - "web3-core-subscriptions": "1.2.11", - "web3-utils": "1.2.11" - }, - "engines": { - "node": ">=8.0.0" - } + "peer": true + }, + "deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true }, - "node_modules/ganache-core/node_modules/web3-core-promievent": { - "version": "1.2.11", + "define-properties": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", + "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", "dev": true, - "license": "LGPL-3.0", - "optional": true, - "dependencies": { - "eventemitter3": "4.0.4" - }, - "engines": { - "node": ">=8.0.0" + "peer": true, + "requires": { + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" } }, - "node_modules/ganache-core/node_modules/web3-core-requestmanager": { - "version": "1.2.11", + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "dev": true, - "license": "LGPL-3.0", - "optional": true, - "dependencies": { - "underscore": "1.9.1", - "web3-core-helpers": "1.2.11", - "web3-providers-http": "1.2.11", - "web3-providers-ipc": "1.2.11", - "web3-providers-ws": "1.2.11" - }, - "engines": { - "node": ">=8.0.0" - } + "peer": true + }, + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true }, - "node_modules/ganache-core/node_modules/web3-core-subscriptions": { - "version": "1.2.11", + "detect-port": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.5.1.tgz", + "integrity": "sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ==", "dev": true, - "license": "LGPL-3.0", - "optional": true, - "dependencies": { - "eventemitter3": "4.0.4", - "underscore": "1.9.1", - "web3-core-helpers": "1.2.11" - }, - "engines": { - "node": ">=8.0.0" + "peer": true, + "requires": { + "address": "^1.0.1", + "debug": "4" } }, - "node_modules/ganache-core/node_modules/web3-core/node_modules/@types/node": { - "version": "12.19.12", - "dev": true, - "license": "MIT", - "optional": true + "diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true }, - "node_modules/ganache-core/node_modules/web3-eth": { - "version": "1.2.11", + "difflib": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/difflib/-/difflib-0.2.4.tgz", + "integrity": "sha512-9YVwmMb0wQHQNr5J9m6BSj6fk4pfGITGQOOs+D9Fl+INODWFOfvhIU1hNv6GgR1RBoC/9NJcwu77zShxV0kT7w==", "dev": true, - "license": "LGPL-3.0", - "optional": true, - "dependencies": { - "underscore": "1.9.1", - "web3-core": "1.2.11", - "web3-core-helpers": "1.2.11", - "web3-core-method": "1.2.11", - "web3-core-subscriptions": "1.2.11", - "web3-eth-abi": "1.2.11", - "web3-eth-accounts": "1.2.11", - "web3-eth-contract": "1.2.11", - "web3-eth-ens": "1.2.11", - "web3-eth-iban": "1.2.11", - "web3-eth-personal": "1.2.11", - "web3-net": "1.2.11", - "web3-utils": "1.2.11" - }, - "engines": { - "node": ">=8.0.0" + "peer": true, + "requires": { + "heap": ">= 0.2.0" } }, - "node_modules/ganache-core/node_modules/web3-eth-abi": { - "version": "1.2.11", + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, - "license": "LGPL-3.0", - "optional": true, - "dependencies": { - "@ethersproject/abi": "5.0.0-beta.153", - "underscore": "1.9.1", - "web3-utils": "1.2.11" - }, - "engines": { - "node": ">=8.0.0" + "requires": { + "path-type": "^4.0.0" } }, - "node_modules/ganache-core/node_modules/web3-eth-accounts": { - "version": "1.2.11", + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, - "license": "LGPL-3.0", - "optional": true, - "dependencies": { - "crypto-browserify": "3.12.0", - "eth-lib": "0.2.8", - "ethereumjs-common": "^1.3.2", - "ethereumjs-tx": "^2.1.1", - "scrypt-js": "^3.0.1", - "underscore": "1.9.1", - "uuid": "3.3.2", - "web3-core": "1.2.11", - "web3-core-helpers": "1.2.11", - "web3-core-method": "1.2.11", - "web3-utils": "1.2.11" - }, - "engines": { - "node": ">=8.0.0" + "requires": { + "esutils": "^2.0.2" } }, - "node_modules/ganache-core/node_modules/web3-eth-accounts/node_modules/eth-lib": { - "version": "0.2.8", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - } - }, - "node_modules/ganache-core/node_modules/web3-eth-accounts/node_modules/uuid": { - "version": "3.3.2", - "dev": true, - "license": "MIT", - "optional": true, - "bin": { - "uuid": "bin/uuid" - } - }, - "node_modules/ganache-core/node_modules/web3-eth-contract": { - "version": "1.2.11", - "dev": true, - "license": "LGPL-3.0", - "optional": true, - "dependencies": { - "@types/bn.js": "^4.11.5", - "underscore": "1.9.1", - "web3-core": "1.2.11", - "web3-core-helpers": "1.2.11", - "web3-core-method": "1.2.11", - "web3-core-promievent": "1.2.11", - "web3-core-subscriptions": "1.2.11", - "web3-eth-abi": "1.2.11", - "web3-utils": "1.2.11" - }, - "engines": { - "node": ">=8.0.0" - } + "dotenv": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", + "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==", + "dev": true }, - "node_modules/ganache-core/node_modules/web3-eth-ens": { - "version": "1.2.11", + "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, - "license": "LGPL-3.0", - "optional": true, - "dependencies": { - "content-hash": "^2.5.2", - "eth-ens-namehash": "2.0.8", - "underscore": "1.9.1", - "web3-core": "1.2.11", - "web3-core-helpers": "1.2.11", - "web3-core-promievent": "1.2.11", - "web3-eth-abi": "1.2.11", - "web3-eth-contract": "1.2.11", - "web3-utils": "1.2.11" - }, - "engines": { - "node": ">=8.0.0" + "peer": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" } }, - "node_modules/ganache-core/node_modules/web3-eth-iban": { - "version": "1.2.11", + "elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", "dev": true, - "license": "LGPL-3.0", - "optional": true, - "dependencies": { + "requires": { "bn.js": "^4.11.9", - "web3-utils": "1.2.11" + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/ganache-core/node_modules/web3-eth-personal": { - "version": "1.2.11", - "dev": true, - "license": "LGPL-3.0", - "optional": true, "dependencies": { - "@types/node": "^12.12.6", - "web3-core": "1.2.11", - "web3-core-helpers": "1.2.11", - "web3-core-method": "1.2.11", - "web3-net": "1.2.11", - "web3-utils": "1.2.11" - }, - "engines": { - "node": ">=8.0.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==", + "dev": true + } } }, - "node_modules/ganache-core/node_modules/web3-eth-personal/node_modules/@types/node": { - "version": "12.19.12", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/web3-net": { - "version": "1.2.11", - "dev": true, - "license": "LGPL-3.0", - "optional": true, - "dependencies": { - "web3-core": "1.2.11", - "web3-core-method": "1.2.11", - "web3-utils": "1.2.11" - }, - "engines": { - "node": ">=8.0.0" - } + "email-addresses": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/email-addresses/-/email-addresses-3.1.0.tgz", + "integrity": "sha512-k0/r7GrWVL32kZlGwfPNgB2Y/mMXVTq/decgLczm/j34whdaspNrZO8CnXPf1laaHxI6ptUlsnAxN+UAPw+fzg==", + "dev": true }, - "node_modules/ganache-core/node_modules/web3-provider-engine": { - "version": "14.2.1", - "dev": true, - "license": "MIT", - "dependencies": { - "async": "^2.5.0", - "backoff": "^2.5.0", - "clone": "^2.0.0", - "cross-fetch": "^2.1.0", - "eth-block-tracker": "^3.0.0", - "eth-json-rpc-infura": "^3.1.0", - "eth-sig-util": "3.0.0", - "ethereumjs-block": "^1.2.2", - "ethereumjs-tx": "^1.2.0", - "ethereumjs-util": "^5.1.5", - "ethereumjs-vm": "^2.3.4", - "json-rpc-error": "^2.0.0", - "json-stable-stringify": "^1.0.1", - "promise-to-callback": "^1.0.0", - "readable-stream": "^2.2.9", - "request": "^2.85.0", - "semaphore": "^1.0.3", - "ws": "^5.1.1", - "xhr": "^2.2.0", - "xtend": "^4.0.1" - } - }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/abstract-leveldown": { - "version": "2.6.3", - "dev": true, - "license": "MIT", - "dependencies": { - "xtend": "~4.0.0" - } + "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/ganache-core/node_modules/web3-provider-engine/node_modules/deferred-leveldown": { - "version": "1.2.2", + "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, - "license": "MIT", - "dependencies": { - "abstract-leveldown": "~2.6.0" + "requires": { + "ansi-colors": "^4.1.1" } }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/eth-sig-util": { - "version": "1.4.2", - "dev": true, - "license": "ISC", - "dependencies": { - "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git", - "ethereumjs-util": "^5.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 }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-account": { - "version": "2.0.5", + "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, - "license": "MPL-2.0", - "dependencies": { - "ethereumjs-util": "^5.0.0", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" + "requires": { + "is-arrayish": "^0.2.1" } }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-block": { - "version": "1.7.1", + "es-abstract": { + "version": "1.21.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.1.tgz", + "integrity": "sha512-QudMsPOz86xYz/1dG1OuGBKOELjCh99IIWHLzy5znUB6j8xG2yMA7bfTV86VSqKF+Y/H08vQPR+9jyXpuC6hfg==", "dev": true, - "license": "MPL-2.0", + "peer": true, + "requires": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-set-tostringtag": "^2.0.1", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "function.prototype.name": "^1.1.5", + "get-intrinsic": "^1.1.3", + "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.4", + "is-array-buffer": "^3.0.1", + "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.2", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.4.3", + "safe-regex-test": "^1.0.0", + "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": { - "async": "^2.0.1", - "ethereum-common": "0.2.0", - "ethereumjs-tx": "^1.2.2", - "ethereumjs-util": "^5.0.0", - "merkle-patricia-tree": "^2.1.2" + "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" + } + } } }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-block/node_modules/ethereum-common": { - "version": "0.2.0", + "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, - "license": "MIT" + "peer": true }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-tx": { - "version": "1.3.7", + "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, - "license": "MPL-2.0", - "dependencies": { - "ethereum-common": "^0.0.18", - "ethereumjs-util": "^5.0.0" + "peer": true, + "requires": { + "get-intrinsic": "^1.1.3", + "has": "^1.0.3", + "has-tostringtag": "^1.0.0" } }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-util": { - "version": "5.2.1", + "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, - "license": "MPL-2.0", - "dependencies": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" + "peer": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" } }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-vm": { - "version": "2.6.0", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "async": "^2.1.2", - "async-eventemitter": "^0.2.2", - "ethereumjs-account": "^2.0.3", - "ethereumjs-block": "~2.2.0", - "ethereumjs-common": "^1.1.0", - "ethereumjs-util": "^6.0.0", - "fake-merkle-patricia-tree": "^1.0.1", - "functional-red-black-tree": "^1.0.1", - "merkle-patricia-tree": "^2.3.2", - "rustbn.js": "~0.2.0", - "safe-buffer": "^5.1.1" - } + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-vm/node_modules/ethereumjs-block": { - "version": "2.2.2", + "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, - "license": "MPL-2.0", + "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": { - "async": "^2.0.1", - "ethereumjs-common": "^1.5.0", - "ethereumjs-tx": "^2.1.1", - "ethereumjs-util": "^5.0.0", - "merkle-patricia-tree": "^2.1.2" + "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" + } + } } }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-vm/node_modules/ethereumjs-block/node_modules/ethereumjs-util": { - "version": "5.2.1", + "eslint": { + "version": "8.31.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.31.0.tgz", + "integrity": "sha512-0tQQEVdmPZ1UtUKXjX7EMm9BlgJ08G90IhWh0PKDCb3ZLsgAOHI8fYSIzYVZej92zsgq+ft0FGsxhJ3xo2tbuA==", "dev": true, - "license": "MPL-2.0", - "dependencies": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-vm/node_modules/ethereumjs-tx": { - "version": "2.1.2", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "ethereumjs-common": "^1.5.0", - "ethereumjs-util": "^6.0.0" - } - }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-vm/node_modules/ethereumjs-util": { - "version": "6.2.1", - "dev": true, - "license": "MPL-2.0", - "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" - } - }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/isarray": { - "version": "0.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-codec": { - "version": "7.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-errors": { - "version": "1.0.5", - "dev": true, - "license": "MIT", - "dependencies": { - "errno": "~0.1.1" - } - }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-iterator-stream": { - "version": "1.3.1", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.1", - "level-errors": "^1.0.3", - "readable-stream": "^1.0.33", - "xtend": "^4.0.0" - } - }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-iterator-stream/node_modules/readable-stream": { - "version": "1.1.14", - "dev": true, - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-ws": { - "version": "0.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "readable-stream": "~1.0.15", - "xtend": "~2.1.1" - } - }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-ws/node_modules/readable-stream": { - "version": "1.0.34", - "dev": true, - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-ws/node_modules/xtend": { - "version": "2.1.2", - "dev": true, - "dependencies": { - "object-keys": "~0.4.0" + "requires": { + "@eslint/eslintrc": "^1.4.1", + "@humanwhocodes/config-array": "^0.11.8", + "@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.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.4.0", + "esquery": "^1.4.0", + "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", + "grapheme-splitter": "^1.0.4", + "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-sdsl": "^4.1.4", + "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", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0" }, - "engines": { - "node": ">=0.4" - } - }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/levelup": { - "version": "1.3.9", - "dev": true, - "license": "MIT", - "dependencies": { - "deferred-leveldown": "~1.2.1", - "level-codec": "~7.0.0", - "level-errors": "~1.0.3", - "level-iterator-stream": "~1.3.0", - "prr": "~1.0.1", - "semver": "~5.4.1", - "xtend": "~4.0.0" - } - }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ltgt": { - "version": "2.2.1", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/memdown": { - "version": "1.4.1", - "dev": true, - "license": "MIT", "dependencies": { - "abstract-leveldown": "~2.7.1", - "functional-red-black-tree": "^1.0.1", - "immediate": "^3.2.3", - "inherits": "~2.0.1", - "ltgt": "~2.2.0", - "safe-buffer": "~5.1.1" + "eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "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 + } } }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/memdown/node_modules/abstract-leveldown": { - "version": "2.7.2", + "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, - "license": "MIT", - "dependencies": { - "xtend": "~4.0.0" + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" } }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/merkle-patricia-tree": { - "version": "2.3.2", + "eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", "dev": true, - "license": "MPL-2.0", + "requires": { + "eslint-visitor-keys": "^2.0.0" + }, "dependencies": { - "async": "^1.4.2", - "ethereumjs-util": "^5.0.0", - "level-ws": "0.0.0", - "levelup": "^1.2.1", - "memdown": "^1.0.0", - "readable-stream": "^2.0.0", - "rlp": "^2.0.0", - "semaphore": ">=1.0.1" + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true + } } }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/merkle-patricia-tree/node_modules/async": { - "version": "1.5.2", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/object-keys": { - "version": "0.4.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/safe-buffer": { - "version": "5.1.2", - "dev": true, - "license": "MIT" + "eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "dev": true }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/semver": { - "version": "5.4.1", + "espree": { + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", + "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" + "requires": { + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.3.0" } }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/string_decoder": { - "version": "0.10.31", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ws": { - "version": "5.2.2", + "esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha512-OarPfz0lFCiW4/AV2Oy1Rp9qu0iusTKqykwTspGCZtPxmF81JR4MmIebvF1F9+UOKth2ZubLQ4XGGaU+hSn99A==", "dev": true, - "license": "MIT", - "dependencies": { - "async-limiter": "~1.0.0" - } + "peer": true }, - "node_modules/ganache-core/node_modules/web3-providers-http": { - "version": "1.2.11", + "esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", "dev": true, - "license": "LGPL-3.0", - "optional": true, - "dependencies": { - "web3-core-helpers": "1.2.11", - "xhr2-cookies": "1.1.0" + "requires": { + "estraverse": "^5.1.0" }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/ganache-core/node_modules/web3-providers-ipc": { - "version": "1.2.11", - "dev": true, - "license": "LGPL-3.0", - "optional": true, "dependencies": { - "oboe": "2.1.4", - "underscore": "1.9.1", - "web3-core-helpers": "1.2.11" - }, - "engines": { - "node": ">=8.0.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 + } } }, - "node_modules/ganache-core/node_modules/web3-providers-ws": { - "version": "1.2.11", + "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, - "license": "LGPL-3.0", - "optional": true, - "dependencies": { - "eventemitter3": "4.0.4", - "underscore": "1.9.1", - "web3-core-helpers": "1.2.11", - "websocket": "^1.0.31" + "requires": { + "estraverse": "^5.2.0" }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/ganache-core/node_modules/web3-shh": { - "version": "1.2.11", - "dev": true, - "license": "LGPL-3.0", - "optional": true, "dependencies": { - "web3-core": "1.2.11", - "web3-core-method": "1.2.11", - "web3-core-subscriptions": "1.2.11", - "web3-net": "1.2.11" - }, - "engines": { - "node": ">=8.0.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 + } } }, - "node_modules/ganache-core/node_modules/web3-utils": { - "version": "1.2.11", - "dev": true, - "license": "LGPL-3.0", - "optional": true, - "dependencies": { - "bn.js": "^4.11.9", - "eth-lib": "0.2.8", - "ethereum-bloom-filters": "^1.0.6", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "underscore": "1.9.1", - "utf8": "3.0.0" - }, - "engines": { - "node": ">=8.0.0" - } + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true }, - "node_modules/ganache-core/node_modules/web3-utils/node_modules/eth-lib": { - "version": "0.2.8", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - } + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true }, - "node_modules/ganache-core/node_modules/websocket": { - "version": "1.0.32", + "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==", "dev": true, - "license": "Apache-2.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" - } - }, - "node_modules/ganache-core/node_modules/websocket/node_modules/debug": { - "version": "2.6.9", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/ganache-core/node_modules/websocket/node_modules/ms": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/whatwg-fetch": { - "version": "2.0.4", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/wrappy": { - "version": "1.0.2", - "dev": true, - "license": "ISC" - }, - "node_modules/ganache-core/node_modules/ws": { - "version": "3.3.3", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "async-limiter": "~1.0.0", - "safe-buffer": "~5.1.0", - "ultron": "~1.1.0" - } - }, - "node_modules/ganache-core/node_modules/ws/node_modules/safe-buffer": { - "version": "5.1.2", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/xhr": { - "version": "2.6.0", - "dev": true, - "license": "MIT", - "dependencies": { - "global": "~4.4.0", - "is-function": "^1.0.1", - "parse-headers": "^2.0.0", - "xtend": "^4.0.0" - } - }, - "node_modules/ganache-core/node_modules/xhr-request": { - "version": "1.1.0", - "dev": true, - "license": "MIT", - "optional": true, - "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" - } - }, - "node_modules/ganache-core/node_modules/xhr-request-promise": { - "version": "0.1.3", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "xhr-request": "^1.1.0" - } - }, - "node_modules/ganache-core/node_modules/xhr2-cookies": { - "version": "1.1.0", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "cookiejar": "^2.1.1" - } - }, - "node_modules/ganache-core/node_modules/xtend": { - "version": "4.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.4" - } - }, - "node_modules/ganache-core/node_modules/yaeti": { - "version": "0.0.6", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.32" - } - }, - "node_modules/ganache-core/node_modules/yallist": { - "version": "3.1.1", - "dev": true, - "license": "ISC" - }, - "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, - "engines": { - "node": "*" - } - }, - "node_modules/get-intrinsic": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", - "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "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, - "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, - "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, - "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_modules/gh-pages/node_modules/globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw==", - "dev": true, - "dependencies": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gh-pages/node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ghost-testrpc": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/ghost-testrpc/-/ghost-testrpc-0.0.2.tgz", - "integrity": "sha512-i08dAEgJ2g8z5buJIrCTduwPIhih3DP+hOCTyyryikfV8T0bNvHnGXO67i0DD1H4GBDETTclPy9njZbfluQYrQ==", - "dev": true, - "dependencies": { - "chalk": "^2.4.2", - "node-emoji": "^1.10.0" - }, - "bin": { - "testrpc-sc": "index.js" - } - }, - "node_modules/ghost-testrpc/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/ghost-testrpc/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/ghost-testrpc/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/ghost-testrpc/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/ghost-testrpc/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/ghost-testrpc/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/ghost-testrpc/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/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dev": 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": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/global-modules": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", - "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", - "dev": true, - "dependencies": { - "global-prefix": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/global-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", - "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", - "dev": true, - "dependencies": { - "ini": "^1.3.5", - "kind-of": "^6.0.2", - "which": "^1.3.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/global-prefix/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/globals": { - "version": "13.17.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", - "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", - "dev": true - }, - "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==", - "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, - "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==", - "dev": true, - "dependencies": { - "minimist": "^1.2.5", - "neo-async": "^2.6.0", - "source-map": "^0.6.1", - "wordwrap": "^1.0.0" - }, - "bin": { - "handlebars": "bin/handlebars" - }, - "engines": { - "node": ">=0.4.7" - }, - "optionalDependencies": { - "uglify-js": "^3.1.4" - } - }, - "node_modules/handlebars/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_modules/har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "deprecated": "this library is no longer supported", - "dev": true, - "dependencies": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/hardhat": { - "version": "2.12.2", - "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.12.2.tgz", - "integrity": "sha512-f3ZhzXy1uyQv0UXnAQ8GCBOWjzv++WJNb7bnm10SsyC3dB7vlPpsMWBNhq7aoRxKrNhX9tCev81KFV3i5BTeMQ==", - "dev": true, - "dependencies": { - "@ethersproject/abi": "^5.1.2", - "@metamask/eth-sig-util": "^4.0.0", - "@nomicfoundation/ethereumjs-block": "^4.0.0", - "@nomicfoundation/ethereumjs-blockchain": "^6.0.0", - "@nomicfoundation/ethereumjs-common": "^3.0.0", - "@nomicfoundation/ethereumjs-evm": "^1.0.0", - "@nomicfoundation/ethereumjs-rlp": "^4.0.0", - "@nomicfoundation/ethereumjs-statemanager": "^1.0.0", - "@nomicfoundation/ethereumjs-trie": "^5.0.0", - "@nomicfoundation/ethereumjs-tx": "^4.0.0", - "@nomicfoundation/ethereumjs-util": "^8.0.0", - "@nomicfoundation/ethereumjs-vm": "^6.0.0", - "@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", - "chalk": "^2.4.2", - "chokidar": "^3.4.0", - "ci-info": "^2.0.0", - "debug": "^4.1.1", - "enquirer": "^2.3.0", - "env-paths": "^2.2.0", - "ethereum-cryptography": "^1.0.3", - "ethereumjs-abi": "^0.6.8", - "find-up": "^2.1.0", - "fp-ts": "1.19.3", - "fs-extra": "^7.0.1", - "glob": "7.2.0", - "immutable": "^4.0.0-rc.12", - "io-ts": "1.10.4", - "keccak": "^3.0.2", - "lodash": "^4.17.11", - "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", - "solc": "0.7.3", - "source-map-support": "^0.5.13", - "stacktrace-parser": "^0.1.10", - "tsort": "0.0.1", - "undici": "^5.4.0", - "uuid": "^8.3.2", - "ws": "^7.4.6" - }, - "bin": { - "hardhat": "internal/cli/cli.js" - }, - "engines": { - "node": "^14.0.0 || ^16.0.0 || ^18.0.0" - }, - "peerDependencies": { - "ts-node": "*", - "typescript": "*" - }, - "peerDependenciesMeta": { - "ts-node": { - "optional": true - }, - "typescript": { - "optional": true - } - } - }, - "node_modules/hardhat-gas-reporter": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.9.tgz", - "integrity": "sha512-INN26G3EW43adGKBNzYWOlI3+rlLnasXTwW79YNnUhXPDa+yHESgt639dJEs37gCjhkbNKcRRJnomXEuMFBXJg==", - "dev": true, - "dependencies": { - "array-uniq": "1.0.3", - "eth-gas-reporter": "^0.2.25", - "sha1": "^1.1.1" - }, - "peerDependencies": { - "hardhat": "^2.0.2" - } - }, - "node_modules/hardhat-tracer": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/hardhat-tracer/-/hardhat-tracer-1.1.1.tgz", - "integrity": "sha512-NgOnnNAvARBtYC5x5c7Qcbw+lr+Jb+0OV1NC2tTpUUQj0ym+/0y42F0CYT/zKnHw3uf046NKg0CNTzYg1j0JWg==", - "dev": true, - "dependencies": { - "ethers": "^5.6.1" - }, - "peerDependencies": { - "chalk": "4.x", - "ethers": "5.x", - "hardhat": "2.x" - } - }, - "node_modules/hardhat/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/hardhat/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/hardhat/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/hardhat/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/hardhat/node_modules/commander": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz", - "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==", - "dev": true - }, - "node_modules/hardhat/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/hardhat/node_modules/ethereum-cryptography": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.1.2.tgz", - "integrity": "sha512-XDSJlg4BD+hq9N2FjvotwUET9Tfxpxc3kWGE2AqUG5vcbeunnbImVk3cj6e/xT3phdW21mE8R5IugU4fspQDcQ==", - "dev": true, - "dependencies": { - "@noble/hashes": "1.1.2", - "@noble/secp256k1": "1.6.3", - "@scure/bip32": "1.1.0", - "@scure/bip39": "1.1.0" - } - }, - "node_modules/hardhat/node_modules/find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", - "dev": true, - "dependencies": { - "locate-path": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/hardhat/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/hardhat/node_modules/jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==", - "dev": true, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/hardhat/node_modules/locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", - "dev": true, - "dependencies": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/hardhat/node_modules/p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "dependencies": { - "p-try": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/hardhat/node_modules/p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", - "dev": true, - "dependencies": { - "p-limit": "^1.1.0" - }, - "engines": { - "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", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/hardhat/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/hardhat/node_modules/solc": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/solc/-/solc-0.7.3.tgz", - "integrity": "sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA==", - "dev": true, - "dependencies": { - "command-exists": "^1.2.8", - "commander": "3.0.2", - "follow-redirects": "^1.12.1", - "fs-extra": "^0.30.0", - "js-sha3": "0.8.0", - "memorystream": "^0.3.1", - "require-from-string": "^2.0.0", - "semver": "^5.5.0", - "tmp": "0.0.33" - }, - "bin": { - "solcjs": "solcjs" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/hardhat/node_modules/solc/node_modules/fs-extra": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", - "integrity": "sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0", - "path-is-absolute": "^1.0.0", - "rimraf": "^2.2.8" - } - }, - "node_modules/hardhat/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==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/hardhat/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/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, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "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==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dev": true, - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true, - "bin": { - "he": "bin/he" - } - }, - "node_modules/heap": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.7.tgz", - "integrity": "sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==", - "dev": true - }, - "node_modules/hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", - "dev": true, - "dependencies": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "node_modules/http-basic": { - "version": "8.1.3", - "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz", - "integrity": "sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==", - "dev": true, - "dependencies": { - "caseless": "^0.12.0", - "concat-stream": "^1.6.2", - "http-response-object": "^3.0.1", - "parse-cache-control": "^1.0.1" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "dev": true, - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/http-response-object": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz", - "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==", - "dev": true, - "dependencies": { - "@types/node": "^10.0.3" - } - }, - "node_modules/http-response-object/node_modules/@types/node": { - "version": "10.17.60", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", - "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==", - "dev": true - }, - "node_modules/http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", - "dev": true, - "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - }, - "engines": { - "node": ">=0.8", - "npm": ">=1.3.7" - } - }, - "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dev": true, - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "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/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "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/ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/immutable": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz", - "integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==", - "dev": true - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true - }, - "node_modules/inquirer": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", - "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", - "dev": true, - "dependencies": { - "ansi-escapes": "^3.2.0", - "chalk": "^2.4.2", - "cli-cursor": "^2.1.0", - "cli-width": "^2.0.0", - "external-editor": "^3.0.3", - "figures": "^2.0.0", - "lodash": "^4.17.12", - "mute-stream": "0.0.7", - "run-async": "^2.2.0", - "rxjs": "^6.4.0", - "string-width": "^2.1.0", - "strip-ansi": "^5.1.0", - "through": "^2.3.6" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/inquirer/node_modules/ansi-escapes": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", - "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/inquirer/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==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/inquirer/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/inquirer/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/inquirer/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/inquirer/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/inquirer/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/inquirer/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/inquirer/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, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/inquirer/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/internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/io-ts": { - "version": "1.10.4", - "resolved": "https://registry.npmjs.org/io-ts/-/io-ts-1.10.4.tgz", - "integrity": "sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g==", - "dev": true, - "dependencies": { - "fp-ts": "^1.0.0" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true - }, - "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "dependencies": { - "has-bigints": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "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-buffer": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", - "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", - "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" - } - ], - "engines": { - "node": ">=4" - } - }, - "node_modules/is-callable": { - "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, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-ci": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", - "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", - "dev": true, - "dependencies": { - "ci-info": "^2.0.0" - }, - "bin": { - "is-ci": "bin.js" - } - }, - "node_modules/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, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-directory": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", - "integrity": "sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "dev": true, - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "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, - "engines": { - "node": ">=4" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-hex-prefixed": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", - "integrity": "sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==", - "dev": true, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "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, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "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-shared-array-buffer": { - "version": "1.0.2", - "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, - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true - }, - "node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-url": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", - "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==", - "dev": true - }, - "node_modules/is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==", - "dev": true - }, - "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, - "dependencies": { - "is-docker": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", - "dev": true - }, - "node_modules/js-sdsl": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.5.tgz", - "integrity": "sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q==", - "dev": true - }, - "node_modules/js-sha3": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", - "dev": true - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", - "dev": true - }, - "node_modules/json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "node_modules/json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", - "dev": true - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "node_modules/json-stringify-safe": { - "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 - }, - "node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/jsonschema": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.1.tgz", - "integrity": "sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/jsprim": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", - "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", - "dev": true, - "dependencies": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/keccak": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.2.tgz", - "integrity": "sha512-PyKKjkH53wDMLGrvmRGSNWgmSxZOUqbnXwKL9tmgbFYA1iAYqW21kfR7mZXV0MlESiefxQQE9X9fTa3X+2MPDQ==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/keccak256": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/keccak256/-/keccak256-1.0.6.tgz", - "integrity": "sha512-8GLiM01PkdJVGUhR1e6M/AvWnSqYS0HaERI+K/QtStGDGlSTx2B1zTqZk4Zlqu5TxHJNTxWAdP9Y+WI50OApUw==", - "dev": true, - "dependencies": { - "bn.js": "^5.2.0", - "buffer": "^6.0.3", - "keccak": "^3.0.2" - } - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/klaw": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", - "integrity": "sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw==", - "dev": true, - "optionalDependencies": { - "graceful-fs": "^4.1.9" - } - }, - "node_modules/klaw-sync": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz", - "integrity": "sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.11" - } - }, - "node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw==", - "dev": true, - "dependencies": { - "invert-kv": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/level": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/level/-/level-8.0.0.tgz", - "integrity": "sha512-ypf0jjAk2BWI33yzEaaotpq7fkOPALKAgDBxggO6Q9HGX2MRXn0wbP1Jn/tJv1gtL867+YOjOB49WaUF3UoJNQ==", - "dev": true, - "dependencies": { - "browser-level": "^1.0.1", - "classic-level": "^1.2.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/level" - } - }, - "node_modules/level-supports": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/level-supports/-/level-supports-4.0.1.tgz", - "integrity": "sha512-PbXpve8rKeNcZ9C1mUicC9auIYFyGpkV9/i6g76tLgANwWhtG2v7I4xNBUlkn3lE2/dZF3Pi0ygYGtLc4RXXdA==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/level-transcoder": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/level-transcoder/-/level-transcoder-1.0.1.tgz", - "integrity": "sha512-t7bFwFtsQeD8cl8NIoQ2iwxA0CL/9IFw7/9gAjOonH0PWTTiRfY7Hq+Ejbsxh86tXobDQ6IOiddjNYIfOBs06w==", - "dev": true, - "dependencies": { - "buffer": "^6.0.3", - "module-error": "^1.0.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "node_modules/lodash.assign": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", - "integrity": "sha512-hFuH8TY+Yji7Eja3mGiuAxBqLagejScbG8GbG0j6o9vzn0YL14My+ktnqtZgFTosKymC9/44wP6s7xyuLfnClw==", - "dev": true - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "node_modules/lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", - "dev": true - }, - "node_modules/log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/loud-rejection": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", - "integrity": "sha512-RPNliZOFkqFumDhvYqOaNY4Uz9oJM2K9tC6JWsJJsNdhuONW4LQHRBpb0qf4pJApVffI5N39SwzWZJuEhfd7eQ==", - "dev": true, - "dependencies": { - "currently-unhandled": "^0.4.1", - "signal-exit": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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==", - "dev": true, - "dependencies": { - "get-func-name": "^2.0.0" - } - }, - "node_modules/lru_map": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz", - "integrity": "sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==", - "dev": true - }, - "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "node_modules/map-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz", - "integrity": "sha512-TzQSV2DiMYgoF5RycneKVUzIa9bQsj/B3tTgsE3dOGqlzHnGIDaC7XBE7grnA+8kZPnfqSGFe95VHc2oc0VFUQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/markdown-table": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.3.tgz", - "integrity": "sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==", - "dev": true - }, - "node_modules/mcl-wasm": { - "version": "0.7.9", - "resolved": "https://registry.npmjs.org/mcl-wasm/-/mcl-wasm-0.7.9.tgz", - "integrity": "sha512-iJIUcQWA88IJB/5L15GnJVnSQJmf/YaxxV6zRavv83HILHaJQb6y0iFyDMdDO0gN8X37tdxmAOrH/P8B6RB8sQ==", - "dev": true, - "engines": { - "node": ">=8.9.0" - } - }, - "node_modules/md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/memory-level": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/memory-level/-/memory-level-1.0.0.tgz", - "integrity": "sha512-UXzwewuWeHBz5krr7EvehKcmLFNoXxGcvuYhC41tRnkrTbJohtS7kVn9akmgirtRygg+f7Yjsfi8Uu5SGSQ4Og==", - "dev": true, - "dependencies": { - "abstract-level": "^1.0.0", - "functional-red-black-tree": "^1.0.1", - "module-error": "^1.0.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/memorystream": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", - "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", - "dev": true, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/meow": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-5.0.0.tgz", - "integrity": "sha512-CbTqYU17ABaLefO8vCU153ZZlprKYWDljcndKKDCFcYQITzWCXZAVk4QMFZPgvzrnUQ3uItnIE/LoUOwrT15Ig==", - "dev": true, - "dependencies": { - "camelcase-keys": "^4.0.0", - "decamelize-keys": "^1.0.0", - "loud-rejection": "^1.0.0", - "minimist-options": "^3.0.1", - "normalize-package-data": "^2.3.4", - "read-pkg-up": "^3.0.0", - "redent": "^2.0.0", - "trim-newlines": "^2.0.0", - "yargs-parser": "^10.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "engines": { - "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==", - "dev": true, - "dependencies": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "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, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/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, - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "node_modules/minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", - "dev": true - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", - "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/minimist-options": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-3.0.2.tgz", - "integrity": "sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ==", - "dev": true, - "dependencies": { - "arrify": "^1.0.1", - "is-plain-obj": "^1.1.0" - }, - "engines": { - "node": ">= 4" - } - }, - "node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/mnemonist": { - "version": "0.38.5", - "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.38.5.tgz", - "integrity": "sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg==", - "dev": true, - "dependencies": { - "obliterator": "^2.0.0" - } - }, - "node_modules/mocha": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.1.0.tgz", - "integrity": "sha512-vUF7IYxEoN7XhQpFLxQAEMtE4W91acW4B6En9l97MwE9stL1A9gusXfoHZCLVHDUJ/7V5+lbCM6yMqzo5vNymg==", - "dev": true, - "dependencies": { - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.3", - "debug": "4.3.4", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.2.0", - "he": "1.2.0", - "js-yaml": "4.1.0", - "log-symbols": "4.1.0", - "minimatch": "5.0.1", - "ms": "2.1.3", - "nanoid": "3.3.3", - "serialize-javascript": "6.0.0", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "workerpool": "6.2.1", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" - }, - "bin": { - "_mocha": "bin/_mocha", - "mocha": "bin/mocha.js" - }, - "engines": { - "node": ">= 14.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mochajs" - } - }, - "node_modules/mocha/node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/mocha/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/mocha/node_modules/minimatch": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", - "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mocha/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/mocha/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/mocha/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, - "engines": { - "node": ">=10" - } - }, - "node_modules/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, - "engines": { - "node": ">=10" - } - }, - "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/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/nanoid": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", - "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", - "dev": true, - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/napi-macros": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/napi-macros/-/napi-macros-2.0.0.tgz", - "integrity": "sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg==", - "dev": true - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "node_modules/natural-compare-lite": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", - "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", - "dev": true - }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true - }, - "node_modules/nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, - "node_modules/node-addon-api": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", - "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==", - "dev": true - }, - "node_modules/node-emoji": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", - "integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==", - "dev": true, - "dependencies": { - "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, - "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, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "dev": true, - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/node-gyp-build": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.5.0.tgz", - "integrity": "sha512-2iGbaQBV+ITgCz76ZEjmhUKAKVf7xfY1sRl4UiKQspfZMH2h06SyhNsnSVy50cwkFQDGLyif6m/6uFXHkOZ6rg==", - "dev": true, - "bin": { - "node-gyp-build": "bin.js", - "node-gyp-build-optional": "optional.js", - "node-gyp-build-test": "build-test.js" - } - }, - "node_modules/nofilter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-1.0.4.tgz", - "integrity": "sha512-N8lidFp+fCz+TD51+haYdbDGrcBWwuHX40F5+z0qkUjMJ5Tp+rdSuAkMJ9N9eoolDlEVTf6u5icM+cNKkKW2mA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/nopt": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", - "integrity": "sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg==", - "dev": true, - "dependencies": { - "abbrev": "1" - }, - "bin": { - "nopt": "bin/nopt.js" - } - }, - "node_modules/normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "node_modules/normalize-package-data/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "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, - "dependencies": { - "bn.js": "4.11.6", - "strip-hex-prefix": "1.0.0" - }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/number-to-bn/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/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, - "engines": { - "node": "*" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-inspect": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", - "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/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, - "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==", - "dev": true, - "dependencies": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.getownpropertydescriptors": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.5.tgz", - "integrity": "sha512-yDNzckpM6ntyQiGTik1fKV1DcVDRS+w8bvpWNCBanvH5LfRX9O8WTHqQzG4RZwRAM4I0oU7TV11Lj5v0g20ibw==", - "dev": true, - "dependencies": { - "array.prototype.reduce": "^1.0.5", - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - }, - "engines": { - "node": ">= 0.8" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/obliterator": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.4.tgz", - "integrity": "sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==", - "dev": true - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==", - "dev": true, - "dependencies": { - "mimic-fn": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/open": { - "version": "7.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", - "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", - "dev": true, - "dependencies": { - "is-docker": "^2.0.0", - "is-wsl": "^2.1.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "dependencies": { - "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" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/os-locale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g==", - "dev": true, - "dependencies": { - "lcid": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dev": true, - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-cache-control": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", - "integrity": "sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==", - "dev": true - }, - "node_modules/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", - "dev": true, - "dependencies": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/patch-package": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-6.5.0.tgz", - "integrity": "sha512-tC3EqJmo74yKqfsMzELaFwxOAu6FH6t+FzFOsnWAuARm7/n2xB5AOeOueE221eM9gtMuIKMKpF9tBy/X2mNP0Q==", - "dev": true, - "dependencies": { - "@yarnpkg/lockfile": "^1.1.0", - "chalk": "^4.1.2", - "cross-spawn": "^6.0.5", - "find-yarn-workspace-root": "^2.0.0", - "fs-extra": "^7.0.1", - "is-ci": "^2.0.0", - "klaw-sync": "^6.0.0", - "minimist": "^1.2.6", - "open": "^7.4.2", - "rimraf": "^2.6.3", - "semver": "^5.6.0", - "slash": "^2.0.0", - "tmp": "^0.0.33", - "yaml": "^1.10.2" - }, - "bin": { - "patch-package": "index.js" - }, - "engines": { - "node": ">=10", - "npm": ">5" - } - }, - "node_modules/patch-package/node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "engines": { - "node": ">=4.8" - } - }, - "node_modules/patch-package/node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/patch-package/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/patch-package/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/patch-package/node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", - "dev": true, - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/patch-package/node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/patch-package/node_modules/slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/patch-package/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/path-browserify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", - "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", - "dev": true - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", - "dev": true - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "dev": true, - "dependencies": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - }, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", - "dev": true - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", - "dev": true, - "dependencies": { - "pinkie": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/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==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/postinstall-postinstall": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/postinstall-postinstall/-/postinstall-postinstall-2.1.0.tgz", - "integrity": "sha512-7hQX6ZlZXIoRiWNrbMQaLzUUfH+sSx39u8EJ9HYuDc1kLo9IXKWjM5RSquZN1ad5GnH8CGFM78fsAAQi3OKEEQ==", - "dev": true, - "hasInstallScript": true - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", - "dev": true, - "optional": true, - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/promise": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", - "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==", - "dev": true, - "dependencies": { - "asap": "~2.0.6" - } - }, - "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==", - "dev": true, - "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/proper-lockfile": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-4.1.2.tgz", - "integrity": "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.4", - "retry": "^0.12.0", - "signal-exit": "^3.0.2" - } - }, - "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/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/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/querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==", - "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", - "dev": true, - "engines": { - "node": ">=0.4.x" - } - }, - "node_modules/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, - "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/quick-lru": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-1.1.0.tgz", - "integrity": "sha512-tRS7sTgyxMXtLum8L65daJnHUhfDUgboRdcWW2bR9vBfrj2+O5HSMbQOJfJJjIVSPFqbBCF37FpwWXGitDc5tA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "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, - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", - "dev": true, - "dependencies": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", - "integrity": "sha512-YFzFrVvpC6frF1sz8psoHDBGF7fLPc+llq/8NB43oagqWkx8ar5zYtsTORtOjw9W2RHLpWP+zTWwBvf1bCmcSw==", - "dev": true, - "dependencies": { - "find-up": "^2.0.0", - "read-pkg": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up/node_modules/find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", - "dev": true, - "dependencies": { - "locate-path": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up/node_modules/locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", - "dev": true, - "dependencies": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up/node_modules/p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "dependencies": { - "p-try": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up/node_modules/p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", - "dev": true, - "dependencies": { - "p-limit": "^1.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up/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/read-pkg-up/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, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg/node_modules/path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "dependencies": { - "pify": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", - "dev": true, - "dependencies": { - "resolve": "^1.1.6" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/recursive-readdir": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", - "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", - "dev": true, - "dependencies": { - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/redent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz", - "integrity": "sha512-XNwrTx77JQCEMXTeb8movBKuK75MgH0RZkujNuDKCezemx/voapl9i2gCSi8WWm8+ox5ycJi1gxF22fR7c0Ciw==", - "dev": true, - "dependencies": { - "indent-string": "^3.0.0", - "strip-indent": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/redent/node_modules/indent-string": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", - "integrity": "sha512-BYqTHXTGUIvg7t1r4sJNKcbDZkL92nkXA8YtRpbjFHRHGDL/NtUeiBJMeE60kIFN/Mg8ESaWQvftaYMGJzQZCQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/regexp.prototype.flags": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", - "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "functions-have-names": "^1.2.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/req-cwd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/req-cwd/-/req-cwd-2.0.0.tgz", - "integrity": "sha512-ueoIoLo1OfB6b05COxAA9UpeoscNpYyM+BqYlA7H6LVF4hKGPXQQSSaD2YmvDVJMkk4UDpAHIeU1zG53IqjvlQ==", - "dev": true, - "dependencies": { - "req-from": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/req-from": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/req-from/-/req-from-2.0.0.tgz", - "integrity": "sha512-LzTfEVDVQHBRfjOUMgNBA+V6DWsSnoeKzf42J7l0xa/B4jyPOuuF5MlNSmomLNGemWTnV2TIdjSSLnEn95fOQA==", - "dev": true, - "dependencies": { - "resolve-from": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/req-from/node_modules/resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", - "dev": true, - "dependencies": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "engines": { - "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, - "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", - "dev": true, - "dependencies": { - "request-promise-core": "1.1.4", - "stealthy-require": "^1.1.1", - "tough-cookie": "^2.3.3" - }, - "engines": { - "node": ">=0.12.0" - }, - "peerDependencies": { - "request": "^2.34" - } - }, - "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, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 0.12" - } - }, - "node_modules/request/node_modules/qs": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", - "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", - "dev": true, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/request/node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "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, - "bin": { - "uuid": "bin/uuid" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==", - "dev": true - }, - "node_modules/resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "dependencies": { - "path-parse": "^1.0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/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, - "engines": { - "node": ">=4" - } - }, - "node_modules/restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==", - "dev": true, - "dependencies": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "node_modules/rlp": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz", - "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==", - "dev": true, - "dependencies": { - "bn.js": "^5.2.0" - }, - "bin": { - "rlp": "bin/rlp" - } - }, - "node_modules/run-async": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "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": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/run-parallel-limit": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/run-parallel-limit/-/run-parallel-limit-1.1.0.tgz", - "integrity": "sha512-jJA7irRNM91jaKc3Hcl1npHsFLOXOoTkPCUL1JEa1R82O2miplXXRaGdjW/KM/98YQWDhJLiSs793CnXfblJUw==", - "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": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/rustbn.js": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/rustbn.js/-/rustbn.js-0.2.0.tgz", - "integrity": "sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA==", - "dev": true - }, - "node_modules/rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "dev": true, - "dependencies": { - "tslib": "^1.9.0" - }, - "engines": { - "npm": ">=2.0.0" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "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/safe-regex-test": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", - "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", - "is-regex": "^1.1.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "node_modules/sc-istanbul": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/sc-istanbul/-/sc-istanbul-0.4.6.tgz", - "integrity": "sha512-qJFF/8tW/zJsbyfh/iT/ZM5QNHE3CXxtLJbZsL+CzdJLBsPD7SedJZoUA4d8iAcN2IoMp/Dx80shOOd2x96X/g==", - "dev": true, - "dependencies": { - "abbrev": "1.0.x", - "async": "1.x", - "escodegen": "1.8.x", - "esprima": "2.7.x", - "glob": "^5.0.15", - "handlebars": "^4.0.1", - "js-yaml": "3.x", - "mkdirp": "0.5.x", - "nopt": "3.x", - "once": "1.x", - "resolve": "1.1.x", - "supports-color": "^3.1.0", - "which": "^1.1.1", - "wordwrap": "^1.0.0" - }, - "bin": { - "istanbul": "lib/cli.js" - } - }, - "node_modules/sc-istanbul/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, - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/sc-istanbul/node_modules/async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==", - "dev": true - }, - "node_modules/sc-istanbul/node_modules/glob": { - "version": "5.0.15", - "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", - "integrity": "sha512-c9IPMazfRITpmAAKi22dK1VKxGDX9ehhqfABDriL/lzO92xcUKEJPQHrVA/2YHSNFB4iFlykVmWvwo48nr3OxA==", - "dev": true, - "dependencies": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - } - }, - "node_modules/sc-istanbul/node_modules/has-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sc-istanbul/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/sc-istanbul/node_modules/js-yaml/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/sc-istanbul/node_modules/resolve": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha512-9znBF0vBcaSN3W2j7wKvdERPwqTxSpCq+if5C0WoTCyV9n24rua28jeuQ2pL/HOf+yUe/Mef+H/5p60K0Id3bg==", - "dev": true - }, - "node_modules/sc-istanbul/node_modules/supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha512-Jds2VIYDrlp5ui7t8abHN2bjAu4LV/q4N2KivFPpGH0lrka0BMq/33AmECUXlKPcHigkNaqfXRENFju+rlcy+A==", - "dev": true, - "dependencies": { - "has-flag": "^1.0.0" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/sc-istanbul/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/scrypt-js": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", - "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==", - "dev": true - }, - "node_modules/secp256k1": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz", - "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "elliptic": "^6.5.4", - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", - "dev": true, - "dependencies": { - "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==", - "dev": true - }, - "node_modules/setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", - "dev": true - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "dev": true - }, - "node_modules/sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - }, - "bin": { - "sha.js": "bin.js" - } - }, - "node_modules/sha1": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/sha1/-/sha1-1.1.1.tgz", - "integrity": "sha512-dZBS6OrMjtgVkopB1Gmo4RQCDKiZsqcpAQpkV/aaj+FCrCg8r4I4qMkDPQjBgLIxlmu9k4nUbWq6ohXahOneYA==", - "dev": true, - "dependencies": { - "charenc": ">= 0.0.1", - "crypt": ">= 0.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/shelljs": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", - "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", - "dev": true, - "dependencies": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" - }, - "bin": { - "shjs": "bin/shjs" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "node_modules/simple-git": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.14.1.tgz", - "integrity": "sha512-1ThF4PamK9wBORVGMK9HK5si4zoGS2GpRO7tkAFObA4FZv6dKaCVHLQT+8zlgiBm6K2h+wEU9yOaFCu/SR3OyA==", - "dev": true, - "dependencies": { - "@kwsites/file-exists": "^1.1.1", - "@kwsites/promise-deferred": "^1.1.1", - "debug": "^4.3.4" - }, - "funding": { - "type": "github", - "url": "https://github.com/steveukx/git-js?sponsor=1" - } - }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, - "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/solc": { - "version": "0.6.12", - "resolved": "https://registry.npmjs.org/solc/-/solc-0.6.12.tgz", - "integrity": "sha512-Lm0Ql2G9Qc7yPP2Ba+WNmzw2jwsrd3u4PobHYlSOxaut3TtUbj9+5ZrT6f4DUpNPEoBaFUOEg9Op9C0mk7ge9g==", - "dev": true, - "dependencies": { - "command-exists": "^1.2.8", - "commander": "3.0.2", - "fs-extra": "^0.30.0", - "js-sha3": "0.8.0", - "memorystream": "^0.3.1", - "require-from-string": "^2.0.0", - "semver": "^5.5.0", - "tmp": "0.0.33" - }, - "bin": { - "solcjs": "solcjs" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/solc/node_modules/commander": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz", - "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==", - "dev": true - }, - "node_modules/solc/node_modules/fs-extra": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", - "integrity": "sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0", - "path-is-absolute": "^1.0.0", - "rimraf": "^2.2.8" - } - }, - "node_modules/solc/node_modules/jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==", - "dev": true, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/solc/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "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==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/solhint": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/solhint/-/solhint-2.3.1.tgz", - "integrity": "sha512-wP/G+Dqj8LNWlCI9Mt6XiQRWQfZwv1rkZe/V+HKtip5SAZJVvp144PdH28KE45ZvR99Hhrp/Mujt74fSmXsFiw==", - "dev": true, - "dependencies": { - "ajv": "^6.6.1", - "antlr4": "4.7.1", - "chalk": "^2.4.2", - "commander": "2.18.0", - "cosmiconfig": "^5.0.7", - "eslint": "^5.6.0", - "fast-diff": "^1.1.2", - "glob": "^7.1.3", - "ignore": "^4.0.6", - "js-yaml": "^3.12.0", - "lodash": "^4.17.11", - "semver": "^6.3.0" - }, - "bin": { - "solhint": "solhint.js" - }, - "optionalDependencies": { - "prettier": "^1.14.3" - } - }, - "node_modules/solhint/node_modules/acorn": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", - "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/solhint/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, - "engines": { - "node": ">=4" - } - }, - "node_modules/solhint/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/solhint/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, - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/solhint/node_modules/astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/solhint/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/solhint/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/solhint/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/solhint/node_modules/commander": { - "version": "2.18.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.18.0.tgz", - "integrity": "sha512-6CYPa+JP2ftfRU2qkDK+UTVeQYosOg/2GbcjIcKPHfinyOLPVGXu/ovN86RP49Re5ndJK1N0kuiidFFuepc4ZQ==", - "dev": true - }, - "node_modules/solhint/node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "engines": { - "node": ">=4.8" - } - }, - "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==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/solhint/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 - }, - "node_modules/solhint/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/solhint/node_modules/eslint": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz", - "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "ajv": "^6.9.1", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "eslint-scope": "^4.0.3", - "eslint-utils": "^1.3.1", - "eslint-visitor-keys": "^1.0.0", - "espree": "^5.0.1", - "esquery": "^1.0.1", - "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", - "functional-red-black-tree": "^1.0.1", - "glob": "^7.1.2", - "globals": "^11.7.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "inquirer": "^6.2.2", - "js-yaml": "^3.13.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.11", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "path-is-inside": "^1.0.2", - "progress": "^2.0.0", - "regexpp": "^2.0.1", - "semver": "^5.5.1", - "strip-ansi": "^4.0.0", - "strip-json-comments": "^2.0.1", - "table": "^5.2.3", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^6.14.0 || ^8.10.0 || >=9.10.0" - } - }, - "node_modules/solhint/node_modules/eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "dev": true, - "dependencies": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/solhint/node_modules/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, - "dependencies": { - "eslint-visitor-keys": "^1.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/solhint/node_modules/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, - "engines": { - "node": ">=4" - } - }, - "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==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/solhint/node_modules/espree": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz", - "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==", - "dev": true, - "dependencies": { - "acorn": "^6.0.7", - "acorn-jsx": "^5.0.0", - "eslint-visitor-keys": "^1.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/solhint/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/solhint/node_modules/file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", - "dev": true, - "dependencies": { - "flat-cache": "^2.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/solhint/node_modules/flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", - "dev": true, - "dependencies": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/solhint/node_modules/flatted": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", - "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", - "dev": true - }, - "node_modules/solhint/node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/solhint/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/solhint/node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/solhint/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/solhint/node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/solhint/node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "dependencies": { - "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" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/solhint/node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/solhint/node_modules/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, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/solhint/node_modules/regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", - "dev": true, - "engines": { - "node": ">=6.5.0" - } - }, - "node_modules/solhint/node_modules/rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/solhint/node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", - "dev": true, - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/solhint/node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/solhint/node_modules/slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/solhint/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, - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/solhint/node_modules/string-width/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==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/solhint/node_modules/string-width/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, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/solhint/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, - "dependencies": { - "ansi-regex": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/solhint/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, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/solhint/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/solhint/node_modules/table": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", - "dev": true, - "dependencies": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/solhint/node_modules/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, - "dependencies": { - "prelude-ls": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/solhint/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/solidity-ast": { - "version": "0.4.35", - "resolved": "https://registry.npmjs.org/solidity-ast/-/solidity-ast-0.4.35.tgz", - "integrity": "sha512-F5bTDLh3rmDxRmLSrs3qt3nvxJprWSEkS7h2KmuXDx7XTfJ6ZKVTV1rtPIYCqJAuPsU/qa8YUeFn7jdOAZcTPA==", - "dev": true - }, - "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==", - "dev": true, - "dependencies": { - "@ethersproject/abi": "^5.0.9", - "@solidity-parser/parser": "^0.14.1", - "chalk": "^2.4.2", - "death": "^1.1.0", - "detect-port": "^1.3.0", - "difflib": "^0.2.4", - "fs-extra": "^8.1.0", - "ghost-testrpc": "^0.0.2", - "global-modules": "^2.0.0", - "globby": "^10.0.1", - "jsonschema": "^1.2.4", - "lodash": "^4.17.15", - "mocha": "7.1.2", - "node-emoji": "^1.10.0", - "pify": "^4.0.1", - "recursive-readdir": "^2.2.2", - "sc-istanbul": "^0.4.5", - "semver": "^7.3.4", - "shelljs": "^0.8.3", - "web3-utils": "^1.3.6" - }, - "bin": { - "solidity-coverage": "plugins/bin.js" - }, - "peerDependencies": { - "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, - "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==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/solidity-coverage/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/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, - "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, - "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", - "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/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==", - "dev": 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, - "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, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/solidity-coverage/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/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, - "dependencies": { - "ms": "^2.1.1" - } - }, - "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, - "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 - }, - "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", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "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, - "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, - "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, - "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", - "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_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" - ], - "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, - "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, - "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", - "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", - "dev": true, - "dependencies": { - "@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" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/solidity-coverage/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/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==", - "dev": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "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==", - "dev": true, - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "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==", - "dev": true, - "dependencies": { - "chalk": "^2.4.2" - }, - "engines": { - "node": ">=8" - } - }, - "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, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "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==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "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==", - "dev": true, - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "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==", - "dev": 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" - } - }, - "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==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "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==", - "dev": true - }, - "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==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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==", - "dev": 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, - "engines": { - "node": ">=4" - } - }, - "node_modules/solidity-coverage/node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "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, - "dependencies": { - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/solidity-coverage/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 - }, - "node_modules/solidity-coverage/node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "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, - "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, - "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, - "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, - "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, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/solidity-coverage/node_modules/which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", - "dev": true - }, - "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, - "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 - }, - "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 - }, - "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==", - "dev": 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" - } - }, - "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, - "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, - "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, - "dependencies": { - "amdefine": ">=0.0.4" - }, - "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_modules/spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", - "dev": true, - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true - }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-license-ids": { - "version": "3.0.12", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz", - "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==", - "dev": true - }, - "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==", - "dev": 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_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/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, - "dependencies": { - "type-fest": "^0.7.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/stacktrace-parser/node_modules/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, - "engines": { - "node": ">=8" - } - }, - "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true, - "engines": { - "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==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/streamsearch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", - "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", - "dev": true, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/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, - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "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, - "dependencies": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/string-width/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, - "engines": { - "node": ">=4" - } - }, - "node_modules/string-width/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, - "dependencies": { - "ansi-regex": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "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==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - }, - "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==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/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, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/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, - "dependencies": { - "is-hex-prefixed": "1.0.0" - }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/strip-indent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", - "integrity": "sha512-RsSNPLpq6YUL7QYy44RnPVTn/lcVZtb48Uof3X5JLbF4zD/Gs7ZFDv2HWol+leoQN2mT86LAzSshGfkTlSOpsA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/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, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/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, - "dependencies": { - "escape-string-regexp": "^1.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-outer/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/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, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "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==", - "dev": 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, - "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, - "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/node_modules/ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/table/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/table/node_modules/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 - }, - "node_modules/table/node_modules/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, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/test-value": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/test-value/-/test-value-2.1.0.tgz", - "integrity": "sha512-+1epbAxtKeXttkGFMTX9H42oqzOTufR1ceCF+GYA5aOmvaPq9wd4PUS8329fn2RRLGNeUkgRLnVpycjx8DsO2w==", - "dev": true, - "dependencies": { - "array-back": "^1.0.3", - "typical": "^2.6.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/test-value/node_modules/array-back": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", - "integrity": "sha512-1WxbZvrmyhkNoeYcizokbmh5oiOCIfyvGtcqbK3Ls1v1fKcquzxnQSceOx6tzq7jmai2kFLWIpGND2cLhH6TPw==", - "dev": true, - "dependencies": { - "typical": "^2.6.0" - }, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/testrpc": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/testrpc/-/testrpc-0.0.1.tgz", - "integrity": "sha512-afH1hO+SQ/VPlmaLUFj2636QMeDvPCeQMc/9RBMW0IfjNe9gFD9Ra3ShqYkB7py0do1ZcCna/9acHyzTJ+GcNA==", - "deprecated": "testrpc has been renamed to ganache-cli, please use this package from now on.", - "dev": true - }, - "node_modules/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 - }, - "node_modules/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, - "dependencies": { - "@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" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/then-request/node_modules/@types/node": { - "version": "8.10.66", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz", - "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==", - "dev": 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, - "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/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "dependencies": { - "os-tmpdir": "~1.0.2" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/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, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/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, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/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, - "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/tough-cookie/node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "dev": true - }, - "node_modules/trim-newlines": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz", - "integrity": "sha512-MTBWv3jhVjTU7XR3IQHllbiJs8sc75a80OEhB6or/q7pLTWgQ0bMGQXXYQSrSuXe6WiKWDZ5txXY5P59a/coVA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/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, - "dependencies": { - "escape-string-regexp": "^1.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/trim-repeated/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/ts-essentials": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-1.0.4.tgz", - "integrity": "sha512-q3N1xS4vZpRouhYHDPwO0bDW3EZ6SK9CrrDHxi/D6BPReSjpVgWIOpLS2o0gSBZm+7q/wyKp6RVM1AeeW7uyfQ==", - "dev": true - }, - "node_modules/ts-generator": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ts-generator/-/ts-generator-0.1.1.tgz", - "integrity": "sha512-N+ahhZxTLYu1HNTQetwWcx3so8hcYbkKBHTr4b4/YgObFTIKkOSSsaa+nal12w8mfrJAyzJfETXawbNjSfP2gQ==", - "dev": true, - "dependencies": { - "@types/mkdirp": "^0.5.2", - "@types/prettier": "^2.1.1", - "@types/resolve": "^0.0.8", - "chalk": "^2.4.1", - "glob": "^7.1.2", - "mkdirp": "^0.5.1", - "prettier": "^2.1.2", - "resolve": "^1.8.1", - "ts-essentials": "^1.0.0" - }, - "bin": { - "ts-generator": "dist/cli/run.js" - } - }, - "node_modules/ts-generator/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/ts-generator/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/ts-generator/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/ts-generator/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/ts-generator/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/ts-generator/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/ts-generator/node_modules/prettier": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", - "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", - "dev": true, - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/ts-generator/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/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, - "dependencies": { - "@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" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, - "node_modules/ts-node/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/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "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==", - "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-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, - "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, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typechain": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/typechain/-/typechain-3.0.0.tgz", - "integrity": "sha512-ft4KVmiN3zH4JUFu2WJBrwfHeDf772Tt2d8bssDTo/YcckKW2D+OwFrHXRC6hJvO3mHjFQTihoMV6fJOi0Hngg==", - "dev": true, - "dependencies": { - "command-line-args": "^4.0.7", - "debug": "^4.1.1", - "fs-extra": "^7.0.0", - "js-sha3": "^0.8.0", - "lodash": "^4.17.15", - "ts-essentials": "^6.0.3", - "ts-generator": "^0.1.1" - }, - "bin": { - "typechain": "dist/cli/cli.js" - } - }, - "node_modules/typechain/node_modules/ts-essentials": { - "version": "6.0.7", - "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-6.0.7.tgz", - "integrity": "sha512-2E4HIIj4tQJlIHuATRHayv0EfMGK3ris/GRk1E3CFnsZzeNV+hUmelbaTZHLtXaZppM5oLhHRtO04gINC4Jusw==", - "dev": true, - "peerDependencies": { - "typescript": ">=3.7.0" - } - }, - "node_modules/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 - }, - "node_modules/typescript": { - "version": "4.8.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", - "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/typical": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", - "integrity": "sha512-ofhi8kjIje6npGozTip9Fr8iecmYfEbS06i0JnIg+rh51KakryWF4+jX8lLKZVhy6N+ID45WYSFCxPOdTWCzNg==", - "dev": true - }, - "node_modules/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, - "bin": { - "uglifyjs": "bin/uglifyjs" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "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, - "dependencies": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/undici": { - "version": "5.12.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.12.0.tgz", - "integrity": "sha512-zMLamCG62PGjd9HHMpo05bSLvvwWOZgGeiWlN/vlqu3+lRo3elxktVGEyLMX+IO7c2eflLjcW74AlkhEZm15mg==", - "dev": true, - "dependencies": { - "busboy": "^1.6.0" - }, - "engines": { - "node": ">=12.18" - } - }, - "node_modules/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, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==", - "dev": true, - "dependencies": { - "punycode": "1.3.2", - "querystring": "0.2.0" - } - }, - "node_modules/url/node_modules/punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==", - "dev": true - }, - "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-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true - }, - "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==", - "dev": true, - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/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 - }, - "node_modules/validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "node_modules/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, - "engines": [ - "node >=0.6.0" - ], - "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "node_modules/web3-utils": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.8.0.tgz", - "integrity": "sha512-7nUIl7UWpLVka2f09CMbKOSEvorvHnaugIabU4mj7zfMvm0tSByLcEu3eyV9qgS11qxxLuOkzBIwCstTflhmpQ==", - "dev": 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" - }, - "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==", - "dev": true, - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.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==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "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, - "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" - } - }, - "node_modules/which-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", - "integrity": "sha512-F6+WgncZi/mJDrammbTuHe1q0R5hOXv/mBaiNA2TCNT/LTHusX0V+CJnj9XT8ki5ln2UZyyddDgHfCzyrOH7MQ==", - "dev": true - }, - "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==", - "dev": true, - "dependencies": { - "string-width": "^1.0.2 || 2" - } - }, - "node_modules/window-size": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz", - "integrity": "sha512-UD7d8HFA2+PZsbKyaOCEy8gMh1oDtHgJh1LfgjQ4zVXmYjAT/kvz3PueITKuqDiIXQe7yzpPnxX3lNc+AhQMyw==", - "dev": true, - "bin": { - "window-size": "cli.js" - }, - "engines": { - "node": ">= 0.10.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==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "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 - }, - "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 - }, - "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, - "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" - } - }, - "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/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, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "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, - "dependencies": { - "mkdirp": "^0.5.1" - }, - "engines": { - "node": ">=4" - } - }, - "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, - "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 - } - } - }, - "node_modules/xmlhttprequest": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", - "integrity": "sha512-58Im/U0mlVBLM38NdZjHyhuMtCqa61469k2YP/AaPbvCoV9aQGUpbJBj1QRm2ytRiVQBD/fsw7L2bJGDVQswBA==", - "dev": true, - "engines": { - "node": ">=0.4.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==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, - "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, - "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" - } - }, - "node_modules/yargs-parser": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz", - "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==", - "dev": true, - "dependencies": { - "camelcase": "^4.1.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==", - "dev": true, - "dependencies": { - "camelcase": "^6.0.0", - "decamelize": "^4.0.0", - "flat": "^5.0.2", - "is-plain-obj": "^2.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-unparser/node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/yargs-unparser/node_modules/decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/yargs-unparser/node_modules/is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/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, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "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, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", - "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", - "dev": true, - "requires": { - "@babel/highlight": "^7.18.6" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", - "dev": true - }, - "@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", - "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" - } - } - } - }, - "@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": { - "@jridgewell/trace-mapping": "0.3.9" - } - }, - "@ensdomains/ens": { - "version": "0.4.5", - "resolved": "https://registry.npmjs.org/@ensdomains/ens/-/ens-0.4.5.tgz", - "integrity": "sha512-JSvpj1iNMFjK6K+uVl4unqMoa9rf5jopb8cya5UGBWz23Nw8hSNT7efgUx4BTlAPAgpNlEioUfeTyQ6J9ZvTVw==", - "dev": true, - "requires": { - "bluebird": "^3.5.2", - "eth-ens-namehash": "^2.0.8", - "solc": "^0.4.20", - "testrpc": "0.0.1", - "web3-utils": "^1.0.0-beta.31" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", - "dev": true - }, - "camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg==", - "dev": true - }, - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w==", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - } - }, - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==", - "dev": true, - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "fs-extra": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", - "integrity": "sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0", - "path-is-absolute": "^1.0.0", - "rimraf": "^2.2.8" - } - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - } - }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==", - "dev": true, - "requires": { - "error-ex": "^1.2.0" - } - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==", - "dev": true, - "requires": { - "pinkie-promise": "^2.0.0" - } - }, - "path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true - }, - "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ==", - "dev": true, - "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - } - }, - "read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A==", - "dev": true, - "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - } - }, - "require-from-string": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-1.2.1.tgz", - "integrity": "sha512-H7AkJWMobeskkttHyhTVtS0fxpFLjxhbfMa6Bk3wimP7sdPRGL3EyCg3sAQenFfAe+xQ+oAc85Nmtvq0ROM83Q==", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "solc": { - "version": "0.4.26", - "resolved": "https://registry.npmjs.org/solc/-/solc-0.4.26.tgz", - "integrity": "sha512-o+c6FpkiHd+HPjmjEVpQgH7fqZ14tJpXhho+/bQXlXbliLIS/xjXb42Vxh+qQY1WCSTMQ0+a5vR9vi0MfhU6mA==", - "dev": true, - "requires": { - "fs-extra": "^0.30.0", - "memorystream": "^0.3.1", - "require-from-string": "^1.1.0", - "semver": "^5.3.0", - "yargs": "^4.7.1" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==", - "dev": true, - "requires": { - "is-utf8": "^0.2.0" - } - }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - } - }, - "y18n": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", - "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==", - "dev": true - }, - "yargs": { - "version": "4.8.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz", - "integrity": "sha512-LqodLrnIDM3IFT+Hf/5sxBnEGECrfdC1uIbgZeJmESCSo4HoCAaKEus8MylXHAkdacGc0ye+Qa+dpkuom8uVYA==", - "dev": true, - "requires": { - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "lodash.assign": "^4.0.3", - "os-locale": "^1.4.0", - "read-pkg-up": "^1.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^1.0.1", - "which-module": "^1.0.0", - "window-size": "^0.2.0", - "y18n": "^3.2.1", - "yargs-parser": "^2.4.1" - } - }, - "yargs-parser": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz", - "integrity": "sha512-9pIKIJhnI5tonzG6OnCFlz/yln8xHYcGl+pn3xR0Vzff0vzN1PbNRaelgfgRUwZ3s4i3jvxT9WhmUGL4whnasA==", - "dev": true, - "requires": { - "camelcase": "^3.0.0", - "lodash.assign": "^4.0.6" - } - } - } - }, - "@ensdomains/resolver": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/@ensdomains/resolver/-/resolver-0.2.4.tgz", - "integrity": "sha512-bvaTH34PMCbv6anRa9I/0zjLJgY4EuznbEMgbV77JBCQ9KNC46rzi0avuxpOfu+xDjPEtSFGqVEOr5GlUSGudA==", - "dev": true - }, - "@eslint/eslintrc": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", - "integrity": "sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==", - "dev": true, - "requires": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.4.0", - "globals": "^13.15.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" - } - }, - "@ethereum-waffle/chai": { - "version": "3.4.4", - "resolved": "https://registry.npmjs.org/@ethereum-waffle/chai/-/chai-3.4.4.tgz", - "integrity": "sha512-/K8czydBtXXkcM9X6q29EqEkc5dN3oYenyH2a9hF7rGAApAJUpH8QBtojxOY/xQ2up5W332jqgxwp0yPiYug1g==", - "dev": true, - "requires": { - "@ethereum-waffle/provider": "^3.4.4", - "ethers": "^5.5.2" - } - }, - "@ethereum-waffle/compiler": { - "version": "3.4.4", - "resolved": "https://registry.npmjs.org/@ethereum-waffle/compiler/-/compiler-3.4.4.tgz", - "integrity": "sha512-RUK3axJ8IkD5xpWjWoJgyHclOeEzDLQFga6gKpeGxiS/zBu+HB0W2FvsrrLalTFIaPw/CGYACRBSIxqiCqwqTQ==", - "dev": true, - "requires": { - "@resolver-engine/imports": "^0.3.3", - "@resolver-engine/imports-fs": "^0.3.3", - "@typechain/ethers-v5": "^2.0.0", - "@types/mkdirp": "^0.5.2", - "@types/node-fetch": "^2.5.5", - "ethers": "^5.0.1", - "mkdirp": "^0.5.1", - "node-fetch": "^2.6.1", - "solc": "^0.6.3", - "ts-generator": "^0.1.1", - "typechain": "^3.0.0" - } - }, - "@ethereum-waffle/ens": { - "version": "3.4.4", - "resolved": "https://registry.npmjs.org/@ethereum-waffle/ens/-/ens-3.4.4.tgz", - "integrity": "sha512-0m4NdwWxliy3heBYva1Wr4WbJKLnwXizmy5FfSSr5PMbjI7SIGCdCB59U7/ZzY773/hY3bLnzLwvG5mggVjJWg==", - "dev": true, - "requires": { - "@ensdomains/ens": "^0.4.4", - "@ensdomains/resolver": "^0.2.4", - "ethers": "^5.5.2" - } - }, - "@ethereum-waffle/mock-contract": { - "version": "3.4.4", - "resolved": "https://registry.npmjs.org/@ethereum-waffle/mock-contract/-/mock-contract-3.4.4.tgz", - "integrity": "sha512-Mp0iB2YNWYGUV+VMl5tjPsaXKbKo8MDH9wSJ702l9EBjdxFf/vBvnMBAC1Fub1lLtmD0JHtp1pq+mWzg/xlLnA==", - "dev": true, - "requires": { - "@ethersproject/abi": "^5.5.0", - "ethers": "^5.5.2" - } - }, - "@ethereum-waffle/provider": { - "version": "3.4.4", - "resolved": "https://registry.npmjs.org/@ethereum-waffle/provider/-/provider-3.4.4.tgz", - "integrity": "sha512-GK8oKJAM8+PKy2nK08yDgl4A80mFuI8zBkE0C9GqTRYQqvuxIyXoLmJ5NZU9lIwyWVv5/KsoA11BgAv2jXE82g==", - "dev": true, - "requires": { - "@ethereum-waffle/ens": "^3.4.4", - "ethers": "^5.5.2", - "ganache-core": "^2.13.2", - "patch-package": "^6.2.2", - "postinstall-postinstall": "^2.1.0" - } - }, - "@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, - "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" - } - }, - "@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, - "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" - } - }, - "@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": { - "@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" - } - }, - "@ethersproject/address": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz", - "integrity": "sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==", - "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" - } - }, - "@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, - "requires": { - "@ethersproject/bytes": "^5.7.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==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "bn.js": "^5.2.1" - } - }, - "@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, - "requires": { - "@ethersproject/logger": "^5.7.0" - } - }, - "@ethersproject/constants": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.7.0.tgz", - "integrity": "sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==", - "dev": true, - "requires": { - "@ethersproject/bignumber": "^5.7.0" - } - }, - "@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" - } - }, - "@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, - "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" - } - }, - "@ethersproject/hdnode": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.7.0.tgz", - "integrity": "sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==", - "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" - } - }, - "@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, - "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" - } - }, - "@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, - "requires": { - "@ethersproject/bytes": "^5.7.0", - "js-sha3": "0.8.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==", - "dev": true, - "requires": { - "@ethersproject/logger": "^5.7.0" - } - }, - "@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": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/sha2": "^5.7.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==", - "dev": true, - "requires": { - "@ethersproject/logger": "^5.7.0" - } - }, - "@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": { - "@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" - } - }, - "@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/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "@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": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "@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" - } - }, - "@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": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "@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": { - "@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" - } - }, - "@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": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "@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": { - "@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" - } - }, - "@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" - } - }, - "@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": { - "@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" - } - }, - "@humanwhocodes/config-array": { - "version": "0.11.7", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.7.tgz", - "integrity": "sha512-kBbPWzN8oVMLb0hOUYXhmxggL/1cJE6ydvjDIGi9EnAGUyA7cLVKQg+d/Dsm+KZwx2czGHrCmMVLiyg8s5JPKw==", - "dev": true, - "requires": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.5" - } - }, - "@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.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", - "dev": true - }, - "@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "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==", - "dev": true, - "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "@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, - "requires": { - "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": { - "@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 - }, - "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, - "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" - } - } - } - }, - "@noble/hashes": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.1.2.tgz", - "integrity": "sha512-KYRCASVTv6aeUi1tsF8/vpyR7zpfs3FUzy2Jqm+MU+LmUKhQ0y2FpfwqkCcxSg2ua4GALJd8k2R76WxwZGbQpA==", - "dev": true - }, - "@noble/secp256k1": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-1.6.3.tgz", - "integrity": "sha512-T04e4iTurVy7I8Sw4+c5OSN9/RkPlo1uKxAomtxQNLq8j1uPAqnsqG1bqvY3Jv7c13gyr6dui0zmh/I3+f/JaQ==", - "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==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - } - }, - "@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 - }, - "@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, - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - } - }, - "@nomicfoundation/ethereumjs-block": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-block/-/ethereumjs-block-4.0.0.tgz", - "integrity": "sha512-bk8uP8VuexLgyIZAHExH1QEovqx0Lzhc9Ntm63nCRKLHXIZkobaFaeCVwTESV7YkPKUk7NiK11s8ryed4CS9yA==", - "dev": true, - "requires": { - "@nomicfoundation/ethereumjs-common": "^3.0.0", - "@nomicfoundation/ethereumjs-rlp": "^4.0.0", - "@nomicfoundation/ethereumjs-trie": "^5.0.0", - "@nomicfoundation/ethereumjs-tx": "^4.0.0", - "@nomicfoundation/ethereumjs-util": "^8.0.0", - "ethereum-cryptography": "0.1.3" - } - }, - "@nomicfoundation/ethereumjs-blockchain": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-blockchain/-/ethereumjs-blockchain-6.0.0.tgz", - "integrity": "sha512-pLFEoea6MWd81QQYSReLlLfH7N9v7lH66JC/NMPN848ySPPQA5renWnE7wPByfQFzNrPBuDDRFFULMDmj1C0xw==", - "dev": true, - "requires": { - "@nomicfoundation/ethereumjs-block": "^4.0.0", - "@nomicfoundation/ethereumjs-common": "^3.0.0", - "@nomicfoundation/ethereumjs-ethash": "^2.0.0", - "@nomicfoundation/ethereumjs-rlp": "^4.0.0", - "@nomicfoundation/ethereumjs-trie": "^5.0.0", - "@nomicfoundation/ethereumjs-util": "^8.0.0", - "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": "3.0.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-3.0.0.tgz", - "integrity": "sha512-WS7qSshQfxoZOpHG/XqlHEGRG1zmyjYrvmATvc4c62+gZXgre1ymYP8ZNgx/3FyZY0TWe9OjFlKOfLqmgOeYwA==", - "dev": true, - "requires": { - "@nomicfoundation/ethereumjs-util": "^8.0.0", - "crc-32": "^1.2.0" - } - }, - "@nomicfoundation/ethereumjs-ethash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-ethash/-/ethereumjs-ethash-2.0.0.tgz", - "integrity": "sha512-WpDvnRncfDUuXdsAXlI4lXbqUDOA+adYRQaEezIkxqDkc+LDyYDbd/xairmY98GnQzo1zIqsIL6GB5MoMSJDew==", - "dev": true, - "requires": { - "@nomicfoundation/ethereumjs-block": "^4.0.0", - "@nomicfoundation/ethereumjs-rlp": "^4.0.0", - "@nomicfoundation/ethereumjs-util": "^8.0.0", - "abstract-level": "^1.0.3", - "bigint-crypto-utils": "^3.0.23", - "ethereum-cryptography": "0.1.3" - } - }, - "@nomicfoundation/ethereumjs-evm": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-evm/-/ethereumjs-evm-1.0.0.tgz", - "integrity": "sha512-hVS6qRo3V1PLKCO210UfcEQHvlG7GqR8iFzp0yyjTg2TmJQizcChKgWo8KFsdMw6AyoLgLhHGHw4HdlP8a4i+Q==", - "dev": true, - "requires": { - "@nomicfoundation/ethereumjs-common": "^3.0.0", - "@nomicfoundation/ethereumjs-util": "^8.0.0", - "@types/async-eventemitter": "^0.2.1", - "async-eventemitter": "^0.2.4", - "debug": "^4.3.3", - "ethereum-cryptography": "0.1.3", - "mcl-wasm": "^0.7.1", - "rustbn.js": "~0.2.0" - } - }, - "@nomicfoundation/ethereumjs-rlp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-4.0.0.tgz", - "integrity": "sha512-GaSOGk5QbUk4eBP5qFbpXoZoZUj/NrW7MRa0tKY4Ew4c2HAS0GXArEMAamtFrkazp0BO4K5p2ZCG3b2FmbShmw==", - "dev": true - }, - "@nomicfoundation/ethereumjs-statemanager": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-statemanager/-/ethereumjs-statemanager-1.0.0.tgz", - "integrity": "sha512-jCtqFjcd2QejtuAMjQzbil/4NHf5aAWxUc+CvS0JclQpl+7M0bxMofR2AJdtz+P3u0ke2euhYREDiE7iSO31vQ==", - "dev": true, - "requires": { - "@nomicfoundation/ethereumjs-common": "^3.0.0", - "@nomicfoundation/ethereumjs-rlp": "^4.0.0", - "@nomicfoundation/ethereumjs-trie": "^5.0.0", - "@nomicfoundation/ethereumjs-util": "^8.0.0", - "debug": "^4.3.3", - "ethereum-cryptography": "0.1.3", - "functional-red-black-tree": "^1.0.1" - } - }, - "@nomicfoundation/ethereumjs-trie": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-trie/-/ethereumjs-trie-5.0.0.tgz", - "integrity": "sha512-LIj5XdE+s+t6WSuq/ttegJzZ1vliwg6wlb+Y9f4RlBpuK35B9K02bO7xU+E6Rgg9RGptkWd6TVLdedTI4eNc2A==", - "dev": true, - "requires": { - "@nomicfoundation/ethereumjs-rlp": "^4.0.0", - "@nomicfoundation/ethereumjs-util": "^8.0.0", - "ethereum-cryptography": "0.1.3", - "readable-stream": "^3.6.0" - } - }, - "@nomicfoundation/ethereumjs-tx": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-4.0.0.tgz", - "integrity": "sha512-Gg3Lir2lNUck43Kp/3x6TfBNwcWC9Z1wYue9Nz3v4xjdcv6oDW9QSMJxqsKw9QEGoBBZ+gqwpW7+F05/rs/g1w==", - "dev": true, - "requires": { - "@nomicfoundation/ethereumjs-common": "^3.0.0", - "@nomicfoundation/ethereumjs-rlp": "^4.0.0", - "@nomicfoundation/ethereumjs-util": "^8.0.0", - "ethereum-cryptography": "0.1.3" - } - }, - "@nomicfoundation/ethereumjs-util": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-8.0.0.tgz", - "integrity": "sha512-2emi0NJ/HmTG+CGY58fa+DQuAoroFeSH9gKu9O6JnwTtlzJtgfTixuoOqLEgyyzZVvwfIpRueuePb8TonL1y+A==", - "dev": true, - "requires": { - "@nomicfoundation/ethereumjs-rlp": "^4.0.0-beta.2", - "ethereum-cryptography": "0.1.3" - } - }, - "@nomicfoundation/ethereumjs-vm": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-vm/-/ethereumjs-vm-6.0.0.tgz", - "integrity": "sha512-JMPxvPQ3fzD063Sg3Tp+UdwUkVxMoo1uML6KSzFhMH3hoQi/LMuXBoEHAoW83/vyNS9BxEe6jm6LmT5xdeEJ6w==", - "dev": true, - "requires": { - "@nomicfoundation/ethereumjs-block": "^4.0.0", - "@nomicfoundation/ethereumjs-blockchain": "^6.0.0", - "@nomicfoundation/ethereumjs-common": "^3.0.0", - "@nomicfoundation/ethereumjs-evm": "^1.0.0", - "@nomicfoundation/ethereumjs-rlp": "^4.0.0", - "@nomicfoundation/ethereumjs-statemanager": "^1.0.0", - "@nomicfoundation/ethereumjs-trie": "^5.0.0", - "@nomicfoundation/ethereumjs-tx": "^4.0.0", - "@nomicfoundation/ethereumjs-util": "^8.0.0", - "@types/async-eventemitter": "^0.2.1", - "async-eventemitter": "^0.2.4", - "debug": "^4.3.3", - "ethereum-cryptography": "0.1.3", - "functional-red-black-tree": "^1.0.1", - "mcl-wasm": "^0.7.1", - "rustbn.js": "~0.2.0" - } - }, - "@nomicfoundation/solidity-analyzer": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.0.tgz", - "integrity": "sha512-xGWAiVCGOycvGiP/qrlf9f9eOn7fpNbyJygcB0P21a1MDuVPlKt0Srp7rvtBEutYQ48ouYnRXm33zlRnlTOPHg==", - "dev": true, - "requires": { - "@nomicfoundation/solidity-analyzer-darwin-arm64": "0.1.0", - "@nomicfoundation/solidity-analyzer-darwin-x64": "0.1.0", - "@nomicfoundation/solidity-analyzer-freebsd-x64": "0.1.0", - "@nomicfoundation/solidity-analyzer-linux-arm64-gnu": "0.1.0", - "@nomicfoundation/solidity-analyzer-linux-arm64-musl": "0.1.0", - "@nomicfoundation/solidity-analyzer-linux-x64-gnu": "0.1.0", - "@nomicfoundation/solidity-analyzer-linux-x64-musl": "0.1.0", - "@nomicfoundation/solidity-analyzer-win32-arm64-msvc": "0.1.0", - "@nomicfoundation/solidity-analyzer-win32-ia32-msvc": "0.1.0", - "@nomicfoundation/solidity-analyzer-win32-x64-msvc": "0.1.0" - } - }, - "@nomicfoundation/solidity-analyzer-darwin-arm64": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.0.tgz", - "integrity": "sha512-vEF3yKuuzfMHsZecHQcnkUrqm8mnTWfJeEVFHpg+cO+le96xQA4lAJYdUan8pXZohQxv1fSReQsn4QGNuBNuCw==", - "dev": true, - "optional": true - }, - "@nomicfoundation/solidity-analyzer-darwin-x64": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-x64/-/solidity-analyzer-darwin-x64-0.1.0.tgz", - "integrity": "sha512-dlHeIg0pTL4dB1l9JDwbi/JG6dHQaU1xpDK+ugYO8eJ1kxx9Dh2isEUtA4d02cQAl22cjOHTvifAk96A+ItEHA==", - "dev": true, - "optional": true - }, - "@nomicfoundation/solidity-analyzer-freebsd-x64": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-freebsd-x64/-/solidity-analyzer-freebsd-x64-0.1.0.tgz", - "integrity": "sha512-WFCZYMv86WowDA4GiJKnebMQRt3kCcFqHeIomW6NMyqiKqhK1kIZCxSLDYsxqlx396kKLPN1713Q1S8tu68GKg==", - "dev": true, - "optional": true - }, - "@nomicfoundation/solidity-analyzer-linux-arm64-gnu": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-gnu/-/solidity-analyzer-linux-arm64-gnu-0.1.0.tgz", - "integrity": "sha512-DTw6MNQWWlCgc71Pq7CEhEqkb7fZnS7oly13pujs4cMH1sR0JzNk90Mp1zpSCsCs4oKan2ClhMlLKtNat/XRKQ==", - "dev": true, - "optional": true - }, - "@nomicfoundation/solidity-analyzer-linux-arm64-musl": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-musl/-/solidity-analyzer-linux-arm64-musl-0.1.0.tgz", - "integrity": "sha512-wUpUnR/3GV5Da88MhrxXh/lhb9kxh9V3Jya2NpBEhKDIRCDmtXMSqPMXHZmOR9DfCwCvG6vLFPr/+YrPCnUN0w==", - "dev": true, - "optional": true - }, - "@nomicfoundation/solidity-analyzer-linux-x64-gnu": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-gnu/-/solidity-analyzer-linux-x64-gnu-0.1.0.tgz", - "integrity": "sha512-lR0AxK1x/MeKQ/3Pt923kPvwigmGX3OxeU5qNtQ9pj9iucgk4PzhbS3ruUeSpYhUxG50jN4RkIGwUMoev5lguw==", - "dev": true, - "optional": true - }, - "@nomicfoundation/solidity-analyzer-linux-x64-musl": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-musl/-/solidity-analyzer-linux-x64-musl-0.1.0.tgz", - "integrity": "sha512-A1he/8gy/JeBD3FKvmI6WUJrGrI5uWJNr5Xb9WdV+DK0F8msuOqpEByLlnTdLkXMwW7nSl3awvLezOs9xBHJEg==", - "dev": true, - "optional": true - }, - "@nomicfoundation/solidity-analyzer-win32-arm64-msvc": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-arm64-msvc/-/solidity-analyzer-win32-arm64-msvc-0.1.0.tgz", - "integrity": "sha512-7x5SXZ9R9H4SluJZZP8XPN+ju7Mx+XeUMWZw7ZAqkdhP5mK19I4vz3x0zIWygmfE8RT7uQ5xMap0/9NPsO+ykw==", - "dev": true, - "optional": true - }, - "@nomicfoundation/solidity-analyzer-win32-ia32-msvc": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-ia32-msvc/-/solidity-analyzer-win32-ia32-msvc-0.1.0.tgz", - "integrity": "sha512-m7w3xf+hnE774YRXu+2mGV7RiF3QJtUoiYU61FascCkQhX3QMQavh7saH/vzb2jN5D24nT/jwvaHYX/MAM9zUw==", - "dev": true, - "optional": true - }, - "@nomicfoundation/solidity-analyzer-win32-x64-msvc": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-x64-msvc/-/solidity-analyzer-win32-x64-msvc-0.1.0.tgz", - "integrity": "sha512-xCuybjY0sLJQnJhupiFAXaek2EqF0AP0eBjgzaalPXSNvCEN6ZYHvUzdA50ENDVeSYFXcUsYf3+FsD3XKaeptA==", - "dev": true, - "optional": true - }, - "@nomiclabs/hardhat-ethers": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.2.1.tgz", - "integrity": "sha512-RHWYwnxryWR8hzRmU4Jm/q4gzvXpetUOJ4OPlwH2YARcDB+j79+yAYCwO0lN1SUOb4++oOTJEe6AWLEc42LIvg==", - "dev": true, - "requires": {} - }, - "@nomiclabs/hardhat-etherscan": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-3.1.2.tgz", - "integrity": "sha512-IEikeOVq0C/7CY6aD74d8L4BpGoc/FNiN6ldiPVg0QIFIUSu4FSGA1dmtJZJKk1tjpwgrfTLQNWnigtEaN9REg==", - "dev": true, - "requires": { - "@ethersproject/abi": "^5.1.2", - "@ethersproject/address": "^5.0.2", - "cbor": "^5.0.2", - "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.4.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" - } - } - } - }, - "@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": { - "solhint": "^2.0.0" - } - }, - "@nomiclabs/hardhat-waffle": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-waffle/-/hardhat-waffle-2.0.3.tgz", - "integrity": "sha512-049PHSnI1CZq6+XTbrMbMv5NaL7cednTfPenx02k3cEh8wBMLa6ys++dBETJa6JjfwgA9nBhhHQ173LJv6k2Pg==", - "dev": true, - "requires": { - "@types/sinon-chai": "^3.2.3", - "@types/web3": "1.0.19" - } - }, - "@openzeppelin/contracts": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.6.0.tgz", - "integrity": "sha512-8vi4d50NNya/bQqCmaVzvHNmwHvS0OBKb7HNtuNwEE3scXWrP31fKQoGxNMT+KbzmrNZzatE3QK5p2gFONI/hg==", - "dev": true - }, - "@openzeppelin/contracts-upgradeable": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.6.0.tgz", - "integrity": "sha512-5OnVuO4HlkjSCJO165a4i2Pu1zQGzMs//o54LPrwUgxvEO2P3ax1QuaSI0cEHHTveA77guS0PnNugpR2JMsPfA==", - "dev": true - }, - "@openzeppelin/hardhat-upgrades": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/@openzeppelin/hardhat-upgrades/-/hardhat-upgrades-1.21.0.tgz", - "integrity": "sha512-Kwl7IN0Hlhj4HluMTTl0DrtU90OI/Q6rG3sAyd2pv3fababe9EuZqs9DydOlkWM45JwTzC+eBzX3TgHsqI13eA==", - "dev": true, - "requires": { - "@openzeppelin/upgrades-core": "^1.20.0", - "chalk": "^4.1.0", - "debug": "^4.1.1", - "proper-lockfile": "^4.1.1" - } - }, - "@openzeppelin/upgrades-core": { - "version": "1.20.4", - "resolved": "https://registry.npmjs.org/@openzeppelin/upgrades-core/-/upgrades-core-1.20.4.tgz", - "integrity": "sha512-Y4/+BPIbnopfE6ZhPOE2CD0V5fnvDxKKm7+kryx5+WrcRCTW3B5DjbXL9xyyoviG8Rn5EXUh5Fk1GLbiYDfu0g==", - "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", - "proper-lockfile": "^4.1.1", - "solidity-ast": "^0.4.15" - }, - "dependencies": { - "cbor": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/cbor/-/cbor-8.1.0.tgz", - "integrity": "sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg==", - "dev": true, - "requires": { - "nofilter": "^3.1.0" - } - }, - "nofilter": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-3.1.0.tgz", - "integrity": "sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==", - "dev": true - } - } - }, - "@resolver-engine/core": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@resolver-engine/core/-/core-0.3.3.tgz", - "integrity": "sha512-eB8nEbKDJJBi5p5SrvrvILn4a0h42bKtbCTri3ZxCGt6UvoQyp7HnGOfki944bUjBSHKK3RvgfViHn+kqdXtnQ==", - "dev": true, - "requires": { - "debug": "^3.1.0", - "is-url": "^1.2.4", - "request": "^2.85.0" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "@resolver-engine/fs": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@resolver-engine/fs/-/fs-0.3.3.tgz", - "integrity": "sha512-wQ9RhPUcny02Wm0IuJwYMyAG8fXVeKdmhm8xizNByD4ryZlx6PP6kRen+t/haF43cMfmaV7T3Cx6ChOdHEhFUQ==", - "dev": true, - "requires": { - "@resolver-engine/core": "^0.3.3", - "debug": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "@resolver-engine/imports": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@resolver-engine/imports/-/imports-0.3.3.tgz", - "integrity": "sha512-anHpS4wN4sRMwsAbMXhMfOD/y4a4Oo0Cw/5+rue7hSwGWsDOQaAU1ClK1OxjUC35/peazxEl8JaSRRS+Xb8t3Q==", - "dev": true, - "requires": { - "@resolver-engine/core": "^0.3.3", - "debug": "^3.1.0", - "hosted-git-info": "^2.6.0", - "path-browserify": "^1.0.0", - "url": "^0.11.0" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "@resolver-engine/imports-fs": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@resolver-engine/imports-fs/-/imports-fs-0.3.3.tgz", - "integrity": "sha512-7Pjg/ZAZtxpeyCFlZR5zqYkz+Wdo84ugB5LApwriT8XFeQoLwGUj4tZFFvvCuxaNCcqZzCYbonJgmGObYBzyCA==", - "dev": true, - "requires": { - "@resolver-engine/fs": "^0.3.3", - "@resolver-engine/imports": "^0.3.3", - "debug": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "@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.0", - "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.0.tgz", - "integrity": "sha512-ftTW3kKX54YXLCxH6BB7oEEoJfoE2pIgw7MINKAs5PsS6nqKPuKk1haTF/EuHmYqG330t5GSrdmtRuHaY1a62Q==", - "dev": true, - "requires": { - "@noble/hashes": "~1.1.1", - "@noble/secp256k1": "~1.6.0", - "@scure/base": "~1.1.0" - } - }, - "@scure/bip39": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.0.tgz", - "integrity": "sha512-pwrPOS16VeTKg98dYXQyIjJEcWfz7/1YJIwxUEPFfQPtc86Ym/1sVgQ2RLoD43AazMk2l/unK4ITySSpW2+82w==", - "dev": true, - "requires": { - "@noble/hashes": "~1.1.1", - "@scure/base": "~1.1.0" - } - }, - "@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" - } - }, - "@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": { - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "tslib": "^1.9.3" - } - }, - "@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": { - "@sentry/hub": "5.30.0", - "@sentry/types": "5.30.0", - "tslib": "^1.9.3" - } - }, - "@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": { - "@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" - } - }, - "@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": { - "@sentry/hub": "5.30.0", - "@sentry/minimal": "5.30.0", - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "tslib": "^1.9.3" - } - }, - "@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, - "requires": { - "@sentry/types": "5.30.0", - "tslib": "^1.9.3" - } - }, - "@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, - "requires": { - "antlr4ts": "^0.5.0-alpha.4" - } - }, - "@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "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==", - "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==", - "dev": true - }, - "@tsconfig/node16": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", - "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", - "dev": true - }, - "@typechain/ethers-v5": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@typechain/ethers-v5/-/ethers-v5-2.0.0.tgz", - "integrity": "sha512-0xdCkyGOzdqh4h5JSf+zoWx85IusEjDcPIwNEHP8mrWSnCae4rvrqB+/gtpdNfX7zjlFlZiMeePn2r63EI3Lrw==", - "dev": true, - "requires": { - "ethers": "^5.0.2" - } - }, - "@types/async-eventemitter": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@types/async-eventemitter/-/async-eventemitter-0.2.1.tgz", - "integrity": "sha512-M2P4Ng26QbAeITiH7w1d7OxtldgfAe0wobpyJzVK/XOb0cUGKU2R4pfAhqcJBXAe2ife5ZOhSv4wk7p+ffURtg==", - "dev": 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==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/chai": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.4.tgz", - "integrity": "sha512-KnRanxnpfpjUTqTCXslZSEdLfXExwgNxYPdiO2WGUj8+HDjFi8R3k5RVKPeSCzLjCcshCAtVO2QBbVuAV4kTnw==", - "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==", - "dev": true, - "requires": { - "@types/chai": "*" - } - }, - "@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==", - "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==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@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, - "requires": { - "@types/node": "*" - } - }, - "@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, - "requires": { - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/json-schema": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", - "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", - "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==", - "dev": true - }, - "@types/mkdirp": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@types/mkdirp/-/mkdirp-0.5.2.tgz", - "integrity": "sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@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 - }, - "@types/node-fetch": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.2.tgz", - "integrity": "sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A==", - "dev": true, - "requires": { - "@types/node": "*", - "form-data": "^3.0.0" - } - }, - "@types/pbkdf2": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz", - "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/prettier": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.1.tgz", - "integrity": "sha512-ri0UmynRRvZiiUJdiz38MmIblKK+oH30MztdBVR95dv/Ubw6neWSb8u1XpRb72L4qsZOhz+L+z9JD40SJmfWow==", - "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==", - "dev": true - }, - "@types/resolve": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz", - "integrity": "sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/secp256k1": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.3.tgz", - "integrity": "sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/semver": { - "version": "7.3.13", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", - "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==", - "dev": true - }, - "@types/sinon": { - "version": "10.0.13", - "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.13.tgz", - "integrity": "sha512-UVjDqJblVNQYvVNUsj0PuYYw0ELRmgt1Nt5Vk0pT5f16ROGfcKJY8o1HVuMOJOpD727RrGB9EGvoaTQE5tgxZQ==", - "dev": true, - "requires": { - "@types/sinonjs__fake-timers": "*" - } - }, - "@types/sinon-chai": { - "version": "3.2.9", - "resolved": "https://registry.npmjs.org/@types/sinon-chai/-/sinon-chai-3.2.9.tgz", - "integrity": "sha512-/19t63pFYU0ikrdbXKBWj9PCdnKyTd0Qkz0X91Ta081cYsq90OxYdcWwK/dwEoDa6dtXgj2HJfmzgq+QZTHdmQ==", - "dev": true, - "requires": { - "@types/chai": "*", - "@types/sinon": "*" - } - }, - "@types/sinonjs__fake-timers": { - "version": "8.1.2", - "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.2.tgz", - "integrity": "sha512-9GcLXF0/v3t80caGs5p2rRfkB+a8VBGLJZVih6CNFkx8IZ994wiKKLSRs9nuFwk1HevWs/1mnUmkApGrSGsShA==", - "dev": true - }, - "@types/underscore": { - "version": "1.11.4", - "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.11.4.tgz", - "integrity": "sha512-uO4CD2ELOjw8tasUrAhvnn2W4A0ZECOvMjCivJr4gA9pGgjv+qxKWY9GLTMVEK8ej85BxQOocUyE7hImmSQYcg==", - "dev": true - }, - "@types/web3": { - "version": "1.0.19", - "resolved": "https://registry.npmjs.org/@types/web3/-/web3-1.0.19.tgz", - "integrity": "sha512-fhZ9DyvDYDwHZUp5/STa9XW2re0E8GxoioYJ4pEUZ13YHpApSagixj7IAdoYH5uAK+UalGq6Ml8LYzmgRA/q+A==", - "dev": true, - "requires": { - "@types/bn.js": "*", - "@types/underscore": "*" - } - }, - "@typescript-eslint/eslint-plugin": { - "version": "5.42.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.42.1.tgz", - "integrity": "sha512-LyR6x784JCiJ1j6sH5Y0K6cdExqCCm8DJUTcwG5ThNXJj/G8o5E56u5EdG4SLy+bZAwZBswC+GYn3eGdttBVCg==", - "dev": true, - "requires": { - "@typescript-eslint/scope-manager": "5.42.1", - "@typescript-eslint/type-utils": "5.42.1", - "@typescript-eslint/utils": "5.42.1", - "debug": "^4.3.4", - "ignore": "^5.2.0", - "natural-compare-lite": "^1.4.0", - "regexpp": "^3.2.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.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "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 - } - } - }, - "@typescript-eslint/parser": { - "version": "5.42.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.42.1.tgz", - "integrity": "sha512-kAV+NiNBWVQDY9gDJDToTE/NO8BHi4f6b7zTsVAJoTkmB/zlfOpiEVBzHOKtlgTndCKe8vj9F/PuolemZSh50Q==", - "dev": true, - "peer": true, - "requires": { - "@typescript-eslint/scope-manager": "5.42.1", - "@typescript-eslint/types": "5.42.1", - "@typescript-eslint/typescript-estree": "5.42.1", - "debug": "^4.3.4" - } - }, - "@typescript-eslint/scope-manager": { - "version": "5.42.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.42.1.tgz", - "integrity": "sha512-QAZY/CBP1Emx4rzxurgqj3rUinfsh/6mvuKbLNMfJMMKYLRBfweus8brgXF8f64ABkIZ3zdj2/rYYtF8eiuksQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.42.1", - "@typescript-eslint/visitor-keys": "5.42.1" - } - }, - "@typescript-eslint/type-utils": { - "version": "5.42.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.42.1.tgz", - "integrity": "sha512-WWiMChneex5w4xPIX56SSnQQo0tEOy5ZV2dqmj8Z371LJ0E+aymWD25JQ/l4FOuuX+Q49A7pzh/CGIQflxMVXg==", - "dev": true, - "requires": { - "@typescript-eslint/typescript-estree": "5.42.1", - "@typescript-eslint/utils": "5.42.1", - "debug": "^4.3.4", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/types": { - "version": "5.42.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.42.1.tgz", - "integrity": "sha512-Qrco9dsFF5lhalz+lLFtxs3ui1/YfC6NdXu+RAGBa8uSfn01cjO7ssCsjIsUs484vny9Xm699FSKwpkCcqwWwA==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "5.42.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.42.1.tgz", - "integrity": "sha512-qElc0bDOuO0B8wDhhW4mYVgi/LZL+igPwXtV87n69/kYC/7NG3MES0jHxJNCr4EP7kY1XVsRy8C/u3DYeTKQmw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.42.1", - "@typescript-eslint/visitor-keys": "5.42.1", - "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.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "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 - } - } - }, - "@typescript-eslint/utils": { - "version": "5.42.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.42.1.tgz", - "integrity": "sha512-Gxvf12xSp3iYZd/fLqiQRD4uKZjDNR01bQ+j8zvhPjpsZ4HmvEFL/tC4amGNyxN9Rq+iqvpHLhlqx6KTxz9ZyQ==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.42.1", - "@typescript-eslint/types": "5.42.1", - "@typescript-eslint/typescript-estree": "5.42.1", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0", - "semver": "^7.3.7" - }, - "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.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "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 - } - } - }, - "@typescript-eslint/visitor-keys": { - "version": "5.42.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.42.1.tgz", - "integrity": "sha512-LOQtSF4z+hejmpUvitPlc4hA7ERGoj2BVkesOcG91HCn8edLGUXbTrErmutmPbl8Bo9HjAvOO/zBKQHExXNA2A==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.42.1", - "eslint-visitor-keys": "^3.3.0" - } - }, - "@yarnpkg/lockfile": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", - "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", - "dev": true - }, - "abbrev": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", - "integrity": "sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q==", - "dev": true - }, - "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, - "requires": { - "event-target-shim": "^5.0.0" - } - }, - "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": { - "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" - } - }, - "acorn": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", - "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", - "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==", - "dev": true, - "requires": {} - }, - "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==", - "dev": true - }, - "address": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/address/-/address-1.2.1.tgz", - "integrity": "sha512-B+6bi5D34+fDYENiH5qOlA0cV2rAGKuWZ9LeyUUehbXy8e0VS9e498yO0Jeeh+iM+6KbfudHTFjXw2MmJD4QRA==", - "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 - }, - "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": { - "debug": "4" - } - }, - "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": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - } - }, - "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": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "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 - }, - "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": { - "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 - } - } - }, - "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": { - "color-convert": "^2.0.1" - } - }, - "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 - }, - "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "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/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "array-back": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz", - "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==", - "dev": true, - "requires": { - "typical": "^2.6.1" - } - }, - "array-find-index": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", - "integrity": "sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==", - "dev": true - }, - "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/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", - "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==", - "dev": 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" - } - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", - "dev": true - }, - "asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", - "dev": 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" - } - }, - "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 - }, - "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 - }, - "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-eventemitter": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/async-eventemitter/-/async-eventemitter-0.2.4.tgz", - "integrity": "sha512-pd20BwL7Yt1zwDFy+8MX8F1+WCT8aQeKj0kQnTrH9WaeRETlRamVhD0JtRPmrV4GfOJ2F9CvdQkZeZhnh2TuHw==", - "dev": true, - "requires": { - "async": "^2.4.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 - }, - "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.11.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", - "dev": true - }, - "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.1.7", - "resolved": "https://registry.npmjs.org/bigint-crypto-utils/-/bigint-crypto-utils-3.1.7.tgz", - "integrity": "sha512-zpCQpIE2Oy5WIQpjC9iYZf8Uh9QqoS51ZCooAcNvzv1AQ3VWdT52D0ksr1+/faeK8HVIej1bxXcP75YcqH3KPA==", - "dev": true, - "requires": { - "bigint-mod-arith": "^3.1.0" - } - }, - "bigint-mod-arith": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bigint-mod-arith/-/bigint-mod-arith-3.1.2.tgz", - "integrity": "sha512-nx8J8bBeiRR+NlsROFH9jHswW5HO8mgfOSqW0AmjicMMvaONDa8AO+5ViKDUUNytBPWiwfvZP4/Bj4Y3lUfvgQ==", - "dev": true - }, - "bignumber.js": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.0.tgz", - "integrity": "sha512-4LwHK4nfDOraBCtst+wOWIHbu1vhvAPJK8g8nROd4iuc3PSEjWif/qwbkh8jwCJz6yDBvtU4KPynETgrfh7y3A==", - "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 - }, - "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 - }, - "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" - } - }, - "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" - } - }, - "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" - } - }, - "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==", - "dev": true, - "requires": { - "streamsearch": "^1.1.0" - } - }, - "bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "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==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "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": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha512-FxAv7HpHrXbh3aPo4o2qxHay2lkLY3x5Mw3KeE4KQE8ysVfziWeRZDwcjauvwBSGEC/nXUPzZy8zeh4HokqOnw==", - "dev": true - }, - "camelcase-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz", - "integrity": "sha512-Ej37YKYbFUI8QiYlvj9YHb6/Z60dZyPJW0Cs8sFilMbd2lP0bw3ylAq9yJkK4lcTA2dID5fG8LjmJYbO7kWb7Q==", - "dev": true, - "requires": { - "camelcase": "^4.1.0", - "map-obj": "^2.0.0", - "quick-lru": "^1.0.0" - } - }, - "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": "5.2.0", - "resolved": "https://registry.npmjs.org/cbor/-/cbor-5.2.0.tgz", - "integrity": "sha512-5IMhi9e1QU76ppa5/ajP1BmMWZ2FHkhAhjeVKQ/EFCgYSEaeVaoGtL7cxJskf9oCCk+XjzaIdc3IuU/dbA/o2A==", - "dev": true, - "requires": { - "bignumber.js": "^9.0.1", - "nofilter": "^1.0.4" - } - }, - "chai": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.7.tgz", - "integrity": "sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==", - "dev": 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" - } - }, - "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 - }, - "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 - }, - "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" - } - } - } - }, - "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==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "classic-level": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/classic-level/-/classic-level-1.2.0.tgz", - "integrity": "sha512-qw5B31ANxSluWz9xBzklRWTUAJ1SXIdaVKTVS7HcTGKOAmExx65Wo5BUICW+YGORe2FOUaDghoI9ZDxj82QcFg==", - "dev": true, - "requires": { - "abstract-level": "^1.0.2", - "catering": "^2.1.0", - "module-error": "^1.0.1", - "napi-macros": "~2.0.0", - "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.5.1", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.5.1.tgz", - "integrity": "sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==", - "dev": true, - "requires": { - "colors": "^1.1.2", - "object-assign": "^4.1.0", - "string-width": "^2.1.1" - }, - "dependencies": { - "colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "dev": true, - "optional": true - } - } - }, - "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" - }, - "dependencies": { - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": 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" - } - } - } - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", - "dev": true - }, - "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": "4.0.7", - "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-4.0.7.tgz", - "integrity": "sha512-aUdPvQRAyBvQd2n7jXcsMDz68ckBJELXNzBybCHOibUWEg0mWTnaYCSRU8h9R+aNRSvDihJtssSRCiDRpLaezA==", - "dev": true, - "requires": { - "array-back": "^2.0.0", - "find-replace": "^1.0.3", - "typical": "^2.6.1" - } - }, - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", - "dev": true - }, - "compare-versions": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-5.0.1.tgz", - "integrity": "sha512-v8Au3l0b+Nwkp4G142JcgJFh1/TUhdxut7wzD1Nq1dyp5oa3tXaqb03EXOAB6jS4gMlalkjAUPZBMiAfKUixHQ==", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "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 - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "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 - }, - "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 - }, - "cosmiconfig": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", - "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", - "dev": true, - "requires": { - "import-fresh": "^2.0.0", - "is-directory": "^0.3.1", - "js-yaml": "^3.13.1", - "parse-json": "^4.0.0" - }, - "dependencies": { - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "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 - }, - "import-fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", - "integrity": "sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==", - "dev": true, - "requires": { - "caller-path": "^2.0.0", - "resolve-from": "^3.0.0" - } - }, - "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, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", - "dev": true - } - } - }, - "crc-32": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", - "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", - "dev": true - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "crypt": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", - "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", - "dev": true - }, - "currently-unhandled": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", - "integrity": "sha512-/fITjgjGU50vjQ4FH6eUoYu+iUoUKIXws2hL15JJpIR+BbTxaXQsMuuyjtNh2WqsSBS5nsaZHFsFecyw5CCAng==", - "dev": true, - "requires": { - "array-find-index": "^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, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "death": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/death/-/death-1.1.0.tgz", - "integrity": "sha512-vsV6S4KVHvTGxbEcij7hkWRv0It+sGGWVOM67dQde/o5Xjnr+KmLjxWJii2uEObIrt1CcM9w0Yaovx+iOlIL+w==", - "dev": true - }, - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "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 - }, - "decamelize-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", - "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", - "dev": true, - "requires": { - "decamelize": "^1.1.0", - "map-obj": "^1.0.0" - }, - "dependencies": { - "map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", - "dev": true - } - } - }, - "deep-eql": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.2.tgz", - "integrity": "sha512-gT18+YW4CcW/DBNTwAmqTtkJh7f9qqScu2qFVlx7kCoeY9tlBu9cUcr7+I+Z/noG8INehS3xQgLpTtd/QUTn4w==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, - "deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "define-properties": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", - "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", - "dev": true, - "requires": { - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true - }, - "depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "dev": true - }, - "detect-port": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.5.1.tgz", - "integrity": "sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ==", - "dev": true, - "requires": { - "address": "^1.0.1", - "debug": "4" - } - }, - "diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", - "dev": true - }, - "difflib": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/difflib/-/difflib-0.2.4.tgz", - "integrity": "sha512-9YVwmMb0wQHQNr5J9m6BSj6fk4pfGITGQOOs+D9Fl+INODWFOfvhIU1hNv6GgR1RBoC/9NJcwu77zShxV0kT7w==", - "dev": true, - "requires": { - "heap": ">= 0.2.0" - } - }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "requires": { - "path-type": "^4.0.0" - } - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "dotenv": { - "version": "16.0.3", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", - "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==", - "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, - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "dev": true, - "requires": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^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 - } - } - }, - "email-addresses": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/email-addresses/-/email-addresses-3.1.0.tgz", - "integrity": "sha512-k0/r7GrWVL32kZlGwfPNgB2Y/mMXVTq/decgLczm/j34whdaspNrZO8CnXPf1laaHxI6ptUlsnAxN+UAPw+fzg==", - "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.20.4", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.4.tgz", - "integrity": "sha512-0UtvRN79eMe2L+UNEF1BwRe364sj/DXhQ/k5FmivgoSdpM90b8Jc0mDzKMGo7QS0BVbOP/bTwBKNnDc9rNzaPA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.1.3", - "get-symbol-description": "^1.0.0", - "has": "^1.0.3", - "has-property-descriptors": "^1.0.0", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.3", - "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-weakref": "^1.0.2", - "object-inspect": "^1.12.2", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.4.3", - "safe-regex-test": "^1.0.0", - "string.prototype.trimend": "^1.0.5", - "string.prototype.trimstart": "^1.0.5", - "unbox-primitive": "^1.0.2" - }, - "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, - "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 - }, - "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" - } - }, - "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==", - "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, - "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 - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "dev": 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, - "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 - }, - "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, - "requires": { - "prelude-ls": "~1.1.2" - } - } - } - }, - "eslint": { - "version": "8.27.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.27.0.tgz", - "integrity": "sha512-0y1bfG2ho7mty+SiILVf9PfuRA49ek4Nc60Wmmu62QlobNR+CeXa4xXIJgcuwSQgZiWaPH+5BDsctpIW0PR/wQ==", - "dev": true, - "requires": { - "@eslint/eslintrc": "^1.3.3", - "@humanwhocodes/config-array": "^0.11.6", - "@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.1.1", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.4.0", - "esquery": "^1.4.0", - "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.15.0", - "grapheme-splitter": "^1.0.4", - "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-sdsl": "^4.1.4", - "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", - "regexpp": "^3.2.0", - "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0" - }, - "dependencies": { - "eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", - "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==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, - "eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^2.0.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true - } - } - }, - "eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", - "dev": true - }, - "espree": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", - "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", - "dev": true, - "requires": { - "acorn": "^8.8.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" - } - }, - "esprima": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha512-OarPfz0lFCiW4/AV2Oy1Rp9qu0iusTKqykwTspGCZtPxmF81JR4MmIebvF1F9+UOKth2ZubLQ4XGGaU+hSn99A==", - "dev": true - }, - "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", - "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 - }, - "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.25", - "resolved": "https://registry.npmjs.org/eth-gas-reporter/-/eth-gas-reporter-0.2.25.tgz", - "integrity": "sha512-1fRgyE4xUB8SoqLgN3eDfpDfwEfRxh2Sz1b7wzFbyQA+9TekMmvSjjoRu9SKcSVyK+vLkLIsVbJDsTWjw195OQ==", - "dev": 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 - }, - "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 - }, - "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" - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": 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 - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": 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, - "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, - "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, - "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" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.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 - }, - "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==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "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==", - "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 - }, - "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 - }, - "ethereum-cryptography": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.1.2.tgz", - "integrity": "sha512-XDSJlg4BD+hq9N2FjvotwUET9Tfxpxc3kWGE2AqUG5vcbeunnbImVk3cj6e/xT3phdW21mE8R5IugU4fspQDcQ==", - "dev": true, - "requires": { - "@noble/hashes": "1.1.2", - "@noble/secp256k1": "1.6.3", - "@scure/bip32": "1.1.0", - "@scure/bip39": "1.1.0" - } - }, - "ethers": { - "version": "4.0.49", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.49.tgz", - "integrity": "sha512-kPltTvWiyu+OktYy1IStSO16i2e7cS9D9OxZ81q2UUaiNPVrm/RTcbxamCXF9VUSKzJIdJV68EAIhTEVBalRWg==", - "dev": 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==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "flat": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz", - "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==", - "dev": true, - "requires": { - "is-buffer": "~2.0.3" - } - }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": 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==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "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 - }, - "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==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.0" - } - }, - "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 - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": 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, - "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, - "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, - "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==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "mocha": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", - "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", - "dev": 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" - } - }, - "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 - }, - "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, - "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==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "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 - }, - "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, - "requires": { - "picomatch": "^2.0.4" - } - }, - "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 - }, - "scrypt-js": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.4.tgz", - "integrity": "sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw==", - "dev": true - }, - "setimmediate": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz", - "integrity": "sha512-/TjEmXQVEzdod/FFskf3o7oOAsGhHf2j1dZqRFbDzq4F3mvvxflIIi4Hd3bLQE9y/CpwqfSQam5JakI/mi3Pog==", - "dev": 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, - "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, - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "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 - }, - "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, - "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 - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", - "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, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.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 - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": 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" - } - }, - "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, - "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==", - "dev": true, - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - } - } - } - }, - "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, - "requires": { - "js-sha3": "^0.8.0" - } - }, - "ethereum-checksum-address": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/ethereum-checksum-address/-/ethereum-checksum-address-0.0.2.tgz", - "integrity": "sha512-GAb7mPvGgcfi1j+Bsnwm9af9Z7dLUKp+5cFm88+kMrKACfh9gLatGLVVK5pSGEG2pOGfrmqCRcuh3RtMjIg8GQ==", - "dev": true, - "requires": { - "keccak256": "^1.0.0", - "meow": "^5.0.0" - } - }, - "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, - "requires": { - "@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" - } - }, - "ethereum-public-key-to-address": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/ethereum-public-key-to-address/-/ethereum-public-key-to-address-0.0.5.tgz", - "integrity": "sha512-j7k9dP49JuK50PtygiTfqjrZLsk0Hc3Vh5jjqCH8pl4mPfwcQwA9Ds+ie7BXr2JdpFDB3cYR8H/1Rwp0jU5Nxg==", - "dev": true, - "requires": { - "ethereum-checksum-address": "0.0.2", - "keccak": "^3.0.1", - "meow": "^5.0.0", - "secp256k1": "^4.0.2" - } - }, - "ethereum-waffle": { - "version": "3.4.4", - "resolved": "https://registry.npmjs.org/ethereum-waffle/-/ethereum-waffle-3.4.4.tgz", - "integrity": "sha512-PA9+jCjw4WC3Oc5ocSMBj5sXvueWQeAbvCA+hUlb6oFgwwKyq5ka3bWQ7QZcjzIX+TdFkxP4IbFmoY2D8Dkj9Q==", - "dev": true, - "requires": { - "@ethereum-waffle/chai": "^3.4.4", - "@ethereum-waffle/compiler": "^3.4.4", - "@ethereum-waffle/mock-contract": "^3.4.4", - "@ethereum-waffle/provider": "^3.4.4", - "ethers": "^5.0.1" - } - }, - "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, - "requires": { - "bn.js": "^4.11.8", - "ethereumjs-util": "^6.0.0" - }, - "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 - }, - "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, - "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" - } - } - } - }, - "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, - "requires": { - "@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" - } - }, - "ethers": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", - "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", - "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/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" - } - }, - "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, - "requires": { - "bn.js": "4.11.6", - "number-to-bn": "1.7.0" - }, - "dependencies": { - "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 - } - } - }, - "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, - "requires": { - "is-hex-prefixed": "1.0.0", - "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==", - "dev": true - }, - "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, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "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, - "requires": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - } - }, - "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 - }, - "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 - }, - "fast-diff": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", - "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", - "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==", - "dev": true, - "requires": { - "@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" - }, - "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" - } - } - } - }, - "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 - }, - "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 - }, - "fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", - "dev": true, - "requires": { - "reusify": "^1.0.4" - } - }, - "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - }, - "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 - } - } - }, - "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, - "requires": { - "flat-cache": "^3.0.4" - } - }, - "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 - }, - "filenamify": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.3.0.tgz", - "integrity": "sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==", - "dev": true, - "requires": { - "filename-reserved-regex": "^2.0.0", - "strip-outer": "^1.0.1", - "trim-repeated": "^1.0.0" - } - }, - "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, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "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, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" - } - }, - "find-replace": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-1.0.3.tgz", - "integrity": "sha512-KrUnjzDCD9426YnCP56zGYy/eieTnhtK6Vn++j+JJzmlsWWwEkDnsyVF575spT6HJ6Ow9tlbT3TQTDsa+O4UWA==", - "dev": true, - "requires": { - "array-back": "^1.0.4", - "test-value": "^2.1.0" - }, - "dependencies": { - "array-back": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", - "integrity": "sha512-1WxbZvrmyhkNoeYcizokbmh5oiOCIfyvGtcqbK3Ls1v1fKcquzxnQSceOx6tzq7jmai2kFLWIpGND2cLhH6TPw==", - "dev": true, - "requires": { - "typical": "^2.6.0" - } - } - } - }, - "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, - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "find-yarn-workspace-root": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz", - "integrity": "sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==", - "dev": true, - "requires": { - "micromatch": "^4.0.2" - } - }, - "flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true - }, - "flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "requires": { - "flatted": "^3.1.0", - "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==", - "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==", - "dev": true - }, - "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 - }, - "form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - }, - "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 - }, - "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, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "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 - }, - "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 - }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "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==", - "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==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0", - "functions-have-names": "^1.2.2" - } - }, - "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 - }, - "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 - }, - "ganache-core": { - "version": "2.13.2", - "resolved": "https://registry.npmjs.org/ganache-core/-/ganache-core-2.13.2.tgz", - "integrity": "sha512-tIF5cR+ANQz0+3pHWxHjIwHqFXcVo0Mb+kcsNhglNFALcYo49aQpnS9dqHartqPfMFjiHh/qFoD3mYK0d/qGgw==", - "dev": true, - "requires": { - "abstract-leveldown": "3.0.0", - "async": "2.6.2", - "bip39": "2.5.0", - "cachedown": "1.0.0", - "clone": "2.1.2", - "debug": "3.2.6", - "encoding-down": "5.0.4", - "eth-sig-util": "3.0.0", - "ethereumjs-abi": "0.6.8", - "ethereumjs-account": "3.0.0", - "ethereumjs-block": "2.2.2", - "ethereumjs-common": "1.5.0", - "ethereumjs-tx": "2.1.2", - "ethereumjs-util": "6.2.1", - "ethereumjs-vm": "4.2.0", - "ethereumjs-wallet": "0.6.5", - "heap": "0.2.6", - "keccak": "3.0.1", - "level-sublevel": "6.6.4", - "levelup": "3.1.1", - "lodash": "4.17.20", - "lru-cache": "5.1.1", - "merkle-patricia-tree": "3.0.0", - "patch-package": "6.2.2", - "seedrandom": "3.0.1", - "source-map-support": "0.5.12", - "tmp": "0.1.0", - "web3": "1.2.11", - "web3-provider-engine": "14.2.1", - "websocket": "1.0.32" - }, - "dependencies": { - "@ethersproject/abi": { - "version": "5.0.0-beta.153", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/address": ">=5.0.0-beta.128", - "@ethersproject/bignumber": ">=5.0.0-beta.130", - "@ethersproject/bytes": ">=5.0.0-beta.129", - "@ethersproject/constants": ">=5.0.0-beta.128", - "@ethersproject/hash": ">=5.0.0-beta.128", - "@ethersproject/keccak256": ">=5.0.0-beta.127", - "@ethersproject/logger": ">=5.0.0-beta.129", - "@ethersproject/properties": ">=5.0.0-beta.131", - "@ethersproject/strings": ">=5.0.0-beta.130" - } - }, - "@ethersproject/abstract-provider": { - "version": "5.0.8", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/bignumber": "^5.0.13", - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/logger": "^5.0.8", - "@ethersproject/networks": "^5.0.7", - "@ethersproject/properties": "^5.0.7", - "@ethersproject/transactions": "^5.0.9", - "@ethersproject/web": "^5.0.12" - } - }, - "@ethersproject/abstract-signer": { - "version": "5.0.10", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/abstract-provider": "^5.0.8", - "@ethersproject/bignumber": "^5.0.13", - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/logger": "^5.0.8", - "@ethersproject/properties": "^5.0.7" - } - }, - "@ethersproject/address": { - "version": "5.0.9", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/bignumber": "^5.0.13", - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/keccak256": "^5.0.7", - "@ethersproject/logger": "^5.0.8", - "@ethersproject/rlp": "^5.0.7" - } - }, - "@ethersproject/base64": { - "version": "5.0.7", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/bytes": "^5.0.9" - } - }, - "@ethersproject/bignumber": { - "version": "5.0.13", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/logger": "^5.0.8", - "bn.js": "^4.4.0" - } - }, - "@ethersproject/bytes": { - "version": "5.0.9", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/logger": "^5.0.8" - } - }, - "@ethersproject/constants": { - "version": "5.0.8", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/bignumber": "^5.0.13" - } - }, - "@ethersproject/hash": { - "version": "5.0.10", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/abstract-signer": "^5.0.10", - "@ethersproject/address": "^5.0.9", - "@ethersproject/bignumber": "^5.0.13", - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/keccak256": "^5.0.7", - "@ethersproject/logger": "^5.0.8", - "@ethersproject/properties": "^5.0.7", - "@ethersproject/strings": "^5.0.8" - } - }, - "@ethersproject/keccak256": { - "version": "5.0.7", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/bytes": "^5.0.9", - "js-sha3": "0.5.7" - } - }, - "@ethersproject/logger": { - "version": "5.0.8", - "dev": true, - "optional": true - }, - "@ethersproject/networks": { - "version": "5.0.7", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/logger": "^5.0.8" - } - }, - "@ethersproject/properties": { - "version": "5.0.7", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/logger": "^5.0.8" - } - }, - "@ethersproject/rlp": { - "version": "5.0.7", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/logger": "^5.0.8" - } - }, - "@ethersproject/signing-key": { - "version": "5.0.8", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/logger": "^5.0.8", - "@ethersproject/properties": "^5.0.7", - "elliptic": "6.5.3" - } - }, - "@ethersproject/strings": { - "version": "5.0.8", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/constants": "^5.0.8", - "@ethersproject/logger": "^5.0.8" - } - }, - "@ethersproject/transactions": { - "version": "5.0.9", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/address": "^5.0.9", - "@ethersproject/bignumber": "^5.0.13", - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/constants": "^5.0.8", - "@ethersproject/keccak256": "^5.0.7", - "@ethersproject/logger": "^5.0.8", - "@ethersproject/properties": "^5.0.7", - "@ethersproject/rlp": "^5.0.7", - "@ethersproject/signing-key": "^5.0.8" - } - }, - "@ethersproject/web": { - "version": "5.0.12", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/base64": "^5.0.7", - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/logger": "^5.0.8", - "@ethersproject/properties": "^5.0.7", - "@ethersproject/strings": "^5.0.8" - } - }, - "@sindresorhus/is": { - "version": "0.14.0", - "dev": true, - "optional": true - }, - "@szmarczak/http-timer": { - "version": "1.1.2", - "dev": true, - "optional": true, - "requires": { - "defer-to-connect": "^1.0.1" - } - }, - "@types/bn.js": { - "version": "4.11.6", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/node": { - "version": "14.14.20", - "dev": true - }, - "@types/pbkdf2": { - "version": "3.1.0", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/secp256k1": { - "version": "4.0.1", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@yarnpkg/lockfile": { - "version": "1.1.0", - "dev": true - }, - "abstract-leveldown": { - "version": "3.0.0", - "dev": true, - "requires": { - "xtend": "~4.0.0" - } - }, - "accepts": { - "version": "1.3.7", - "dev": true, - "optional": true, - "requires": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" - } - }, - "aes-js": { - "version": "3.1.2", - "dev": true, - "optional": true - }, - "ajv": { - "version": "6.12.6", - "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" - } - }, - "ansi-styles": { - "version": "3.2.1", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "arr-diff": { - "version": "4.0.0", - "dev": true - }, - "arr-flatten": { - "version": "1.1.0", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "dev": true - }, - "array-flatten": { - "version": "1.1.1", - "dev": true, - "optional": true - }, - "array-unique": { - "version": "0.3.2", - "dev": true - }, - "asn1": { - "version": "0.2.4", - "dev": true, - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "asn1.js": { - "version": "5.4.1", - "dev": true, - "optional": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "safer-buffer": "^2.1.0" - } - }, - "assert-plus": { - "version": "1.0.0", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "dev": true - }, - "async": { - "version": "2.6.2", - "dev": true, - "requires": { - "lodash": "^4.17.11" - } - }, - "async-eventemitter": { - "version": "0.2.4", - "dev": true, - "requires": { - "async": "^2.4.0" - } - }, - "async-limiter": { - "version": "1.0.1", - "dev": true - }, - "asynckit": { - "version": "0.4.0", - "dev": true - }, - "atob": { - "version": "2.1.2", - "dev": true - }, - "aws-sign2": { - "version": "0.7.0", - "dev": true - }, - "aws4": { - "version": "1.11.0", - "dev": true - }, - "babel-code-frame": { - "version": "6.26.0", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "js-tokens": { - "version": "3.0.2", - "dev": true - }, - "strip-ansi": { - "version": "3.0.1", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "dev": true - } - } - }, - "babel-core": { - "version": "6.26.3", - "dev": true, - "requires": { - "babel-code-frame": "^6.26.0", - "babel-generator": "^6.26.0", - "babel-helpers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-register": "^6.26.0", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "convert-source-map": "^1.5.1", - "debug": "^2.6.9", - "json5": "^0.5.1", - "lodash": "^4.17.4", - "minimatch": "^3.0.4", - "path-is-absolute": "^1.0.1", - "private": "^0.1.8", - "slash": "^1.0.0", - "source-map": "^0.5.7" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "json5": { - "version": "0.5.1", - "dev": true - }, - "ms": { - "version": "2.0.0", - "dev": true - }, - "slash": { - "version": "1.0.0", - "dev": true - } - } - }, - "babel-generator": { - "version": "6.26.1", - "dev": true, - "requires": { - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "detect-indent": "^4.0.0", - "jsesc": "^1.3.0", - "lodash": "^4.17.4", - "source-map": "^0.5.7", - "trim-right": "^1.0.1" - }, - "dependencies": { - "jsesc": { - "version": "1.3.0", - "dev": true - } - } - }, - "babel-helper-builder-binary-assignment-operator-visitor": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-helper-explode-assignable-expression": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-helper-call-delegate": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helper-define-map": { - "version": "6.26.0", - "dev": true, - "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" - } - }, - "babel-helper-explode-assignable-expression": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helper-function-name": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helper-get-function-arity": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-helper-hoist-variables": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-helper-optimise-call-expression": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-helper-regex": { - "version": "6.26.0", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" - } - }, - "babel-helper-remap-async-to-generator": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helper-replace-supers": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-helper-optimise-call-expression": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helpers": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-messages": { - "version": "6.23.0", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-check-es2015-constants": { - "version": "6.22.0", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-syntax-async-functions": { - "version": "6.13.0", - "dev": true - }, - "babel-plugin-syntax-exponentiation-operator": { - "version": "6.13.0", - "dev": true - }, - "babel-plugin-syntax-trailing-function-commas": { - "version": "6.22.0", - "dev": true - }, - "babel-plugin-transform-async-to-generator": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-helper-remap-async-to-generator": "^6.24.1", - "babel-plugin-syntax-async-functions": "^6.8.0", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-arrow-functions": { - "version": "6.22.0", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-block-scoped-functions": { - "version": "6.22.0", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-block-scoping": { - "version": "6.26.0", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" - } - }, - "babel-plugin-transform-es2015-classes": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-helper-define-map": "^6.24.1", - "babel-helper-function-name": "^6.24.1", - "babel-helper-optimise-call-expression": "^6.24.1", - "babel-helper-replace-supers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-computed-properties": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-destructuring": { - "version": "6.23.0", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-duplicate-keys": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-for-of": { - "version": "6.23.0", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-function-name": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-literals": { - "version": "6.22.0", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-modules-amd": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-modules-commonjs": { - "version": "6.26.2", - "dev": true, - "requires": { - "babel-plugin-transform-strict-mode": "^6.24.1", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-types": "^6.26.0" - } - }, - "babel-plugin-transform-es2015-modules-systemjs": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-modules-umd": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-plugin-transform-es2015-modules-amd": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-object-super": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-helper-replace-supers": "^6.24.1", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-parameters": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-helper-call-delegate": "^6.24.1", - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-shorthand-properties": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-spread": { - "version": "6.22.0", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-sticky-regex": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-template-literals": { - "version": "6.22.0", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-typeof-symbol": { - "version": "6.23.0", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-unicode-regex": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "regexpu-core": "^2.0.0" - } - }, - "babel-plugin-transform-exponentiation-operator": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1", - "babel-plugin-syntax-exponentiation-operator": "^6.8.0", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-regenerator": { - "version": "6.26.0", - "dev": true, - "requires": { - "regenerator-transform": "^0.10.0" - } - }, - "babel-plugin-transform-strict-mode": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-preset-env": { - "version": "1.7.0", - "dev": true, - "requires": { - "babel-plugin-check-es2015-constants": "^6.22.0", - "babel-plugin-syntax-trailing-function-commas": "^6.22.0", - "babel-plugin-transform-async-to-generator": "^6.22.0", - "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoping": "^6.23.0", - "babel-plugin-transform-es2015-classes": "^6.23.0", - "babel-plugin-transform-es2015-computed-properties": "^6.22.0", - "babel-plugin-transform-es2015-destructuring": "^6.23.0", - "babel-plugin-transform-es2015-duplicate-keys": "^6.22.0", - "babel-plugin-transform-es2015-for-of": "^6.23.0", - "babel-plugin-transform-es2015-function-name": "^6.22.0", - "babel-plugin-transform-es2015-literals": "^6.22.0", - "babel-plugin-transform-es2015-modules-amd": "^6.22.0", - "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0", - "babel-plugin-transform-es2015-modules-systemjs": "^6.23.0", - "babel-plugin-transform-es2015-modules-umd": "^6.23.0", - "babel-plugin-transform-es2015-object-super": "^6.22.0", - "babel-plugin-transform-es2015-parameters": "^6.23.0", - "babel-plugin-transform-es2015-shorthand-properties": "^6.22.0", - "babel-plugin-transform-es2015-spread": "^6.22.0", - "babel-plugin-transform-es2015-sticky-regex": "^6.22.0", - "babel-plugin-transform-es2015-template-literals": "^6.22.0", - "babel-plugin-transform-es2015-typeof-symbol": "^6.23.0", - "babel-plugin-transform-es2015-unicode-regex": "^6.22.0", - "babel-plugin-transform-exponentiation-operator": "^6.22.0", - "babel-plugin-transform-regenerator": "^6.22.0", - "browserslist": "^3.2.6", - "invariant": "^2.2.2", - "semver": "^5.3.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "dev": true - } - } - }, - "babel-register": { - "version": "6.26.0", - "dev": true, - "requires": { - "babel-core": "^6.26.0", - "babel-runtime": "^6.26.0", - "core-js": "^2.5.0", - "home-or-tmp": "^2.0.0", - "lodash": "^4.17.4", - "mkdirp": "^0.5.1", - "source-map-support": "^0.4.15" - }, - "dependencies": { - "source-map-support": { - "version": "0.4.18", - "dev": true, - "requires": { - "source-map": "^0.5.6" - } - } - } - }, - "babel-runtime": { - "version": "6.26.0", - "dev": true, - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "babel-template": { - "version": "6.26.0", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "lodash": "^4.17.4" - } - }, - "babel-traverse": { - "version": "6.26.0", - "dev": true, - "requires": { - "babel-code-frame": "^6.26.0", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "debug": "^2.6.8", - "globals": "^9.18.0", - "invariant": "^2.2.2", - "lodash": "^4.17.4" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "globals": { - "version": "9.18.0", - "dev": true - }, - "ms": { - "version": "2.0.0", - "dev": true - } - } - }, - "babel-types": { - "version": "6.26.0", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "esutils": "^2.0.2", - "lodash": "^4.17.4", - "to-fast-properties": "^1.0.3" - }, - "dependencies": { - "to-fast-properties": { - "version": "1.0.3", - "dev": true - } - } - }, - "babelify": { - "version": "7.3.0", - "dev": true, - "requires": { - "babel-core": "^6.0.14", - "object-assign": "^4.0.0" - } - }, - "babylon": { - "version": "6.18.0", - "dev": true - }, - "backoff": { - "version": "2.5.0", - "dev": true, - "requires": { - "precond": "0.2" - } - }, - "balanced-match": { - "version": "1.0.0", - "dev": true - }, - "base": { - "version": "0.11.2", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - } - } - }, - "base-x": { - "version": "3.0.8", - "dev": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "base64-js": { - "version": "1.5.1", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "dev": true, - "requires": { - "tweetnacl": "^0.14.3" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "dev": true - } - } - }, - "bignumber.js": { - "version": "9.0.1", - "dev": true, - "optional": true - }, - "bip39": { - "version": "2.5.0", - "dev": true, - "requires": { - "create-hash": "^1.1.0", - "pbkdf2": "^3.0.9", - "randombytes": "^2.0.1", - "safe-buffer": "^5.0.1", - "unorm": "^1.3.3" - } - }, - "blakejs": { - "version": "1.1.0", - "dev": true - }, - "bluebird": { - "version": "3.7.2", - "dev": true, - "optional": true - }, - "bn.js": { - "version": "4.11.9", - "dev": true - }, - "body-parser": { - "version": "1.19.0", - "dev": true, - "optional": true, - "requires": { - "bytes": "3.1.0", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "dev": true, - "optional": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "dev": true, - "optional": true - }, - "qs": { - "version": "6.7.0", - "dev": true, - "optional": true - } - } - }, - "brace-expansion": { - "version": "1.1.11", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "brorand": { - "version": "1.1.0", - "dev": true - }, - "browserify-aes": { - "version": "1.2.0", - "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", - "dev": true, - "optional": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "dev": true, - "optional": 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", - "dev": true, - "optional": true, - "requires": { - "bn.js": "^5.0.0", - "randombytes": "^2.0.1" - }, - "dependencies": { - "bn.js": { - "version": "5.1.3", - "dev": true, - "optional": true - } - } - }, - "browserify-sign": { - "version": "4.2.1", - "dev": true, - "optional": true, - "requires": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.3", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "bn.js": { - "version": "5.1.3", - "dev": true, - "optional": true - }, - "readable-stream": { - "version": "3.6.0", - "dev": true, - "optional": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "browserslist": { - "version": "3.2.8", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30000844", - "electron-to-chromium": "^1.3.47" - } - }, - "bs58": { - "version": "4.0.1", - "dev": true, - "requires": { - "base-x": "^3.0.2" - } - }, - "bs58check": { - "version": "2.1.2", - "dev": true, - "requires": { - "bs58": "^4.0.0", - "create-hash": "^1.1.0", - "safe-buffer": "^5.1.2" - } - }, - "buffer": { - "version": "5.7.1", - "dev": true, - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "buffer-from": { - "version": "1.1.1", - "dev": true - }, - "buffer-to-arraybuffer": { - "version": "0.0.5", - "dev": true, - "optional": true - }, - "buffer-xor": { - "version": "1.0.3", - "dev": true - }, - "bufferutil": { - "version": "4.0.3", - "dev": true, - "requires": { - "node-gyp-build": "^4.2.0" - } - }, - "bytes": { - "version": "3.1.0", - "dev": true, - "optional": true - }, - "bytewise": { - "version": "1.1.0", - "dev": true, - "requires": { - "bytewise-core": "^1.2.2", - "typewise": "^1.0.3" - } - }, - "bytewise-core": { - "version": "1.2.3", - "dev": true, - "requires": { - "typewise-core": "^1.2" - } - }, - "cache-base": { - "version": "1.0.1", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - } - }, - "cacheable-request": { - "version": "6.1.0", - "dev": true, - "optional": 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": { - "lowercase-keys": { - "version": "2.0.0", - "dev": true, - "optional": true - } - } - }, - "cachedown": { - "version": "1.0.0", - "dev": true, - "requires": { - "abstract-leveldown": "^2.4.1", - "lru-cache": "^3.2.0" - }, - "dependencies": { - "abstract-leveldown": { - "version": "2.7.2", - "dev": true, - "requires": { - "xtend": "~4.0.0" - } - }, - "lru-cache": { - "version": "3.2.0", - "dev": true, - "requires": { - "pseudomap": "^1.0.1" - } - } - } - }, - "call-bind": { - "version": "1.0.2", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "caniuse-lite": { - "version": "1.0.30001174", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "dev": true - }, - "chalk": { - "version": "2.4.2", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "checkpoint-store": { - "version": "1.1.0", - "dev": true, - "requires": { - "functional-red-black-tree": "^1.0.1" - } - }, - "chownr": { - "version": "1.1.4", - "dev": true, - "optional": true - }, - "ci-info": { - "version": "2.0.0", - "dev": true - }, - "cids": { - "version": "0.7.5", - "dev": true, - "optional": true, - "requires": { - "buffer": "^5.5.0", - "class-is": "^1.1.0", - "multibase": "~0.6.0", - "multicodec": "^1.0.0", - "multihashes": "~0.4.15" - }, - "dependencies": { - "multicodec": { - "version": "1.0.4", - "dev": true, - "optional": true, - "requires": { - "buffer": "^5.6.0", - "varint": "^5.0.0" - } - } - } - }, - "cipher-base": { - "version": "1.0.4", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "class-is": { - "version": "1.1.0", - "dev": true, - "optional": true - }, - "class-utils": { - "version": "0.3.6", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-buffer": { - "version": "1.1.6", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "dev": true - } - } - }, - "clone": { - "version": "2.1.2", - "dev": true - }, - "clone-response": { - "version": "1.0.2", - "dev": true, - "optional": true, - "requires": { - "mimic-response": "^1.0.0" - } - }, - "collection-visit": { - "version": "1.0.0", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color-convert": { - "version": "1.9.3", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "dev": true, - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "component-emitter": { - "version": "1.3.0", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "dev": true - }, - "concat-stream": { - "version": "1.6.2", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "content-disposition": { - "version": "0.5.3", - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "5.1.2" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "dev": true, - "optional": true - } - } - }, - "content-hash": { - "version": "2.5.2", - "dev": true, - "optional": true, - "requires": { - "cids": "^0.7.1", - "multicodec": "^0.5.5", - "multihashes": "^0.4.15" - } - }, - "content-type": { - "version": "1.0.4", - "dev": true, - "optional": true - }, - "convert-source-map": { - "version": "1.7.0", - "dev": true, - "requires": { - "safe-buffer": "~5.1.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "dev": true - } - } - }, - "cookie": { - "version": "0.4.0", - "dev": true, - "optional": true - }, - "cookie-signature": { - "version": "1.0.6", - "dev": true, - "optional": true - }, - "cookiejar": { - "version": "2.1.2", - "dev": true, - "optional": true - }, - "copy-descriptor": { - "version": "0.1.1", - "dev": true - }, - "core-js": { - "version": "2.6.12", - "dev": true - }, - "core-js-pure": { - "version": "3.8.2", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "dev": true - }, - "cors": { - "version": "2.8.5", - "dev": true, - "optional": true, - "requires": { - "object-assign": "^4", - "vary": "^1" - } - }, - "create-ecdh": { - "version": "4.0.4", - "dev": true, - "optional": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" - } - }, - "create-hash": { - "version": "1.2.0", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "cross-fetch": { - "version": "2.2.3", - "dev": true, - "requires": { - "node-fetch": "2.1.2", - "whatwg-fetch": "2.0.4" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "dev": true, - "optional": 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", - "dev": true, - "requires": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" - } - }, - "dashdash": { - "version": "1.14.1", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "debug": { - "version": "3.2.6", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "decode-uri-component": { - "version": "0.2.0", - "dev": true - }, - "decompress-response": { - "version": "3.3.0", - "dev": true, - "optional": true, - "requires": { - "mimic-response": "^1.0.0" - } - }, - "deep-equal": { - "version": "1.1.1", - "dev": true, - "requires": { - "is-arguments": "^1.0.4", - "is-date-object": "^1.0.1", - "is-regex": "^1.0.4", - "object-is": "^1.0.1", - "object-keys": "^1.1.1", - "regexp.prototype.flags": "^1.2.0" - } - }, - "defer-to-connect": { - "version": "1.1.3", - "dev": true, - "optional": true - }, - "deferred-leveldown": { - "version": "4.0.2", - "dev": true, - "requires": { - "abstract-leveldown": "~5.0.0", - "inherits": "^2.0.3" - }, - "dependencies": { - "abstract-leveldown": { - "version": "5.0.0", - "dev": true, - "requires": { - "xtend": "~4.0.0" - } - } - } - }, - "define-properties": { - "version": "1.1.3", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "define-property": { - "version": "2.0.2", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - } - }, - "defined": { - "version": "1.0.0", - "dev": true - }, - "delayed-stream": { - "version": "1.0.0", - "dev": true - }, - "depd": { - "version": "1.1.2", - "dev": true, - "optional": true - }, - "des.js": { - "version": "1.0.1", - "dev": true, - "optional": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "destroy": { - "version": "1.0.4", - "dev": true, - "optional": true - }, - "detect-indent": { - "version": "4.0.0", - "dev": true, - "requires": { - "repeating": "^2.0.0" - } - }, - "diffie-hellman": { - "version": "5.0.3", - "dev": true, - "optional": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - } - }, - "dom-walk": { - "version": "0.1.2", - "dev": true - }, - "dotignore": { - "version": "0.1.2", - "dev": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "duplexer3": { - "version": "0.1.4", - "dev": true, - "optional": true - }, - "ecc-jsbn": { - "version": "0.1.2", - "dev": true, - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ee-first": { - "version": "1.1.1", - "dev": true, - "optional": true - }, - "electron-to-chromium": { - "version": "1.3.636", - "dev": true - }, - "elliptic": { - "version": "6.5.3", - "dev": true, - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.0" - } - }, - "encodeurl": { - "version": "1.0.2", - "dev": true, - "optional": true - }, - "encoding": { - "version": "0.1.13", - "dev": true, - "requires": { - "iconv-lite": "^0.6.2" - }, - "dependencies": { - "iconv-lite": { - "version": "0.6.2", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - } - } - } - }, - "encoding-down": { - "version": "5.0.4", - "dev": true, - "requires": { - "abstract-leveldown": "^5.0.0", - "inherits": "^2.0.3", - "level-codec": "^9.0.0", - "level-errors": "^2.0.0", - "xtend": "^4.0.1" - }, - "dependencies": { - "abstract-leveldown": { - "version": "5.0.0", - "dev": true, - "requires": { - "xtend": "~4.0.0" - } - } - } - }, - "end-of-stream": { - "version": "1.4.4", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "errno": { - "version": "0.1.8", - "dev": true, - "requires": { - "prr": "~1.0.1" - } - }, - "es-abstract": { - "version": "1.18.0-next.1", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.2", - "is-negative-zero": "^2.0.0", - "is-regex": "^1.1.1", - "object-inspect": "^1.8.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.1", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es5-ext": { - "version": "0.10.53", - "dev": true, - "requires": { - "es6-iterator": "~2.0.3", - "es6-symbol": "~3.1.3", - "next-tick": "~1.0.0" - } - }, - "es6-iterator": { - "version": "2.0.3", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "es6-symbol": { - "version": "3.1.3", - "dev": true, - "requires": { - "d": "^1.0.1", - "ext": "^1.1.2" - } - }, - "escape-html": { - "version": "1.0.3", - "dev": true, - "optional": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "dev": true - }, - "etag": { - "version": "1.8.1", - "dev": true, - "optional": true - }, - "eth-block-tracker": { - "version": "3.0.1", - "dev": true, - "requires": { - "eth-query": "^2.1.0", - "ethereumjs-tx": "^1.3.3", - "ethereumjs-util": "^5.1.3", - "ethjs-util": "^0.1.3", - "json-rpc-engine": "^3.6.0", - "pify": "^2.3.0", - "tape": "^4.6.3" - }, - "dependencies": { - "ethereumjs-tx": { - "version": "1.3.7", - "dev": true, - "requires": { - "ethereum-common": "^0.0.18", - "ethereumjs-util": "^5.0.0" - } - }, - "ethereumjs-util": { - "version": "5.2.1", - "dev": true, - "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - }, - "pify": { - "version": "2.3.0", - "dev": true - } - } - }, - "eth-ens-namehash": { - "version": "2.0.8", - "dev": true, - "optional": true, - "requires": { - "idna-uts46-hx": "^2.3.1", - "js-sha3": "^0.5.7" - } - }, - "eth-json-rpc-infura": { - "version": "3.2.1", - "dev": true, - "requires": { - "cross-fetch": "^2.1.1", - "eth-json-rpc-middleware": "^1.5.0", - "json-rpc-engine": "^3.4.0", - "json-rpc-error": "^2.0.0" - } - }, - "eth-json-rpc-middleware": { - "version": "1.6.0", - "dev": true, - "requires": { - "async": "^2.5.0", - "eth-query": "^2.1.2", - "eth-tx-summary": "^3.1.2", - "ethereumjs-block": "^1.6.0", - "ethereumjs-tx": "^1.3.3", - "ethereumjs-util": "^5.1.2", - "ethereumjs-vm": "^2.1.0", - "fetch-ponyfill": "^4.0.0", - "json-rpc-engine": "^3.6.0", - "json-rpc-error": "^2.0.0", - "json-stable-stringify": "^1.0.1", - "promise-to-callback": "^1.0.0", - "tape": "^4.6.3" - }, - "dependencies": { - "abstract-leveldown": { - "version": "2.6.3", - "dev": true, - "requires": { - "xtend": "~4.0.0" - } - }, - "deferred-leveldown": { - "version": "1.2.2", - "dev": true, - "requires": { - "abstract-leveldown": "~2.6.0" - } - }, - "ethereumjs-account": { - "version": "2.0.5", - "dev": true, - "requires": { - "ethereumjs-util": "^5.0.0", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - }, - "ethereumjs-block": { - "version": "1.7.1", - "dev": true, - "requires": { - "async": "^2.0.1", - "ethereum-common": "0.2.0", - "ethereumjs-tx": "^1.2.2", - "ethereumjs-util": "^5.0.0", - "merkle-patricia-tree": "^2.1.2" - }, - "dependencies": { - "ethereum-common": { - "version": "0.2.0", - "dev": true - } - } - }, - "ethereumjs-tx": { - "version": "1.3.7", - "dev": true, - "requires": { - "ethereum-common": "^0.0.18", - "ethereumjs-util": "^5.0.0" - } - }, - "ethereumjs-util": { - "version": "5.2.1", - "dev": true, - "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - }, - "ethereumjs-vm": { - "version": "2.6.0", - "dev": true, - "requires": { - "async": "^2.1.2", - "async-eventemitter": "^0.2.2", - "ethereumjs-account": "^2.0.3", - "ethereumjs-block": "~2.2.0", - "ethereumjs-common": "^1.1.0", - "ethereumjs-util": "^6.0.0", - "fake-merkle-patricia-tree": "^1.0.1", - "functional-red-black-tree": "^1.0.1", - "merkle-patricia-tree": "^2.3.2", - "rustbn.js": "~0.2.0", - "safe-buffer": "^5.1.1" - }, - "dependencies": { - "ethereumjs-block": { - "version": "2.2.2", - "dev": true, - "requires": { - "async": "^2.0.1", - "ethereumjs-common": "^1.5.0", - "ethereumjs-tx": "^2.1.1", - "ethereumjs-util": "^5.0.0", - "merkle-patricia-tree": "^2.1.2" - }, - "dependencies": { - "ethereumjs-util": { - "version": "5.2.1", - "dev": true, - "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - } - } - }, - "ethereumjs-tx": { - "version": "2.1.2", - "dev": true, - "requires": { - "ethereumjs-common": "^1.5.0", - "ethereumjs-util": "^6.0.0" - } - }, - "ethereumjs-util": { - "version": "6.2.1", - "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" - } - } - } - }, - "isarray": { - "version": "0.0.1", - "dev": true - }, - "level-codec": { - "version": "7.0.1", - "dev": true - }, - "level-errors": { - "version": "1.0.5", - "dev": true, - "requires": { - "errno": "~0.1.1" - } - }, - "level-iterator-stream": { - "version": "1.3.1", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "level-errors": "^1.0.3", - "readable-stream": "^1.0.33", - "xtend": "^4.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "1.1.14", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - } - } - }, - "level-ws": { - "version": "0.0.0", - "dev": true, - "requires": { - "readable-stream": "~1.0.15", - "xtend": "~2.1.1" - }, - "dependencies": { - "readable-stream": { - "version": "1.0.34", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "xtend": { - "version": "2.1.2", - "dev": true, - "requires": { - "object-keys": "~0.4.0" - } - } - } - }, - "levelup": { - "version": "1.3.9", - "dev": true, - "requires": { - "deferred-leveldown": "~1.2.1", - "level-codec": "~7.0.0", - "level-errors": "~1.0.3", - "level-iterator-stream": "~1.3.0", - "prr": "~1.0.1", - "semver": "~5.4.1", - "xtend": "~4.0.0" - } - }, - "ltgt": { - "version": "2.2.1", - "dev": true - }, - "memdown": { - "version": "1.4.1", - "dev": true, - "requires": { - "abstract-leveldown": "~2.7.1", - "functional-red-black-tree": "^1.0.1", - "immediate": "^3.2.3", - "inherits": "~2.0.1", - "ltgt": "~2.2.0", - "safe-buffer": "~5.1.1" - }, - "dependencies": { - "abstract-leveldown": { - "version": "2.7.2", - "dev": true, - "requires": { - "xtend": "~4.0.0" - } - } - } - }, - "merkle-patricia-tree": { - "version": "2.3.2", - "dev": true, - "requires": { - "async": "^1.4.2", - "ethereumjs-util": "^5.0.0", - "level-ws": "0.0.0", - "levelup": "^1.2.1", - "memdown": "^1.0.0", - "readable-stream": "^2.0.0", - "rlp": "^2.0.0", - "semaphore": ">=1.0.1" - }, - "dependencies": { - "async": { - "version": "1.5.2", - "dev": true - } - } - }, - "object-keys": { - "version": "0.4.0", - "dev": true - }, - "safe-buffer": { - "version": "5.1.2", - "dev": true - }, - "semver": { - "version": "5.4.1", - "dev": true - }, - "string_decoder": { - "version": "0.10.31", - "dev": true - } - } - }, - "eth-lib": { - "version": "0.1.29", - "dev": true, - "optional": 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" - } - }, - "eth-query": { - "version": "2.1.2", - "dev": true, - "requires": { - "json-rpc-random-id": "^1.0.0", - "xtend": "^4.0.1" - } - }, - "eth-sig-util": { - "version": "3.0.0", - "dev": true, - "requires": { - "buffer": "^5.2.1", - "elliptic": "^6.4.0", - "ethereumjs-abi": "0.6.5", - "ethereumjs-util": "^5.1.1", - "tweetnacl": "^1.0.0", - "tweetnacl-util": "^0.15.0" - }, - "dependencies": { - "ethereumjs-abi": { - "version": "0.6.5", - "dev": true, - "requires": { - "bn.js": "^4.10.0", - "ethereumjs-util": "^4.3.0" - }, - "dependencies": { - "ethereumjs-util": { - "version": "4.5.1", - "dev": true, - "requires": { - "bn.js": "^4.8.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.0.0" - } - } - } - }, - "ethereumjs-util": { - "version": "5.2.1", - "dev": true, - "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - } - } - }, - "eth-tx-summary": { - "version": "3.2.4", - "dev": true, - "requires": { - "async": "^2.1.2", - "clone": "^2.0.0", - "concat-stream": "^1.5.1", - "end-of-stream": "^1.1.0", - "eth-query": "^2.0.2", - "ethereumjs-block": "^1.4.1", - "ethereumjs-tx": "^1.1.1", - "ethereumjs-util": "^5.0.1", - "ethereumjs-vm": "^2.6.0", - "through2": "^2.0.3" - }, - "dependencies": { - "abstract-leveldown": { - "version": "2.6.3", - "dev": true, - "requires": { - "xtend": "~4.0.0" - } - }, - "deferred-leveldown": { - "version": "1.2.2", - "dev": true, - "requires": { - "abstract-leveldown": "~2.6.0" - } - }, - "ethereumjs-account": { - "version": "2.0.5", - "dev": true, - "requires": { - "ethereumjs-util": "^5.0.0", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - }, - "ethereumjs-block": { - "version": "1.7.1", - "dev": true, - "requires": { - "async": "^2.0.1", - "ethereum-common": "0.2.0", - "ethereumjs-tx": "^1.2.2", - "ethereumjs-util": "^5.0.0", - "merkle-patricia-tree": "^2.1.2" - }, - "dependencies": { - "ethereum-common": { - "version": "0.2.0", - "dev": true - } - } - }, - "ethereumjs-tx": { - "version": "1.3.7", - "dev": true, - "requires": { - "ethereum-common": "^0.0.18", - "ethereumjs-util": "^5.0.0" - } - }, - "ethereumjs-util": { - "version": "5.2.1", - "dev": true, - "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - }, - "ethereumjs-vm": { - "version": "2.6.0", - "dev": true, - "requires": { - "async": "^2.1.2", - "async-eventemitter": "^0.2.2", - "ethereumjs-account": "^2.0.3", - "ethereumjs-block": "~2.2.0", - "ethereumjs-common": "^1.1.0", - "ethereumjs-util": "^6.0.0", - "fake-merkle-patricia-tree": "^1.0.1", - "functional-red-black-tree": "^1.0.1", - "merkle-patricia-tree": "^2.3.2", - "rustbn.js": "~0.2.0", - "safe-buffer": "^5.1.1" - }, - "dependencies": { - "ethereumjs-block": { - "version": "2.2.2", - "dev": true, - "requires": { - "async": "^2.0.1", - "ethereumjs-common": "^1.5.0", - "ethereumjs-tx": "^2.1.1", - "ethereumjs-util": "^5.0.0", - "merkle-patricia-tree": "^2.1.2" - }, - "dependencies": { - "ethereumjs-util": { - "version": "5.2.1", - "dev": true, - "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - } - } - }, - "ethereumjs-tx": { - "version": "2.1.2", - "dev": true, - "requires": { - "ethereumjs-common": "^1.5.0", - "ethereumjs-util": "^6.0.0" - } - }, - "ethereumjs-util": { - "version": "6.2.1", - "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" - } - } - } - }, - "isarray": { - "version": "0.0.1", - "dev": true - }, - "level-codec": { - "version": "7.0.1", - "dev": true - }, - "level-errors": { - "version": "1.0.5", - "dev": true, - "requires": { - "errno": "~0.1.1" - } - }, - "level-iterator-stream": { - "version": "1.3.1", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "level-errors": "^1.0.3", - "readable-stream": "^1.0.33", - "xtend": "^4.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "1.1.14", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - } - } - }, - "level-ws": { - "version": "0.0.0", - "dev": true, - "requires": { - "readable-stream": "~1.0.15", - "xtend": "~2.1.1" - }, - "dependencies": { - "readable-stream": { - "version": "1.0.34", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "xtend": { - "version": "2.1.2", - "dev": true, - "requires": { - "object-keys": "~0.4.0" - } - } - } - }, - "levelup": { - "version": "1.3.9", - "dev": true, - "requires": { - "deferred-leveldown": "~1.2.1", - "level-codec": "~7.0.0", - "level-errors": "~1.0.3", - "level-iterator-stream": "~1.3.0", - "prr": "~1.0.1", - "semver": "~5.4.1", - "xtend": "~4.0.0" - } - }, - "ltgt": { - "version": "2.2.1", - "dev": true - }, - "memdown": { - "version": "1.4.1", - "dev": true, - "requires": { - "abstract-leveldown": "~2.7.1", - "functional-red-black-tree": "^1.0.1", - "immediate": "^3.2.3", - "inherits": "~2.0.1", - "ltgt": "~2.2.0", - "safe-buffer": "~5.1.1" - }, - "dependencies": { - "abstract-leveldown": { - "version": "2.7.2", - "dev": true, - "requires": { - "xtend": "~4.0.0" - } - } - } - }, - "merkle-patricia-tree": { - "version": "2.3.2", - "dev": true, - "requires": { - "async": "^1.4.2", - "ethereumjs-util": "^5.0.0", - "level-ws": "0.0.0", - "levelup": "^1.2.1", - "memdown": "^1.0.0", - "readable-stream": "^2.0.0", - "rlp": "^2.0.0", - "semaphore": ">=1.0.1" - }, - "dependencies": { - "async": { - "version": "1.5.2", - "dev": true - } - } - }, - "object-keys": { - "version": "0.4.0", - "dev": true - }, - "safe-buffer": { - "version": "5.1.2", - "dev": true - }, - "semver": { - "version": "5.4.1", - "dev": true - }, - "string_decoder": { - "version": "0.10.31", - "dev": true - } - } - }, - "ethashjs": { - "version": "0.0.8", - "dev": true, - "requires": { - "async": "^2.1.2", - "buffer-xor": "^2.0.1", - "ethereumjs-util": "^7.0.2", - "miller-rabin": "^4.0.0" - }, - "dependencies": { - "bn.js": { - "version": "5.1.3", - "dev": true - }, - "buffer-xor": { - "version": "2.0.2", - "dev": true, - "requires": { - "safe-buffer": "^5.1.1" - } - }, - "ethereumjs-util": { - "version": "7.0.7", - "dev": true, - "requires": { - "@types/bn.js": "^4.11.3", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "0.1.6", - "rlp": "^2.2.4" - } - } - } - }, - "ethereum-bloom-filters": { - "version": "1.0.7", - "dev": true, - "optional": true, - "requires": { - "js-sha3": "^0.8.0" - }, - "dependencies": { - "js-sha3": { - "version": "0.8.0", - "dev": true, - "optional": true - } - } - }, - "ethereum-common": { - "version": "0.0.18", - "dev": true - }, - "ethereum-cryptography": { - "version": "0.1.3", - "dev": true, - "requires": { - "@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" - } - }, - "ethereumjs-abi": { - "version": "0.6.8", - "dev": true, - "requires": { - "bn.js": "^4.11.8", - "ethereumjs-util": "^6.0.0" - } - }, - "ethereumjs-account": { - "version": "3.0.0", - "dev": true, - "requires": { - "ethereumjs-util": "^6.0.0", - "rlp": "^2.2.1", - "safe-buffer": "^5.1.1" - } - }, - "ethereumjs-block": { - "version": "2.2.2", - "dev": true, - "requires": { - "async": "^2.0.1", - "ethereumjs-common": "^1.5.0", - "ethereumjs-tx": "^2.1.1", - "ethereumjs-util": "^5.0.0", - "merkle-patricia-tree": "^2.1.2" - }, - "dependencies": { - "abstract-leveldown": { - "version": "2.6.3", - "dev": true, - "requires": { - "xtend": "~4.0.0" - } - }, - "deferred-leveldown": { - "version": "1.2.2", - "dev": true, - "requires": { - "abstract-leveldown": "~2.6.0" - } - }, - "ethereumjs-util": { - "version": "5.2.1", - "dev": true, - "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - }, - "isarray": { - "version": "0.0.1", - "dev": true - }, - "level-codec": { - "version": "7.0.1", - "dev": true - }, - "level-errors": { - "version": "1.0.5", - "dev": true, - "requires": { - "errno": "~0.1.1" - } - }, - "level-iterator-stream": { - "version": "1.3.1", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "level-errors": "^1.0.3", - "readable-stream": "^1.0.33", - "xtend": "^4.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "1.1.14", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - } - } - }, - "level-ws": { - "version": "0.0.0", - "dev": true, - "requires": { - "readable-stream": "~1.0.15", - "xtend": "~2.1.1" - }, - "dependencies": { - "readable-stream": { - "version": "1.0.34", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "xtend": { - "version": "2.1.2", - "dev": true, - "requires": { - "object-keys": "~0.4.0" - } - } - } - }, - "levelup": { - "version": "1.3.9", - "dev": true, - "requires": { - "deferred-leveldown": "~1.2.1", - "level-codec": "~7.0.0", - "level-errors": "~1.0.3", - "level-iterator-stream": "~1.3.0", - "prr": "~1.0.1", - "semver": "~5.4.1", - "xtend": "~4.0.0" - } - }, - "ltgt": { - "version": "2.2.1", - "dev": true - }, - "memdown": { - "version": "1.4.1", - "dev": true, - "requires": { - "abstract-leveldown": "~2.7.1", - "functional-red-black-tree": "^1.0.1", - "immediate": "^3.2.3", - "inherits": "~2.0.1", - "ltgt": "~2.2.0", - "safe-buffer": "~5.1.1" - }, - "dependencies": { - "abstract-leveldown": { - "version": "2.7.2", - "dev": true, - "requires": { - "xtend": "~4.0.0" - } - } - } - }, - "merkle-patricia-tree": { - "version": "2.3.2", - "dev": true, - "requires": { - "async": "^1.4.2", - "ethereumjs-util": "^5.0.0", - "level-ws": "0.0.0", - "levelup": "^1.2.1", - "memdown": "^1.0.0", - "readable-stream": "^2.0.0", - "rlp": "^2.0.0", - "semaphore": ">=1.0.1" - }, - "dependencies": { - "async": { - "version": "1.5.2", - "dev": true - } - } - }, - "object-keys": { - "version": "0.4.0", - "dev": true - }, - "safe-buffer": { - "version": "5.1.2", - "dev": true - }, - "semver": { - "version": "5.4.1", - "dev": true - }, - "string_decoder": { - "version": "0.10.31", - "dev": true - } - } - }, - "ethereumjs-blockchain": { - "version": "4.0.4", - "dev": true, - "requires": { - "async": "^2.6.1", - "ethashjs": "~0.0.7", - "ethereumjs-block": "~2.2.2", - "ethereumjs-common": "^1.5.0", - "ethereumjs-util": "^6.1.0", - "flow-stoplight": "^1.0.0", - "level-mem": "^3.0.1", - "lru-cache": "^5.1.1", - "rlp": "^2.2.2", - "semaphore": "^1.1.0" - } - }, - "ethereumjs-common": { - "version": "1.5.0", - "dev": true - }, - "ethereumjs-tx": { - "version": "2.1.2", - "dev": true, - "requires": { - "ethereumjs-common": "^1.5.0", - "ethereumjs-util": "^6.0.0" - } - }, - "ethereumjs-util": { - "version": "6.2.1", - "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" - } - }, - "ethereumjs-vm": { - "version": "4.2.0", - "dev": true, - "requires": { - "async": "^2.1.2", - "async-eventemitter": "^0.2.2", - "core-js-pure": "^3.0.1", - "ethereumjs-account": "^3.0.0", - "ethereumjs-block": "^2.2.2", - "ethereumjs-blockchain": "^4.0.3", - "ethereumjs-common": "^1.5.0", - "ethereumjs-tx": "^2.1.2", - "ethereumjs-util": "^6.2.0", - "fake-merkle-patricia-tree": "^1.0.1", - "functional-red-black-tree": "^1.0.1", - "merkle-patricia-tree": "^2.3.2", - "rustbn.js": "~0.2.0", - "safe-buffer": "^5.1.1", - "util.promisify": "^1.0.0" - }, - "dependencies": { - "abstract-leveldown": { - "version": "2.6.3", - "dev": true, - "requires": { - "xtend": "~4.0.0" - } - }, - "deferred-leveldown": { - "version": "1.2.2", - "dev": true, - "requires": { - "abstract-leveldown": "~2.6.0" - } - }, - "isarray": { - "version": "0.0.1", - "dev": true - }, - "level-codec": { - "version": "7.0.1", - "dev": true - }, - "level-errors": { - "version": "1.0.5", - "dev": true, - "requires": { - "errno": "~0.1.1" - } - }, - "level-iterator-stream": { - "version": "1.3.1", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "level-errors": "^1.0.3", - "readable-stream": "^1.0.33", - "xtend": "^4.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "1.1.14", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - } - } - }, - "level-ws": { - "version": "0.0.0", - "dev": true, - "requires": { - "readable-stream": "~1.0.15", - "xtend": "~2.1.1" - }, - "dependencies": { - "readable-stream": { - "version": "1.0.34", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "xtend": { - "version": "2.1.2", - "dev": true, - "requires": { - "object-keys": "~0.4.0" - } - } - } - }, - "levelup": { - "version": "1.3.9", - "dev": true, - "requires": { - "deferred-leveldown": "~1.2.1", - "level-codec": "~7.0.0", - "level-errors": "~1.0.3", - "level-iterator-stream": "~1.3.0", - "prr": "~1.0.1", - "semver": "~5.4.1", - "xtend": "~4.0.0" - } - }, - "ltgt": { - "version": "2.2.1", - "dev": true - }, - "memdown": { - "version": "1.4.1", - "dev": true, - "requires": { - "abstract-leveldown": "~2.7.1", - "functional-red-black-tree": "^1.0.1", - "immediate": "^3.2.3", - "inherits": "~2.0.1", - "ltgt": "~2.2.0", - "safe-buffer": "~5.1.1" - }, - "dependencies": { - "abstract-leveldown": { - "version": "2.7.2", - "dev": true, - "requires": { - "xtend": "~4.0.0" - } - } - } - }, - "merkle-patricia-tree": { - "version": "2.3.2", - "dev": true, - "requires": { - "async": "^1.4.2", - "ethereumjs-util": "^5.0.0", - "level-ws": "0.0.0", - "levelup": "^1.2.1", - "memdown": "^1.0.0", - "readable-stream": "^2.0.0", - "rlp": "^2.0.0", - "semaphore": ">=1.0.1" - }, - "dependencies": { - "async": { - "version": "1.5.2", - "dev": true - }, - "ethereumjs-util": { - "version": "5.2.1", - "dev": true, - "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - } - } - }, - "object-keys": { - "version": "0.4.0", - "dev": true - }, - "safe-buffer": { - "version": "5.1.2", - "dev": true - }, - "semver": { - "version": "5.4.1", - "dev": true - }, - "string_decoder": { - "version": "0.10.31", - "dev": true - } - } - }, - "ethereumjs-wallet": { - "version": "0.6.5", - "dev": true, - "optional": true, - "requires": { - "aes-js": "^3.1.1", - "bs58check": "^2.1.2", - "ethereum-cryptography": "^0.1.3", - "ethereumjs-util": "^6.0.0", - "randombytes": "^2.0.6", - "safe-buffer": "^5.1.2", - "scryptsy": "^1.2.1", - "utf8": "^3.0.0", - "uuid": "^3.3.2" - } - }, - "ethjs-unit": { - "version": "0.1.6", - "dev": true, - "optional": true, - "requires": { - "bn.js": "4.11.6", - "number-to-bn": "1.7.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.6", - "dev": true, - "optional": true - } - } - }, - "ethjs-util": { - "version": "0.1.6", - "dev": true, - "requires": { - "is-hex-prefixed": "1.0.0", - "strip-hex-prefix": "1.0.0" - } - }, - "eventemitter3": { - "version": "4.0.4", - "dev": true, - "optional": true - }, - "events": { - "version": "3.2.0", - "dev": true - }, - "evp_bytestokey": { - "version": "1.0.3", - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "expand-brackets": { - "version": "2.1.4", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-buffer": { - "version": "1.1.6", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "dev": true - }, - "kind-of": { - "version": "5.1.0", - "dev": true - }, - "ms": { - "version": "2.0.0", - "dev": true - } - } - }, - "express": { - "version": "4.17.1", - "dev": true, - "optional": true, - "requires": { - "accepts": "~1.3.7", - "array-flatten": "1.1.1", - "body-parser": "1.19.0", - "content-disposition": "0.5.3", - "content-type": "~1.0.4", - "cookie": "0.4.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~1.1.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "~1.1.2", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.5", - "qs": "6.7.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.1.2", - "send": "0.17.1", - "serve-static": "1.14.1", - "setprototypeof": "1.1.1", - "statuses": "~1.5.0", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "dev": true, - "optional": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "dev": true, - "optional": true - }, - "qs": { - "version": "6.7.0", - "dev": true, - "optional": true - }, - "safe-buffer": { - "version": "5.1.2", - "dev": true, - "optional": true - } - } - }, - "ext": { - "version": "1.4.0", - "dev": true, - "requires": { - "type": "^2.0.0" - }, - "dependencies": { - "type": { - "version": "2.1.0", - "dev": true - } - } - }, - "extend": { - "version": "3.0.2", - "dev": true - }, - "extend-shallow": { - "version": "3.0.2", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - }, - "extglob": { - "version": "2.0.4", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "dev": true - } - } - }, - "extsprintf": { - "version": "1.3.0", - "dev": true - }, - "fake-merkle-patricia-tree": { - "version": "1.0.1", - "dev": true, - "requires": { - "checkpoint-store": "^1.1.0" - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "dev": true - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "dev": true - }, - "fetch-ponyfill": { - "version": "4.1.0", - "dev": true, - "requires": { - "node-fetch": "~1.7.1" - }, - "dependencies": { - "is-stream": { - "version": "1.1.0", - "dev": true - }, - "node-fetch": { - "version": "1.7.3", - "dev": true, - "requires": { - "encoding": "^0.1.11", - "is-stream": "^1.0.1" - } - } - } - }, - "finalhandler": { - "version": "1.1.2", - "dev": true, - "optional": true, - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "dev": true, - "optional": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "dev": true, - "optional": true - } - } - }, - "find-yarn-workspace-root": { - "version": "1.2.1", - "dev": true, - "requires": { - "fs-extra": "^4.0.3", - "micromatch": "^3.1.4" - }, - "dependencies": { - "braces": { - "version": "2.3.2", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fs-extra": { - "version": "4.0.3", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "dev": true - }, - "is-extendable": { - "version": "0.1.1", - "dev": true - }, - "is-number": { - "version": "3.0.0", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "micromatch": { - "version": "3.1.10", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "to-regex-range": { - "version": "2.1.1", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - } - } - }, - "flow-stoplight": { - "version": "1.0.0", - "dev": true - }, - "for-each": { - "version": "0.3.3", - "dev": true, - "requires": { - "is-callable": "^1.1.3" - } - }, - "for-in": { - "version": "1.0.2", - "dev": true - }, - "forever-agent": { - "version": "0.6.1", - "dev": true - }, - "form-data": { - "version": "2.3.3", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "forwarded": { - "version": "0.1.2", - "dev": true, - "optional": true - }, - "fragment-cache": { - "version": "0.2.1", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "fresh": { - "version": "0.5.2", - "dev": true, - "optional": true - }, - "fs-extra": { - "version": "7.0.1", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "dev": true - }, - "function-bind": { - "version": "1.1.1", - "dev": true - }, - "functional-red-black-tree": { - "version": "1.0.1", - "dev": true - }, - "get-intrinsic": { - "version": "1.0.2", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - } - }, - "get-stream": { - "version": "5.2.0", - "dev": true, - "optional": true, - "requires": { - "pump": "^3.0.0" - } - }, - "get-value": { - "version": "2.0.6", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.3", - "dev": 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" - } - }, - "global": { - "version": "4.4.0", - "dev": true, - "requires": { - "min-document": "^2.19.0", - "process": "^0.11.10" - } - }, - "got": { - "version": "9.6.0", - "dev": true, - "optional": 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" - }, - "dependencies": { - "get-stream": { - "version": "4.1.0", - "dev": true, - "optional": true, - "requires": { - "pump": "^3.0.0" - } - } - } - }, - "graceful-fs": { - "version": "4.2.4", - "dev": true - }, - "har-schema": { - "version": "2.0.0", - "dev": true - }, - "har-validator": { - "version": "5.1.5", - "dev": true, - "requires": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - } - }, - "has": { - "version": "1.0.3", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "dev": true - } - } - }, - "has-flag": { - "version": "3.0.0", - "dev": true - }, - "has-symbol-support-x": { - "version": "1.4.2", - "dev": true, - "optional": true - }, - "has-symbols": { - "version": "1.0.1", - "dev": true - }, - "has-to-string-tag-x": { - "version": "1.4.1", - "dev": true, - "optional": true, - "requires": { - "has-symbol-support-x": "^1.4.1" - } - }, - "has-value": { - "version": "1.0.0", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "has-values": { - "version": "1.0.0", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-buffer": { - "version": "1.1.6", - "dev": true - }, - "is-number": { - "version": "3.0.0", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "hash-base": { - "version": "3.1.0", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "hash.js": { - "version": "1.1.7", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "heap": { - "version": "0.2.6", - "dev": true - }, - "hmac-drbg": { - "version": "1.0.1", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "home-or-tmp": { - "version": "2.0.0", - "dev": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.1" - } - }, - "http-cache-semantics": { - "version": "4.1.0", - "dev": true, - "optional": true - }, - "http-errors": { - "version": "1.7.2", - "dev": true, - "optional": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "dev": true, - "optional": true - } - } - }, - "http-https": { - "version": "1.0.0", - "dev": true, - "optional": true - }, - "http-signature": { - "version": "1.2.0", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "iconv-lite": { - "version": "0.4.24", - "dev": true, - "optional": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "idna-uts46-hx": { - "version": "2.3.1", - "dev": true, - "optional": true, - "requires": { - "punycode": "2.1.0" - }, - "dependencies": { - "punycode": { - "version": "2.1.0", - "dev": true, - "optional": true - } - } - }, - "ieee754": { - "version": "1.2.1", - "dev": true - }, - "immediate": { - "version": "3.2.3", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "dev": true - }, - "invariant": { - "version": "2.2.4", - "dev": true, - "requires": { - "loose-envify": "^1.0.0" - } - }, - "ipaddr.js": { - "version": "1.9.1", - "dev": true, - "optional": true - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-arguments": { - "version": "1.1.0", - "dev": true, - "requires": { - "call-bind": "^1.0.0" - } - }, - "is-callable": { - "version": "1.2.2", - "dev": true - }, - "is-ci": { - "version": "2.0.0", - "dev": true, - "requires": { - "ci-info": "^2.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-date-object": { - "version": "1.0.2", - "dev": true - }, - "is-descriptor": { - "version": "1.0.2", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extendable": { - "version": "1.0.1", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - }, - "is-finite": { - "version": "1.1.0", - "dev": true - }, - "is-fn": { - "version": "1.0.0", - "dev": true - }, - "is-function": { - "version": "1.0.2", - "dev": true - }, - "is-hex-prefixed": { - "version": "1.0.0", - "dev": true - }, - "is-negative-zero": { - "version": "2.0.1", - "dev": true - }, - "is-object": { - "version": "1.0.2", - "dev": true, - "optional": true - }, - "is-plain-obj": { - "version": "1.1.0", - "dev": true, - "optional": true - }, - "is-plain-object": { - "version": "2.0.4", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "is-regex": { - "version": "1.1.1", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-retry-allowed": { - "version": "1.2.0", - "dev": true, - "optional": true - }, - "is-symbol": { - "version": "1.0.3", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "dev": true - }, - "is-windows": { - "version": "1.0.2", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "dev": true - }, - "isstream": { - "version": "0.1.2", - "dev": true - }, - "isurl": { - "version": "1.0.0", - "dev": true, - "optional": true, - "requires": { - "has-to-string-tag-x": "^1.2.0", - "is-object": "^1.0.1" - } - }, - "js-sha3": { - "version": "0.5.7", - "dev": true, - "optional": true - }, - "js-tokens": { - "version": "4.0.0", - "dev": true - }, - "jsbn": { - "version": "0.1.1", - "dev": true - }, - "json-buffer": { - "version": "3.0.0", - "dev": true, - "optional": true - }, - "json-rpc-engine": { - "version": "3.8.0", - "dev": true, - "requires": { - "async": "^2.0.1", - "babel-preset-env": "^1.7.0", - "babelify": "^7.3.0", - "json-rpc-error": "^2.0.0", - "promise-to-callback": "^1.0.0", - "safe-event-emitter": "^1.0.1" - } - }, - "json-rpc-error": { - "version": "2.0.0", - "dev": true, - "requires": { - "inherits": "^2.0.1" - } - }, - "json-rpc-random-id": { - "version": "1.0.1", - "dev": true - }, - "json-schema": { - "version": "0.2.3", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "dev": true - }, - "json-stable-stringify": { - "version": "1.0.1", - "dev": true, - "requires": { - "jsonify": "~0.0.0" - } - }, - "json-stringify-safe": { - "version": "5.0.1", - "dev": true - }, - "jsonfile": { - "version": "4.0.0", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsonify": { - "version": "0.0.0", - "dev": true - }, - "jsprim": { - "version": "1.4.1", - "dev": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "keccak": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "requires": { - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" - } - }, - "keyv": { - "version": "3.1.0", - "dev": true, - "optional": true, - "requires": { - "json-buffer": "3.0.0" - } - }, - "kind-of": { - "version": "6.0.3", - "dev": true - }, - "klaw-sync": { - "version": "6.0.0", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11" - } - }, - "level-codec": { - "version": "9.0.2", - "dev": true, - "requires": { - "buffer": "^5.6.0" - } - }, - "level-errors": { - "version": "2.0.1", - "dev": true, - "requires": { - "errno": "~0.1.1" - } - }, - "level-iterator-stream": { - "version": "2.0.3", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.5", - "xtend": "^4.0.0" - } - }, - "level-mem": { - "version": "3.0.1", - "dev": true, - "requires": { - "level-packager": "~4.0.0", - "memdown": "~3.0.0" - }, - "dependencies": { - "abstract-leveldown": { - "version": "5.0.0", - "dev": true, - "requires": { - "xtend": "~4.0.0" - } - }, - "ltgt": { - "version": "2.2.1", - "dev": true - }, - "memdown": { - "version": "3.0.0", - "dev": true, - "requires": { - "abstract-leveldown": "~5.0.0", - "functional-red-black-tree": "~1.0.1", - "immediate": "~3.2.3", - "inherits": "~2.0.1", - "ltgt": "~2.2.0", - "safe-buffer": "~5.1.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "dev": true - } - } - }, - "level-packager": { - "version": "4.0.1", - "dev": true, - "requires": { - "encoding-down": "~5.0.0", - "levelup": "^3.0.0" - } - }, - "level-post": { - "version": "1.0.7", - "dev": true, - "requires": { - "ltgt": "^2.1.2" - } - }, - "level-sublevel": { - "version": "6.6.4", - "dev": true, - "requires": { - "bytewise": "~1.1.0", - "level-codec": "^9.0.0", - "level-errors": "^2.0.0", - "level-iterator-stream": "^2.0.3", - "ltgt": "~2.1.1", - "pull-defer": "^0.2.2", - "pull-level": "^2.0.3", - "pull-stream": "^3.6.8", - "typewiselite": "~1.0.0", - "xtend": "~4.0.0" - } - }, - "level-ws": { - "version": "1.0.0", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.2.8", - "xtend": "^4.0.1" - } - }, - "levelup": { - "version": "3.1.1", - "dev": true, - "requires": { - "deferred-leveldown": "~4.0.0", - "level-errors": "~2.0.0", - "level-iterator-stream": "~3.0.0", - "xtend": "~4.0.0" - }, - "dependencies": { - "level-iterator-stream": { - "version": "3.0.1", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "xtend": "^4.0.0" - } - } - } - }, - "lodash": { - "version": "4.17.20", - "dev": true - }, - "looper": { - "version": "2.0.0", - "dev": true - }, - "loose-envify": { - "version": "1.4.0", - "dev": true, - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "lowercase-keys": { - "version": "1.0.1", - "dev": true, - "optional": true - }, - "lru-cache": { - "version": "5.1.1", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "ltgt": { - "version": "2.1.3", - "dev": true - }, - "map-cache": { - "version": "0.2.2", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "md5.js": { - "version": "1.3.5", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "media-typer": { - "version": "0.3.0", - "dev": true, - "optional": true - }, - "merge-descriptors": { - "version": "1.0.1", - "dev": true, - "optional": true - }, - "merkle-patricia-tree": { - "version": "3.0.0", - "dev": true, - "requires": { - "async": "^2.6.1", - "ethereumjs-util": "^5.2.0", - "level-mem": "^3.0.1", - "level-ws": "^1.0.0", - "readable-stream": "^3.0.6", - "rlp": "^2.0.0", - "semaphore": ">=1.0.1" - }, - "dependencies": { - "ethereumjs-util": { - "version": "5.2.1", - "dev": true, - "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - }, - "readable-stream": { - "version": "3.6.0", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "methods": { - "version": "1.1.2", - "dev": true, - "optional": true - }, - "miller-rabin": { - "version": "4.0.1", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - } - }, - "mime": { - "version": "1.6.0", - "dev": true, - "optional": true - }, - "mime-db": { - "version": "1.45.0", - "dev": true - }, - "mime-types": { - "version": "2.1.28", - "dev": true, - "requires": { - "mime-db": "1.45.0" - } - }, - "mimic-response": { - "version": "1.0.1", - "dev": true, - "optional": true - }, - "min-document": { - "version": "2.19.0", - "dev": true, - "requires": { - "dom-walk": "^0.1.0" - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.5", - "dev": true - }, - "minizlib": { - "version": "1.3.3", - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.9.0" - }, - "dependencies": { - "minipass": { - "version": "2.9.0", - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - } - } - }, - "mixin-deep": { - "version": "1.3.2", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - } - }, - "mkdirp": { - "version": "0.5.5", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "mkdirp-promise": { - "version": "5.0.1", - "dev": true, - "optional": true, - "requires": { - "mkdirp": "*" - } - }, - "mock-fs": { - "version": "4.13.0", - "dev": true, - "optional": true - }, - "ms": { - "version": "2.1.3", - "dev": true - }, - "multibase": { - "version": "0.6.1", - "dev": true, - "optional": true, - "requires": { - "base-x": "^3.0.8", - "buffer": "^5.5.0" - } - }, - "multicodec": { - "version": "0.5.7", - "dev": true, - "optional": true, - "requires": { - "varint": "^5.0.0" - } - }, - "multihashes": { - "version": "0.4.21", - "dev": true, - "optional": true, - "requires": { - "buffer": "^5.5.0", - "multibase": "^0.7.0", - "varint": "^5.0.0" - }, - "dependencies": { - "multibase": { - "version": "0.7.0", - "dev": true, - "optional": true, - "requires": { - "base-x": "^3.0.8", - "buffer": "^5.5.0" - } - } - } - }, - "nano-json-stream-parser": { - "version": "0.1.2", - "dev": true, - "optional": true - }, - "nanomatch": { - "version": "1.2.13", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - } - }, - "negotiator": { - "version": "0.6.2", - "dev": true, - "optional": true - }, - "next-tick": { - "version": "1.0.0", - "dev": true - }, - "nice-try": { - "version": "1.0.5", - "dev": true - }, - "node-addon-api": { - "version": "2.0.2", - "bundled": true, - "dev": true - }, - "node-fetch": { - "version": "2.1.2", - "dev": true - }, - "node-gyp-build": { - "version": "4.2.3", - "bundled": true, - "dev": true - }, - "normalize-url": { - "version": "4.5.0", - "dev": true, - "optional": true - }, - "number-to-bn": { - "version": "1.7.0", - "dev": true, - "optional": true, - "requires": { - "bn.js": "4.11.6", - "strip-hex-prefix": "1.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.6", - "dev": true, - "optional": true - } - } - }, - "oauth-sign": { - "version": "0.9.0", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-buffer": { - "version": "1.1.6", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-descriptor": { - "version": "0.1.6", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "dev": true - } - } - }, - "kind-of": { - "version": "3.2.2", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "object-inspect": { - "version": "1.9.0", - "dev": true - }, - "object-is": { - "version": "1.1.4", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" - } - }, - "object-keys": { - "version": "1.1.1", - "dev": true - }, - "object-visit": { - "version": "1.0.1", - "dev": true, - "requires": { - "isobject": "^3.0.0" - } - }, - "object.assign": { - "version": "4.1.2", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.1", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1" - } - }, - "object.pick": { - "version": "1.3.0", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "oboe": { - "version": "2.1.4", - "dev": true, - "optional": true, - "requires": { - "http-https": "^1.0.0" - } - }, - "on-finished": { - "version": "2.3.0", - "dev": true, - "optional": true, - "requires": { - "ee-first": "1.1.1" - } - }, - "once": { - "version": "1.4.0", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "os-homedir": { - "version": "1.0.2", - "dev": true - }, - "os-tmpdir": { - "version": "1.0.2", - "dev": true - }, - "p-cancelable": { - "version": "1.1.0", - "dev": true, - "optional": true - }, - "p-timeout": { - "version": "1.2.1", - "dev": true, - "optional": true, - "requires": { - "p-finally": "^1.0.0" - }, - "dependencies": { - "p-finally": { - "version": "1.0.0", - "dev": true, - "optional": true - } - } - }, - "parse-asn1": { - "version": "5.1.6", - "dev": true, - "optional": 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-headers": { - "version": "2.0.3", - "dev": true - }, - "parseurl": { - "version": "1.3.3", - "dev": true, - "optional": true - }, - "pascalcase": { - "version": "0.1.1", - "dev": true - }, - "patch-package": { - "version": "6.2.2", - "dev": true, - "requires": { - "@yarnpkg/lockfile": "^1.1.0", - "chalk": "^2.4.2", - "cross-spawn": "^6.0.5", - "find-yarn-workspace-root": "^1.2.1", - "fs-extra": "^7.0.1", - "is-ci": "^2.0.0", - "klaw-sync": "^6.0.0", - "minimist": "^1.2.0", - "rimraf": "^2.6.3", - "semver": "^5.6.0", - "slash": "^2.0.0", - "tmp": "^0.0.33" - }, - "dependencies": { - "cross-spawn": { - "version": "6.0.5", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "path-key": { - "version": "2.0.1", - "dev": true - }, - "semver": { - "version": "5.7.1", - "dev": true - }, - "shebang-command": { - "version": "1.2.0", - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "dev": true - }, - "slash": { - "version": "2.0.0", - "dev": true - }, - "tmp": { - "version": "0.0.33", - "dev": true, - "requires": { - "os-tmpdir": "~1.0.2" - } - }, - "which": { - "version": "1.3.1", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "path-is-absolute": { - "version": "1.0.1", - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "dev": true - }, - "path-to-regexp": { - "version": "0.1.7", - "dev": true, - "optional": true - }, - "pbkdf2": { - "version": "3.1.1", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "performance-now": { - "version": "2.1.0", - "dev": true - }, - "posix-character-classes": { - "version": "0.1.1", - "dev": true - }, - "precond": { - "version": "0.2.3", - "dev": true - }, - "prepend-http": { - "version": "2.0.0", - "dev": true, - "optional": true - }, - "private": { - "version": "0.1.8", - "dev": true - }, - "process": { - "version": "0.11.10", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "dev": true - }, - "promise-to-callback": { - "version": "1.0.0", - "dev": true, - "requires": { - "is-fn": "^1.0.0", - "set-immediate-shim": "^1.0.1" - } - }, - "proxy-addr": { - "version": "2.0.6", - "dev": true, - "optional": true, - "requires": { - "forwarded": "~0.1.2", - "ipaddr.js": "1.9.1" - } - }, - "prr": { - "version": "1.0.1", - "dev": true - }, - "pseudomap": { - "version": "1.0.2", - "dev": true - }, - "psl": { - "version": "1.8.0", - "dev": true - }, - "public-encrypt": { - "version": "4.0.3", - "dev": true, - "optional": 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" - } - }, - "pull-cat": { - "version": "1.1.11", - "dev": true - }, - "pull-defer": { - "version": "0.2.3", - "dev": true - }, - "pull-level": { - "version": "2.0.4", - "dev": true, - "requires": { - "level-post": "^1.0.7", - "pull-cat": "^1.1.9", - "pull-live": "^1.0.1", - "pull-pushable": "^2.0.0", - "pull-stream": "^3.4.0", - "pull-window": "^2.1.4", - "stream-to-pull-stream": "^1.7.1" - } - }, - "pull-live": { - "version": "1.0.1", - "dev": true, - "requires": { - "pull-cat": "^1.1.9", - "pull-stream": "^3.4.0" - } - }, - "pull-pushable": { - "version": "2.2.0", - "dev": true - }, - "pull-stream": { - "version": "3.6.14", - "dev": true - }, - "pull-window": { - "version": "2.1.4", - "dev": true, - "requires": { - "looper": "^2.0.0" - } - }, - "pump": { - "version": "3.0.0", - "dev": true, - "optional": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "punycode": { - "version": "2.1.1", - "dev": true - }, - "qs": { - "version": "6.5.2", - "dev": true - }, - "query-string": { - "version": "5.1.1", - "dev": true, - "optional": true, - "requires": { - "decode-uri-component": "^0.2.0", - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" - } - }, - "randombytes": { - "version": "2.1.0", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "dev": true, - "optional": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "range-parser": { - "version": "1.2.1", - "dev": true, - "optional": true - }, - "raw-body": { - "version": "2.4.0", - "dev": true, - "optional": true, - "requires": { - "bytes": "3.1.0", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - } - }, - "readable-stream": { - "version": "2.3.7", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "dev": true - } - } - }, - "regenerate": { - "version": "1.4.2", - "dev": true - }, - "regenerator-runtime": { - "version": "0.11.1", - "dev": true - }, - "regenerator-transform": { - "version": "0.10.1", - "dev": true, - "requires": { - "babel-runtime": "^6.18.0", - "babel-types": "^6.19.0", - "private": "^0.1.6" - } - }, - "regex-not": { - "version": "1.0.2", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "regexp.prototype.flags": { - "version": "1.3.0", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - }, - "dependencies": { - "es-abstract": { - "version": "1.17.7", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.2", - "is-regex": "^1.1.1", - "object-inspect": "^1.8.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.1", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - } - } - }, - "regexpu-core": { - "version": "2.0.0", - "dev": true, - "requires": { - "regenerate": "^1.2.1", - "regjsgen": "^0.2.0", - "regjsparser": "^0.1.4" - } - }, - "regjsgen": { - "version": "0.2.0", - "dev": true - }, - "regjsparser": { - "version": "0.1.5", - "dev": true, - "requires": { - "jsesc": "~0.5.0" - }, - "dependencies": { - "jsesc": { - "version": "0.5.0", - "dev": true - } - } - }, - "repeat-element": { - "version": "1.1.3", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "dev": true - }, - "repeating": { - "version": "2.0.1", - "dev": true, - "requires": { - "is-finite": "^1.0.0" - } - }, - "request": { - "version": "2.88.2", - "dev": true, - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "resolve-url": { - "version": "0.2.1", - "dev": true - }, - "responselike": { - "version": "1.0.2", - "dev": true, - "optional": true, - "requires": { - "lowercase-keys": "^1.0.0" - } - }, - "resumer": { - "version": "0.0.0", - "dev": true, - "requires": { - "through": "~2.3.4" - } - }, - "ret": { - "version": "0.1.15", - "dev": true - }, - "rimraf": { - "version": "2.6.3", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "ripemd160": { - "version": "2.0.2", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "rlp": { - "version": "2.2.6", - "dev": true, - "requires": { - "bn.js": "^4.11.1" - } - }, - "rustbn.js": { - "version": "0.2.0", - "dev": true - }, - "safe-buffer": { - "version": "5.2.1", - "dev": true - }, - "safe-event-emitter": { - "version": "1.0.1", - "dev": true, - "requires": { - "events": "^3.0.0" - } - }, - "safe-regex": { - "version": "1.1.0", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "dev": true - }, - "scrypt-js": { - "version": "3.0.1", - "dev": true - }, - "scryptsy": { - "version": "1.2.1", - "dev": true, - "optional": true, - "requires": { - "pbkdf2": "^3.0.3" - } - }, - "secp256k1": { - "version": "4.0.2", - "dev": true, - "requires": { - "elliptic": "^6.5.2", - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" - } - }, - "seedrandom": { - "version": "3.0.1", - "dev": true - }, - "semaphore": { - "version": "1.1.0", - "dev": true - }, - "send": { - "version": "0.17.1", - "dev": true, - "optional": true, - "requires": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "~1.7.2", - "mime": "1.6.0", - "ms": "2.1.1", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "dev": true, - "optional": true, - "requires": { - "ms": "2.0.0" - }, - "dependencies": { - "ms": { - "version": "2.0.0", - "dev": true, - "optional": true - } - } - }, - "ms": { - "version": "2.1.1", - "dev": true, - "optional": true - } - } - }, - "serve-static": { - "version": "1.14.1", - "dev": true, - "optional": true, - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.17.1" - } - }, - "servify": { - "version": "0.1.12", - "dev": true, - "optional": true, - "requires": { - "body-parser": "^1.16.0", - "cors": "^2.8.1", - "express": "^4.14.0", - "request": "^2.79.0", - "xhr": "^2.3.3" - } - }, - "set-immediate-shim": { - "version": "1.0.1", - "dev": true - }, - "set-value": { - "version": "2.0.1", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "dev": true - } - } - }, - "setimmediate": { - "version": "1.0.5", - "dev": true - }, - "setprototypeof": { - "version": "1.1.1", - "dev": true, - "optional": true - }, - "sha.js": { - "version": "2.4.11", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "simple-concat": { - "version": "1.0.1", - "dev": true, - "optional": true - }, - "simple-get": { - "version": "2.8.1", - "dev": true, - "optional": true, - "requires": { - "decompress-response": "^3.3.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, - "snapdragon": { - "version": "0.8.2", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-buffer": { - "version": "1.1.6", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "dev": true - }, - "kind-of": { - "version": "5.1.0", - "dev": true - }, - "ms": { - "version": "2.0.0", - "dev": true - } - } - }, - "snapdragon-node": { - "version": "2.1.1", + "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, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - } - } + "peer": true }, - "snapdragon-util": { + "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, - "requires": { - "kind-of": "^3.2.0" - }, - "dependencies": { - "is-buffer": { - "version": "1.1.6", - "dev": true - }, - "kind-of": { - "version": "3.2.2", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "source-map": { - "version": "0.5.7", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.3", - "dev": true, - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-support": { - "version": "0.5.12", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "dev": true - } - } - }, - "source-map-url": { - "version": "0.4.0", - "dev": true - }, - "split-string": { - "version": "3.1.0", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "sshpk": { - "version": "1.16.1", - "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", - "dev": true - } - } - }, - "static-extend": { - "version": "0.1.2", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-buffer": { - "version": "1.1.6", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "dev": true - } - } - }, - "statuses": { - "version": "1.5.0", - "dev": true, - "optional": true - }, - "stream-to-pull-stream": { - "version": "1.7.3", - "dev": true, - "requires": { - "looper": "^3.0.0", - "pull-stream": "^3.2.3" - }, - "dependencies": { - "looper": { - "version": "3.0.0", - "dev": true - } - } - }, - "strict-uri-encode": { - "version": "1.1.0", - "dev": true, - "optional": true - }, - "string_decoder": { - "version": "1.1.1", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "dev": true - } - } - }, - "string.prototype.trim": { - "version": "1.2.3", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1" - } - }, - "string.prototype.trimend": { - "version": "1.0.3", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" - } - }, - "string.prototype.trimstart": { - "version": "1.0.3", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" - } + "peer": true }, - "strip-hex-prefix": { - "version": "1.0.0", + "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": { - "is-hex-prefixed": "1.0.0" + "color-convert": "^1.9.0" } }, - "supports-color": { - "version": "5.5.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": { - "has-flag": "^3.0.0" + "sprintf-js": "~1.0.2" } }, - "swarm-js": { - "version": "0.1.40", + "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, - "optional": true, - "requires": { - "bluebird": "^3.5.0", - "buffer": "^5.0.5", - "eth-lib": "^0.1.26", - "fs-extra": "^4.0.2", - "got": "^7.1.0", - "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": { - "fs-extra": { - "version": "4.0.3", - "dev": true, - "optional": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "get-stream": { - "version": "3.0.0", - "dev": true, - "optional": true - }, - "got": { - "version": "7.1.0", - "dev": true, - "optional": true, - "requires": { - "decompress-response": "^3.2.0", - "duplexer3": "^0.1.4", - "get-stream": "^3.0.0", - "is-plain-obj": "^1.1.0", - "is-retry-allowed": "^1.0.0", - "is-stream": "^1.0.0", - "isurl": "^1.0.0-alpha5", - "lowercase-keys": "^1.0.0", - "p-cancelable": "^0.3.0", - "p-timeout": "^1.1.1", - "safe-buffer": "^5.0.1", - "timed-out": "^4.0.0", - "url-parse-lax": "^1.0.0", - "url-to-options": "^1.0.1" - } - }, - "is-stream": { - "version": "1.1.0", - "dev": true, - "optional": true - }, - "p-cancelable": { - "version": "0.3.0", - "dev": true, - "optional": true - }, - "prepend-http": { - "version": "1.0.4", - "dev": true, - "optional": true - }, - "url-parse-lax": { - "version": "1.0.0", - "dev": true, - "optional": true, - "requires": { - "prepend-http": "^1.0.1" - } - } - } + "peer": true }, - "tape": { - "version": "4.13.3", + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true, - "requires": { - "deep-equal": "~1.1.1", - "defined": "~1.0.0", - "dotignore": "~0.1.2", - "for-each": "~0.3.3", - "function-bind": "~1.1.1", - "glob": "~7.1.6", - "has": "~1.0.3", - "inherits": "~2.0.4", - "is-regex": "~1.0.5", - "minimist": "~1.2.5", - "object-inspect": "~1.7.0", - "resolve": "~1.17.0", - "resumer": "~0.0.0", - "string.prototype.trim": "~1.2.1", - "through": "~2.3.8" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "dev": 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" - } - }, - "is-regex": { - "version": "1.0.5", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "object-inspect": { - "version": "1.7.0", - "dev": true - }, - "resolve": { - "version": "1.17.0", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - } - } + "peer": true }, - "tar": { - "version": "4.4.13", + "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, - "optional": true, + "peer": true, "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.8.6", - "minizlib": "^1.2.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.3" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" }, "dependencies": { - "fs-minipass": { - "version": "1.2.7", - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.6.0" - } - }, - "minipass": { - "version": "2.9.0", + "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, - "optional": true, + "peer": true, "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" + "has-flag": "^3.0.0" } } } }, - "through": { - "version": "2.3.8", - "dev": true - }, - "through2": { - "version": "2.0.5", + "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": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" + "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" } }, - "timed-out": { - "version": "4.0.1", - "dev": true, - "optional": true - }, - "tmp": { - "version": "0.1.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": { - "rimraf": "^2.6.3" + "colors": "^1.1.2", + "object-assign": "^4.1.0", + "string-width": "^2.1.1" } }, - "to-object-path": { - "version": "0.3.0", + "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": { - "kind-of": "^3.0.2" + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" }, "dependencies": { - "is-buffer": { - "version": "1.1.6", - "dev": 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==", + "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" + } }, - "kind-of": { - "version": "3.2.2", + "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": { - "is-buffer": "^1.1.5" + "ansi-regex": "^4.1.0" } } } }, - "to-readable-stream": { - "version": "1.0.0", - "dev": true, - "optional": true - }, - "to-regex": { - "version": "3.0.2", + "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": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" + "color-name": "1.1.3" } }, - "toidentifier": { - "version": "1.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, - "optional": true + "peer": true }, - "tough-cookie": { - "version": "2.5.0", + "colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", "dev": true, - "requires": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - } - }, - "trim-right": { - "version": "1.0.1", - "dev": true + "peer": true }, - "tunnel-agent": { - "version": "0.6.0", + "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": { - "safe-buffer": "^5.0.1" + "ms": "^2.1.1" } }, - "tweetnacl": { - "version": "1.0.3", - "dev": true - }, - "tweetnacl-util": { - "version": "0.15.1", - "dev": true - }, - "type": { + "decamelize": { "version": "1.2.0", - "dev": true - }, - "type-is": { - "version": "1.6.18", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", "dev": true, - "optional": true, - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - } + "peer": true }, - "typedarray": { - "version": "0.0.6", - "dev": true - }, - "typedarray-to-buffer": { - "version": "3.1.5", + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", "dev": true, - "requires": { - "is-typedarray": "^1.0.0" - } + "peer": true }, - "typewise": { - "version": "1.0.3", + "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, - "requires": { - "typewise-core": "^1.2.0" - } - }, - "typewise-core": { - "version": "1.2.0", - "dev": true - }, - "typewiselite": { - "version": "1.0.0", - "dev": true + "peer": true }, - "ultron": { - "version": "1.1.1", + "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, - "optional": true + "peer": true }, - "underscore": { - "version": "1.9.1", + "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, - "optional": true + "peer": true }, - "union-value": { - "version": "1.0.1", + "ethereum-cryptography": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.1.2.tgz", + "integrity": "sha512-XDSJlg4BD+hq9N2FjvotwUET9Tfxpxc3kWGE2AqUG5vcbeunnbImVk3cj6e/xT3phdW21mE8R5IugU4fspQDcQ==", "dev": true, + "peer": true, "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "0.1.1", - "dev": true - } + "@noble/hashes": "1.1.2", + "@noble/secp256k1": "1.6.3", + "@scure/bip32": "1.1.0", + "@scure/bip39": "1.1.0" } }, - "universalify": { - "version": "0.1.2", - "dev": true - }, - "unorm": { - "version": "1.6.0", - "dev": true - }, - "unpipe": { - "version": "1.0.0", - "dev": true, - "optional": true - }, - "unset-value": { - "version": "1.0.0", + "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": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "dev": true - } + "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" } }, - "uri-js": { - "version": "4.4.1", + "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, "requires": { - "punycode": "^2.1.0" + "locate-path": "^3.0.0" } }, - "urix": { - "version": "0.1.0", - "dev": true - }, - "url-parse-lax": { - "version": "3.0.0", + "flat": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz", + "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==", "dev": true, - "optional": true, + "peer": true, "requires": { - "prepend-http": "^2.0.0" + "is-buffer": "~2.0.3" } }, - "url-set-query": { - "version": "1.0.0", - "dev": true, - "optional": true - }, - "url-to-options": { - "version": "1.0.1", + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", "dev": true, - "optional": true - }, - "use": { - "version": "3.1.1", - "dev": true + "optional": true, + "peer": true }, - "utf-8-validate": { - "version": "5.0.4", + "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": { - "node-gyp-build": "^4.2.0" + "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" } }, - "utf8": { - "version": "3.0.0", - "dev": true, - "optional": true - }, - "util-deprecate": { - "version": "1.0.2", - "dev": true - }, - "util.promisify": { - "version": "1.1.1", + "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, "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "for-each": "^0.3.3", - "has-symbols": "^1.0.1", - "object.getownpropertydescriptors": "^2.1.1" + "is-glob": "^4.0.1" } }, - "utils-merge": { - "version": "1.0.1", - "dev": true, - "optional": true - }, - "uuid": { - "version": "3.4.0", - "dev": true - }, - "varint": { - "version": "5.0.2", - "dev": true, - "optional": true - }, - "vary": { - "version": "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, - "optional": true + "peer": true }, - "verror": { - "version": "1.10.0", + "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==", "dev": true, + "peer": true, "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.0" } }, - "web3": { - "version": "1.2.11", + "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, - "optional": true, - "requires": { - "web3-bzz": "1.2.11", - "web3-core": "1.2.11", - "web3-eth": "1.2.11", - "web3-eth-personal": "1.2.11", - "web3-net": "1.2.11", - "web3-shh": "1.2.11", - "web3-utils": "1.2.11" - } + "peer": true }, - "web3-bzz": { - "version": "1.2.11", + "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, - "optional": true, - "requires": { - "@types/node": "^12.12.6", - "got": "9.6.0", - "swarm-js": "^0.1.40", - "underscore": "1.9.1" - }, - "dependencies": { - "@types/node": { - "version": "12.19.12", - "dev": true, - "optional": true - } - } + "peer": true }, - "web3-core": { - "version": "1.2.11", + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", "dev": true, - "optional": true, + "peer": true, "requires": { - "@types/bn.js": "^4.11.5", - "@types/node": "^12.12.6", - "bignumber.js": "^9.0.0", - "web3-core-helpers": "1.2.11", - "web3-core-method": "1.2.11", - "web3-core-requestmanager": "1.2.11", - "web3-utils": "1.2.11" - }, - "dependencies": { - "@types/node": { - "version": "12.19.12", - "dev": true, - "optional": true - } + "argparse": "^1.0.7", + "esprima": "^4.0.0" } }, - "web3-core-helpers": { - "version": "1.2.11", + "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, - "optional": true, + "peer": true, "requires": { - "underscore": "1.9.1", - "web3-eth-iban": "1.2.11", - "web3-utils": "1.2.11" + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" } }, - "web3-core-method": { - "version": "1.2.11", + "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, - "optional": true, + "peer": true, "requires": { - "@ethersproject/transactions": "^5.0.0-beta.135", - "underscore": "1.9.1", - "web3-core-helpers": "1.2.11", - "web3-core-promievent": "1.2.11", - "web3-core-subscriptions": "1.2.11", - "web3-utils": "1.2.11" + "chalk": "^2.4.2" } }, - "web3-core-promievent": { - "version": "1.2.11", + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, - "optional": true, + "peer": true, "requires": { - "eventemitter3": "4.0.4" + "brace-expansion": "^1.1.7" } }, - "web3-core-requestmanager": { - "version": "1.2.11", + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", "dev": true, - "optional": true, + "peer": true, "requires": { - "underscore": "1.9.1", - "web3-core-helpers": "1.2.11", - "web3-providers-http": "1.2.11", - "web3-providers-ipc": "1.2.11", - "web3-providers-ws": "1.2.11" + "minimist": "^1.2.5" } }, - "web3-core-subscriptions": { - "version": "1.2.11", + "mocha": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", + "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", "dev": true, - "optional": true, + "peer": true, "requires": { - "eventemitter3": "4.0.4", - "underscore": "1.9.1", - "web3-core-helpers": "1.2.11" + "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" } }, - "web3-eth": { - "version": "1.2.11", + "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, - "optional": true, - "requires": { - "underscore": "1.9.1", - "web3-core": "1.2.11", - "web3-core-helpers": "1.2.11", - "web3-core-method": "1.2.11", - "web3-core-subscriptions": "1.2.11", - "web3-eth-abi": "1.2.11", - "web3-eth-accounts": "1.2.11", - "web3-eth-contract": "1.2.11", - "web3-eth-ens": "1.2.11", - "web3-eth-iban": "1.2.11", - "web3-eth-personal": "1.2.11", - "web3-net": "1.2.11", - "web3-utils": "1.2.11" - } + "peer": true }, - "web3-eth-abi": { - "version": "1.2.11", + "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, - "optional": true, + "peer": true, "requires": { - "@ethersproject/abi": "5.0.0-beta.153", - "underscore": "1.9.1", - "web3-utils": "1.2.11" + "p-try": "^2.0.0" } }, - "web3-eth-accounts": { - "version": "1.2.11", + "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==", "dev": true, - "optional": true, + "peer": true, "requires": { - "crypto-browserify": "3.12.0", - "eth-lib": "0.2.8", - "ethereumjs-common": "^1.3.2", - "ethereumjs-tx": "^2.1.1", - "scrypt-js": "^3.0.1", - "underscore": "1.9.1", - "uuid": "3.3.2", - "web3-core": "1.2.11", - "web3-core-helpers": "1.2.11", - "web3-core-method": "1.2.11", - "web3-utils": "1.2.11" - }, - "dependencies": { - "eth-lib": { - "version": "0.2.8", - "dev": true, - "optional": true, - "requires": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - } - }, - "uuid": { - "version": "3.3.2", - "dev": true, - "optional": true - } + "p-limit": "^2.0.0" } }, - "web3-eth-contract": { - "version": "1.2.11", + "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, - "optional": true, - "requires": { - "@types/bn.js": "^4.11.5", - "underscore": "1.9.1", - "web3-core": "1.2.11", - "web3-core-helpers": "1.2.11", - "web3-core-method": "1.2.11", - "web3-core-promievent": "1.2.11", - "web3-core-subscriptions": "1.2.11", - "web3-eth-abi": "1.2.11", - "web3-utils": "1.2.11" - } + "peer": true }, - "web3-eth-ens": { - "version": "1.2.11", + "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, - "optional": true, + "peer": true, "requires": { - "content-hash": "^2.5.2", - "eth-ens-namehash": "2.0.8", - "underscore": "1.9.1", - "web3-core": "1.2.11", - "web3-core-helpers": "1.2.11", - "web3-core-promievent": "1.2.11", - "web3-eth-abi": "1.2.11", - "web3-eth-contract": "1.2.11", - "web3-utils": "1.2.11" + "picomatch": "^2.0.4" } }, - "web3-eth-iban": { - "version": "1.2.11", + "scrypt-js": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.4.tgz", + "integrity": "sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw==", "dev": true, - "optional": true, - "requires": { - "bn.js": "^4.11.9", - "web3-utils": "1.2.11" - } + "peer": true }, - "web3-eth-personal": { - "version": "1.2.11", + "setimmediate": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz", + "integrity": "sha512-/TjEmXQVEzdod/FFskf3o7oOAsGhHf2j1dZqRFbDzq4F3mvvxflIIi4Hd3bLQE9y/CpwqfSQam5JakI/mi3Pog==", "dev": true, - "optional": true, - "requires": { - "@types/node": "^12.12.6", - "web3-core": "1.2.11", - "web3-core-helpers": "1.2.11", - "web3-core-method": "1.2.11", - "web3-net": "1.2.11", - "web3-utils": "1.2.11" - }, - "dependencies": { - "@types/node": { - "version": "12.19.12", - "dev": true, - "optional": true - } - } + "peer": true }, - "web3-net": { - "version": "1.2.11", + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "dev": true, - "optional": true, + "peer": true, "requires": { - "web3-core": "1.2.11", - "web3-core-method": "1.2.11", - "web3-utils": "1.2.11" + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" } }, - "web3-provider-engine": { - "version": "14.2.1", + "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": { - "async": "^2.5.0", - "backoff": "^2.5.0", - "clone": "^2.0.0", - "cross-fetch": "^2.1.0", - "eth-block-tracker": "^3.0.0", - "eth-json-rpc-infura": "^3.1.0", - "eth-sig-util": "3.0.0", - "ethereumjs-block": "^1.2.2", - "ethereumjs-tx": "^1.2.0", - "ethereumjs-util": "^5.1.5", - "ethereumjs-vm": "^2.3.4", - "json-rpc-error": "^2.0.0", - "json-stable-stringify": "^1.0.1", - "promise-to-callback": "^1.0.0", - "readable-stream": "^2.2.9", - "request": "^2.85.0", - "semaphore": "^1.0.3", - "ws": "^5.1.1", - "xhr": "^2.2.0", - "xtend": "^4.0.1" - }, - "dependencies": { - "abstract-leveldown": { - "version": "2.6.3", - "dev": true, - "requires": { - "xtend": "~4.0.0" - } - }, - "deferred-leveldown": { - "version": "1.2.2", - "dev": true, - "requires": { - "abstract-leveldown": "~2.6.0" - } - }, - "eth-sig-util": { - "version": "1.4.2", - "dev": true, - "requires": { - "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git", - "ethereumjs-util": "^5.1.1" - } - }, - "ethereumjs-account": { - "version": "2.0.5", - "dev": true, - "requires": { - "ethereumjs-util": "^5.0.0", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - }, - "ethereumjs-block": { - "version": "1.7.1", - "dev": true, - "requires": { - "async": "^2.0.1", - "ethereum-common": "0.2.0", - "ethereumjs-tx": "^1.2.2", - "ethereumjs-util": "^5.0.0", - "merkle-patricia-tree": "^2.1.2" - }, - "dependencies": { - "ethereum-common": { - "version": "0.2.0", - "dev": true - } - } - }, - "ethereumjs-tx": { - "version": "1.3.7", - "dev": true, - "requires": { - "ethereum-common": "^0.0.18", - "ethereumjs-util": "^5.0.0" - } - }, - "ethereumjs-util": { - "version": "5.2.1", - "dev": true, - "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - }, - "ethereumjs-vm": { - "version": "2.6.0", - "dev": true, - "requires": { - "async": "^2.1.2", - "async-eventemitter": "^0.2.2", - "ethereumjs-account": "^2.0.3", - "ethereumjs-block": "~2.2.0", - "ethereumjs-common": "^1.1.0", - "ethereumjs-util": "^6.0.0", - "fake-merkle-patricia-tree": "^1.0.1", - "functional-red-black-tree": "^1.0.1", - "merkle-patricia-tree": "^2.3.2", - "rustbn.js": "~0.2.0", - "safe-buffer": "^5.1.1" - }, - "dependencies": { - "ethereumjs-block": { - "version": "2.2.2", - "dev": true, - "requires": { - "async": "^2.0.1", - "ethereumjs-common": "^1.5.0", - "ethereumjs-tx": "^2.1.1", - "ethereumjs-util": "^5.0.0", - "merkle-patricia-tree": "^2.1.2" - }, - "dependencies": { - "ethereumjs-util": { - "version": "5.2.1", - "dev": true, - "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - } - } - }, - "ethereumjs-tx": { - "version": "2.1.2", - "dev": true, - "requires": { - "ethereumjs-common": "^1.5.0", - "ethereumjs-util": "^6.0.0" - } - }, - "ethereumjs-util": { - "version": "6.2.1", - "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" - } - } - } - }, - "isarray": { - "version": "0.0.1", - "dev": true - }, - "level-codec": { - "version": "7.0.1", - "dev": true - }, - "level-errors": { - "version": "1.0.5", - "dev": true, - "requires": { - "errno": "~0.1.1" - } - }, - "level-iterator-stream": { - "version": "1.3.1", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "level-errors": "^1.0.3", - "readable-stream": "^1.0.33", - "xtend": "^4.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "1.1.14", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - } - } - }, - "level-ws": { - "version": "0.0.0", - "dev": true, - "requires": { - "readable-stream": "~1.0.15", - "xtend": "~2.1.1" - }, - "dependencies": { - "readable-stream": { - "version": "1.0.34", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "xtend": { - "version": "2.1.2", - "dev": true, - "requires": { - "object-keys": "~0.4.0" - } - } - } - }, - "levelup": { - "version": "1.3.9", - "dev": true, - "requires": { - "deferred-leveldown": "~1.2.1", - "level-codec": "~7.0.0", - "level-errors": "~1.0.3", - "level-iterator-stream": "~1.3.0", - "prr": "~1.0.1", - "semver": "~5.4.1", - "xtend": "~4.0.0" - } - }, - "ltgt": { - "version": "2.2.1", - "dev": true - }, - "memdown": { - "version": "1.4.1", - "dev": true, - "requires": { - "abstract-leveldown": "~2.7.1", - "functional-red-black-tree": "^1.0.1", - "immediate": "^3.2.3", - "inherits": "~2.0.1", - "ltgt": "~2.2.0", - "safe-buffer": "~5.1.1" - }, - "dependencies": { - "abstract-leveldown": { - "version": "2.7.2", - "dev": true, - "requires": { - "xtend": "~4.0.0" - } - } - } - }, - "merkle-patricia-tree": { - "version": "2.3.2", - "dev": true, - "requires": { - "async": "^1.4.2", - "ethereumjs-util": "^5.0.0", - "level-ws": "0.0.0", - "levelup": "^1.2.1", - "memdown": "^1.0.0", - "readable-stream": "^2.0.0", - "rlp": "^2.0.0", - "semaphore": ">=1.0.1" - }, - "dependencies": { - "async": { - "version": "1.5.2", - "dev": true - } - } - }, - "object-keys": { - "version": "0.4.0", - "dev": true - }, - "safe-buffer": { - "version": "5.1.2", - "dev": true - }, - "semver": { - "version": "5.4.1", - "dev": true - }, - "string_decoder": { - "version": "0.10.31", - "dev": true - }, - "ws": { - "version": "5.2.2", - "dev": true, - "requires": { - "async-limiter": "~1.0.0" - } - } + "ansi-regex": "^3.0.0" } }, - "web3-providers-http": { - "version": "1.2.11", + "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, - "optional": true, - "requires": { - "web3-core-helpers": "1.2.11", - "xhr2-cookies": "1.1.0" - } + "peer": true }, - "web3-providers-ipc": { - "version": "1.2.11", + "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, - "optional": true, + "peer": true, "requires": { - "oboe": "2.1.4", - "underscore": "1.9.1", - "web3-core-helpers": "1.2.11" + "has-flag": "^3.0.0" } }, - "web3-providers-ws": { - "version": "1.2.11", + "uuid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz", + "integrity": "sha512-nWg9+Oa3qD2CQzHIP4qKUqwNfzKn8P0LtFhotaCTFchsV7ZfDhAybeip/HZVeMIpZi9JgY1E3nUlwaCmZT1sEg==", "dev": true, - "optional": true, - "requires": { - "eventemitter3": "4.0.4", - "underscore": "1.9.1", - "web3-core-helpers": "1.2.11", - "websocket": "^1.0.31" - } + "peer": true }, - "web3-shh": { - "version": "1.2.11", + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, - "optional": true, + "peer": true, "requires": { - "web3-core": "1.2.11", - "web3-core-method": "1.2.11", - "web3-core-subscriptions": "1.2.11", - "web3-net": "1.2.11" + "isexe": "^2.0.0" } }, - "web3-utils": { - "version": "1.2.11", + "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, - "optional": true, + "peer": true, "requires": { - "bn.js": "^4.11.9", - "eth-lib": "0.2.8", - "ethereum-bloom-filters": "^1.0.6", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "underscore": "1.9.1", - "utf8": "3.0.0" + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" }, "dependencies": { - "eth-lib": { - "version": "0.2.8", + "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, - "optional": true, + "peer": true, "requires": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" + "ansi-regex": "^4.1.0" } } } }, - "websocket": { - "version": "1.0.32", + "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": { - "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" + "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": { - "debug": { - "version": "2.6.9", + "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": { - "ms": "2.0.0" + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" } }, - "ms": { - "version": "2.0.0", - "dev": true + "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" + } } } }, - "whatwg-fetch": { - "version": "2.0.4", - "dev": true - }, - "wrappy": { - "version": "1.0.2", - "dev": true - }, - "ws": { - "version": "3.3.3", + "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, - "optional": true, + "peer": true, "requires": { - "async-limiter": "~1.0.0", - "safe-buffer": "~5.1.0", - "ultron": "~1.1.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "dev": true, - "optional": true - } + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" } }, - "xhr": { - "version": "2.6.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==", "dev": true, + "peer": true, "requires": { - "global": "~4.4.0", - "is-function": "^1.0.1", - "parse-headers": "^2.0.0", - "xtend": "^4.0.0" + "flat": "^4.1.0", + "lodash": "^4.17.15", + "yargs": "^13.3.0" } - }, - "xhr-request": { - "version": "1.1.0", + } + } + }, + "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" + } + }, + "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, + "requires": { + "@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" + } + }, + "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, + "requires": { + "bn.js": "^4.11.8", + "ethereumjs-util": "^6.0.0" + }, + "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, - "optional": 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" + "@types/node": "*" } }, - "xhr-request-promise": { - "version": "0.1.3", + "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, - "optional": true, "requires": { - "xhr-request": "^1.1.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" } - }, - "xhr2-cookies": { - "version": "1.1.0", + } + } + }, + "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, + "requires": { + "@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" + } + }, + "ethers": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", + "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", + "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/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" + } + }, + "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, + "requires": { + "bn.js": "4.11.6", + "number-to-bn": "1.7.0" + }, + "dependencies": { + "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, + "peer": true + } + } + }, + "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, + "requires": { + "is-hex-prefixed": "1.0.0", + "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==", + "dev": true + }, + "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, + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "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 + }, + "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, + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + } + }, + "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 + }, + "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 + }, + "fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "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==", + "dev": true, + "requires": { + "@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" + }, + "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, - "optional": true, "requires": { - "cookiejar": "^2.1.1" + "is-glob": "^4.0.1" } - }, - "xtend": { - "version": "4.0.2", - "dev": true - }, - "yaeti": { - "version": "0.0.6", - "dev": true - }, - "yallist": { - "version": "3.1.1", + } + } + }, + "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 + }, + "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 + }, + "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, + "requires": { + "reusify": "^1.0.4" + } + }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + }, + "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 } } }, + "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, + "requires": { + "flat-cache": "^3.0.4" + } + }, + "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 + }, + "filenamify": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.3.0.tgz", + "integrity": "sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==", + "dev": true, + "requires": { + "filename-reserved-regex": "^2.0.0", + "strip-outer": "^1.0.1", + "trim-repeated": "^1.0.0" + } + }, + "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, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "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, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + } + }, + "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, + "requires": { + "array-back": "^3.0.1" + } + }, + "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, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true + }, + "flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "requires": { + "flatted": "^3.1.0", + "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==", + "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==", + "dev": true + }, + "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, + "requires": { + "is-callable": "^1.1.3" + } + }, + "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 + }, + "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, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "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 + }, + "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, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "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 + }, + "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 + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "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==", + "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==", + "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" + } + }, + "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 + }, + "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 + }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -33481,7 +16423,8 @@ "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 + "dev": true, + "peer": true }, "get-intrinsic": { "version": "1.1.3", @@ -33498,13 +16441,15 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", "integrity": "sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==", - "dev": true + "dev": true, + "peer": true }, "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" @@ -33515,6 +16460,7 @@ "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" } @@ -33580,6 +16526,7 @@ "resolved": "https://registry.npmjs.org/ghost-testrpc/-/ghost-testrpc-0.0.2.tgz", "integrity": "sha512-i08dAEgJ2g8z5buJIrCTduwPIhih3DP+hOCTyyryikfV8T0bNvHnGXO67i0DD1H4GBDETTclPy9njZbfluQYrQ==", "dev": true, + "peer": true, "requires": { "chalk": "^2.4.2", "node-emoji": "^1.10.0" @@ -33590,6 +16537,7 @@ "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" } @@ -33599,6 +16547,7 @@ "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", @@ -33610,6 +16559,7 @@ "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" } @@ -33618,25 +16568,29 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true + "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 + "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 + "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" } @@ -33671,6 +16625,7 @@ "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", "dev": true, + "peer": true, "requires": { "global-prefix": "^3.0.0" } @@ -33680,6 +16635,7 @@ "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", "dev": true, + "peer": true, "requires": { "ini": "^1.3.5", "kind-of": "^6.0.2", @@ -33691,19 +16647,30 @@ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, + "peer": true, "requires": { "isexe": "^2.0.0" } } } }, - "globals": { - "version": "13.17.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", - "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "globals": { + "version": "13.19.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", + "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", "dev": true, + "peer": true, "requires": { - "type-fest": "^0.20.2" + "define-properties": "^1.1.3" } }, "globby": { @@ -33720,6 +16687,16 @@ "slash": "^3.0.0" } }, + "gopd": { + "version": "1.0.1", + "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" + } + }, "graceful-fs": { "version": "4.2.10", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", @@ -33736,13 +16713,15 @@ "version": "1.10.5", "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true + "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==", "dev": true, + "peer": true, "requires": { "minimist": "^1.2.5", "neo-async": "^2.6.0", @@ -33755,7 +16734,8 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true + "dev": true, + "peer": true } } }, @@ -33763,22 +16743,24 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", - "dev": true + "dev": true, + "peer": 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.12.2", - "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.12.2.tgz", - "integrity": "sha512-f3ZhzXy1uyQv0UXnAQ8GCBOWjzv++WJNb7bnm10SsyC3dB7vlPpsMWBNhq7aoRxKrNhX9tCev81KFV3i5BTeMQ==", + "version": "2.12.6", + "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.12.6.tgz", + "integrity": "sha512-0Ent1O5DsPgvaVb5sxEgsQ3bJRt/Ex92tsoO+xjoNH2Qc4bFmhI5/CHVlFikulalxOPjNmw5XQ2vJFuVQFESAA==", "dev": true, "requires": { "@ethersproject/abi": "^5.1.2", @@ -33828,7 +16810,7 @@ "source-map-support": "^0.5.13", "stacktrace-parser": "^0.1.10", "tsort": "0.0.1", - "undici": "^5.4.0", + "undici": "^5.14.0", "uuid": "^8.3.2", "ws": "^7.4.6" }, @@ -33868,12 +16850,6 @@ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, - "commander": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz", - "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==", - "dev": true - }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", @@ -33907,15 +16883,6 @@ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true }, - "jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, "locate-path": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", @@ -33956,53 +16923,6 @@ "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", "dev": true }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "solc": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/solc/-/solc-0.7.3.tgz", - "integrity": "sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA==", - "dev": true, - "requires": { - "command-exists": "^1.2.8", - "commander": "3.0.2", - "follow-redirects": "^1.12.1", - "fs-extra": "^0.30.0", - "js-sha3": "0.8.0", - "memorystream": "^0.3.1", - "require-from-string": "^2.0.0", - "semver": "^5.5.0", - "tmp": "0.0.33" - }, - "dependencies": { - "fs-extra": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", - "integrity": "sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0", - "path-is-absolute": "^1.0.0", - "rimraf": "^2.2.8" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -34014,11 +16934,22 @@ } } }, + "hardhat-contract-sizer": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/hardhat-contract-sizer/-/hardhat-contract-sizer-2.6.1.tgz", + "integrity": "sha512-b8wS7DBvyo22kmVwpzstAQTdDCThpl/ySBqZh5ga9Yxjf61/uTL12TEg5nl7lDeWy73ntEUzxMwY6XxbQEc2wA==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "cli-table3": "^0.6.0" + } + }, "hardhat-gas-reporter": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.9.tgz", "integrity": "sha512-INN26G3EW43adGKBNzYWOlI3+rlLnasXTwW79YNnUhXPDa+yHESgt639dJEs37gCjhkbNKcRRJnomXEuMFBXJg==", "dev": true, + "peer": true, "requires": { "array-uniq": "1.0.3", "eth-gas-reporter": "^0.2.25", @@ -34026,9 +16957,9 @@ } }, "hardhat-tracer": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/hardhat-tracer/-/hardhat-tracer-1.1.1.tgz", - "integrity": "sha512-NgOnnNAvARBtYC5x5c7Qcbw+lr+Jb+0OV1NC2tTpUUQj0ym+/0y42F0CYT/zKnHw3uf046NKg0CNTzYg1j0JWg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/hardhat-tracer/-/hardhat-tracer-1.2.1.tgz", + "integrity": "sha512-ZZVXZfWfRzPkjGdkLoxC4v3Dqja7cpG1mOOr+3+m9xGmqfw9P6cKMDo+wYtGPNM6KttwsJ226Gqt5AwBjMxgTg==", "dev": true, "requires": { "ethers": "^5.6.1" @@ -34047,7 +16978,8 @@ "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 + "dev": true, + "peer": true }, "has-flag": { "version": "4.0.0", @@ -34060,10 +16992,18 @@ "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", "dev": true, + "peer": true, "requires": { "get-intrinsic": "^1.1.1" } }, + "has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "dev": true, + "peer": true + }, "has-symbols": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", @@ -34075,6 +17015,7 @@ "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" } @@ -34110,7 +17051,8 @@ "version": "0.2.7", "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.7.tgz", "integrity": "sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==", - "dev": true + "dev": true, + "peer": true }, "hmac-drbg": { "version": "1.0.1", @@ -34123,17 +17065,12 @@ "minimalistic-crypto-utils": "^1.0.1" } }, - "hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, "http-basic": { "version": "8.1.3", "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz", "integrity": "sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==", "dev": true, + "peer": true, "requires": { "caseless": "^0.12.0", "concat-stream": "^1.6.2", @@ -34159,6 +17096,7 @@ "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz", "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==", "dev": true, + "peer": true, "requires": { "@types/node": "^10.0.3" }, @@ -34167,7 +17105,8 @@ "version": "10.17.60", "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==", - "dev": true + "dev": true, + "peer": true } } }, @@ -34176,6 +17115,7 @@ "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", @@ -34201,15 +17141,6 @@ "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" - } - }, "ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", @@ -34217,15 +17148,15 @@ "dev": true }, "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", "dev": true }, "immutable": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz", - "integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.2.2.tgz", + "integrity": "sha512-fTMKDwtbvO5tldky9QZ2fMX7slR0mYpY5nbnFWYp0fOzDhHqhgIw9KoYgxLWsoNTS9ZHGauHj18DTyEw6BK3Og==", "dev": true }, "import-fresh": { @@ -34270,7 +17201,8 @@ "version": "1.3.8", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true + "dev": true, + "peer": true }, "inquirer": { "version": "6.5.2", @@ -34352,6 +17284,39 @@ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": 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 + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "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 + }, + "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, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, "strip-ansi": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", @@ -34373,12 +17338,13 @@ } }, "internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.4.tgz", + "integrity": "sha512-tA8URYccNzMo94s5MQZgH8NB/XTa6HsOo0MLfXTKKEnHVVdegzaQoFZ7Jp44bdvLvY2waT5dc+j5ICEswhi7UQ==", "dev": true, + "peer": true, "requires": { - "get-intrinsic": "^1.1.0", + "get-intrinsic": "^1.1.3", "has": "^1.0.3", "side-channel": "^1.0.4" } @@ -34387,13 +17353,8 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", - "dev": true - }, - "invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ==", - "dev": true + "dev": true, + "peer": true }, "io-ts": { "version": "1.10.4", @@ -34404,6 +17365,18 @@ "fp-ts": "^1.0.0" } }, + "is-array-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.1.tgz", + "integrity": "sha512-ASfLknmY8Xa2XtB4wmbz13Wu202baeA18cJBCeCy0wXUHZF0IPyVEXqKEcd+t2fNSLLL1vC6k7lxZEojNbISXQ==", + "dev": true, + "peer": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-typed-array": "^1.1.10" + } + }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -34415,6 +17388,7 @@ "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" } @@ -34433,6 +17407,7 @@ "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" @@ -34448,22 +17423,15 @@ "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 - }, - "is-ci": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", - "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", "dev": true, - "requires": { - "ci-info": "^2.0.0" - } + "peer": 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" } @@ -34474,12 +17442,6 @@ "integrity": "sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw==", "dev": true }, - "is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "dev": true - }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -34487,9 +17449,9 @@ "dev": 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==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "is-glob": { @@ -34511,7 +17473,8 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", - "dev": true + "dev": true, + "peer": true }, "is-number": { "version": "7.0.0", @@ -34524,6 +17487,7 @@ "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" } @@ -34535,9 +17499,9 @@ "dev": true }, "is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "dev": true }, "is-regex": { @@ -34545,6 +17509,7 @@ "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" @@ -34555,6 +17520,7 @@ "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" } @@ -34564,6 +17530,7 @@ "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" } @@ -34573,15 +17540,31 @@ "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==", + "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" + } + }, "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true + "dev": true, + "peer": true }, "is-unicode-supported": { "version": "0.1.0", @@ -34589,41 +17572,22 @@ "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", "dev": true }, - "is-url": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", - "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==", - "dev": true - }, - "is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==", - "dev": true - }, "is-weakref": { "version": "1.0.2", "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" } }, - "is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, - "requires": { - "is-docker": "^2.0.0" - } - }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true + "dev": true, + "peer": true }, "isexe": { "version": "2.0.0", @@ -34635,12 +17599,13 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", - "dev": true + "dev": true, + "peer": true }, "js-sdsl": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.5.tgz", - "integrity": "sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.2.0.tgz", + "integrity": "sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ==", "dev": true }, "js-sha3": { @@ -34668,7 +17633,8 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", - "dev": true + "dev": true, + "peer": true }, "json-parse-better-errors": { "version": "1.0.2", @@ -34680,7 +17646,8 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", - "dev": true + "dev": true, + "peer": true }, "json-schema-traverse": { "version": "0.4.1", @@ -34698,7 +17665,8 @@ "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 + "dev": true, + "peer": true }, "jsonfile": { "version": "4.0.0", @@ -34713,13 +17681,15 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.1.tgz", "integrity": "sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ==", - "dev": true + "dev": true, + "peer": true }, "jsprim": { "version": "1.4.2", "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", @@ -34728,9 +17698,9 @@ } }, "keccak": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.2.tgz", - "integrity": "sha512-PyKKjkH53wDMLGrvmRGSNWgmSxZOUqbnXwKL9tmgbFYA1iAYqW21kfR7mZXV0MlESiefxQQE9X9fTa3X+2MPDQ==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.3.tgz", + "integrity": "sha512-JZrLIAJWuZxKbCilMpNz5Vj7Vtb4scDG3dMXLOsbzBmQGyjwE61BbW7bJkfKKCShXiQZt3T6sBgALRtmd+nZaQ==", "dev": true, "requires": { "node-addon-api": "^2.0.0", @@ -34738,22 +17708,12 @@ "readable-stream": "^3.6.0" } }, - "keccak256": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/keccak256/-/keccak256-1.0.6.tgz", - "integrity": "sha512-8GLiM01PkdJVGUhR1e6M/AvWnSqYS0HaERI+K/QtStGDGlSTx2B1zTqZk4Zlqu5TxHJNTxWAdP9Y+WI50OApUw==", - "dev": true, - "requires": { - "bn.js": "^5.2.0", - "buffer": "^6.0.3", - "keccak": "^3.0.2" - } - }, "kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true + "dev": true, + "peer": true }, "klaw": { "version": "1.3.1", @@ -34764,30 +17724,12 @@ "graceful-fs": "^4.1.9" } }, - "klaw-sync": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz", - "integrity": "sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11" - } - }, "kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", "dev": true }, - "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw==", - "dev": true, - "requires": { - "invert-kv": "^1.0.0" - } - }, "level": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/level/-/level-8.0.0.tgz", @@ -34824,18 +17766,6 @@ "type-check": "~0.4.0" } }, - "load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - } - }, "locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -34851,11 +17781,12 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, - "lodash.assign": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", - "integrity": "sha512-hFuH8TY+Yji7Eja3mGiuAxBqLagejScbG8GbG0j6o9vzn0YL14My+ktnqtZgFTosKymC9/44wP6s7xyuLfnClw==", - "dev": true + "lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "dev": true, + "peer": true }, "lodash.merge": { "version": "4.6.2", @@ -34867,7 +17798,8 @@ "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", - "dev": true + "dev": true, + "peer": true }, "log-symbols": { "version": "4.1.0", @@ -34879,21 +17811,12 @@ "is-unicode-supported": "^0.1.0" } }, - "loud-rejection": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", - "integrity": "sha512-RPNliZOFkqFumDhvYqOaNY4Uz9oJM2K9tC6JWsJJsNdhuONW4LQHRBpb0qf4pJApVffI5N39SwzWZJuEhfd7eQ==", - "dev": true, - "requires": { - "currently-unhandled": "^0.4.1", - "signal-exit": "^3.0.0" - } - }, "loupe": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz", "integrity": "sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==", "dev": true, + "peer": true, "requires": { "get-func-name": "^2.0.0" } @@ -34928,17 +17851,12 @@ "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "dev": true }, - "map-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz", - "integrity": "sha512-TzQSV2DiMYgoF5RycneKVUzIa9bQsj/B3tTgsE3dOGqlzHnGIDaC7XBE7grnA+8kZPnfqSGFe95VHc2oc0VFUQ==", - "dev": true - }, "markdown-table": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.3.tgz", "integrity": "sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==", - "dev": true + "dev": true, + "peer": true }, "mcl-wasm": { "version": "0.7.9", @@ -34974,23 +17892,6 @@ "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", "dev": true }, - "meow": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-5.0.0.tgz", - "integrity": "sha512-CbTqYU17ABaLefO8vCU153ZZlprKYWDljcndKKDCFcYQITzWCXZAVk4QMFZPgvzrnUQ3uItnIE/LoUOwrT15Ig==", - "dev": true, - "requires": { - "camelcase-keys": "^4.0.0", - "decamelize-keys": "^1.0.0", - "loud-rejection": "^1.0.0", - "minimist-options": "^3.0.1", - "normalize-package-data": "^2.3.4", - "read-pkg-up": "^3.0.0", - "redent": "^2.0.0", - "trim-newlines": "^2.0.0", - "yargs-parser": "^10.0.0" - } - }, "merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -35011,13 +17912,15 @@ "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true + "dev": true, + "peer": 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" } @@ -35055,16 +17958,6 @@ "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", "dev": true }, - "minimist-options": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-3.0.2.tgz", - "integrity": "sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ==", - "dev": true, - "requires": { - "arrify": "^1.0.1", - "is-plain-obj": "^1.1.0" - } - }, "mkdirp": { "version": "0.5.6", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", @@ -35084,9 +17977,9 @@ } }, "mocha": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.1.0.tgz", - "integrity": "sha512-vUF7IYxEoN7XhQpFLxQAEMtE4W91acW4B6En9l97MwE9stL1A9gusXfoHZCLVHDUJ/7V5+lbCM6yMqzo5vNymg==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", + "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==", "dev": true, "requires": { "ansi-colors": "4.1.1", @@ -35150,12 +18043,6 @@ "requires": { "has-flag": "^4.0.0" } - }, - "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 } } }, @@ -35205,7 +18092,8 @@ "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true + "dev": true, + "peer": true }, "nice-try": { "version": "1.0.5", @@ -35224,6 +18112,7 @@ "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", "integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==", "dev": true, + "peer": true, "requires": { "lodash": "^4.17.21" } @@ -35233,6 +18122,7 @@ "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" @@ -35242,29 +18132,21 @@ "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true + "dev": true, + "peer": true } } }, - "node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "dev": true, - "requires": { - "whatwg-url": "^5.0.0" - } - }, "node-gyp-build": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.5.0.tgz", - "integrity": "sha512-2iGbaQBV+ITgCz76ZEjmhUKAKVf7xfY1sRl4UiKQspfZMH2h06SyhNsnSVy50cwkFQDGLyif6m/6uFXHkOZ6rg==", + "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==", "dev": true }, "nofilter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-1.0.4.tgz", - "integrity": "sha512-N8lidFp+fCz+TD51+haYdbDGrcBWwuHX40F5+z0qkUjMJ5Tp+rdSuAkMJ9N9eoolDlEVTf6u5icM+cNKkKW2mA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-3.1.0.tgz", + "integrity": "sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==", "dev": true }, "nopt": { @@ -35272,47 +18154,23 @@ "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", "integrity": "sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg==", "dev": true, + "peer": true, "requires": { "abbrev": "1" } }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", - "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" @@ -35322,7 +18180,8 @@ "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 + "dev": true, + "peer": true } } }, @@ -35330,7 +18189,8 @@ "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true + "dev": true, + "peer": true }, "object-assign": { "version": "4.1.1", @@ -35348,13 +18208,15 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true + "dev": true, + "peer": 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", @@ -35367,6 +18229,7 @@ "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.5.tgz", "integrity": "sha512-yDNzckpM6ntyQiGTik1fKV1DcVDRS+w8bvpWNCBanvH5LfRX9O8WTHqQzG4RZwRAM4I0oU7TV11Lj5v0g20ibw==", "dev": true, + "peer": true, "requires": { "array.prototype.reduce": "^1.0.5", "call-bind": "^1.0.2", @@ -35398,16 +18261,6 @@ "mimic-fn": "^1.0.0" } }, - "open": { - "version": "7.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", - "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", - "dev": true, - "requires": { - "is-docker": "^2.0.0", - "is-wsl": "^2.1.1" - } - }, "optionator": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", @@ -35422,14 +18275,12 @@ "word-wrap": "^1.2.3" } }, - "os-locale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g==", + "ordinal": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/ordinal/-/ordinal-1.0.3.tgz", + "integrity": "sha512-cMddMgb2QElm8G7vdaa02jhUNbTSrhsgAGUz1OokD83uJTwSUn+nKoNoKVVaRa08yF6sgfO7Maou1+bgLd9rdQ==", "dev": true, - "requires": { - "lcid": "^1.0.0" - } + "peer": true }, "os-tmpdir": { "version": "1.0.2", @@ -35483,7 +18334,8 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", "integrity": "sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==", - "dev": true + "dev": true, + "peer": true }, "parse-json": { "version": "4.0.0", @@ -35495,100 +18347,6 @@ "json-parse-better-errors": "^1.0.1" } }, - "patch-package": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-6.5.0.tgz", - "integrity": "sha512-tC3EqJmo74yKqfsMzELaFwxOAu6FH6t+FzFOsnWAuARm7/n2xB5AOeOueE221eM9gtMuIKMKpF9tBy/X2mNP0Q==", - "dev": true, - "requires": { - "@yarnpkg/lockfile": "^1.1.0", - "chalk": "^4.1.2", - "cross-spawn": "^6.0.5", - "find-yarn-workspace-root": "^2.0.0", - "fs-extra": "^7.0.1", - "is-ci": "^2.0.0", - "klaw-sync": "^6.0.0", - "minimist": "^1.2.6", - "open": "^7.4.2", - "rimraf": "^2.6.3", - "semver": "^5.6.0", - "slash": "^2.0.0", - "tmp": "^0.0.33", - "yaml": "^1.10.2" - }, - "dependencies": { - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", - "dev": true - }, - "slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", - "dev": true - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "path-browserify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", - "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", - "dev": true - }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -35629,7 +18387,8 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "dev": true + "dev": true, + "peer": true }, "pbkdf2": { "version": "3.1.2", @@ -35648,7 +18407,8 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", - "dev": true + "dev": true, + "peer": true }, "picomatch": { "version": "2.3.1", @@ -35657,10 +18417,11 @@ "dev": true }, "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "dev": true + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "peer": true }, "pinkie": { "version": "2.0.4", @@ -35725,12 +18486,6 @@ } } }, - "postinstall-postinstall": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/postinstall-postinstall/-/postinstall-postinstall-2.1.0.tgz", - "integrity": "sha512-7hQX6ZlZXIoRiWNrbMQaLzUUfH+sSx39u8EJ9HYuDc1kLo9IXKWjM5RSquZN1ad5GnH8CGFM78fsAAQi3OKEEQ==", - "dev": true - }, "prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -35748,7 +18503,8 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true + "dev": true, + "peer": true }, "progress": { "version": "2.0.3", @@ -35761,6 +18517,7 @@ "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==", "dev": true, + "peer": true, "requires": { "asap": "~2.0.6" } @@ -35787,146 +18544,52 @@ } }, "psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", - "dev": true - }, - "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 - }, - "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" - } - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==", - "dev": true - }, - "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": "1.1.0", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-1.1.0.tgz", - "integrity": "sha512-tRS7sTgyxMXtLum8L65daJnHUhfDUgboRdcWW2bR9vBfrj2+O5HSMbQOJfJJjIVSPFqbBCF37FpwWXGitDc5tA==", - "dev": true - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "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" - } - }, - "read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", - "dev": true, - "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - }, - "dependencies": { - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "requires": { - "pify": "^3.0.0" - } - } - } - }, - "read-pkg-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", - "integrity": "sha512-YFzFrVvpC6frF1sz8psoHDBGF7fLPc+llq/8NB43oagqWkx8ar5zYtsTORtOjw9W2RHLpWP+zTWwBvf1bCmcSw==", - "dev": true, - "requires": { - "find-up": "^2.0.0", - "read-pkg": "^3.0.0" - }, - "dependencies": { - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", - "dev": true, - "requires": { - "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", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true - } + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", + "dev": true, + "peer": true + }, + "punycode": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.2.0.tgz", + "integrity": "sha512-LN6QV1IJ9ZhxWTNdktaPClrNfp8xdSAYS0Zk2ddX7XsXZAxckMHPCBcHRo0cTcEIgYPRiGEkmji3Idkh2yFtYw==", + "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" + } + }, + "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 + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "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" } }, "readable-stream": { @@ -35954,6 +18617,7 @@ "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", "dev": true, + "peer": true, "requires": { "resolve": "^1.1.6" } @@ -35963,33 +18627,24 @@ "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", "dev": true, + "peer": true, "requires": { "minimatch": "^3.0.5" } }, - "redent": { + "reduce-flatten": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz", - "integrity": "sha512-XNwrTx77JQCEMXTeb8movBKuK75MgH0RZkujNuDKCezemx/voapl9i2gCSi8WWm8+ox5ycJi1gxF22fR7c0Ciw==", + "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-2.0.0.tgz", + "integrity": "sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w==", "dev": true, - "requires": { - "indent-string": "^3.0.0", - "strip-indent": "^2.0.0" - }, - "dependencies": { - "indent-string": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", - "integrity": "sha512-BYqTHXTGUIvg7t1r4sJNKcbDZkL92nkXA8YtRpbjFHRHGDL/NtUeiBJMeE60kIFN/Mg8ESaWQvftaYMGJzQZCQ==", - "dev": true - } - } + "peer": true }, "regexp.prototype.flags": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", "dev": true, + "peer": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.3", @@ -36007,6 +18662,7 @@ "resolved": "https://registry.npmjs.org/req-cwd/-/req-cwd-2.0.0.tgz", "integrity": "sha512-ueoIoLo1OfB6b05COxAA9UpeoscNpYyM+BqYlA7H6LVF4hKGPXQQSSaD2YmvDVJMkk4UDpAHIeU1zG53IqjvlQ==", "dev": true, + "peer": true, "requires": { "req-from": "^2.0.0" } @@ -36016,6 +18672,7 @@ "resolved": "https://registry.npmjs.org/req-from/-/req-from-2.0.0.tgz", "integrity": "sha512-LzTfEVDVQHBRfjOUMgNBA+V6DWsSnoeKzf42J7l0xa/B4jyPOuuF5MlNSmomLNGemWTnV2TIdjSSLnEn95fOQA==", "dev": true, + "peer": true, "requires": { "resolve-from": "^3.0.0" }, @@ -36024,7 +18681,8 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", - "dev": true + "dev": true, + "peer": true } } }, @@ -36033,6 +18691,7 @@ "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", @@ -36056,28 +18715,19 @@ "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 + "dev": true, + "peer": 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 + "dev": true, + "peer": true } } }, @@ -36086,6 +18736,7 @@ "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" } @@ -36095,6 +18746,7 @@ "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", @@ -36114,10 +18766,11 @@ "dev": true }, "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==", - "dev": true + "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", @@ -36234,6 +18887,7 @@ "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", @@ -36251,6 +18905,7 @@ "resolved": "https://registry.npmjs.org/sc-istanbul/-/sc-istanbul-0.4.6.tgz", "integrity": "sha512-qJFF/8tW/zJsbyfh/iT/ZM5QNHE3CXxtLJbZsL+CzdJLBsPD7SedJZoUA4d8iAcN2IoMp/Dx80shOOd2x96X/g==", "dev": true, + "peer": true, "requires": { "abbrev": "1.0.x", "async": "1.x", @@ -36273,6 +18928,7 @@ "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" } @@ -36281,13 +18937,15 @@ "version": "1.5.2", "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==", - "dev": true + "dev": true, + "peer": true }, "glob": { "version": "5.0.15", "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", "integrity": "sha512-c9IPMazfRITpmAAKi22dK1VKxGDX9ehhqfABDriL/lzO92xcUKEJPQHrVA/2YHSNFB4iFlykVmWvwo48nr3OxA==", "dev": true, + "peer": true, "requires": { "inflight": "^1.0.4", "inherits": "2", @@ -36300,13 +18958,15 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", "integrity": "sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA==", - "dev": true + "dev": true, + "peer": true }, "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": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -36316,7 +18976,8 @@ "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 + "dev": true, + "peer": true } } }, @@ -36324,13 +18985,15 @@ "version": "1.1.7", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", "integrity": "sha512-9znBF0vBcaSN3W2j7wKvdERPwqTxSpCq+if5C0WoTCyV9n24rua28jeuQ2pL/HOf+yUe/Mef+H/5p60K0Id3bg==", - "dev": true + "dev": true, + "peer": true }, "supports-color": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", "integrity": "sha512-Jds2VIYDrlp5ui7t8abHN2bjAu4LV/q4N2KivFPpGH0lrka0BMq/33AmECUXlKPcHigkNaqfXRENFju+rlcy+A==", "dev": true, + "peer": true, "requires": { "has-flag": "^1.0.0" } @@ -36340,6 +19003,7 @@ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, + "peer": true, "requires": { "isexe": "^2.0.0" } @@ -36382,7 +19046,8 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "dev": true + "dev": true, + "peer": true }, "setimmediate": { "version": "1.0.5", @@ -36411,6 +19076,7 @@ "resolved": "https://registry.npmjs.org/sha1/-/sha1-1.1.1.tgz", "integrity": "sha512-dZBS6OrMjtgVkopB1Gmo4RQCDKiZsqcpAQpkV/aaj+FCrCg8r4I4qMkDPQjBgLIxlmu9k4nUbWq6ohXahOneYA==", "dev": true, + "peer": true, "requires": { "charenc": ">= 0.0.1", "crypt": ">= 0.0.1" @@ -36436,6 +19102,7 @@ "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", "dev": true, + "peer": true, "requires": { "glob": "^7.0.0", "interpret": "^1.0.0", @@ -36460,9 +19127,9 @@ "dev": true }, "simple-git": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.14.1.tgz", - "integrity": "sha512-1ThF4PamK9wBORVGMK9HK5si4zoGS2GpRO7tkAFObA4FZv6dKaCVHLQT+8zlgiBm6K2h+wEU9yOaFCu/SR3OyA==", + "version": "3.15.1", + "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.15.1.tgz", + "integrity": "sha512-73MVa5984t/JP4JcQt0oZlKGr42ROYWC3BcUZfuHtT3IHKPspIvL0cZBnvPXF7LL3S/qVeVHVdYYmJ3LOTw4Rg==", "dev": true, "requires": { "@kwsites/file-exists": "^1.1.1", @@ -36487,28 +19154,22 @@ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, + "peer": true, "requires": { "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", "is-fullwidth-code-point": "^3.0.0" - }, - "dependencies": { - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - } } }, "solc": { - "version": "0.6.12", - "resolved": "https://registry.npmjs.org/solc/-/solc-0.6.12.tgz", - "integrity": "sha512-Lm0Ql2G9Qc7yPP2Ba+WNmzw2jwsrd3u4PobHYlSOxaut3TtUbj9+5ZrT6f4DUpNPEoBaFUOEg9Op9C0mk7ge9g==", + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/solc/-/solc-0.7.3.tgz", + "integrity": "sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA==", "dev": true, "requires": { "command-exists": "^1.2.8", "commander": "3.0.2", + "follow-redirects": "^1.12.1", "fs-extra": "^0.30.0", "js-sha3": "0.8.0", "memorystream": "^0.3.1", @@ -36822,6 +19483,12 @@ "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": 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 + }, "js-yaml": { "version": "3.14.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", @@ -36994,9 +19661,9 @@ } }, "solidity-ast": { - "version": "0.4.35", - "resolved": "https://registry.npmjs.org/solidity-ast/-/solidity-ast-0.4.35.tgz", - "integrity": "sha512-F5bTDLh3rmDxRmLSrs3qt3nvxJprWSEkS7h2KmuXDx7XTfJ6ZKVTV1rtPIYCqJAuPsU/qa8YUeFn7jdOAZcTPA==", + "version": "0.4.40", + "resolved": "https://registry.npmjs.org/solidity-ast/-/solidity-ast-0.4.40.tgz", + "integrity": "sha512-M8uLBT2jgFB7B0iVAC5a2l71J8vim7aEm03AZkaHbDqyrl1pE+i5PriMEw6WlwGfHp3/Ym7cn9BqvVLQgRk+Yw==", "dev": true }, "solidity-coverage": { @@ -37004,6 +19671,7 @@ "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.8.2.tgz", "integrity": "sha512-cv2bWb7lOXPE9/SSleDO6czkFiMHgP4NXPj+iW9W7iEKLBk7Cj0AGBiNmGX3V1totl9wjPrT0gHmABZKZt65rQ==", "dev": true, + "peer": true, "requires": { "@ethersproject/abi": "^5.0.9", "@solidity-parser/parser": "^0.14.1", @@ -37031,19 +19699,22 @@ "version": "3.2.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true + "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==", - "dev": true + "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" } @@ -37053,6 +19724,7 @@ "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" } @@ -37061,13 +19733,15 @@ "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true + "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", @@ -37079,6 +19753,7 @@ "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", @@ -37095,6 +19770,7 @@ "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", @@ -37106,6 +19782,7 @@ "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" } @@ -37114,46 +19791,60 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true + "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 + "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 + "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 + "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 + "dev": true, + "peer": true }, "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, "requires": { "locate-path": "^3.0.0" } @@ -37163,6 +19854,7 @@ "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz", "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==", "dev": true, + "peer": true, "requires": { "is-buffer": "~2.0.3" } @@ -37172,6 +19864,7 @@ "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", @@ -37183,13 +19876,15 @@ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", "dev": true, - "optional": 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", @@ -37204,6 +19899,7 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, + "peer": true, "requires": { "is-glob": "^4.0.1" } @@ -37213,6 +19909,7 @@ "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", @@ -37228,13 +19925,22 @@ "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 + "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 }, "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" @@ -37245,6 +19951,7 @@ "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" @@ -37255,6 +19962,7 @@ "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" } @@ -37264,6 +19972,7 @@ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, + "peer": true, "requires": { "yallist": "^4.0.0" } @@ -37273,6 +19982,7 @@ "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" } @@ -37282,6 +19992,7 @@ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", "dev": true, + "peer": true, "requires": { "minimist": "^1.2.5" } @@ -37291,6 +20002,7 @@ "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.1.2.tgz", "integrity": "sha512-o96kdRKMKI3E8U0bjnfqW4QMk12MwZ4mhdBTf+B5a1q9+aq2HRnj+3ZdJu0B/ZhJeK78MgYuv6L8d/rA5AeBJA==", "dev": true, + "peer": true, "requires": { "ansi-colors": "3.2.3", "browser-stdout": "1.3.1", @@ -37323,6 +20035,7 @@ "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" } @@ -37333,13 +20046,15 @@ "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 + "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" } @@ -37349,6 +20064,7 @@ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", "dev": true, + "peer": true, "requires": { "p-limit": "^2.0.0" } @@ -37357,34 +20073,25 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true + "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==", "dev": true, + "peer": true, "requires": { "picomatch": "^2.0.4" } }, - "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 - }, "semver": { "version": "7.3.8", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, + "peer": true, "requires": { "lru-cache": "^6.0.0" } @@ -37394,6 +20101,7 @@ "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", @@ -37405,6 +20113,7 @@ "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" } @@ -37413,13 +20122,15 @@ "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 + "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" } @@ -37429,21 +20140,17 @@ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, + "peer": true, "requires": { "isexe": "^2.0.0" } }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", - "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", @@ -37454,19 +20161,22 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true + "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 + "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", @@ -37485,6 +20195,7 @@ "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" @@ -37495,6 +20206,7 @@ "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", "dev": true, + "peer": true, "requires": { "flat": "^4.1.0", "lodash": "^4.17.15", @@ -37509,6 +20221,7 @@ "integrity": "sha512-CBdZ2oa/BHhS4xj5DlhjWNHcan57/5YuvfdLf17iVmIpd9KRm+DFLmC6nBNj+6Ua7Kt3TmOjDpQT1aTYOQtoUA==", "dev": true, "optional": true, + "peer": true, "requires": { "amdefine": ">=0.0.4" } @@ -37531,38 +20244,6 @@ } } }, - "spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.12", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz", - "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==", - "dev": true - }, "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", @@ -37574,6 +20255,7 @@ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", "dev": true, + "peer": true, "requires": { "asn1": "~0.2.3", "assert-plus": "^1.0.0", @@ -37590,7 +20272,8 @@ "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", - "dev": true + "dev": true, + "peer": true } } }, @@ -37621,7 +20304,8 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", "integrity": "sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g==", - "dev": true + "dev": true, + "peer": true }, "streamsearch": { "version": "1.1.0", @@ -37638,31 +20322,22 @@ "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": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "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": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "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 - }, - "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, - "requires": { - "ansi-regex": "^3.0.0" - } - } + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" } }, "string.prototype.trimend": { @@ -37670,6 +20345,7 @@ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", "dev": true, + "peer": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", @@ -37681,6 +20357,7 @@ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", "dev": true, + "peer": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", @@ -37696,12 +20373,6 @@ "ansi-regex": "^5.0.1" } }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true - }, "strip-hex-prefix": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", @@ -37711,12 +20382,6 @@ "is-hex-prefixed": "1.0.0" } }, - "strip-indent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", - "integrity": "sha512-RsSNPLpq6YUL7QYy44RnPVTn/lcVZtb48Uof3X5JLbF4zD/Gs7ZFDv2HWol+leoQN2mT86LAzSshGfkTlSOpsA==", - "dev": true - }, "strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -37754,6 +20419,7 @@ "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", @@ -37765,6 +20431,7 @@ "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" } @@ -37774,6 +20441,7 @@ "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", @@ -37783,10 +20451,11 @@ }, "dependencies": { "ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dev": true, + "peer": true, "requires": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -37794,58 +20463,44 @@ "uri-js": "^4.2.2" } }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, "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 - }, - "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" - } + "peer": true } } }, - "test-value": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/test-value/-/test-value-2.1.0.tgz", - "integrity": "sha512-+1epbAxtKeXttkGFMTX9H42oqzOTufR1ceCF+GYA5aOmvaPq9wd4PUS8329fn2RRLGNeUkgRLnVpycjx8DsO2w==", + "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": "^1.0.3", - "typical": "^2.6.0" + "array-back": "^4.0.1", + "deep-extend": "~0.6.0", + "typical": "^5.2.0", + "wordwrapjs": "^4.0.0" }, "dependencies": { "array-back": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", - "integrity": "sha512-1WxbZvrmyhkNoeYcizokbmh5oiOCIfyvGtcqbK3Ls1v1fKcquzxnQSceOx6tzq7jmai2kFLWIpGND2cLhH6TPw==", + "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, - "requires": { - "typical": "^2.6.0" - } + "peer": true + }, + "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 } } }, - "testrpc": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/testrpc/-/testrpc-0.0.1.tgz", - "integrity": "sha512-afH1hO+SQ/VPlmaLUFj2636QMeDvPCeQMc/9RBMW0IfjNe9gFD9Ra3ShqYkB7py0do1ZcCna/9acHyzTJ+GcNA==", - "dev": true - }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -37857,6 +20512,7 @@ "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", @@ -37875,18 +20531,8 @@ "version": "8.10.66", "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz", "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==", - "dev": true - }, - "form-data": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", - "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } + "peer": true } } }, @@ -37925,30 +20571,11 @@ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", "dev": true, + "peer": true, "requires": { "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "dependencies": { - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - } - } - }, - "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "dev": true - }, - "trim-newlines": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz", - "integrity": "sha512-MTBWv3jhVjTU7XR3IQHllbiJs8sc75a80OEhB6or/q7pLTWgQ0bMGQXXYQSrSuXe6WiKWDZ5txXY5P59a/coVA==", - "dev": true + "punycode": "^2.1.1" + } }, "trim-repeated": { "version": "1.0.0", @@ -37967,93 +20594,27 @@ } } }, - "ts-essentials": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-1.0.4.tgz", - "integrity": "sha512-q3N1xS4vZpRouhYHDPwO0bDW3EZ6SK9CrrDHxi/D6BPReSjpVgWIOpLS2o0gSBZm+7q/wyKp6RVM1AeeW7uyfQ==", - "dev": true - }, - "ts-generator": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ts-generator/-/ts-generator-0.1.1.tgz", - "integrity": "sha512-N+ahhZxTLYu1HNTQetwWcx3so8hcYbkKBHTr4b4/YgObFTIKkOSSsaa+nal12w8mfrJAyzJfETXawbNjSfP2gQ==", + "ts-command-line-args": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/ts-command-line-args/-/ts-command-line-args-2.3.1.tgz", + "integrity": "sha512-FR3y7pLl/fuUNSmnPhfLArGqRrpojQgIEEOVzYx9DhTmfIN7C9RWSfpkJEF4J+Gk7aVx5pak8I7vWZsaN4N84g==", "dev": true, + "peer": true, "requires": { - "@types/mkdirp": "^0.5.2", - "@types/prettier": "^2.1.1", - "@types/resolve": "^0.0.8", - "chalk": "^2.4.1", - "glob": "^7.1.2", - "mkdirp": "^0.5.1", - "prettier": "^2.1.2", - "resolve": "^1.8.1", - "ts-essentials": "^1.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 - }, - "prettier": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", - "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", - "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" - } - } + "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", @@ -38109,6 +20670,7 @@ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", "dev": true, + "peer": true, "requires": { "safe-buffer": "^5.0.1" } @@ -38138,7 +20700,8 @@ "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 + "dev": true, + "peer": true }, "type-fest": { "version": "0.20.2", @@ -38147,59 +20710,101 @@ "dev": true }, "typechain": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/typechain/-/typechain-3.0.0.tgz", - "integrity": "sha512-ft4KVmiN3zH4JUFu2WJBrwfHeDf772Tt2d8bssDTo/YcckKW2D+OwFrHXRC6hJvO3mHjFQTihoMV6fJOi0Hngg==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/typechain/-/typechain-8.1.1.tgz", + "integrity": "sha512-uF/sUvnXTOVF2FHKhQYnxHk4su4JjZR8vr4mA2mBaRwHTbwh0jIlqARz9XJr1tA0l7afJGvEa1dTSi4zt039LQ==", "dev": true, + "peer": true, "requires": { - "command-line-args": "^4.0.7", - "debug": "^4.1.1", + "@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", - "ts-essentials": "^6.0.3", - "ts-generator": "^0.1.1" + "mkdirp": "^1.0.4", + "prettier": "^2.3.1", + "ts-command-line-args": "^2.2.0", + "ts-essentials": "^7.0.1" }, "dependencies": { - "ts-essentials": { - "version": "6.0.7", - "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-6.0.7.tgz", - "integrity": "sha512-2E4HIIj4tQJlIHuATRHayv0EfMGK3ris/GRk1E3CFnsZzeNV+hUmelbaTZHLtXaZppM5oLhHRtO04gINC4Jusw==", + "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.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.2.tgz", + "integrity": "sha512-BtRV9BcncDyI2tsuS19zzhzoxD8Dh8LiCx7j7tHzrkz8GFXAexeWFdi22mjE1d16dftH2qNaytVxqiRTGlMfpw==", "dev": true, - "requires": {} + "peer": true } } }, + "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, + "requires": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "is-typed-array": "^1.1.9" + } + }, "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 + "dev": true, + "peer": true }, "typescript": { - "version": "4.8.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", - "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", + "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", "dev": true }, "typical": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", - "integrity": "sha512-ofhi8kjIje6npGozTip9Fr8iecmYfEbS06i0JnIg+rh51KakryWF4+jX8lLKZVhy6N+ID45WYSFCxPOdTWCzNg==", - "dev": true + "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 + "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==", "dev": true, + "peer": true, "requires": { "call-bind": "^1.0.2", "has-bigints": "^1.0.2", @@ -38208,9 +20813,9 @@ } }, "undici": { - "version": "5.12.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.12.0.tgz", - "integrity": "sha512-zMLamCG62PGjd9HHMpo05bSLvvwWOZgGeiWlN/vlqu3+lRo3elxktVGEyLMX+IO7c2eflLjcW74AlkhEZm15mg==", + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.15.0.tgz", + "integrity": "sha512-wCAZJDyjw9Myv+Ay62LAoB+hZLPW9SmKbQkbHIhMw/acKSlpn7WohdMUc/Vd4j1iSMBO0hWwU8mjB7a5p5bl8g==", "dev": true, "requires": { "busboy": "^1.6.0" @@ -38237,29 +20842,12 @@ "punycode": "^2.1.0" } }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==", - "dev": true - } - } - }, "utf8": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==", - "dev": true + "dev": true, + "peer": true }, "util-deprecate": { "version": "1.0.2", @@ -38279,21 +20867,12 @@ "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", "dev": true }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, "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, + "peer": true, "requires": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", @@ -38301,10 +20880,11 @@ } }, "web3-utils": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.8.0.tgz", - "integrity": "sha512-7nUIl7UWpLVka2f09CMbKOSEvorvHnaugIabU4mj7zfMvm0tSByLcEu3eyV9qgS11qxxLuOkzBIwCstTflhmpQ==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.8.1.tgz", + "integrity": "sha512-LgnM9p6V7rHHUGfpMZod+NST8cRfGzJ1BTXAyNo7A9cJX9LczBfSRxJp+U/GInYe9mby40t3v22AJdlELibnsQ==", "dev": true, + "peer": true, "requires": { "bn.js": "^5.2.1", "ethereum-bloom-filters": "^1.0.6", @@ -38315,22 +20895,6 @@ "utf8": "3.0.0" } }, - "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 - }, - "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": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -38345,6 +20909,7 @@ "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", @@ -38354,26 +20919,74 @@ } }, "which-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", - "integrity": "sha512-F6+WgncZi/mJDrammbTuHe1q0R5hOXv/mBaiNA2TCNT/LTHusX0V+CJnj9XT8ki5ln2UZyyddDgHfCzyrOH7MQ==", - "dev": true + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", + "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==", + "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", + "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" + } + } } }, - "window-size": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz", - "integrity": "sha512-UD7d8HFA2+PZsbKyaOCEy8gMh1oDtHgJh1LfgjQ4zVXmYjAT/kvz3PueITKuqDiIXQe7yzpPnxX3lNc+AhQMyw==", - "dev": true - }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -38384,7 +20997,28 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", - "dev": true + "dev": true, + "peer": true + }, + "wordwrapjs": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-4.0.1.tgz", + "integrity": "sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA==", + "dev": true, + "peer": true, + "requires": { + "reduce-flatten": "^2.0.0", + "typical": "^5.2.0" + }, + "dependencies": { + "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 + } + } }, "workerpool": { "version": "6.2.1", @@ -38401,25 +21035,6 @@ "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" - }, - "dependencies": { - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": 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" - } - } } }, "wrappy": { @@ -38448,7 +21063,8 @@ "version": "1.8.0", "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", "integrity": "sha512-58Im/U0mlVBLM38NdZjHyhuMtCqa61469k2YP/AaPbvCoV9aQGUpbJBj1QRm2ytRiVQBD/fsw7L2bJGDVQswBA==", - "dev": true + "dev": true, + "peer": true }, "y18n": { "version": "5.0.8", @@ -38462,12 +21078,6 @@ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true }, - "yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "dev": true - }, "yargs": { "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", @@ -38481,41 +21091,13 @@ "string-width": "^4.2.0", "y18n": "^5.0.5", "yargs-parser": "^20.2.2" - }, - "dependencies": { - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": 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" - } - }, - "yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true - } } }, "yargs-parser": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz", - "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==", - "dev": true, - "requires": { - "camelcase": "^4.1.0" - } + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true }, "yargs-unparser": { "version": "2.0.0", @@ -38527,26 +21109,6 @@ "decamelize": "^4.0.0", "flat": "^5.0.2", "is-plain-obj": "^2.1.0" - }, - "dependencies": { - "camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true - }, - "decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true - }, - "is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "dev": true - } } }, "yn": { diff --git a/package.json b/package.json index 6cea1bd1..28fb91ba 100644 --- a/package.json +++ b/package.json @@ -3,39 +3,36 @@ "scripts": { "lint": "eslint . --ext .ts", "lint:fix": "eslint --fix . --ext .ts", - "solidity-coverage": "NO_GAS_ENFORCE=1 npx hardhat coverage" + "solidity-coverage": "NO_GAS_ENFORCE=1 npx hardhat coverage", + "test": "npx hardhat test", + "deploy-goerli": "npx hardhat run --network goerli scripts/ssv-network-deploy.ts", + "validate-upgrade-goerli": "npx hardhat run --network goerli scripts/ssv-network-validate-upgrade.ts", + "upgrade-goerli": "npx hardhat run --network goerli scripts/ssv-network-upgrade.ts", + "slither": "slither contracts --solc-remaps @openzeppelin=node_modules/@openzeppelin" }, "devDependencies": { - "@nomiclabs/hardhat-ethers": "^2.0.5", - "@nomiclabs/hardhat-etherscan": "^3.0.3", - "@nomiclabs/hardhat-solhint": "^3.0.0", - "@nomiclabs/hardhat-waffle": "^2.0.3", - "@openzeppelin/contracts": "4.6.0", - "@openzeppelin/contracts-upgradeable": "4.6.0", - "@openzeppelin/hardhat-upgrades": "^1.17.0", + "@nomicfoundation/hardhat-toolbox": "^2.0.0", + "@nomiclabs/hardhat-solhint": "^2.0.0", + "@openzeppelin/contracts": "^4.8.0", + "@openzeppelin/contracts-upgradeable": "^4.8.0", + "@openzeppelin/hardhat-upgrades": "^1.22.0", "@types/chai": "^4.3.0", "@types/chai-as-promised": "^7.1.5", "@types/cli-table": "^0.3.0", "@types/mocha": "^9.1.0", "@types/node": "^17.0.23", "@typescript-eslint/eslint-plugin": "^5.36.0", - "chai": "^4.3.6", "chai-as-promised": "^7.1.1", "cli-table": "^0.3.11", "dotenv": "^16.0.0", "eslint": "^8.23.0", - "ethereum-public-key-to-address": "0.0.5", - "ethereum-waffle": "^3.4.4", - "ethers": "^5.6.2", "gh-pages": "^3.2.3", - "hardhat": "^2.12.2", - "hardhat-gas-reporter": "^1.0.9", - "hardhat-tracer": "^1.1.1", + "hardhat": "^2.12.5", + "hardhat-contract-sizer": "^2.6.1", + "hardhat-tracer": "^1.2.1", "prompts": "^2.4.2", "simple-git": "^3.10.0", - "solidity-coverage": "^0.8.2", "ts-node": "^10.7.0", - "typechain": "^3.0.0", "typescript": "^4.6.3" } } diff --git a/scripts/deploy.ts b/scripts/ssv-network-deploy.ts similarity index 88% rename from scripts/deploy.ts rename to scripts/ssv-network-deploy.ts index 4b2a2ffb..b5264950 100644 --- a/scripts/deploy.ts +++ b/scripts/ssv-network-deploy.ts @@ -9,8 +9,11 @@ async function main() { process.env.OPERATOR_MAX_FEE_INCREASE, process.env.DECLARE_OPERATOR_FEE_PERIOD, process.env.EXECUTE_OPERATOR_FEE_PERIOD, - process.env.MINIMAL_BLOCKS_BEFORE_LIQUIDATION, - ]); + process.env.MINIMUM_BLOCKS_BEFORE_LIQUIDATION + ], + { + kind: "uups" + }); await contract.deployed(); console.log(`SSVNetwork deployed to: ${contract.address}`); } diff --git a/scripts/ssv-network-upgrade.ts b/scripts/ssv-network-upgrade.ts new file mode 100644 index 00000000..ccd7a156 --- /dev/null +++ b/scripts/ssv-network-upgrade.ts @@ -0,0 +1,19 @@ +const { ethers, upgrades } = require("hardhat"); + +async function main() { + const proxyAddress = process.env.PROXY_ADDRESS; + const SSVNetwork = await ethers.getContractFactory("SSVNetwork"); + + await upgrades.validateUpgrade(proxyAddress, SSVNetwork, { kind: 'uups' }); + console.log("Upgrading SSVNetwork..."); + + await upgrades.upgradeProxy(proxyAddress, SSVNetwork, { kind: 'uups' }); + console.log("SSVNetwork upgraded successfully"); +} + +main() + .then(() => process.exit(0)) + .catch(error => { + console.error(error); + process.exit(1); + }); \ No newline at end of file diff --git a/scripts/ssv-network-validate-upgrade.ts b/scripts/ssv-network-validate-upgrade.ts new file mode 100644 index 00000000..283839df --- /dev/null +++ b/scripts/ssv-network-validate-upgrade.ts @@ -0,0 +1,16 @@ +const { ethers, upgrades } = require("hardhat"); + +async function main() { + const proxyAddress = process.env.PROXY_ADDRESS; + const SSVNetwork = await ethers.getContractFactory("SSVNetwork"); + + await upgrades.validateUpgrade(proxyAddress, SSVNetwork, { kind: 'uups' }); + console.log("Contract validation finished"); +} + +main() + .then(() => process.exit(0)) + .catch(error => { + console.error(error); + process.exit(1); + }); \ No newline at end of file diff --git a/test/account/deposit.ts b/test/account/deposit.ts index 0dde686a..491197e8 100644 --- a/test/account/deposit.ts +++ b/test/account/deposit.ts @@ -58,10 +58,10 @@ describe('Deposit Tests', () => { }); 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(uint64[],uint256,(uint32,uint64,uint64,uint64,uint64,bool))'](cluster1.args.operatorIds, minDepositAmount, cluster1.args.cluster)).to.be.revertedWith('ClusterDoesNotExists'); + await expect(ssvNetworkContract.connect(helpers.DB.owners[1])['deposit(uint64[],uint256,(uint32,uint64,uint64,uint64,uint64,bool))'](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(uint64[],uint256,(uint32,uint64,uint64,uint64,uint64,bool))']([1,2,4,5], minDepositAmount, cluster1.args.cluster)).to.be.revertedWith('ClusterDoesNotExists'); + await expect(ssvNetworkContract.connect(helpers.DB.owners[4])['deposit(uint64[],uint256,(uint32,uint64,uint64,uint64,uint64,bool))']([1,2,4,5], minDepositAmount, cluster1.args.cluster)).to.be.revertedWithCustomError(ssvNetworkContract,'ClusterDoesNotExists'); }); }); diff --git a/test/account/withdraw.ts b/test/account/withdraw.ts index 24c14d52..597ee93f 100644 --- a/test/account/withdraw.ts +++ b/test/account/withdraw.ts @@ -68,28 +68,28 @@ describe('Withdraw Tests', () => { }); it('Withdraw more than the cluster balance reverts "InsufficientBalance"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).withdraw(cluster1.args.operatorIds, minDepositAmount, cluster1.args.cluster)).to.be.revertedWith('InsufficientBalance'); + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).withdraw(cluster1.args.operatorIds, minDepositAmount, cluster1.args.cluster)).to.be.revertedWithCustomError(ssvNetworkContract,'InsufficientBalance'); }); it('Withdraw from a liquidatable cluster reverts "InsufficientBalance"', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).withdraw(cluster1.args.operatorIds, helpers.CONFIG.minimalOperatorFee, cluster1.args.cluster)).to.be.revertedWith('InsufficientBalance'); + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).withdraw(cluster1.args.operatorIds, helpers.CONFIG.minimalOperatorFee, cluster1.args.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(uint64,uint256)'](1, minDepositAmount)).to.be.revertedWith('CallerNotOwner'); + await expect(ssvNetworkContract.connect(helpers.DB.owners[2])['withdrawOperatorEarnings(uint64,uint256)'](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(uint64,uint256)'](1, minDepositAmount - )).to.be.revertedWith('InsufficientBalance'); + )).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])['withdrawOperatorEarnings(uint64)'](12)).to.be.revertedWith('CallerNotOwner'); + await expect(ssvNetworkContract.connect(helpers.DB.owners[2])['withdrawOperatorEarnings(uint64)'](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])['withdrawOperatorEarnings(uint64)'](12)).to.be.revertedWith('InsufficientBalance'); + await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorEarnings(uint64)'](12)).to.be.revertedWithCustomError(ssvNetworkContract,'InsufficientBalance'); }); }); diff --git a/test/dao/liquidation-threshold.ts b/test/dao/liquidation-threshold.ts index b03f6bc5..f8cff160 100644 --- a/test/dao/liquidation-threshold.ts +++ b/test/dao/liquidation-threshold.ts @@ -23,10 +23,10 @@ describe('Liquidation Threshold Tests', () => { }); it('Change liquidation threshold period reverts "NewBlockPeriodIsBelowMinimum"', async () => { - await expect(ssvNetworkContract.updateLiquidationThresholdPeriod(helpers.CONFIG.minimalBlocksBeforeLiquidation - 10)).to.be.revertedWith('NewBlockPeriodIsBelowMinimum'); + await expect(ssvNetworkContract.updateLiquidationThresholdPeriod(helpers.CONFIG.minimalBlocksBeforeLiquidation - 10)).to.be.revertedWithCustomError(ssvNetworkContract,'NewBlockPeriodIsBelowMinimum'); }); it('Change liquidation threshold period reverts "caller is not the owner"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[3]).updateLiquidationThresholdPeriod(helpers.CONFIG.minimalBlocksBeforeLiquidation)).to.be.revertedWith('caller is not the owner'); + await expect(ssvNetworkContract.connect(helpers.DB.owners[3]).updateLiquidationThresholdPeriod(helpers.CONFIG.minimalBlocksBeforeLiquidation)).to.be.revertedWith('Ownable: caller is not the owner'); }); }); diff --git a/test/dao/network-fee-change.ts b/test/dao/network-fee-change.ts index 4606ea80..f56a49e6 100644 --- a/test/dao/network-fee-change.ts +++ b/test/dao/network-fee-change.ts @@ -30,6 +30,6 @@ describe('Network Fee Tests', () => { it('Change network fee from an address thats not the DAO reverts "caller is not the owner"', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[3]).updateNetworkFee(networkFee - )).to.be.revertedWith('caller is not the owner'); + )).to.be.revertedWith('Ownable: caller is not the owner'); }); }); diff --git a/test/dao/network-fee-withdraw.ts b/test/dao/network-fee-withdraw.ts index 8d38b8c9..fb5d2a09 100644 --- a/test/dao/network-fee-withdraw.ts +++ b/test/dao/network-fee-withdraw.ts @@ -70,12 +70,12 @@ describe('DAO Network Fee Withdraw Tests', () => { it('Withdraw network earnings with not enough balance reverts "InsufficientBalance"', async () => { const amount = await ssvNetworkContract.getNetworkEarnings() * 2; await expect(ssvNetworkContract.withdrawNetworkEarnings(amount - )).to.be.revertedWith('InsufficientBalance'); + )).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 ssvNetworkContract.getNetworkEarnings(); await expect(ssvNetworkContract.connect(helpers.DB.owners[3]).withdrawNetworkEarnings(amount - )).to.be.revertedWith('caller is not the owner'); + )).to.be.revertedWith('Ownable: caller is not the owner'); }); }); diff --git a/test/helpers/contract-helpers.ts b/test/helpers/contract-helpers.ts index df8720d0..d4839325 100644 --- a/test/helpers/contract-helpers.ts +++ b/test/helpers/contract-helpers.ts @@ -73,7 +73,10 @@ export const initializeContract = async () => { CONFIG.declareOperatorFeePeriod, CONFIG.executeOperatorFeePeriod, CONFIG.minimalBlocksBeforeLiquidation - ]); + ], + { + kind: 'uups' + }); await DB.ssvNetwork.contract.deployed(); diff --git a/test/liquidate/liquidate.ts b/test/liquidate/liquidate.ts index be746e35..e97f8ca4 100644 --- a/test/liquidate/liquidate.ts +++ b/test/liquidate/liquidate.ts @@ -107,7 +107,7 @@ describe('Liquidate Tests', () => { firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster - )).to.be.revertedWith('ClusterNotLiquidatable'); + )).to.be.revertedWithCustomError(ssvNetworkContract,'ClusterNotLiquidatable'); }); it('Liquidate a cluster that is not liquidatable reverts "IncorrectClusterState"', async () => { @@ -122,7 +122,7 @@ describe('Liquidate Tests', () => { balance: 0, disabled: false } - )).to.be.revertedWith('IncorrectClusterState'); + )).to.be.revertedWithCustomError(ssvNetworkContract,'IncorrectClusterState'); }); it('Liquidate second time a cluster that is liquidated already reverts "ClusterIsLiquidated"', async () => { @@ -138,7 +138,7 @@ describe('Liquidate Tests', () => { firstCluster.owner, updatedCluster.operatorIds, updatedCluster.cluster - )).to.be.revertedWith('ClusterIsLiquidated'); + )).to.be.revertedWithCustomError(ssvNetworkContract,'ClusterIsLiquidated'); }); it('Is liquidated', async () => { @@ -162,7 +162,7 @@ describe('Liquidate Tests', () => { ), [GasGroup.LIQUIDATE_POD]); const updatedCluster = liquidatedCluster.eventsByName.ClusterLiquidated[0].args; - await expect(ssvNetworkContract.isLiquidated(helpers.DB.owners[0].address, firstCluster.operatorIds, updatedCluster.cluster)).to.be.revertedWith('ClusterDoesNotExists'); + await expect(ssvNetworkContract.isLiquidated(helpers.DB.owners[0].address, firstCluster.operatorIds, updatedCluster.cluster)).to.be.revertedWithCustomError(ssvNetworkContract,'ClusterDoesNotExists'); }); }); diff --git a/test/liquidate/reactivate.ts b/test/liquidate/reactivate.ts index 12e30b89..3b2871cd 100644 --- a/test/liquidate/reactivate.ts +++ b/test/liquidate/reactivate.ts @@ -78,7 +78,7 @@ describe('Reactivate Tests', () => { }); it('Reactivate an enabled cluster reverts "ClusterAlreadyEnabled"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).reactivate(firstCluster.operatorIds, minDepositAmount, firstCluster.cluster)).to.be.revertedWith('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 "InsufficientFunds"', async () => { @@ -87,7 +87,7 @@ describe('Reactivate Tests', () => { 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.revertedWith('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 cluster with a removed operator in the cluster', async () => { diff --git a/test/operators/register.ts b/test/operators/register.ts index feb648f8..8108d22b 100644 --- a/test/operators/register.ts +++ b/test/operators/register.ts @@ -30,7 +30,7 @@ describe('Register Operator Tests', () => { await expect(ssvNetworkContract.registerOperator( helpers.DataGenerator.publicKey(0), '10' - )).to.be.revertedWith('FeeTooLow'); + )).to.be.revertedWithCustomError(ssvNetworkContract,'FeeTooLow'); }); it('Get operator by id', async () => { @@ -50,6 +50,6 @@ describe('Register Operator Tests', () => { helpers.CONFIG.minimalOperatorFee, ), [GasGroup.REGISTER_OPERATOR]); - await expect(ssvNetworkContract.getOperatorById(3)).to.be.revertedWith('OperatorDoesNotExist'); + await expect(ssvNetworkContract.getOperatorById(3)).to.be.revertedWithCustomError(ssvNetworkContract,'OperatorDoesNotExist'); }); }); diff --git a/test/operators/remove.ts b/test/operators/remove.ts index e18d1c1c..621e357d 100644 --- a/test/operators/remove.ts +++ b/test/operators/remove.ts @@ -38,7 +38,7 @@ describe('Remove Operator Tests', () => { it('Remove operator I do not own reverts "CallerNotOwner"', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).removeOperator(1)) - .to.be.revertedWith('CallerNotOwner'); + .to.be.revertedWithCustomError(ssvNetworkContract,'CallerNotOwner'); }); it('Remove operator gas limits', async () => { diff --git a/test/operators/update-fee.ts b/test/operators/update-fee.ts index 66095fa6..49ace804 100644 --- a/test/operators/update-fee.ts +++ b/test/operators/update-fee.ts @@ -57,63 +57,63 @@ describe('Operator Fee Tests', () => { it('Get fee from operator that does not exist reverts "OperatorDoesNotExist"', async () => { await expect(ssvNetworkContract.getOperatorFee(12 - )).to.be.revertedWith('OperatorDoesNotExist'); + )).to.be.revertedWithCustomError(ssvNetworkContract,'OperatorDoesNotExist'); }); it('Declare fee of operator I do not own reverts "CallerNotOwner"', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).declareOperatorFee(1, initialFee + initialFee / 10 - )).to.be.revertedWith('CallerNotOwner'); + )).to.be.revertedWithCustomError(ssvNetworkContract,'CallerNotOwner'); }); it('Declare fee with a wrong Publickey reverts "OperatorDoesNotExist"', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).declareOperatorFee(12, initialFee + initialFee / 10 - )).to.be.revertedWith('OperatorDoesNotExist'); + )).to.be.revertedWithCustomError(ssvNetworkContract,'OperatorDoesNotExist'); }); it('Declare fee with too low of a fee reverts "FeeTooLow"', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[2]).declareOperatorFee(1, helpers.CONFIG.minimalOperatorFee - 1 - )).to.be.revertedWith('FeeTooLow'); + )).to.be.revertedWithCustomError(ssvNetworkContract,'FeeTooLow'); }); it('Declare fee above the operators max fee increase limit reverts "FeeExceedsIncreaseLimit"', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[2]).declareOperatorFee(1, initialFee + initialFee / 5 - )).to.be.revertedWith('FeeExceedsIncreaseLimit'); + )).to.be.revertedWithCustomError(ssvNetworkContract,'FeeExceedsIncreaseLimit'); }); it('Cancel declared fee without a pending request reverts "NoFeeDelcared"', async () => { await expect(ssvNetworkContract.cancelDeclaredOperatorFee(1 - )).to.be.revertedWith('NoFeeDelcared'); + )).to.be.revertedWithCustomError(ssvNetworkContract,'NoFeeDelcared'); }); it('Cancel declared fee of an operator I do not own reverts "CallerNotOwner"', async () => { await trackGas(ssvNetworkContract.declareOperatorFee(1, initialFee + initialFee / 10), [GasGroup.REGISTER_OPERATOR]); await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).cancelDeclaredOperatorFee(1 - )).to.be.revertedWith('CallerNotOwner'); + )).to.be.revertedWithCustomError(ssvNetworkContract,'CallerNotOwner'); }); it('Execute declared fee of an operator I do not own reverts "CallerNotOwner"', async () => { await trackGas(ssvNetworkContract.declareOperatorFee(1, initialFee + initialFee / 10), [GasGroup.REGISTER_OPERATOR]); await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).executeOperatorFee(1 - )).to.be.revertedWith('CallerNotOwner'); + )).to.be.revertedWithCustomError(ssvNetworkContract,'CallerNotOwner'); }); it('Execute declared fee without a pending request reverts "NoFeeDelcared"', async () => { await expect(ssvNetworkContract.executeOperatorFee(1 - )).to.be.revertedWith('NoFeeDelcared'); + )).to.be.revertedWithCustomError(ssvNetworkContract,'NoFeeDelcared'); }); it('Execute declared fee too early reverts "ApprovalNotWithinTimeframe"', async () => { await trackGas(ssvNetworkContract.declareOperatorFee(1, initialFee + initialFee / 10), [GasGroup.REGISTER_OPERATOR]); await progressTime(helpers.CONFIG.declareOperatorFeePeriod - 10); await expect(ssvNetworkContract.executeOperatorFee(1 - )).to.be.revertedWith('ApprovalNotWithinTimeframe'); + )).to.be.revertedWithCustomError(ssvNetworkContract,'ApprovalNotWithinTimeframe'); }); it('Execute declared fee too late reverts "ApprovalNotWithinTimeframe"', async () => { await trackGas(ssvNetworkContract.declareOperatorFee(1, initialFee + initialFee / 10), [GasGroup.REGISTER_OPERATOR]); await progressTime(helpers.CONFIG.declareOperatorFeePeriod + helpers.CONFIG.executeOperatorFeePeriod + 1); await expect(ssvNetworkContract.executeOperatorFee(1 - )).to.be.revertedWith('ApprovalNotWithinTimeframe'); + )).to.be.revertedWithCustomError(ssvNetworkContract,'ApprovalNotWithinTimeframe'); }); //Dao @@ -153,22 +153,22 @@ describe('Operator Fee Tests', () => { it('Increase fee from an address thats not the DAO reverts "caller is not the owner"', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).updateOperatorFeeIncreaseLimit(1000 - )).to.be.revertedWith('caller is not the owner'); + )).to.be.revertedWith('Ownable: caller is not the owner'); }); it('Update the declare fee period from an address thats not the DAO reverts "caller is not the owner"', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).updateDeclareOperatorFeePeriod(1200 - )).to.be.revertedWith('caller is not the owner'); + )).to.be.revertedWith('Ownable: caller is not the owner'); }); it('Update the execute fee period from an address thats not the DAO reverts "caller is not the owner"', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).updateExecuteOperatorFeePeriod(1200)) - .to.be.revertedWith('caller is not the owner'); + .to.be.revertedWith('Ownable: caller is not the owner'); }); it('DAO declared fee without a pending request reverts "NoFeeDelcared"', async () => { await trackGas(ssvNetworkContract.declareOperatorFee(1, initialFee + initialFee / 10), [GasGroup.REGISTER_OPERATOR]); await expect(ssvNetworkContract.getOperatorDeclaredFee(2 - )).to.be.revertedWith('NoFeeDelcared'); + )).to.be.revertedWithCustomError(ssvNetworkContract,'NoFeeDelcared'); }); }); diff --git a/test/sanity/balances.ts b/test/sanity/balances.ts index cdc5476c..1576e7cc 100644 --- a/test/sanity/balances.ts +++ b/test/sanity/balances.ts @@ -110,7 +110,7 @@ describe('Balance Tests', () => { it('Check cluster balance returns error - InsufficientFunds', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation + 10); - await expect(ssvNetworkContract.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster)).to.be.revertedWith('InsufficientFunds'); + await expect(ssvNetworkContract.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster)).to.be.revertedWithCustomError(ssvNetworkContract,'InsufficientFunds'); }); it('Check cluster balance with removed operator', async () => { diff --git a/test/validators/register.ts b/test/validators/register.ts index 0b0c1e80..6369c69e 100644 --- a/test/validators/register.ts +++ b/test/validators/register.ts @@ -425,7 +425,7 @@ describe('Register Validator Tests', () => { balance: 0, disabled: false } - )).to.be.revertedWith('IncorrectClusterState'); + )).to.be.revertedWithCustomError(ssvNetworkContract,'IncorrectClusterState'); }); it('Register validator returns an error - OperatorDoesNotExist', async () => { @@ -442,7 +442,7 @@ describe('Register Validator Tests', () => { balance: 0, disabled: false } - )).to.be.revertedWith('OperatorDoesNotExist'); + )).to.be.revertedWithCustomError(ssvNetworkContract,'OperatorDoesNotExist'); }); it('Register validator with removed operator returns an error - OperatorDoesNotExist', async () => { @@ -460,7 +460,7 @@ describe('Register Validator Tests', () => { balance: 0, disabled: false } - )).to.be.revertedWith('OperatorDoesNotExist'); + )).to.be.revertedWithCustomError(ssvNetworkContract,'OperatorDoesNotExist'); }); it('Register validator emits ValidatorAdded event', async () => { @@ -482,18 +482,18 @@ describe('Register Validator Tests', () => { }); it('Register cluster returns an error - The operators list should be in ascending order', async () => { - await expect(helpers.registerValidators(2, 1, minDepositAmount, [3, 2, 1, 4])).to.be.revertedWith('UnsortedOperatorsList'); + await expect(helpers.registerValidators(2, 1, minDepositAmount, [3, 2, 1, 4])).to.be.revertedWithCustomError(ssvNetworkContract,'UnsortedOperatorsList'); }); it('Invalid operator amount reverts "InvalidOperatorIdsLength"', async () => { // 2 Operators - await expect(helpers.registerValidators(2, 1, minDepositAmount, [1, 2])).to.be.revertedWith('InvalidOperatorIdsLength'); + 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.revertedWith('InvalidOperatorIdsLength'); + 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.revertedWith('InvalidOperatorIdsLength'); + 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 invalild public key reverts "InvalidPublicKeyLength"', async () => { @@ -510,7 +510,7 @@ describe('Register Validator Tests', () => { balance: 0, disabled: false } - )).to.be.revertedWith('InvalidPublicKeyLength'); + )).to.be.revertedWithCustomError(ssvNetworkContract,'InvalidPublicKeyLength'); }); it('Register validator returns an error - InsufficientBalance', async () => { @@ -528,7 +528,7 @@ describe('Register Validator Tests', () => { balance: 0, disabled: false } - )).to.be.revertedWith('InsufficientBalance'); + )).to.be.revertedWithCustomError(ssvNetworkContract,'InsufficientBalance'); }); it('Register validator returns an error - ValidatorAlreadyExists', async () => { @@ -546,7 +546,7 @@ describe('Register Validator Tests', () => { balance: 0, disabled: false } - )).to.be.revertedWith('ValidatorAlreadyExists'); + )).to.be.revertedWithCustomError(ssvNetworkContract,'ValidatorAlreadyExists'); }); it('Get cluster burn rate', async () => { diff --git a/test/validators/remove.ts b/test/validators/remove.ts index 03ec1eba..4046dfda 100644 --- a/test/validators/remove.ts +++ b/test/validators/remove.ts @@ -84,7 +84,7 @@ describe('Remove Validator Tests', () => { helpers.DataGenerator.publicKey(1), firstCluster.operatorIds, firstCluster.cluster - )).to.be.revertedWith('NoValidatorOwnership'); + )).to.be.revertedWithCustomError(ssvNetworkContract,'NoValidatorOwnership'); }); it('Remove validator twice', async () => { @@ -100,7 +100,7 @@ describe('Remove Validator Tests', () => { helpers.DataGenerator.publicKey(1), firstCluster.operatorIds, firstCluster.cluster - )).to.be.revertedWith('ValidatorDoesNotExist'); + )).to.be.revertedWithCustomError(ssvNetworkContract,'ValidatorDoesNotExist'); }); it('Register / remove validator twice', async () => { From 57dbfac02684c53a4043b8747b28aef1362e8835 Mon Sep 17 00:00:00 2001 From: andrew-blox <102898824+andrew-blox@users.noreply.github.com> Date: Wed, 18 Jan 2023 12:14:21 +0200 Subject: [PATCH 115/149] Real RSA data * Add real RSA data * update gas test * update gas usage * remove comments --- test-e2e/register-validator-gas.ts | 42 +++++++++--------- test/account/deposit.ts | 2 +- test/account/withdraw.ts | 2 +- test/dao/network-fee-withdraw.ts | 2 +- test/helpers/contract-helpers.ts | 24 ++++++++++- test/helpers/gas-usage.ts | 18 ++++---- test/liquidate/liquidate.ts | 6 +-- test/liquidate/reactivate.ts | 4 +- test/operators/remove.ts | 2 +- test/sanity/balances.ts | 2 +- test/validators/register.ts | 68 +++++++++++++++--------------- test/validators/remove.ts | 6 +-- 12 files changed, 100 insertions(+), 78 deletions(-) diff --git a/test-e2e/register-validator-gas.ts b/test-e2e/register-validator-gas.ts index 02b2e835..d83783af 100644 --- a/test-e2e/register-validator-gas.ts +++ b/test-e2e/register-validator-gas.ts @@ -28,7 +28,7 @@ describe('Register Validator Gas Tests', () => { const tx = await ssvNetworkContract.connect(helpers.DB.owners[6]).registerValidator( helpers.DataGenerator.publicKey(5), [1,2,3,4], - helpers.DataGenerator.shares(0), + helpers.DataGenerator.shares(4), minDepositAmount, { validatorCount: 0, @@ -53,7 +53,7 @@ describe('Register Validator Gas Tests', () => { const tx1 = await ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( helpers.DataGenerator.publicKey(1), [1,2,3,4], - helpers.DataGenerator.shares(0), + helpers.DataGenerator.shares(4), minDepositAmount, { validatorCount: 0, @@ -65,24 +65,24 @@ describe('Register Validator Gas Tests', () => { } ); const receipt1 = await tx1.wait(); - const pod1 = (receipt1.events[3].args[4]); + const pod1 = (receipt1.events[2].args[4]); // Second Validator with a deposit const tx2 = await ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( helpers.DataGenerator.publicKey(2), [1,2,3,4], - helpers.DataGenerator.shares(0), + helpers.DataGenerator.shares(4), minDepositAmount, pod1 ); const receipt2 = await tx2.wait(); - const pod2 = (receipt2.events[3].args[4]); + const pod2 = (receipt2.events[2].args[4]); // Third Validator without a deposit const tx3 = await ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( helpers.DataGenerator.publicKey(3), [1,2,3,4], - helpers.DataGenerator.shares(0), + helpers.DataGenerator.shares(4), 0, pod2 ); @@ -97,7 +97,7 @@ describe('Register Validator Gas Tests', () => { const tx1 = await ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( helpers.DataGenerator.publicKey(1), [1,2,3,4,5,6,7], - helpers.DataGenerator.shares(1), + helpers.DataGenerator.shares(7), minDepositAmount * 2, { validatorCount: 0, @@ -109,24 +109,24 @@ describe('Register Validator Gas Tests', () => { } ); const receipt1 = await tx1.wait(); - const pod1 = (receipt1.events[3].args[4]); + const pod1 = (receipt1.events[2].args[4]); // Second Validator with a deposit const tx2 = await ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( helpers.DataGenerator.publicKey(2), [1,2,3,4,5,6,7], - helpers.DataGenerator.shares(1), + helpers.DataGenerator.shares(7), minDepositAmount * 2, pod1 ); const receipt2 = await tx2.wait(); - const pod2 = (receipt2.events[3].args[4]); + const pod2 = (receipt2.events[2].args[4]); // Third Validator without a deposit const tx3 = await ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( helpers.DataGenerator.publicKey(3), [1,2,3,4,5,6,7], - helpers.DataGenerator.shares(1), + helpers.DataGenerator.shares(7), 0, pod2 ); @@ -141,7 +141,7 @@ describe('Register Validator Gas Tests', () => { const tx1 = await ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( helpers.DataGenerator.publicKey(1), [1,2,3,4,5,6,7,8,9,10], - helpers.DataGenerator.shares(2), + helpers.DataGenerator.shares(10), minDepositAmount * 3, { validatorCount: 0, @@ -153,24 +153,24 @@ describe('Register Validator Gas Tests', () => { } ); const receipt1 = await tx1.wait(); - const pod1 = (receipt1.events[3].args[4]); + const pod1 = (receipt1.events[2].args[4]); // Second Validator with a deposit const tx2 = await ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( helpers.DataGenerator.publicKey(2), [1,2,3,4,5,6,7,8,9,10], - helpers.DataGenerator.shares(2), + helpers.DataGenerator.shares(10), minDepositAmount * 3, pod1 ); const receipt2 = await tx2.wait(); - const pod2 = (receipt2.events[3].args[4]); + const pod2 = (receipt2.events[2].args[4]); // Third Validator without a deposit const tx3 = await ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( helpers.DataGenerator.publicKey(3), [1,2,3,4,5,6,7,8,9,10], - helpers.DataGenerator.shares(2), + helpers.DataGenerator.shares(10), 0, pod2 ); @@ -185,7 +185,7 @@ describe('Register Validator Gas Tests', () => { const tx1 = await 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(2), + helpers.DataGenerator.shares(13), minDepositAmount * 4, { validatorCount: 0, @@ -197,24 +197,24 @@ describe('Register Validator Gas Tests', () => { } ); const receipt1 = await tx1.wait(); - const pod1 = (receipt1.events[3].args[4]); + const pod1 = (receipt1.events[2].args[4]); // Second Validator with a deposit const tx2 = await 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(2), + helpers.DataGenerator.shares(13), minDepositAmount * 4, pod1 ); const receipt2 = await tx2.wait(); - const pod2 = (receipt2.events[3].args[4]); + const pod2 = (receipt2.events[2].args[4]); // Third Validator without a deposit const tx3 = await ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( helpers.DataGenerator.publicKey(3), [1,2,3,4,5,6,7,8,9,10,11,12,13], - helpers.DataGenerator.shares(2), + helpers.DataGenerator.shares(13), 0, pod2 ); diff --git a/test/account/deposit.ts b/test/account/deposit.ts index 491197e8..12e1cae9 100644 --- a/test/account/deposit.ts +++ b/test/account/deposit.ts @@ -21,7 +21,7 @@ describe('Deposit Tests', () => { await ssvNetworkContract.connect(helpers.DB.owners[6]).registerValidator( '0x221111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111119', [1,2,3,4], - helpers.DataGenerator.shares(0), + helpers.DataGenerator.shares(4), '1000000000000000', { validatorCount: 0, diff --git a/test/account/withdraw.ts b/test/account/withdraw.ts index 597ee93f..ce6460d3 100644 --- a/test/account/withdraw.ts +++ b/test/account/withdraw.ts @@ -23,7 +23,7 @@ describe('Withdraw Tests', () => { await ssvNetworkContract.connect(helpers.DB.owners[6]).registerValidator( '0x221111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111119', [1,2,3,4], - helpers.DataGenerator.shares(0), + helpers.DataGenerator.shares(4), '1000000000000000', { validatorCount: 0, diff --git a/test/dao/network-fee-withdraw.ts b/test/dao/network-fee-withdraw.ts index fb5d2a09..39509d71 100644 --- a/test/dao/network-fee-withdraw.ts +++ b/test/dao/network-fee-withdraw.ts @@ -33,7 +33,7 @@ describe('DAO Network Fee Withdraw Tests', () => { await ssvNetworkContract.connect(helpers.DB.owners[6]).registerValidator( '0x221111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111119', [1,2,3,4], - helpers.DataGenerator.shares(0), + helpers.DataGenerator.shares(4), '1000000000000000', { validatorCount: 0, diff --git a/test/helpers/contract-helpers.ts b/test/helpers/contract-helpers.ts index d4839325..4067001e 100644 --- a/test/helpers/contract-helpers.ts +++ b/test/helpers/contract-helpers.ts @@ -7,9 +7,31 @@ import { trackGas, GasGroup } from './gas-usage'; export let DB: any; export let CONFIG: any; +const SHARES_RSA = [ + // 4 shares + '0x018281ac5380c3461afba00bfdd853b1cfe52cfcd9b3e43d2971848e9d95ad8ee0134aa6af6ff52b96a7eba070eb1064603e8c027bb7e3b11c399e2aeef8e25953c47cba31440c7f09b64e42d0f429e155b7fdeba9dec68e1cfb057d26659f157a7898e60347a7971b00a3332bc1c2ee6c9c8bc628a4985eeeb0d685707c8c939731c99797af712e3a1f65325748b12776938c2b5a5bd8d258a4258998be971c661837f0427bd95e189e07ec831d43aaf6cb1820fccbb735e228b741395d0386b2e3c397fe1f9fe0f3e9e998dcfb41de10b7df8d42a10387f1d6d47c721a9582cc82675fb24f50674aeeb5115e55f7382800999da85346c9ab794d154648cbcd5e7667ab0b73a0d9caeed618e015dcb66193c24c86249e2958badd1b5fb541a5865fa0cac6621580fd96191699c83d75738d899960670889a4425c5b066720e607ce1c1fe32e27e4f880758299ac2d03b6523e22895e583561cce8019f4b87fd6a99c7b1444ca10f41fb2b98d6f50717058984795d76fcfefc627e0d7a18ea9b52b8dac0b6b38c3579dc8111ff8ce14d7cb221cc51a5c113f13c86bb141030ff08e9924c97508430182ff72b3ac79f3fcfdd6fe16981ab4fa674e571c44f4a36cf5731c0e15fdc6dbceb2e129a4eb9e0eb8251b3d1e242eced9bd4b3dd6ce2c6e737b7d0d57fafb34f459d8725d216b9d5f1ff790a2e228f0376ced846b65d814ffe031ce40adeedbcee7bf158af3ee4375eee14fee246d046091ebacc8e2da3cae5d7b1ab5936f152ec2d1f7d4be4623b4db0f0e49e9940056ca4012fa1a1d3b4c81ae02a07869064d42edc76a7faa8f48d754d3f4e9942e34f5da49b7d3f2ec2eb66f427634eb43f68b9ec1cba34e368070f25a483e7b482a98c8cda30976fc791fbf376ad40fcb38a38dbbfee35b7d333daa2729769a632902f9950fd2e0f1e6174d9ebc369d002123176a3f73ec71001e0de34df65eb208d493e8c36b5da34a03e42399fc6b1c49da35096eabc77474d968653a414b9ab42cbbec502cf4705662dfbc73281757fe4535093a872072189c3b9ea3b5d6843f8221d6cb82e9cfc6d0388948c931680a8679361f38d53ea21b160e436a9f050e51c1e8453484fa1e9f3a20d16319d4626421d6b03df8a267e29407a7c04e0a43211769002ab61a1f9017f52994282a6d1699cb85cf2013d4b341081234ca3274dff0e1b77678809c92ac8181a53c72f047e972280c8eafc4be871e3faf3616f29ec389b4953469a2a30ede4a8a9e5e62792c8d37063571b075228aab33324b62850f0844d8952d1ae6a99a6b887067a66087acea207a9ef6b4f55a82c6e30d6dcb983a7c63714f6dc409f46f6b338cfc2de5969c1ecda938ce889f4aa8fb4eee8dc0d5ffc0d2ac7f0dd65a622fd515ca2a21376e9ba15e99241a85a3951871bd438b047517e8e0b4ddf2ff273a30b3ed483f6f20b183ba311e2c4de0a905e9cb4fdf2560c3b5ede0f988623dfe8d2ed27ca157e060e3558b2cfb1d87ae8751dc7432db61056b5e185356d2e72f732c29b5b47a1c287ce5f1be1c162f0b8a1ed93a30269948463679e55e013485b61775328ce08bad3e4ecf8aab485002f65407c0a1afd90e5a3e44909ba6d0d428e77b92ab873bf0217cd6ff7d6d48616efe4d4dc122ac787ee4f6d9c030b1a10403268c0158c7cd7ae821a6754601f710b9731e37c0dc067b5a2ab', + // 7 shares + '0x02a2871c338c3206657ce90c00655f526a2055355bde197116efcc55de8b7bc69db23f2a78c91ccee05bd48c03f1d4903631930f49165acc5e605bcdbd1a4bcdd7b44366f2af42e4126cbffc9e34ec9fa29662a401c5aa7ebef5e4ee287c895617dc930f49165acc5e605bcdbd1a4bcdd7b44366f2af42e4126cbffc9e34ec9fa29662a401c5aa7ebef5e4ee287c895617dcaf4dd395545044ac2c83fe26548751891ac655ede78d6d346d5c1611ec39cd5b828440dddc8d5739253a272b128ea962af4dd395545044ac2c83fe26548751891ac655ede78d6d346d5c1611ec39cd5b828440dddc8d5739253a272b128ea962871c338c3206657ce90c00655f526a2055355bde197116efcc55de8b7bc69db23f2a78c91ccee05bd48c03f1d4903631b7d586100b1137d7c7fc4c9b6aad63021581fcd3fa6bb55455e6eb5e42fdba1b1fe1e25b8a350c47f4904064241c034c5dc03027fb3532501eff0877819eedebeb982d651c47ccc7cecf2cc508ad3ba7dd802e993acbaf696a6dcce1eada8ad77c75fc6085a183990b6fadbfb888205b29e17a00671ce8d04b9f3dd64283c29a58ec2ea3a4f1da6227c207708024bc6243e77f41ad7c219e40e14a4b965a9e9957a44fceba379b7c0082d25446c8d3cbb5e0f81b5fea835f5277f6cb3e62df9680f182571466fdbd28585cd2571c832ce11ff9c9a1d144a505f2ff198b6ab3ba19b0ce3096967635c916be872dacefe2c5477c6da28d6a47fd49d8ecad7f161a8d69fb343ca785c795c3242639866789f8d8631693c4a5c68e5a95061e176635d39e28f9afa9a1f23b5ddaaa6212bc699982631ed39ea56134e10efd459421f4abb9a8d9881e78d538c536e0e3062dd3f0f4ac19e2bf0e8329eaf86279235e6b13507f27a3a1afb5845ffe3fe09b1865f2c9cdccd7efc2c1a45244e67cd62ea7ac5a3316e19ed019d7ba0ac6e420f303e2a951e043e7d69b98a8e0975c69c373074a69f40e423bc4787338b33fa1dc15642849a66d89be6c614c9d7372918ed3f12c8767aeda14800cdde15ed83e1df9824b71fcfe636cdb755c374a9df628a9e2f189c900b02a57306e4099b794cb42fa84dc43e186e9e10e2c786a75b32ffdeaf228a77e53b013d830ebbbbb72af84dbf2f64bd66f0584f26a38324d93ae0acb717c60daa7c947fb4cce4d1865fbbb9982631ed39ea56134e10efd459421f4abb9a8d9881e78d538c536e0e3062dd3f0f4ac19e2bf0e8329eaf86279235e6b13507f27a3a1afb5845ffe3fe09b1865f2c9cdccd7efc2c1a45244e67cd62ea7ac5a3316e19ed019d7ba0ac6e420f303e2a951e043e7d69b98a8e0975c69c373074a69f40e423bc4787338b33fa1dc15642849a66d89be6c614c9d7372918ed3f12c8767aeda14800cdde15ed83e1df9824b71fcfe636cdb755c374a9df628a9e2f189c900b02a57306e4099b794cb42fa84dc43e186e9e10e2c786a75b32ffdeaf228a77e53b013d830ebbbbb72af84dbf2f64bd66f0584f26a38324d93ae0acb717c60daa7c947fb4cce4d1865fbbb343775b368f031ebb11cf73a910c86aa91ab662ccd0dabbec26d656551c1fa4bdd55f72c8f24e0442a453f229633f2db01cb728f38dea94fa3d7319d0689c128eb60ca2935673df587f8c60901fd8ac0eba49510ba1b7f51198c7840524eb237c35da262718eb64918f7c39cf64e47bcdd88abd4c16b0ea220e4f598f721e8d1338422d8c77ea63eac77c7644c516d4d7118fbae442839563243684046c25a445b48d4678e5fd1005124b4c02e122756d4f79d8aa9fd6d2b03d1011c669a4cafa16f2e236539ce6014bf4b0e240d127c1d478db2a9e5bd3c33e79246ee208ae51e96142a76553bca928a7cc8e6f8619106f311ae58953272bc96cc5b0b3d0d57343775b368f031ebb11cf73a910c86aa91ab662ccd0dabbec26d656551c1fa4bdd55f72c8f24e0442a453f229633f2db01cb728f38dea94fa3d7319d0689c128eb60ca2935673df587f8c60901fd8ac0eba49510ba1b7f51198c7840524eb237c35da262718eb64918f7c39cf64e47bcdd88abd4c16b0ea220e4f598f721e8d1338422d8c77ea63eac77c7644c516d4d7118fbae442839563243684046c25a445b48d4678e5fd1005124b4c02e122756d4f79d8aa9fd6d2b03d1011c669a4cafa16f2e236539ce6014bf4b0e240d127c1d478db2a9e5bd3c33e79246ee208ae51e96142a76553bca928a7cc8e6f8619106f311ae58953272bc96cc5b0b3d0d579c98d5c9687ada34ee6a6734575ddbf685490ea50d88dafaa3fcc004ca41b7cc31119d92b7b9dadd5f7deefb3ffcc0e9b19d0ec70be4d07e8a657277bfb36bbb3e465c2c5edcfcc21c6be449dc5d67b2c774809e7103f81d3bd36900fc59bc92e935df496164acd8935a7734eb04ac979bc317d0525b7ecb835a79740d80b7d0643ddbd8bcafeaf7f12a61affbbe627f6c561545bd0edaaa1db01c90342c0cad0a25bd92447e27cd03dea84c53d4696f9e16df06d354ce2c34a26b481075eb53c0748e66c2a21425edf9dbc82c60b16dabfa788b78c7926166762df864e2288fb7db2e4deb57c23cce6e9a85524f10ee2b57df91054d00aa80155a376579caeb9c98d5c9687ada34ee6a6734575ddbf685490ea50d88dafaa3fcc004ca41b7cc31119d92b7b9dadd5f7deefb3ffcc0e9b19d0ec70be4d07e8a657277bfb36bbb3e465c2c5edcfcc21c6be449dc5d67b2c774809e7103f81d3bd36900fc59bc92e935df496164acd8935a7734eb04ac979bc317d0525b7ecb835a79740d80b7d0643ddbd8bcafeaf7f12a61affbbe627f6c561545bd0edaaa1db01c90342c0cad0a25bd92447e27cd03dea84c53d4696f9e16df06d354ce2c34a26b481075eb53c0748e66c2a21425edf9dbc82c60b16dabfa788b78c7926166762df864e2288fb7db2e4deb57c23cce6e9a85524f10ee2b57df91054d00aa80155a376579caeb', + // 10 shares + '0x03c2871c338c3206657ce90c00655f526a2055355bde197116efcc55de8b7bc69db23f2a78c91ccee05bd48c03f1d4903631930f49165acc5e605bcdbd1a4bcdd7b44366f2af42e4126cbffc9e34ec9fa29662a401c5aa7ebef5e4ee287c895617dc930f49165acc5e605bcdbd1a4bcdd7b44366f2af42e4126cbffc9e34ec9fa29662a401c5aa7ebef5e4ee287c895617dcaf4dd395545044ac2c83fe26548751891ac655ede78d6d346d5c1611ec39cd5b828440dddc8d5739253a272b128ea962af4dd395545044ac2c83fe26548751891ac655ede78d6d346d5c1611ec39cd5b828440dddc8d5739253a272b128ea962af4dd395545044ac2c83fe26548751891ac655ede78d6d346d5c1611ec39cd5b828440dddc8d5739253a272b128ea962af4dd395545044ac2c83fe26548751891ac655ede78d6d346d5c1611ec39cd5b828440dddc8d5739253a272b128ea962871c338c3206657ce90c00655f526a2055355bde197116efcc55de8b7bc69db23f2a78c91ccee05bd48c03f1d4903631871c338c3206657ce90c00655f526a2055355bde197116efcc55de8b7bc69db23f2a78c91ccee05bd48c03f1d4903631b7d586100b1137d7c7fc4c9b6aad63021581fcd3fa6bb55455e6eb5e42fdba1b1fe1e25b8a350c47f4904064241c034c5dc03027fb3532501eff0877819eedebeb982d651c47ccc7cecf2cc508ad3ba7dd802e993acbaf696a6dcce1eada8ad77c75fc6085a183990b6fadbfb888205b29e17a00671ce8d04b9f3dd64283c29a58ec2ea3a4f1da6227c207708024bc6243e77f41ad7c219e40e14a4b965a9e9957a44fceba379b7c0082d25446c8d3cbb5e0f81b5fea835f5277f6cb3e62df9680f182571466fdbd28585cd2571c832ce11ff9c9a1d144a505f2ff198b6ab3ba19b0ce3096967635c916be872dacefe2c5477c6da28d6a47fd49d8ecad7f161a8d69fb343ca785c795c3242639866789f8d8631693c4a5c68e5a95061e176635d39e28f9afa9a1f23b5ddaaa6212bc699982631ed39ea56134e10efd459421f4abb9a8d9881e78d538c536e0e3062dd3f0f4ac19e2bf0e8329eaf86279235e6b13507f27a3a1afb5845ffe3fe09b1865f2c9cdccd7efc2c1a45244e67cd62ea7ac5a3316e19ed019d7ba0ac6e420f303e2a951e043e7d69b98a8e0975c69c373074a69f40e423bc4787338b33fa1dc15642849a66d89be6c614c9d7372918ed3f12c8767aeda14800cdde15ed83e1df9824b71fcfe636cdb755c374a9df628a9e2f189c900b02a57306e4099b794cb42fa84dc43e186e9e10e2c786a75b32ffdeaf228a77e53b013d830ebbbbb72af84dbf2f64bd66f0584f26a38324d93ae0acb717c60daa7c947fb4cce4d1865fbbb9982631ed39ea56134e10efd459421f4abb9a8d9881e78d538c536e0e3062dd3f0f4ac19e2bf0e8329eaf86279235e6b13507f27a3a1afb5845ffe3fe09b1865f2c9cdccd7efc2c1a45244e67cd62ea7ac5a3316e19ed019d7ba0ac6e420f303e2a951e043e7d69b98a8e0975c69c373074a69f40e423bc4787338b33fa1dc15642849a66d89be6c614c9d7372918ed3f12c8767aeda14800cdde15ed83e1df9824b71fcfe636cdb755c374a9df628a9e2f189c900b02a57306e4099b794cb42fa84dc43e186e9e10e2c786a75b32ffdeaf228a77e53b013d830ebbbbb72af84dbf2f64bd66f0584f26a38324d93ae0acb717c60daa7c947fb4cce4d1865fbbb9982631ed39ea56134e10efd459421f4abb9a8d9881e78d538c536e0e3062dd3f0f4ac19e2bf0e8329eaf86279235e6b13507f27a3a1afb5845ffe3fe09b1865f2c9cdccd7efc2c1a45244e67cd62ea7ac5a3316e19ed019d7ba0ac6e420f303e2a951e043e7d69b98a8e0975c69c373074a69f40e423bc4787338b33fa1dc15642849a66d89be6c614c9d7372918ed3f12c8767aeda14800cdde15ed83e1df9824b71fcfe636cdb755c374a9df628a9e2f189c900b02a57306e4099b794cb42fa84dc43e186e9e10e2c786a75b32ffdeaf228a77e53b013d830ebbbbb72af84dbf2f64bd66f0584f26a38324d93ae0acb717c60daa7c947fb4cce4d1865fbbb343775b368f031ebb11cf73a910c86aa91ab662ccd0dabbec26d656551c1fa4bdd55f72c8f24e0442a453f229633f2db01cb728f38dea94fa3d7319d0689c128eb60ca2935673df587f8c60901fd8ac0eba49510ba1b7f51198c7840524eb237c35da262718eb64918f7c39cf64e47bcdd88abd4c16b0ea220e4f598f721e8d1338422d8c77ea63eac77c7644c516d4d7118fbae442839563243684046c25a445b48d4678e5fd1005124b4c02e122756d4f79d8aa9fd6d2b03d1011c669a4cafa16f2e236539ce6014bf4b0e240d127c1d478db2a9e5bd3c33e79246ee208ae51e96142a76553bca928a7cc8e6f8619106f311ae58953272bc96cc5b0b3d0d57343775b368f031ebb11cf73a910c86aa91ab662ccd0dabbec26d656551c1fa4bdd55f72c8f24e0442a453f229633f2db01cb728f38dea94fa3d7319d0689c128eb60ca2935673df587f8c60901fd8ac0eba49510ba1b7f51198c7840524eb237c35da262718eb64918f7c39cf64e47bcdd88abd4c16b0ea220e4f598f721e8d1338422d8c77ea63eac77c7644c516d4d7118fbae442839563243684046c25a445b48d4678e5fd1005124b4c02e122756d4f79d8aa9fd6d2b03d1011c669a4cafa16f2e236539ce6014bf4b0e240d127c1d478db2a9e5bd3c33e79246ee208ae51e96142a76553bca928a7cc8e6f8619106f311ae58953272bc96cc5b0b3d0d57343775b368f031ebb11cf73a910c86aa91ab662ccd0dabbec26d656551c1fa4bdd55f72c8f24e0442a453f229633f2db01cb728f38dea94fa3d7319d0689c128eb60ca2935673df587f8c60901fd8ac0eba49510ba1b7f51198c7840524eb237c35da262718eb64918f7c39cf64e47bcdd88abd4c16b0ea220e4f598f721e8d1338422d8c77ea63eac77c7644c516d4d7118fbae442839563243684046c25a445b48d4678e5fd1005124b4c02e122756d4f79d8aa9fd6d2b03d1011c669a4cafa16f2e236539ce6014bf4b0e240d127c1d478db2a9e5bd3c33e79246ee208ae51e96142a76553bca928a7cc8e6f8619106f311ae58953272bc96cc5b0b3d0d57343775b368f031ebb11cf73a910c86aa91ab662ccd0dabbec26d656551c1fa4bdd55f72c8f24e0442a453f229633f2db01cb728f38dea94fa3d7319d0689c128eb60ca2935673df587f8c60901fd8ac0eba49510ba1b7f51198c7840524eb237c35da262718eb64918f7c39cf64e47bcdd88abd4c16b0ea220e4f598f721e8d1338422d8c77ea63eac77c7644c516d4d7118fbae442839563243684046c25a445b48d4678e5fd1005124b4c02e122756d4f79d8aa9fd6d2b03d1011c669a4cafa16f2e236539ce6014bf4b0e240d127c1d478db2a9e5bd3c33e79246ee208ae51e96142a76553bca928a7cc8e6f8619106f311ae58953272bc96cc5b0b3d0d579c98d5c9687ada34ee6a6734575ddbf685490ea50d88dafaa3fcc004ca41b7cc31119d92b7b9dadd5f7deefb3ffcc0e9b19d0ec70be4d07e8a657277bfb36bbb3e465c2c5edcfcc21c6be449dc5d67b2c774809e7103f81d3bd36900fc59bc92e935df496164acd8935a7734eb04ac979bc317d0525b7ecb835a79740d80b7d0643ddbd8bcafeaf7f12a61affbbe627f6c561545bd0edaaa1db01c90342c0cad0a25bd92447e27cd03dea84c53d4696f9e16df06d354ce2c34a26b481075eb53c0748e66c2a21425edf9dbc82c60b16dabfa788b78c7926166762df864e2288fb7db2e4deb57c23cce6e9a85524f10ee2b57df91054d00aa80155a376579caeb9c98d5c9687ada34ee6a6734575ddbf685490ea50d88dafaa3fcc004ca41b7cc31119d92b7b9dadd5f7deefb3ffcc0e9b19d0ec70be4d07e8a657277bfb36bbb3e465c2c5edcfcc21c6be449dc5d67b2c774809e7103f81d3bd36900fc59bc92e935df496164acd8935a7734eb04ac979bc317d0525b7ecb835a79740d80b7d0643ddbd8bcafeaf7f12a61affbbe627f6c561545bd0edaaa1db01c90342c0cad0a25bd92447e27cd03dea84c53d4696f9e16df06d354ce2c34a26b481075eb53c0748e66c2a21425edf9dbc82c60b16dabfa788b78c7926166762df864e2288fb7db2e4deb57c23cce6e9a85524f10ee2b57df91054d00aa80155a376579caeb', + // 13 shares + '0x04e2871c338c3206657ce90c00655f526a2055355bde197116efcc55de8b7bc69db23f2a78c91ccee05bd48c03f1d4903631930f49165acc5e605bcdbd1a4bcdd7b44366f2af42e4126cbffc9e34ec9fa29662a401c5aa7ebef5e4ee287c895617dc930f49165acc5e605bcdbd1a4bcdd7b44366f2af42e4126cbffc9e34ec9fa29662a401c5aa7ebef5e4ee287c895617dc930f49165acc5e605bcdbd1a4bcdd7b44366f2af42e4126cbffc9e34ec9fa29662a401c5aa7ebef5e4ee287c895617dcaf4dd395545044ac2c83fe26548751891ac655ede78d6d346d5c1611ec39cd5b828440dddc8d5739253a272b128ea962af4dd395545044ac2c83fe26548751891ac655ede78d6d346d5c1611ec39cd5b828440dddc8d5739253a272b128ea962af4dd395545044ac2c83fe26548751891ac655ede78d6d346d5c1611ec39cd5b828440dddc8d5739253a272b128ea962af4dd395545044ac2c83fe26548751891ac655ede78d6d346d5c1611ec39cd5b828440dddc8d5739253a272b128ea962af4dd395545044ac2c83fe26548751891ac655ede78d6d346d5c1611ec39cd5b828440dddc8d5739253a272b128ea962871c338c3206657ce90c00655f526a2055355bde197116efcc55de8b7bc69db23f2a78c91ccee05bd48c03f1d4903631871c338c3206657ce90c00655f526a2055355bde197116efcc55de8b7bc69db23f2a78c91ccee05bd48c03f1d4903631871c338c3206657ce90c00655f526a2055355bde197116efcc55de8b7bc69db23f2a78c91ccee05bd48c03f1d4903631b7d586100b1137d7c7fc4c9b6aad63021581fcd3fa6bb55455e6eb5e42fdba1b1fe1e25b8a350c47f4904064241c034c5dc03027fb3532501eff0877819eedebeb982d651c47ccc7cecf2cc508ad3ba7dd802e993acbaf696a6dcce1eada8ad77c75fc6085a183990b6fadbfb888205b29e17a00671ce8d04b9f3dd64283c29a58ec2ea3a4f1da6227c207708024bc6243e77f41ad7c219e40e14a4b965a9e9957a44fceba379b7c0082d25446c8d3cbb5e0f81b5fea835f5277f6cb3e62df9680f182571466fdbd28585cd2571c832ce11ff9c9a1d144a505f2ff198b6ab3ba19b0ce3096967635c916be872dacefe2c5477c6da28d6a47fd49d8ecad7f161a8d69fb343ca785c795c3242639866789f8d8631693c4a5c68e5a95061e176635d39e28f9afa9a1f23b5ddaaa6212bc699982631ed39ea56134e10efd459421f4abb9a8d9881e78d538c536e0e3062dd3f0f4ac19e2bf0e8329eaf86279235e6b13507f27a3a1afb5845ffe3fe09b1865f2c9cdccd7efc2c1a45244e67cd62ea7ac5a3316e19ed019d7ba0ac6e420f303e2a951e043e7d69b98a8e0975c69c373074a69f40e423bc4787338b33fa1dc15642849a66d89be6c614c9d7372918ed3f12c8767aeda14800cdde15ed83e1df9824b71fcfe636cdb755c374a9df628a9e2f189c900b02a57306e4099b794cb42fa84dc43e186e9e10e2c786a75b32ffdeaf228a77e53b013d830ebbbbb72af84dbf2f64bd66f0584f26a38324d93ae0acb717c60daa7c947fb4cce4d1865fbbb9982631ed39ea56134e10efd459421f4abb9a8d9881e78d538c536e0e3062dd3f0f4ac19e2bf0e8329eaf86279235e6b13507f27a3a1afb5845ffe3fe09b1865f2c9cdccd7efc2c1a45244e67cd62ea7ac5a3316e19ed019d7ba0ac6e420f303e2a951e043e7d69b98a8e0975c69c373074a69f40e423bc4787338b33fa1dc15642849a66d89be6c614c9d7372918ed3f12c8767aeda14800cdde15ed83e1df9824b71fcfe636cdb755c374a9df628a9e2f189c900b02a57306e4099b794cb42fa84dc43e186e9e10e2c786a75b32ffdeaf228a77e53b013d830ebbbbb72af84dbf2f64bd66f0584f26a38324d93ae0acb717c60daa7c947fb4cce4d1865fbbb9982631ed39ea56134e10efd459421f4abb9a8d9881e78d538c536e0e3062dd3f0f4ac19e2bf0e8329eaf86279235e6b13507f27a3a1afb5845ffe3fe09b1865f2c9cdccd7efc2c1a45244e67cd62ea7ac5a3316e19ed019d7ba0ac6e420f303e2a951e043e7d69b98a8e0975c69c373074a69f40e423bc4787338b33fa1dc15642849a66d89be6c614c9d7372918ed3f12c8767aeda14800cdde15ed83e1df9824b71fcfe636cdb755c374a9df628a9e2f189c900b02a57306e4099b794cb42fa84dc43e186e9e10e2c786a75b32ffdeaf228a77e53b013d830ebbbbb72af84dbf2f64bd66f0584f26a38324d93ae0acb717c60daa7c947fb4cce4d1865fbbb9982631ed39ea56134e10efd459421f4abb9a8d9881e78d538c536e0e3062dd3f0f4ac19e2bf0e8329eaf86279235e6b13507f27a3a1afb5845ffe3fe09b1865f2c9cdccd7efc2c1a45244e67cd62ea7ac5a3316e19ed019d7ba0ac6e420f303e2a951e043e7d69b98a8e0975c69c373074a69f40e423bc4787338b33fa1dc15642849a66d89be6c614c9d7372918ed3f12c8767aeda14800cdde15ed83e1df9824b71fcfe636cdb755c374a9df628a9e2f189c900b02a57306e4099b794cb42fa84dc43e186e9e10e2c786a75b32ffdeaf228a77e53b013d830ebbbbb72af84dbf2f64bd66f0584f26a38324d93ae0acb717c60daa7c947fb4cce4d1865fbbb343775b368f031ebb11cf73a910c86aa91ab662ccd0dabbec26d656551c1fa4bdd55f72c8f24e0442a453f229633f2db01cb728f38dea94fa3d7319d0689c128eb60ca2935673df587f8c60901fd8ac0eba49510ba1b7f51198c7840524eb237c35da262718eb64918f7c39cf64e47bcdd88abd4c16b0ea220e4f598f721e8d1338422d8c77ea63eac77c7644c516d4d7118fbae442839563243684046c25a445b48d4678e5fd1005124b4c02e122756d4f79d8aa9fd6d2b03d1011c669a4cafa16f2e236539ce6014bf4b0e240d127c1d478db2a9e5bd3c33e79246ee208ae51e96142a76553bca928a7cc8e6f8619106f311ae58953272bc96cc5b0b3d0d57343775b368f031ebb11cf73a910c86aa91ab662ccd0dabbec26d656551c1fa4bdd55f72c8f24e0442a453f229633f2db01cb728f38dea94fa3d7319d0689c128eb60ca2935673df587f8c60901fd8ac0eba49510ba1b7f51198c7840524eb237c35da262718eb64918f7c39cf64e47bcdd88abd4c16b0ea220e4f598f721e8d1338422d8c77ea63eac77c7644c516d4d7118fbae442839563243684046c25a445b48d4678e5fd1005124b4c02e122756d4f79d8aa9fd6d2b03d1011c669a4cafa16f2e236539ce6014bf4b0e240d127c1d478db2a9e5bd3c33e79246ee208ae51e96142a76553bca928a7cc8e6f8619106f311ae58953272bc96cc5b0b3d0d57343775b368f031ebb11cf73a910c86aa91ab662ccd0dabbec26d656551c1fa4bdd55f72c8f24e0442a453f229633f2db01cb728f38dea94fa3d7319d0689c128eb60ca2935673df587f8c60901fd8ac0eba49510ba1b7f51198c7840524eb237c35da262718eb64918f7c39cf64e47bcdd88abd4c16b0ea220e4f598f721e8d1338422d8c77ea63eac77c7644c516d4d7118fbae442839563243684046c25a445b48d4678e5fd1005124b4c02e122756d4f79d8aa9fd6d2b03d1011c669a4cafa16f2e236539ce6014bf4b0e240d127c1d478db2a9e5bd3c33e79246ee208ae51e96142a76553bca928a7cc8e6f8619106f311ae58953272bc96cc5b0b3d0d57343775b368f031ebb11cf73a910c86aa91ab662ccd0dabbec26d656551c1fa4bdd55f72c8f24e0442a453f229633f2db01cb728f38dea94fa3d7319d0689c128eb60ca2935673df587f8c60901fd8ac0eba49510ba1b7f51198c7840524eb237c35da262718eb64918f7c39cf64e47bcdd88abd4c16b0ea220e4f598f721e8d1338422d8c77ea63eac77c7644c516d4d7118fbae442839563243684046c25a445b48d4678e5fd1005124b4c02e122756d4f79d8aa9fd6d2b03d1011c669a4cafa16f2e236539ce6014bf4b0e240d127c1d478db2a9e5bd3c33e79246ee208ae51e96142a76553bca928a7cc8e6f8619106f311ae58953272bc96cc5b0b3d0d57343775b368f031ebb11cf73a910c86aa91ab662ccd0dabbec26d656551c1fa4bdd55f72c8f24e0442a453f229633f2db01cb728f38dea94fa3d7319d0689c128eb60ca2935673df587f8c60901fd8ac0eba49510ba1b7f51198c7840524eb237c35da262718eb64918f7c39cf64e47bcdd88abd4c16b0ea220e4f598f721e8d1338422d8c77ea63eac77c7644c516d4d7118fbae442839563243684046c25a445b48d4678e5fd1005124b4c02e122756d4f79d8aa9fd6d2b03d1011c669a4cafa16f2e236539ce6014bf4b0e240d127c1d478db2a9e5bd3c33e79246ee208ae51e96142a76553bca928a7cc8e6f8619106f311ae58953272bc96cc5b0b3d0d579c98d5c9687ada34ee6a6734575ddbf685490ea50d88dafaa3fcc004ca41b7cc31119d92b7b9dadd5f7deefb3ffcc0e9b19d0ec70be4d07e8a657277bfb36bbb3e465c2c5edcfcc21c6be449dc5d67b2c774809e7103f81d3bd36900fc59bc92e935df496164acd8935a7734eb04ac979bc317d0525b7ecb835a79740d80b7d0643ddbd8bcafeaf7f12a61affbbe627f6c561545bd0edaaa1db01c90342c0cad0a25bd92447e27cd03dea84c53d4696f9e16df06d354ce2c34a26b481075eb53c0748e66c2a21425edf9dbc82c60b16dabfa788b78c7926166762df864e2288fb7db2e4deb57c23cce6e9a85524f10ee2b57df91054d00aa80155a376579caeb9c98d5c9687ada34ee6a6734575ddbf685490ea50d88dafaa3fcc004ca41b7cc31119d92b7b9dadd5f7deefb3ffcc0e9b19d0ec70be4d07e8a657277bfb36bbb3e465c2c5edcfcc21c6be449dc5d67b2c774809e7103f81d3bd36900fc59bc92e935df496164acd8935a7734eb04ac979bc317d0525b7ecb835a79740d80b7d0643ddbd8bcafeaf7f12a61affbbe627f6c561545bd0edaaa1db01c90342c0cad0a25bd92447e27cd03dea84c53d4696f9e16df06d354ce2c34a26b481075eb53c0748e66c2a21425edf9dbc82c60b16dabfa788b78c7926166762df864e2288fb7db2e4deb57c23cce6e9a85524f10ee2b57df91054d00aa80155a376579caeb9c98d5c9687ada34ee6a6734575ddbf685490ea50d88dafaa3fcc004ca41b7cc31119d92b7b9dadd5f7deefb3ffcc0e9b19d0ec70be4d07e8a657277bfb36bbb3e465c2c5edcfcc21c6be449dc5d67b2c774809e7103f81d3bd36900fc59bc92e935df496164acd8935a7734eb04ac979bc317d0525b7ecb835a79740d80b7d0643ddbd8bcafeaf7f12a61affbbe627f6c561545bd0edaaa1db01c90342c0cad0a25bd92447e27cd03dea84c53d4696f9e16df06d354ce2c34a26b481075eb53c0748e66c2a21425edf9dbc82c60b16dabfa788b78c7926166762df864e2288fb7db2e4deb57c23cce6e9a85524f10ee2b57df91054d00aa80155a376579caeb' +]; + export const DataGenerator = { publicKey: (index: number) => `0x${index.toString(16).padStart(96, '1')}`, - shares: (index: number) => `0x${index.toString(16).padStart(360, '1')}`, + 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]; + } + }, cluster: { new: (size = 4) => { const usedOperatorIds: any = {}; diff --git a/test/helpers/gas-usage.ts b/test/helpers/gas-usage.ts index 61777cbe..098fa452 100644 --- a/test/helpers/gas-usage.ts +++ b/test/helpers/gas-usage.ts @@ -36,17 +36,17 @@ const MAX_GAS_PER_GROUP: any = { [GasGroup.REMOVE_OPERATOR]: 62000, [GasGroup.REMOVE_OPERATOR_WITH_WITHDRAW]: 62000, - [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]: 176500, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE]: 194500, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT]: 153500, + [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]: 195000, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE]: 211500, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT]: 173750, - [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_7]: 219500, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]: 236500, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_7]: 196500, + [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_7]: 258000, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]: 275000, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_7]: 237000, - [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_13]: 306200, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]: 323200, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_13]: 283200, + [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_13]: 385000, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]: 402000, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_13]: 365000, [GasGroup.REMOVE_VALIDATOR]: 120000, [GasGroup.TRANSFER_VALIDATOR_NEW_CLUSTER]: 400000, diff --git a/test/liquidate/liquidate.ts b/test/liquidate/liquidate.ts index e97f8ca4..5e41cfee 100644 --- a/test/liquidate/liquidate.ts +++ b/test/liquidate/liquidate.ts @@ -21,7 +21,7 @@ describe('Liquidate Tests', () => { await ssvNetworkContract.connect(helpers.DB.owners[6]).registerValidator( '0x221111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111119', [1,2,3,4], - helpers.DataGenerator.shares(0), + helpers.DataGenerator.shares(4), '1000000000000000', { validatorCount: 0, @@ -38,7 +38,7 @@ describe('Liquidate Tests', () => { const register = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( helpers.DataGenerator.publicKey(1), [1,2,3,4], - helpers.DataGenerator.shares(0), + helpers.DataGenerator.shares(4), minDepositAmount, { validatorCount: 0, @@ -96,7 +96,7 @@ describe('Liquidate Tests', () => { await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( helpers.DataGenerator.publicKey(2), updatedCluster.operatorIds, - helpers.DataGenerator.shares(0), + helpers.DataGenerator.shares(4), `${minDepositAmount*2}`, updatedCluster.cluster ), [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]); diff --git a/test/liquidate/reactivate.ts b/test/liquidate/reactivate.ts index 3b2871cd..cf126c89 100644 --- a/test/liquidate/reactivate.ts +++ b/test/liquidate/reactivate.ts @@ -22,7 +22,7 @@ describe('Reactivate Tests', () => { await ssvNetworkContract.connect(helpers.DB.owners[6]).registerValidator( '0x221111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111119', [1,2,3,4], - helpers.DataGenerator.shares(0), + helpers.DataGenerator.shares(4), '1000000000000000', { validatorCount: 0, @@ -39,7 +39,7 @@ describe('Reactivate Tests', () => { const register = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( helpers.DataGenerator.publicKey(1), [1,2,3,4], - helpers.DataGenerator.shares(0), + helpers.DataGenerator.shares(4), minDepositAmount, { validatorCount: 0, diff --git a/test/operators/remove.ts b/test/operators/remove.ts index 621e357d..125faa27 100644 --- a/test/operators/remove.ts +++ b/test/operators/remove.ts @@ -18,7 +18,7 @@ describe('Remove Operator Tests', () => { await ssvNetworkContract.connect(helpers.DB.owners[6]).registerValidator( '0x221111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111119', [1,2,3,4], - helpers.DataGenerator.shares(0), + helpers.DataGenerator.shares(4), '1000000000000000', { validatorCount: 0, diff --git a/test/sanity/balances.ts b/test/sanity/balances.ts index 1576e7cc..3bdfc761 100644 --- a/test/sanity/balances.ts +++ b/test/sanity/balances.ts @@ -30,7 +30,7 @@ describe('Balance Tests', () => { await ssvNetworkContract.connect(helpers.DB.owners[6]).registerValidator( '0x221111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111119', [1,2,3,4], - helpers.DataGenerator.shares(0), + helpers.DataGenerator.shares(4), '1000000000000000', { validatorCount: 0, diff --git a/test/validators/register.ts b/test/validators/register.ts index 6369c69e..efe54570 100644 --- a/test/validators/register.ts +++ b/test/validators/register.ts @@ -21,7 +21,7 @@ describe('Register Validator Tests', () => { await ssvNetworkContract.connect(helpers.DB.owners[6]).registerValidator( '0x221111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111119', [1,2,3,4], - helpers.DataGenerator.shares(0), + helpers.DataGenerator.shares(4), '1000000000000000', { validatorCount: 0, @@ -39,7 +39,7 @@ describe('Register Validator Tests', () => { await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( helpers.DataGenerator.publicKey(1), helpers.DataGenerator.cluster.new(), - helpers.DataGenerator.shares(0), + helpers.DataGenerator.shares(4), minDepositAmount, { validatorCount: 0, @@ -57,7 +57,7 @@ describe('Register Validator Tests', () => { const { eventsByName } = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( helpers.DataGenerator.publicKey(1), [1,2,3,4], - helpers.DataGenerator.shares(0), + helpers.DataGenerator.shares(4), minDepositAmount, { validatorCount: 0, @@ -75,7 +75,7 @@ describe('Register Validator Tests', () => { await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( helpers.DataGenerator.publicKey(2), [1,2,3,4], - helpers.DataGenerator.shares(0), + helpers.DataGenerator.shares(4), minDepositAmount, args.cluster ), [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]); @@ -86,7 +86,7 @@ describe('Register Validator Tests', () => { const { eventsByName } = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( helpers.DataGenerator.publicKey(1), [1,2,3,4], - helpers.DataGenerator.shares(0), + helpers.DataGenerator.shares(4), minDepositAmount, { validatorCount: 0, @@ -104,7 +104,7 @@ describe('Register Validator Tests', () => { await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( helpers.DataGenerator.publicKey(2), [1,2,3,4], - helpers.DataGenerator.shares(0), + helpers.DataGenerator.shares(4), minDepositAmount, args.cluster ), [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]); @@ -113,7 +113,7 @@ describe('Register Validator Tests', () => { await trackGas(ssvNetworkContract.connect(helpers.DB.owners[2]).registerValidator( helpers.DataGenerator.publicKey(4), [2,3,4,5], - helpers.DataGenerator.shares(0), + helpers.DataGenerator.shares(4), minDepositAmount, { validatorCount: 0, @@ -131,7 +131,7 @@ describe('Register Validator Tests', () => { const { eventsByName } = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( helpers.DataGenerator.publicKey(1), [1,2,3,4], - helpers.DataGenerator.shares(0), + helpers.DataGenerator.shares(4), `${minDepositAmount*2}`, { validatorCount: 0, @@ -147,7 +147,7 @@ describe('Register Validator Tests', () => { await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( helpers.DataGenerator.publicKey(2), [1,2,3,4], - helpers.DataGenerator.shares(0), + helpers.DataGenerator.shares(4), 0, args.cluster ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT]); @@ -160,7 +160,7 @@ describe('Register Validator Tests', () => { await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( helpers.DataGenerator.publicKey(1), helpers.DataGenerator.cluster.new(7), - helpers.DataGenerator.shares(0), + helpers.DataGenerator.shares(7), minDepositAmount, { validatorCount: 0, @@ -178,7 +178,7 @@ describe('Register Validator Tests', () => { 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(0), + helpers.DataGenerator.shares(7), minDepositAmount, { validatorCount: 0, @@ -196,7 +196,7 @@ describe('Register Validator Tests', () => { await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( helpers.DataGenerator.publicKey(2), [1,2,3,4,5,6,7], - helpers.DataGenerator.shares(0), + helpers.DataGenerator.shares(7), minDepositAmount, args.cluster ), [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_7]); @@ -207,7 +207,7 @@ describe('Register Validator Tests', () => { 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(0), + helpers.DataGenerator.shares(7), minDepositAmount, { validatorCount: 0, @@ -225,7 +225,7 @@ describe('Register Validator Tests', () => { await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( helpers.DataGenerator.publicKey(2), [1,2,3,4,5,6,7], - helpers.DataGenerator.shares(0), + helpers.DataGenerator.shares(7), minDepositAmount, args.cluster ), [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_7]); @@ -234,7 +234,7 @@ describe('Register Validator Tests', () => { await trackGas(ssvNetworkContract.connect(helpers.DB.owners[2]).registerValidator( helpers.DataGenerator.publicKey(4), [2,3,4,5,6,7,8], - helpers.DataGenerator.shares(0), + helpers.DataGenerator.shares(7), minDepositAmount, { validatorCount: 0, @@ -252,7 +252,7 @@ describe('Register Validator Tests', () => { 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(0), + helpers.DataGenerator.shares(7), `${minDepositAmount*2}`, { validatorCount: 0, @@ -268,7 +268,7 @@ describe('Register Validator Tests', () => { await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( helpers.DataGenerator.publicKey(2), [1,2,3,4,5,6,7], - helpers.DataGenerator.shares(0), + helpers.DataGenerator.shares(7), 0, args.cluster ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_7]); @@ -281,7 +281,7 @@ describe('Register Validator Tests', () => { await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( helpers.DataGenerator.publicKey(1), helpers.DataGenerator.cluster.new(13), - helpers.DataGenerator.shares(0), + helpers.DataGenerator.shares(13), minDepositAmount, { validatorCount: 0, @@ -299,7 +299,7 @@ describe('Register Validator Tests', () => { 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(0), + helpers.DataGenerator.shares(13), minDepositAmount, { validatorCount: 0, @@ -317,7 +317,7 @@ describe('Register Validator Tests', () => { 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(0), + helpers.DataGenerator.shares(13), minDepositAmount, args.cluster ), [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_13]); @@ -328,7 +328,7 @@ describe('Register Validator Tests', () => { 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(0), + helpers.DataGenerator.shares(13), minDepositAmount, { validatorCount: 0, @@ -346,7 +346,7 @@ describe('Register Validator Tests', () => { 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(0), + helpers.DataGenerator.shares(13), minDepositAmount, args.cluster ), [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_13]); @@ -355,7 +355,7 @@ describe('Register Validator Tests', () => { 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(0), + helpers.DataGenerator.shares(13), minDepositAmount, { validatorCount: 0, @@ -373,7 +373,7 @@ describe('Register Validator Tests', () => { 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(0), + helpers.DataGenerator.shares(13), `${minDepositAmount*2}`, { validatorCount: 0, @@ -389,7 +389,7 @@ describe('Register Validator Tests', () => { 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(0), + helpers.DataGenerator.shares(13), 0, args.cluster ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_13]); @@ -400,7 +400,7 @@ describe('Register Validator Tests', () => { await ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( helpers.DataGenerator.publicKey(2), [1, 2, 3, 4], - helpers.DataGenerator.shares(0), + helpers.DataGenerator.shares(4), minDepositAmount, { validatorCount: 0, @@ -415,7 +415,7 @@ describe('Register Validator Tests', () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( helpers.DataGenerator.publicKey(3), [1, 2, 3, 4], - helpers.DataGenerator.shares(0), + helpers.DataGenerator.shares(4), minDepositAmount, { validatorCount: 2, @@ -432,7 +432,7 @@ describe('Register Validator Tests', () => { await expect(ssvNetworkContract.registerValidator( helpers.DataGenerator.publicKey(2), [1, 2, 3, 25], - helpers.DataGenerator.shares(0), + helpers.DataGenerator.shares(4), minDepositAmount, { validatorCount: 0, @@ -448,9 +448,9 @@ describe('Register Validator Tests', () => { it('Register validator with removed operator returns an error - OperatorDoesNotExist', async () => { await ssvNetworkContract.removeOperator(1); await expect(ssvNetworkContract.registerValidator( - helpers.DataGenerator.publicKey(2), + helpers.DataGenerator.publicKey(4), [1, 2, 3, 4], - helpers.DataGenerator.shares(0), + helpers.DataGenerator.shares(4), minDepositAmount, { validatorCount: 0, @@ -468,7 +468,7 @@ describe('Register Validator Tests', () => { await expect(ssvNetworkContract.registerValidator( helpers.DataGenerator.publicKey(1), [1, 2, 3, 4], - helpers.DataGenerator.shares(0), + helpers.DataGenerator.shares(4), minDepositAmount, { validatorCount: 0, @@ -500,7 +500,7 @@ describe('Register Validator Tests', () => { await expect(ssvNetworkContract.registerValidator( helpers.DataGenerator.shares(0), [1, 2, 3, 4], - helpers.DataGenerator.shares(0), + helpers.DataGenerator.shares(4), minDepositAmount, { validatorCount: 0, @@ -518,7 +518,7 @@ describe('Register Validator Tests', () => { await expect(ssvNetworkContract.registerValidator( helpers.DataGenerator.publicKey(1), [1, 2, 3, 4], - helpers.DataGenerator.shares(0), + helpers.DataGenerator.shares(4), helpers.CONFIG.minimalOperatorFee, { validatorCount: 0, @@ -536,7 +536,7 @@ describe('Register Validator Tests', () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[6]).registerValidator( '0x221111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111119', [1,2,3,4], - helpers.DataGenerator.shares(0), + helpers.DataGenerator.shares(4), minDepositAmount, { validatorCount: 0, diff --git a/test/validators/remove.ts b/test/validators/remove.ts index 4046dfda..c9d1b2ec 100644 --- a/test/validators/remove.ts +++ b/test/validators/remove.ts @@ -23,7 +23,7 @@ describe('Remove Validator Tests', () => { await ssvNetworkContract.connect(helpers.DB.owners[6]).registerValidator( '0x221111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111119', [1,2,3,4], - helpers.DataGenerator.shares(0), + helpers.DataGenerator.shares(4), '1000000000000000', { validatorCount: 0, @@ -40,7 +40,7 @@ describe('Remove Validator Tests', () => { const register = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( helpers.DataGenerator.publicKey(1), [1,2,3,4], - helpers.DataGenerator.shares(0), + helpers.DataGenerator.shares(4), minDepositAmount, { validatorCount: 0, @@ -116,7 +116,7 @@ describe('Remove Validator Tests', () => { const newRegister = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( helpers.DataGenerator.publicKey(1), updatedCluster.operatorIds, - helpers.DataGenerator.shares(0), + helpers.DataGenerator.shares(4), 0, updatedCluster.cluster ), [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]); From e9f3b36346786d5706c9e8c5ab7b8d509cf3ae0b Mon Sep 17 00:00:00 2001 From: mtabasco Date: Wed, 18 Jan 2023 13:40:00 +0100 Subject: [PATCH 116/149] naming changes (#169) --- contracts/ISSVNetwork.sol | 16 ++--------- contracts/SSVNetwork.sol | 60 ++++++++++++--------------------------- hardhat.config.ts | 2 +- test/account/deposit.ts | 14 ++++----- test/sanity/balances.ts | 24 ++++++++-------- test/validators/remove.ts | 2 +- 6 files changed, 42 insertions(+), 76 deletions(-) diff --git a/contracts/ISSVNetwork.sol b/contracts/ISSVNetwork.sol index 59963789..6a9a014e 100644 --- a/contracts/ISSVNetwork.sol +++ b/contracts/ISSVNetwork.sol @@ -117,7 +117,7 @@ interface ISSVNetwork { event ClusterWithdrawn(address owner, uint64[] operatorIds, uint256 value, Cluster cluster); event OperatorWithdrawn(uint256 value, uint64 operatorId, address owner); - event ClusterDeposit( + event ClusterDeposited( address owner, uint64[] operatorIds, uint256 value, @@ -146,13 +146,11 @@ interface ISSVNetwork { error ClusterNotLiquidatable(); error InvalidPublicKeyLength(); error InvalidOperatorIdsLength(); - error NoValidatorOwnership(); - error ParametersMismatch(); + error ValidatorOwnedByOtherAddress(); error InsufficientFunds(); error ClusterAlreadyEnabled(); error ClusterIsLiquidated(); error ClusterDoesNotExists(); - error BurnRatePositive(); error IncorrectClusterState(); error UnsortedOperatorsList(); error NewBlockPeriodIsBelowMinimum(); @@ -250,12 +248,6 @@ interface ISSVNetwork { Cluster memory cluster ) external; - function deposit( - uint64[] memory operatorIds, - uint256 amount, - Cluster memory cluster - ) external; - function withdrawOperatorEarnings(uint64 operatorId, uint256 tokenAmount) external; function withdrawOperatorEarnings(uint64 operatorId) external; @@ -327,11 +319,9 @@ interface ISSVNetwork { /** * @dev Gets the operators current snapshot. * @param id Operator's id. - * @return currentBlock the block that the snapshot is updated to. - * @return index the index of the operator. * @return balance the current balance of the operator. */ - function getOperatorEarnings(uint64 id) external view returns (uint64 currentBlock, uint64 index, uint256 balance); + function getOperatorEarnings(uint64 id) external view returns (uint256 balance); function getBalance( address owner, diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index c03e4a5e..27994195 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -344,7 +344,7 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { revert ValidatorDoesNotExist(); } if (owner != msg.sender) { - revert NoValidatorOwnership(); + revert ValidatorOwnedByOtherAddress(); } { @@ -521,39 +521,25 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { _deposit(shrunkAmount); - emit ClusterDeposit(owner, operatorIds, amount, cluster); + emit ClusterDeposited(owner, operatorIds, amount, cluster); } - function deposit( - uint64[] calldata operatorIds, - uint256 amount, - Cluster memory cluster - ) external override { - _validateClusterIsNotLiquidated(cluster); - - uint64 shrunkAmount = amount.shrink(); - - bytes32 hashedCluster = _validateHashedCluster(msg.sender, operatorIds, cluster); - cluster.balance += shrunkAmount; + function _withdrawOperatorEarnings(uint64 operatorId, uint256 amount) private { - _clusters[hashedCluster] = keccak256(abi.encodePacked(cluster.validatorCount, cluster.networkFee, cluster.networkFeeIndex, cluster.index, cluster.balance, cluster.disabled )); - - _deposit(shrunkAmount); - - emit ClusterDeposit(msg.sender, operatorIds, amount, cluster); - } - - function withdrawOperatorEarnings(uint64 operatorId, uint256 amount) external override { Operator memory operator = _operators[operatorId]; if (operator.owner != msg.sender) revert CallerNotOwner(); operator.snapshot = _getSnapshot(operator, uint64(block.number)); - uint64 shrunkAmount = amount.shrink(); + uint64 shrunkAmount; - if (operator.snapshot.balance < shrunkAmount) { + if(amount == 0 && operator.snapshot.balance > 0) { + shrunkAmount = operator.snapshot.balance; + } else if(amount > 0 && operator.snapshot.balance >= amount.shrink()) { + shrunkAmount = amount.shrink(); + } else { revert InsufficientBalance(); } @@ -561,27 +547,17 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { _operators[operatorId] = operator; - _transferOperatorBalanceUnsafe(operatorId, amount); - } - - function withdrawOperatorEarnings(uint64 operatorId) external override { - Operator memory operator = _operators[operatorId]; - - if (operator.owner != msg.sender) revert CallerNotOwner(); - - operator.snapshot = _getSnapshot(operator, uint64(block.number)); + _transferOperatorBalanceUnsafe(operatorId, shrunkAmount.expand()); - uint64 operatorBalance = operator.snapshot.balance; - - if (operatorBalance <= 0) { - revert InsufficientBalance(); - } + } - operator.snapshot.balance -= operatorBalance; - _operators[operatorId] = operator; + function withdrawOperatorEarnings(uint64 operatorId, uint256 amount) external override { + _withdrawOperatorEarnings(operatorId, amount); + } - _transferOperatorBalanceUnsafe(operatorId, operatorBalance.expand()); + function withdrawOperatorEarnings(uint64 operatorId) external override { + _withdrawOperatorEarnings(operatorId, 0); } function withdraw( @@ -781,9 +757,9 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { /* Balance External View Functions */ /***********************************/ - function getOperatorEarnings(uint64 id) external view override returns (uint64 currentBlock, uint64 index, uint256 balance) { + function getOperatorEarnings(uint64 id) external view override returns (uint256) { Snapshot memory s = _getSnapshot(_operators[id], uint64(block.number)); - return (s.block, s.index, s.balance.expand()); + return s.balance.expand(); } function getBalance( diff --git a/hardhat.config.ts b/hardhat.config.ts index b884b317..053a163d 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -19,7 +19,7 @@ const config: HardhatUserConfig = { settings: { optimizer: { enabled: true, - runs: 600 + runs: 1000 } } } diff --git a/test/account/deposit.ts b/test/account/deposit.ts index 12e1cae9..b38b70cd 100644 --- a/test/account/deposit.ts +++ b/test/account/deposit.ts @@ -37,19 +37,19 @@ describe('Deposit Tests', () => { cluster1 = await helpers.registerValidators(4, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); }); - it('Deposit to a cluster I own emits "ClusterDeposit', async () => { + it('Deposit to a cluster I own emits "ClusterDeposited', async () => { await helpers.DB.ssvToken.connect(helpers.DB.owners[4]).approve(ssvNetworkContract.address, minDepositAmount); - await expect(ssvNetworkContract.connect(helpers.DB.owners[4])['deposit(uint64[],uint256,(uint32,uint64,uint64,uint64,uint64,bool))'](cluster1.args.operatorIds, minDepositAmount, cluster1.args.cluster)).to.emit(ssvNetworkContract, 'ClusterDeposit'); + await expect(ssvNetworkContract.connect(helpers.DB.owners[4])['deposit(address,uint64[],uint256,(uint32,uint64,uint64,uint64,uint64,bool))'](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(uint64[],uint256,(uint32,uint64,uint64,uint64,uint64,bool))'](cluster1.args.operatorIds, minDepositAmount, cluster1.args.cluster), [GasGroup.DEPOSIT]); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4])['deposit(address,uint64[],uint256,(uint32,uint64,uint64,uint64,uint64,bool))'](helpers.DB.owners[4].address, cluster1.args.operatorIds, minDepositAmount, cluster1.args.cluster), [GasGroup.DEPOSIT]); }); - it('Deposit to a cluster I do not own emits "ClusterDeposit"', async () => { + 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(address,uint64[],uint256,(uint32,uint64,uint64,uint64,uint64,bool))'](helpers.DB.owners[4].address, cluster1.args.operatorIds, minDepositAmount, cluster1.args.cluster)).to.emit(ssvNetworkContract, 'ClusterDeposit'); + await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['deposit(address,uint64[],uint256,(uint32,uint64,uint64,uint64,uint64,bool))'](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 () => { @@ -58,10 +58,10 @@ describe('Deposit Tests', () => { }); 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(uint64[],uint256,(uint32,uint64,uint64,uint64,uint64,bool))'](cluster1.args.operatorIds, minDepositAmount, cluster1.args.cluster)).to.be.revertedWithCustomError(ssvNetworkContract,'ClusterDoesNotExists'); + await expect(ssvNetworkContract.connect(helpers.DB.owners[1])['deposit(address,uint64[],uint256,(uint32,uint64,uint64,uint64,uint64,bool))'](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(uint64[],uint256,(uint32,uint64,uint64,uint64,uint64,bool))']([1,2,4,5], minDepositAmount, cluster1.args.cluster)).to.be.revertedWithCustomError(ssvNetworkContract,'ClusterDoesNotExists'); + await expect(ssvNetworkContract.connect(helpers.DB.owners[4])['deposit(address,uint64[],uint256,(uint32,uint64,uint64,uint64,uint64,bool))'](helpers.DB.owners[1].address,[1,2,4,5], minDepositAmount, cluster1.args.cluster)).to.be.revertedWithCustomError(ssvNetworkContract,'ClusterDoesNotExists'); }); }); diff --git a/test/sanity/balances.ts b/test/sanity/balances.ts index 3bdfc761..3e755ded 100644 --- a/test/sanity/balances.ts +++ b/test/sanity/balances.ts @@ -92,20 +92,20 @@ describe('Balance Tests', () => { it('Check operators earnings in three blocks, one after the other', async () => { await utils.progressBlocks(1); - expect((await ssvNetworkContract.getOperatorEarnings(1)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 2 + helpers.CONFIG.minimalOperatorFee * 2); - expect((await ssvNetworkContract.getOperatorEarnings(2)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 2 + helpers.CONFIG.minimalOperatorFee * 2); - expect((await ssvNetworkContract.getOperatorEarnings(3)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 2 + helpers.CONFIG.minimalOperatorFee * 2); - expect((await ssvNetworkContract.getOperatorEarnings(4)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 2 + helpers.CONFIG.minimalOperatorFee * 2); + expect(await ssvNetworkContract.getOperatorEarnings(1)).to.equal(helpers.CONFIG.minimalOperatorFee * 2 + helpers.CONFIG.minimalOperatorFee * 2); + expect(await ssvNetworkContract.getOperatorEarnings(2)).to.equal(helpers.CONFIG.minimalOperatorFee * 2 + helpers.CONFIG.minimalOperatorFee * 2); + expect(await ssvNetworkContract.getOperatorEarnings(3)).to.equal(helpers.CONFIG.minimalOperatorFee * 2 + helpers.CONFIG.minimalOperatorFee * 2); + expect(await ssvNetworkContract.getOperatorEarnings(4)).to.equal(helpers.CONFIG.minimalOperatorFee * 2 + helpers.CONFIG.minimalOperatorFee * 2); await utils.progressBlocks(1); - expect((await ssvNetworkContract.getOperatorEarnings(1)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 4 + helpers.CONFIG.minimalOperatorFee * 2); - expect((await ssvNetworkContract.getOperatorEarnings(2)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 4 + helpers.CONFIG.minimalOperatorFee * 2); - expect((await ssvNetworkContract.getOperatorEarnings(3)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 4 + helpers.CONFIG.minimalOperatorFee * 2); - expect((await ssvNetworkContract.getOperatorEarnings(4)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 4 + helpers.CONFIG.minimalOperatorFee * 2); + expect(await ssvNetworkContract.getOperatorEarnings(1)).to.equal(helpers.CONFIG.minimalOperatorFee * 4 + helpers.CONFIG.minimalOperatorFee * 2); + expect(await ssvNetworkContract.getOperatorEarnings(2)).to.equal(helpers.CONFIG.minimalOperatorFee * 4 + helpers.CONFIG.minimalOperatorFee * 2); + expect(await ssvNetworkContract.getOperatorEarnings(3)).to.equal(helpers.CONFIG.minimalOperatorFee * 4 + helpers.CONFIG.minimalOperatorFee * 2); + expect(await ssvNetworkContract.getOperatorEarnings(4)).to.equal(helpers.CONFIG.minimalOperatorFee * 4 + helpers.CONFIG.minimalOperatorFee * 2); await utils.progressBlocks(1); - expect((await ssvNetworkContract.getOperatorEarnings(1)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 6 + helpers.CONFIG.minimalOperatorFee * 2); - expect((await ssvNetworkContract.getOperatorEarnings(2)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 6 + helpers.CONFIG.minimalOperatorFee * 2); - expect((await ssvNetworkContract.getOperatorEarnings(3)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 6 + helpers.CONFIG.minimalOperatorFee * 2); - expect((await ssvNetworkContract.getOperatorEarnings(4)).balance).to.equal(helpers.CONFIG.minimalOperatorFee * 6 + helpers.CONFIG.minimalOperatorFee * 2); + expect(await ssvNetworkContract.getOperatorEarnings(1)).to.equal(helpers.CONFIG.minimalOperatorFee * 6 + helpers.CONFIG.minimalOperatorFee * 2); + expect(await ssvNetworkContract.getOperatorEarnings(2)).to.equal(helpers.CONFIG.minimalOperatorFee * 6 + helpers.CONFIG.minimalOperatorFee * 2); + expect(await ssvNetworkContract.getOperatorEarnings(3)).to.equal(helpers.CONFIG.minimalOperatorFee * 6 + helpers.CONFIG.minimalOperatorFee * 2); + expect(await ssvNetworkContract.getOperatorEarnings(4)).to.equal(helpers.CONFIG.minimalOperatorFee * 6 + helpers.CONFIG.minimalOperatorFee * 2); }); it('Check cluster balance returns error - InsufficientFunds', async () => { diff --git a/test/validators/remove.ts b/test/validators/remove.ts index c9d1b2ec..a11cc9e5 100644 --- a/test/validators/remove.ts +++ b/test/validators/remove.ts @@ -84,7 +84,7 @@ describe('Remove Validator Tests', () => { helpers.DataGenerator.publicKey(1), firstCluster.operatorIds, firstCluster.cluster - )).to.be.revertedWithCustomError(ssvNetworkContract,'NoValidatorOwnership'); + )).to.be.revertedWithCustomError(ssvNetworkContract,'ValidatorOwnedByOtherAddress'); }); it('Remove validator twice', async () => { From 6a069eede8082825661ced2b95be3d1b7229e9c3 Mon Sep 17 00:00:00 2001 From: Wadym Date: Wed, 25 Jan 2023 20:13:20 +0100 Subject: [PATCH 117/149] IO1-2358-index-events (#175) --- contracts/ISSVNetwork.sol | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/contracts/ISSVNetwork.sol b/contracts/ISSVNetwork.sol index 6a9a014e..2a252701 100644 --- a/contracts/ISSVNetwork.sol +++ b/contracts/ISSVNetwork.sol @@ -46,7 +46,7 @@ interface ISSVNetwork { * @param cluster All the cluster data. */ event ValidatorAdded( - address owner, + address indexed owner, uint64[] operatorIds, bytes publicKey, bytes shares, @@ -60,7 +60,7 @@ interface ISSVNetwork { * @param cluster All the cluster data. */ event ValidatorRemoved( - address owner, + address indexed owner, uint64[] operatorIds, bytes publicKey, Cluster cluster @@ -88,9 +88,9 @@ interface ISSVNetwork { uint256 fee ); - event ClusterLiquidated(address owner, uint64[] operatorIds, Cluster cluster); + event ClusterLiquidated(address indexed owner, uint64[] operatorIds, Cluster cluster); - event ClusterReactivated(address owner, uint64[] operatorIds, Cluster cluster); + event ClusterReactivated(address indexed owner, uint64[] operatorIds, Cluster cluster); event OperatorFeeIncreaseLimitUpdated(uint64 value); @@ -114,11 +114,11 @@ interface ISSVNetwork { */ event NetworkEarningsWithdrawn(uint256 value, address recipient); - event ClusterWithdrawn(address owner, uint64[] operatorIds, uint256 value, Cluster cluster); + event ClusterWithdrawn(address indexed owner, uint64[] operatorIds, uint256 value, Cluster cluster); event OperatorWithdrawn(uint256 value, uint64 operatorId, address owner); event ClusterDeposited( - address owner, + address indexed owner, uint64[] operatorIds, uint256 value, Cluster cluster From a9bc0dc96adeb5f1fcf042e2318454cd14b0eb82 Mon Sep 17 00:00:00 2001 From: Or-blox <117833150+Or-blox@users.noreply.github.com> Date: Thu, 26 Jan 2023 11:26:28 +0200 Subject: [PATCH 118/149] Final names (#174) * changed the tests name * update * updated the rest * checking * after Andrew comments --- test/account/deposit.ts | 2 +- test/account/withdraw.ts | 2 +- test/dao/liquidation-threshold.ts | 2 +- test/dao/network-fee-change.ts | 2 +- test/dao/network-fee-withdraw.ts | 2 +- test/liquidate/liquidate.ts | 56 +++++++++---------- test/liquidate/reactivate.ts | 23 ++++---- test/operators/others.ts | 2 +- test/operators/register.ts | 16 +++--- test/operators/remove.ts | 14 ++--- test/operators/update-fee.ts | 2 +- test/sanity/balances.ts | 14 ++--- test/validators/register.ts | 93 ++++++++++++++++--------------- test/validators/remove.ts | 60 ++++++++++---------- 14 files changed, 146 insertions(+), 144 deletions(-) diff --git a/test/account/deposit.ts b/test/account/deposit.ts index b38b70cd..321d6849 100644 --- a/test/account/deposit.ts +++ b/test/account/deposit.ts @@ -64,4 +64,4 @@ describe('Deposit Tests', () => { 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(address,uint64[],uint256,(uint32,uint64,uint64,uint64,uint64,bool))'](helpers.DB.owners[1].address,[1,2,4,5], minDepositAmount, cluster1.args.cluster)).to.be.revertedWithCustomError(ssvNetworkContract,'ClusterDoesNotExists'); }); -}); +}); \ No newline at end of file diff --git a/test/account/withdraw.ts b/test/account/withdraw.ts index ce6460d3..cd765522 100644 --- a/test/account/withdraw.ts +++ b/test/account/withdraw.ts @@ -92,4 +92,4 @@ describe('Withdraw Tests', () => { it('Withdraw more than the operator total balance reverts "InsufficientBalance"', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[0])['withdrawOperatorEarnings(uint64)'](12)).to.be.revertedWithCustomError(ssvNetworkContract,'InsufficientBalance'); }); -}); +}); \ No newline at end of file diff --git a/test/dao/liquidation-threshold.ts b/test/dao/liquidation-threshold.ts index f8cff160..154f9db1 100644 --- a/test/dao/liquidation-threshold.ts +++ b/test/dao/liquidation-threshold.ts @@ -29,4 +29,4 @@ describe('Liquidation Threshold Tests', () => { it('Change liquidation threshold period reverts "caller is not the owner"', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[3]).updateLiquidationThresholdPeriod(helpers.CONFIG.minimalBlocksBeforeLiquidation)).to.be.revertedWith('Ownable: caller is not the owner'); }); -}); +}); \ No newline at end of file diff --git a/test/dao/network-fee-change.ts b/test/dao/network-fee-change.ts index f56a49e6..c7319f15 100644 --- a/test/dao/network-fee-change.ts +++ b/test/dao/network-fee-change.ts @@ -32,4 +32,4 @@ describe('Network Fee Tests', () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[3]).updateNetworkFee(networkFee )).to.be.revertedWith('Ownable: caller is not the owner'); }); -}); +}); \ No newline at end of file diff --git a/test/dao/network-fee-withdraw.ts b/test/dao/network-fee-withdraw.ts index 39509d71..494960a4 100644 --- a/test/dao/network-fee-withdraw.ts +++ b/test/dao/network-fee-withdraw.ts @@ -78,4 +78,4 @@ describe('DAO Network Fee Withdraw Tests', () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[3]).withdrawNetworkEarnings(amount )).to.be.revertedWith('Ownable: caller is not the owner'); }); -}); +}); \ No newline at end of file diff --git a/test/liquidate/liquidate.ts b/test/liquidate/liquidate.ts index 5e41cfee..dace376f 100644 --- a/test/liquidate/liquidate.ts +++ b/test/liquidate/liquidate.ts @@ -6,6 +6,7 @@ import { trackGas, GasGroup } from '../helpers/gas-usage'; let ssvNetworkContract: any, minDepositAmount: any, firstCluster: any; +// Declare globals describe('Liquidate Tests', () => { beforeEach(async () => { // Initialize contract @@ -52,18 +53,7 @@ describe('Liquidate Tests', () => { firstCluster = register.eventsByName.ValidatorAdded[0].args; }); - it('Get if the cluster is liquidatable', async () => { - await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - expect(await ssvNetworkContract.isLiquidatable(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster)).to.equal(true); - }); - - it('Liquidatable with removed operator', async () => { - await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - await ssvNetworkContract.removeOperator(1); - expect(await ssvNetworkContract.isLiquidatable(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster)).to.equal(true); - }); - - it('Liquidate emits ClusterLiquidated event', async () => { + it('Liquidate a cluster emits "ClusterLiquidated"', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); await expect(ssvNetworkContract.liquidate( @@ -73,6 +63,12 @@ describe('Liquidate Tests', () => { )).to.emit(ssvNetworkContract, 'ClusterLiquidated'); }); + it('Liquidatable with removed operator', async () => { + await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); + await ssvNetworkContract.removeOperator(1); + expect(await ssvNetworkContract.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); @@ -83,7 +79,7 @@ describe('Liquidate Tests', () => { ), [GasGroup.LIQUIDATE_POD]); }); - it('Liquidate and register validator in disabled cluster', async () => { + it('Liquidate and register validator in a disabled cluster', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); const liquidatedCluster = await trackGas(ssvNetworkContract.liquidate( firstCluster.owner, @@ -101,6 +97,23 @@ describe('Liquidate Tests', () => { updatedCluster.cluster ), [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]); }); + + it('Liquidate cluster 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_POD]); + const updatedCluster = liquidatedCluster.eventsByName.ClusterLiquidated[0].args; + + expect(await ssvNetworkContract.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 ssvNetworkContract.isLiquidatable(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster)).to.equal(true); + }); it('Liquidate a cluster that is not liquidatable reverts "ClusterNotLiquidatable"', async () => { await expect(ssvNetworkContract.liquidate( @@ -125,7 +138,7 @@ describe('Liquidate Tests', () => { )).to.be.revertedWithCustomError(ssvNetworkContract,'IncorrectClusterState'); }); - it('Liquidate second time a cluster that is liquidated already reverts "ClusterIsLiquidated"', async () => { + it('Liquidate already liquidated cluster reverts "ClusterIsLiquidated"', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); const liquidatedCluster = await trackGas(ssvNetworkContract.liquidate( firstCluster.owner, @@ -141,18 +154,6 @@ describe('Liquidate Tests', () => { )).to.be.revertedWithCustomError(ssvNetworkContract,'ClusterIsLiquidated'); }); - it('Is liquidated', async () => { - await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - const liquidatedCluster = await trackGas(ssvNetworkContract.liquidate( - firstCluster.owner, - firstCluster.operatorIds, - firstCluster.cluster - ), [GasGroup.LIQUIDATE_POD]); - const updatedCluster = liquidatedCluster.eventsByName.ClusterLiquidated[0].args; - - expect(await ssvNetworkContract.isLiquidated(firstCluster.owner, firstCluster.operatorIds, updatedCluster.cluster)).to.equal(true); - }); - it('Is liquidated reverts "ClusterDoesNotExists"', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); const liquidatedCluster = await trackGas(ssvNetworkContract.liquidate( @@ -164,5 +165,4 @@ describe('Liquidate Tests', () => { await expect(ssvNetworkContract.isLiquidated(helpers.DB.owners[0].address, firstCluster.operatorIds, updatedCluster.cluster)).to.be.revertedWithCustomError(ssvNetworkContract,'ClusterDoesNotExists'); }); - -}); +}); \ No newline at end of file diff --git a/test/liquidate/reactivate.ts b/test/liquidate/reactivate.ts index cf126c89..9f88857d 100644 --- a/test/liquidate/reactivate.ts +++ b/test/liquidate/reactivate.ts @@ -6,6 +6,7 @@ import { trackGas, GasGroup } from '../helpers/gas-usage'; let ssvNetworkContract: any, minDepositAmount: any, firstCluster: any; +// Declare globals describe('Reactivate Tests', () => { beforeEach(async () => { // Initialize contract @@ -77,6 +78,16 @@ describe('Reactivate Tests', () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).reactivate(updatedClusterAfrerRemove.operatorIds, 0, updatedClusterAfrerRemove.cluster)).to.emit(ssvNetworkContract, 'ClusterReactivated'); }); + it('Reactivate a cluster with a removed operator in the cluster', async () => { + await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); + const liquidatedCluster = await trackGas(ssvNetworkContract.liquidate(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster), [GasGroup.LIQUIDATE_POD]); + 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_POD]); + }); + 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'); }); @@ -89,14 +100,4 @@ describe('Reactivate Tests', () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).reactivate(updatedCluster.operatorIds, helpers.CONFIG.minimalOperatorFee, updatedCluster.cluster)).to.be.revertedWithCustomError(ssvNetworkContract,'InsufficientBalance'); }); - - it('Reactivate a cluster with a removed operator in the cluster', async () => { - await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - const liquidatedCluster = await trackGas(ssvNetworkContract.liquidate(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster), [GasGroup.LIQUIDATE_POD]); - 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_POD]); - }); -}); +}); \ No newline at end of file diff --git a/test/operators/others.ts b/test/operators/others.ts index cb589183..24eccad6 100644 --- a/test/operators/others.ts +++ b/test/operators/others.ts @@ -17,4 +17,4 @@ describe('Others Operator Tests', () => { .to.emit(ssvNetworkContract, 'FeeRecipientAddressUpdated') .withArgs(helpers.DB.owners[1].address, helpers.DB.owners[2].address); }); -}); +}); \ No newline at end of file diff --git a/test/operators/register.ts b/test/operators/register.ts index 8108d22b..86c1e711 100644 --- a/test/operators/register.ts +++ b/test/operators/register.ts @@ -26,13 +26,6 @@ describe('Register Operator Tests', () => { ), [GasGroup.REGISTER_OPERATOR]); }); - it('Register an operator with a fee thats too low reverts "FeeTooLow"', async () => { - await expect(ssvNetworkContract.registerOperator( - helpers.DataGenerator.publicKey(0), - '10' - )).to.be.revertedWithCustomError(ssvNetworkContract,'FeeTooLow'); - }); - it('Get operator by id', async () => { await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerOperator( helpers.DataGenerator.publicKey(0), @@ -52,4 +45,11 @@ describe('Register Operator Tests', () => { await expect(ssvNetworkContract.getOperatorById(3)).to.be.revertedWithCustomError(ssvNetworkContract,'OperatorDoesNotExist'); }); -}); + + it('Register an operator with a fee thats too low reverts "FeeTooLow"', async () => { + await expect(ssvNetworkContract.registerOperator( + helpers.DataGenerator.publicKey(0), + '10' + )).to.be.revertedWithCustomError(ssvNetworkContract,'FeeTooLow'); + }); +}); \ No newline at end of file diff --git a/test/operators/remove.ts b/test/operators/remove.ts index 125faa27..95d497cd 100644 --- a/test/operators/remove.ts +++ b/test/operators/remove.ts @@ -36,16 +36,11 @@ describe('Remove Operator Tests', () => { .to.emit(ssvNetworkContract, 'OperatorRemoved').withArgs(1); }); - 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'); - }); - it('Remove operator gas limits', async () => { await trackGas(ssvNetworkContract.removeOperator(1), [GasGroup.REMOVE_OPERATOR]); }); - it('Remove operator with 0 balance', async () => { + it('Remove operator with 0 balance emits "OperatorWithdrawn"', async () => { await expect(ssvNetworkContract.removeOperator(5)).not.to.emit(ssvNetworkContract, 'OperatorWithdrawn'); }); @@ -58,4 +53,9 @@ describe('Remove Operator Tests', () => { await helpers.registerValidators(4, 1, `${helpers.CONFIG.minimalBlocksBeforeLiquidation * helpers.CONFIG.minimalOperatorFee * 4}`, [1,2,3,4], [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'); + }); +}); \ No newline at end of file diff --git a/test/operators/update-fee.ts b/test/operators/update-fee.ts index 49ace804..c9de0685 100644 --- a/test/operators/update-fee.ts +++ b/test/operators/update-fee.ts @@ -171,4 +171,4 @@ describe('Operator Fee Tests', () => { await expect(ssvNetworkContract.getOperatorDeclaredFee(2 )).to.be.revertedWithCustomError(ssvNetworkContract,'NoFeeDelcared'); }); -}); +}); \ No newline at end of file diff --git a/test/sanity/balances.ts b/test/sanity/balances.ts index 3e755ded..aa4d06ee 100644 --- a/test/sanity/balances.ts +++ b/test/sanity/balances.ts @@ -1,11 +1,12 @@ +// Declare imports import * as helpers from '../helpers/contract-helpers'; import * as utils from '../helpers/utils'; - import { expect } from 'chai'; import { GasGroup } from '../helpers/gas-usage'; let ssvNetworkContract: any, cluster1: any, minDepositAmount: any, burnPerBlock: any, networkFee: any, initNetworkFeeBalance: any; +// Declare globals describe('Balance Tests', () => { beforeEach(async () => { // Initialize contract @@ -108,14 +109,13 @@ describe('Balance Tests', () => { expect(await ssvNetworkContract.getOperatorEarnings(4)).to.equal(helpers.CONFIG.minimalOperatorFee * 6 + helpers.CONFIG.minimalOperatorFee * 2); }); - it('Check cluster balance returns error - InsufficientFunds', async () => { - await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation + 10); - await expect(ssvNetworkContract.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster)).to.be.revertedWithCustomError(ssvNetworkContract,'InsufficientFunds'); - }); - it('Check cluster balance with removed operator', async () => { await ssvNetworkContract.removeOperator(1); expect(await ssvNetworkContract.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster)).not.equals(0); }); -}); + it('Check cluster balance with not enough balance reverts "InsufficientFunds"', async () => { + await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation + 10); + await expect(ssvNetworkContract.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster)).to.be.revertedWithCustomError(ssvNetworkContract,'InsufficientFunds'); + }); +}); \ No newline at end of file diff --git a/test/validators/register.ts b/test/validators/register.ts index efe54570..0f6487fe 100644 --- a/test/validators/register.ts +++ b/test/validators/register.ts @@ -1,9 +1,9 @@ // Declare imports import * as helpers from '../helpers/contract-helpers'; import { expect } from 'chai'; - import { trackGas, GasGroup } from '../helpers/gas-usage'; +// Declare globals let ssvNetworkContract: any, minDepositAmount: any; describe('Register Validator Tests', () => { @@ -33,8 +33,26 @@ describe('Register Validator Tests', () => { } ); }); + + it('Register validator with 4 operators emits "ValidatorAdded"', async () => { + await helpers.DB.ssvToken.approve(ssvNetworkContract.address, minDepositAmount); + await expect(ssvNetworkContract.registerValidator( + helpers.DataGenerator.publicKey(1), + [1, 2, 3, 4], + helpers.DataGenerator.shares(4), + minDepositAmount, + { + validatorCount: 0, + networkFee: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + disabled: false + } + )).to.emit(ssvNetworkContract, 'ValidatorAdded'); + }); - it('4 operators: Register 1 new validator gas usage', async () => { + it('Register validator with 4 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), @@ -52,7 +70,7 @@ describe('Register Validator Tests', () => { ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); }); - it('4 operators: Register 2 validators in same cluster gas usage', async () => { + 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), @@ -81,7 +99,7 @@ describe('Register Validator Tests', () => { ), [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]); }); - it('4 operators: Register 2 validators in same cluster and 1 validator in new cluster gas usage', async () => { + 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), @@ -126,7 +144,7 @@ describe('Register Validator Tests', () => { ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); }); - it('4 operators: Register 2 validators in same cluster with one time deposit gas usage', async () => { + 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), @@ -155,7 +173,7 @@ describe('Register Validator Tests', () => { // 7 operators - it('7 operators: Register 1 new validator gas usage', async () => { + 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), @@ -173,7 +191,7 @@ describe('Register Validator Tests', () => { ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]); }); - it('7 operators: Register 2 validators in same cluster gas usage', async () => { + 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), @@ -202,7 +220,7 @@ describe('Register Validator Tests', () => { ), [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_7]); }); - it('7 operators: Register 2 validators in same cluster and 1 validator in new cluster gas usage', async () => { + 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), @@ -247,7 +265,7 @@ describe('Register Validator Tests', () => { ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]); }); - it('7 operators: Register 2 validators in same cluster with one time deposit gas usage', async () => { + 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), @@ -276,7 +294,7 @@ describe('Register Validator Tests', () => { // 13 operators - it('13 operators: Register 1 new validator gas usage', async () => { + 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), @@ -294,7 +312,7 @@ describe('Register Validator Tests', () => { ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]); }); - it('13 operators: Register 2 validators in same cluster gas usage', async () => { + 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), @@ -323,7 +341,7 @@ describe('Register Validator Tests', () => { ), [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_13]); }); - it('13 operators: Register 2 validators in same cluster and 1 validator in new cluster gas usage', async () => { + 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), @@ -368,7 +386,7 @@ describe('Register Validator Tests', () => { ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]); }); - it('13 operators: Register 2 validators in same cluster with one time deposit gas usage', async () => { + 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), @@ -395,7 +413,15 @@ describe('Register Validator Tests', () => { ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_13]); }); - it('Register validator returns an error - IncorrectClusterState', async () => { + it('Get cluster burn rate', async () => { + expect(await ssvNetworkContract.getClusterBurnRate([1,2,3,4])).to.equal(helpers.CONFIG.minimalOperatorFee * 4); + }); + + it('Get cluster burn rate when one of the operators does not exsit', async () => { + expect(await ssvNetworkContract.getClusterBurnRate([1,2,3,41])).to.equal(helpers.CONFIG.minimalOperatorFee * 3); + }); + + 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), @@ -428,7 +454,7 @@ describe('Register Validator Tests', () => { )).to.be.revertedWithCustomError(ssvNetworkContract,'IncorrectClusterState'); }); - it('Register validator returns an error - OperatorDoesNotExist', async () => { + it('Register validator when an operator does not exsit in the cluster reverts "OperatorDoesNotExist"', async () => { await expect(ssvNetworkContract.registerValidator( helpers.DataGenerator.publicKey(2), [1, 2, 3, 25], @@ -445,7 +471,7 @@ describe('Register Validator Tests', () => { )).to.be.revertedWithCustomError(ssvNetworkContract,'OperatorDoesNotExist'); }); - it('Register validator with removed operator returns an error - OperatorDoesNotExist', async () => { + 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), @@ -463,29 +489,12 @@ describe('Register Validator Tests', () => { )).to.be.revertedWithCustomError(ssvNetworkContract,'OperatorDoesNotExist'); }); - it('Register validator emits ValidatorAdded event', async () => { - await helpers.DB.ssvToken.approve(ssvNetworkContract.address, minDepositAmount); - await expect(ssvNetworkContract.registerValidator( - helpers.DataGenerator.publicKey(1), - [1, 2, 3, 4], - helpers.DataGenerator.shares(4), - minDepositAmount, - { - validatorCount: 0, - networkFee: 0, - networkFeeIndex: 0, - index: 0, - balance: 0, - disabled: false - } - )).to.emit(ssvNetworkContract, 'ValidatorAdded'); - }); - it('Register cluster returns an error - The operators list should be in ascending order', async () => { + it('Register cluster with unsorted operators reverts "The operators list should be in ascending order"', async () => { await expect(helpers.registerValidators(2, 1, minDepositAmount, [3, 2, 1, 4])).to.be.revertedWithCustomError(ssvNetworkContract,'UnsortedOperatorsList'); }); - it('Invalid operator amount reverts "InvalidOperatorIdsLength"', async () => { + 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'); @@ -513,7 +522,7 @@ describe('Register Validator Tests', () => { )).to.be.revertedWithCustomError(ssvNetworkContract,'InvalidPublicKeyLength'); }); - it('Register validator returns an error - InsufficientBalance', async () => { + 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), @@ -531,7 +540,7 @@ describe('Register Validator Tests', () => { )).to.be.revertedWithCustomError(ssvNetworkContract,'InsufficientBalance'); }); - it('Register validator returns an error - ValidatorAlreadyExists', async () => { + it('Register an existing validator reverts "ValidatorAlreadyExists"', async () => { await helpers.DB.ssvToken.approve(ssvNetworkContract.address, helpers.CONFIG.minimalOperatorFee); await expect(ssvNetworkContract.connect(helpers.DB.owners[6]).registerValidator( '0x221111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111119', @@ -548,12 +557,4 @@ describe('Register Validator Tests', () => { } )).to.be.revertedWithCustomError(ssvNetworkContract,'ValidatorAlreadyExists'); }); - - it('Get cluster burn rate', async () => { - expect(await ssvNetworkContract.getClusterBurnRate([1,2,3,4])).to.equal(helpers.CONFIG.minimalOperatorFee * 4); - }); - - it('Get cluster burn rate by not existed operator in the list', async () => { - expect(await ssvNetworkContract.getClusterBurnRate([1,2,3,41])).to.equal(helpers.CONFIG.minimalOperatorFee * 3); - }); -}); +}); \ No newline at end of file diff --git a/test/validators/remove.ts b/test/validators/remove.ts index a11cc9e5..28a10538 100644 --- a/test/validators/remove.ts +++ b/test/validators/remove.ts @@ -1,10 +1,10 @@ // Decalre imports import * as helpers from '../helpers/contract-helpers'; import * as utils from '../helpers/utils'; - import { expect } from 'chai'; import { trackGas, GasGroup } from '../helpers/gas-usage'; +// Declare globals let ssvNetworkContract: any, minDepositAmount: any, firstCluster: any; describe('Remove Validator Tests', () => { @@ -54,7 +54,7 @@ describe('Remove Validator Tests', () => { firstCluster = register.eventsByName.ValidatorAdded[0].args; }); - it('Remove validator emits ValidatorRemoved event', async () => { + it('Remove validator emits "ValidatorRemoved"', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).removeValidator( helpers.DataGenerator.publicKey(1), firstCluster.operatorIds, @@ -62,7 +62,7 @@ describe('Remove Validator Tests', () => { )).to.emit(ssvNetworkContract, 'ValidatorRemoved'); }); - it('Remove validator track gas', async () => { + it('Remove validator gas limit', async () => { await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).removeValidator( helpers.DataGenerator.publicKey(1), firstCluster.operatorIds, @@ -70,7 +70,7 @@ describe('Remove Validator Tests', () => { ), [GasGroup.REMOVE_VALIDATOR]); }); - it('Remove validator with removed operator in a cluster', async () => { + 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), @@ -79,31 +79,7 @@ describe('Remove Validator Tests', () => { ), [GasGroup.REMOVE_VALIDATOR]); }); - it('Remove validator with an invalid owner', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[3]).removeValidator( - helpers.DataGenerator.publicKey(1), - firstCluster.operatorIds, - firstCluster.cluster - )).to.be.revertedWithCustomError(ssvNetworkContract,'ValidatorOwnedByOtherAddress'); - }); - - it('Remove validator twice', async () => { - // 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'); - }); - - it('Register / remove validator twice', async () => { + 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), @@ -145,4 +121,28 @@ describe('Remove Validator Tests', () => { updatedCluster.cluster ), [GasGroup.REMOVE_VALIDATOR]); }); -}); + + it('Remove validator with an invalid owner reverts "ValidatorOwnedByOtherAddress"', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[3]).removeValidator( + helpers.DataGenerator.publicKey(1), + firstCluster.operatorIds, + firstCluster.cluster + )).to.be.revertedWithCustomError(ssvNetworkContract,'ValidatorOwnedByOtherAddress'); + }); + + 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]); + + // 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'); + }); +}); \ No newline at end of file From fad1ed571f04473419546910706feeb01d51d7a1 Mon Sep 17 00:00:00 2001 From: mtabasco Date: Wed, 8 Feb 2023 16:47:33 +0100 Subject: [PATCH 119/149] Change contracts structure - IO1-2233 (#176) * naming changes * create views contract and libraries for Operator, Network, and Cluster * update tests, refactor libraries * deploy & upgrade test cases, upgrade scripts * update README * use underscore notation * cleanup, add deploy tests --- .env.example | 3 +- README.md | 184 +++- contracts/ISSVNetwork.sol | 139 +-- contracts/ISSVNetworkCore.sol | 84 ++ contracts/ISSVNetworkViews.sol | 82 ++ contracts/SSVNetwork.sol | 877 ++++++++---------- contracts/SSVNetworkViews.sol | 287 ++++++ contracts/libraries/ClusterLib.sol | 103 ++ contracts/libraries/NetworkLib.sol | 45 + contracts/libraries/OperatorLib.sol | 18 + contracts/{utils => libraries}/Types.sol | 7 +- contracts/mocks/SSVNetworkBasicUpgrade.sol | 17 + contracts/mocks/SSVNetworkLibUpgrade.sol | 24 + contracts/mocks/SSVNetworkReinitializable.sol | 13 + .../mocks/SSVNetworkViewsBasicUpgrade.sol | 16 + contracts/mocks/SSVNetworkViewsLibUpgrade.sol | 25 + .../mocks/SSVNetworkViewsReinitializable.sol | 13 + .../mocks/libraries/NetworkLibUpgrade.sol | 51 + hardhat.config.ts | 3 +- package.json | 9 +- scripts/deploy-all.ts | 49 + scripts/ssv-network-deploy.ts | 26 - scripts/upgrade-ssv-network-views.ts | 19 + ...work-upgrade.ts => upgrade-ssv-network.ts} | 14 +- scripts/validate-upgrade-ssv-network-views.ts | 14 + ...ade.ts => validate-upgrade-ssv-network.ts} | 10 +- test/dao/liquidation-threshold.ts | 10 +- test/dao/network-fee-change.ts | 8 +- test/dao/network-fee-withdraw.ts | 16 +- test/deployment/deploy.ts | 153 +++ test/helpers/contract-helpers.ts | 13 +- test/helpers/gas-usage.ts | 18 +- test/liquidate/liquidate.ts | 18 +- test/operators/register.ts | 14 +- test/operators/update-fee.ts | 21 +- test/sanity/balances.ts | 64 +- test/validators/register.ts | 21 +- 37 files changed, 1698 insertions(+), 790 deletions(-) create mode 100644 contracts/ISSVNetworkCore.sol create mode 100644 contracts/ISSVNetworkViews.sol create mode 100644 contracts/SSVNetworkViews.sol create mode 100644 contracts/libraries/ClusterLib.sol create mode 100644 contracts/libraries/NetworkLib.sol create mode 100644 contracts/libraries/OperatorLib.sol rename contracts/{utils => libraries}/Types.sol (76%) create mode 100644 contracts/mocks/SSVNetworkBasicUpgrade.sol create mode 100644 contracts/mocks/SSVNetworkLibUpgrade.sol create mode 100644 contracts/mocks/SSVNetworkReinitializable.sol create mode 100644 contracts/mocks/SSVNetworkViewsBasicUpgrade.sol create mode 100644 contracts/mocks/SSVNetworkViewsLibUpgrade.sol create mode 100644 contracts/mocks/SSVNetworkViewsReinitializable.sol create mode 100644 contracts/mocks/libraries/NetworkLibUpgrade.sol create mode 100644 scripts/deploy-all.ts delete mode 100644 scripts/ssv-network-deploy.ts create mode 100644 scripts/upgrade-ssv-network-views.ts rename scripts/{ssv-network-upgrade.ts => upgrade-ssv-network.ts} (53%) create mode 100644 scripts/validate-upgrade-ssv-network-views.ts rename scripts/{ssv-network-validate-upgrade.ts => validate-upgrade-ssv-network.ts} (67%) create mode 100644 test/deployment/deploy.ts diff --git a/.env.example b/.env.example index 31b8e6a0..4723b6f9 100644 --- a/.env.example +++ b/.env.example @@ -12,4 +12,5 @@ SET_OPERATOR_FEE_PERIOD=259200 # 3 days APPROVE_OPERATOR_FEE_PERIOD=345600 # 4 days VALIDATORS_PER_OPERATOR_LIMIT=2000 REGISTERED_OPERATORS_PER_ACCOUNT_LIMIT=10 -PROXY_ADDRESS= +SSVNETWORK_PROXY_ADDRESS= +SSVNETWORKVIEWS_PROXY_ADDRESS= diff --git a/README.md b/README.md index 25636870..f25e9b07 100644 --- a/README.md +++ b/README.md @@ -1,57 +1,116 @@ # SSV Network Project + + This repository contains a SSVNetwork smart contacts project. + + ## Quick start -The first things you need to do are cloning this repository and installing its -dependencies: + + +The first things you need to do are cloning this repository and installing its dependencies: + + ```sh + git clone git@github.com:bloxapp/ssv-network.git + cd ssv-network + npm install + ``` -### Run locally HardHat TestNetwork node + + +### Run locally HardHat TestNetwork node + Once installed, to run Hardhat's testing network: + + ```sh + npx hardhat node + ``` + + For more details about it and how to use MainNet forking you can find [here](https://hardhat.org/hardhat-network/). + + ### Compile contracts -Take a look at `contracts/` folder, you should be able to find `SSVNetwork.sol`. -To compile it, simply run: + +Take a look at `contracts/` folder, you should be able to find: +- `SSVNetwork.sol`: Base contract for SSV Network operations. +- `SSVNetworkViews.sol`: Contract with view functions only to retrive information from SSVNetwork contract. +- `libraries`: Folder which contains library contracts that implement operators, clusters and network functionalities. + + + +To compile them, simply run: + + ```sh + npx hardhat compile + ``` + + ## CI/CD Workflow + + ### Step 1: Test contracts + Take a look at `test/` folder, you should be able to find tests related to specific actions. + It comes with tests that use [Ethers.js](https://github.com/ethers-io/ethers.js/). + To run tests, run: + + ```sh + npx hardhat test + ``` + + ### Step 2: Deploy new contracts + We use [UUPS Proxy Upgrade pattern](https://docs.openzeppelin.com/contracts/4.x/api/proxy) for smart contracts to have an ability to upgrade them later. -To deploy the contract we will use a Hardhat script. Inside `scripts/` you will find `ssv-network-deploy.ts` and `ssv-network-upgrade.ts` files. -As general rule, you can target any network configured in the `hardhat.config.ts`, -specifying the right [network]_ETH_NODE_URL and [network]_OWNER_PRIVATE_KEY in `.env` file. +To deploy the contract we will use a Hardhat script. Inside `scripts/` you will find: +- `deploy-all.ts`: Deploys both `SSVNetwork.sol` and `SSVNetworkViews.sol`. +- `validate-upgrade-ssv-network`: Validates if `SSVNetwork` is upgrade safe. +- `validate-upgrade-ssv-network-views`: Validates if `SSVNetworkViews` is upgrade safe. +- `upgrade-ssv-network`: Upgrades `SSVNetwork` contract. +- `upgrade-ssv-network-views`: Upgrades `SSVNetworkViews` contract. + +As general rule, you can target any network configured in the `hardhat.config.ts`, specifying the right [network]_ETH_NODE_URL and [network]_OWNER_PRIVATE_KEY in `.env` file. + + #### Deploy SSV Network + + Before run the cli command, in `.env` need to add the following seetings: + + ```sh + [NETWORK]_ETH_NODE_URL=# RPC URL of the node [NETWORK]_OWNER_PRIVATE_KEY=# Private key of the deployer account, without 0x prefix GAS_PRICE=# example 30000000000 @@ -64,65 +123,120 @@ DECLARE_OPERATOR_FEE_PERIOD=# custom param EXECUTE_OPERATOR_FEE_PERIOD=# custom param VALIDATORS_PER_OPERATOR_LIMIT=# custom param REGISTERED_OPERATORS_PER_ACCOUNT_LIMIT=# custom param -PROXY_ADDRESS=# Proxy address, set it when runnning ssv-network-upgrade.ts script +SSVNETWORK_PROXY_ADDRESS=# SSVNetwork proxy address, set it when runnning upgrade-ssv-network.ts script +SSVNETWORKVIEWS_PROXY_ADDRESS=# SSVNetworkViews proxy address, set it when runnning upgrade-ssv-network-views.ts script ``` + Then run: + ```sh -npx hardhat run --network scripts/ssv-network-deploy.ts + +npx hardhat run --network scripts/deploy-all.ts + ``` -Output of this action will be smart SSV Network contract proxy address. + +Output of this action will be: + +```sh +Deploying contracts with the account:0xf39Fd6... +Deploying SSVNetwork with ssvToken 0x6471F7... +SSVNetwork proxy deployed to: 0x8A7916... +SSVNetwork implementation deployed to: 0x2279B7... +Deploying SSVNetworkViews with SSVNetwork 0x8A7916... +SSVNetworkViews proxy deployed to: 0xB7f8BC... +SSVNetworkViews implementation deployed to: 0x610178... +``` + +You can now go to Etherscan and see: +- `SSVNetwork` proxy contract is deployed to the address shown previously in `SSVNetwork proxy deployed to` +- `SSVNetwork` implementation contract is deployed to the address shown previously in `SSVNetwork implementation deployed to` +- `SSVNetworkViews` proxy contract is deployed to the address shown previously in `SSVNetworkViews proxy deployed to` +- `SSVNetworkViews` implementation contract is deployed to the address shown previously in `SSVNetworkViews implementation deployed to` + +Example: [https://goerli.etherscan.io/address/0xe2e28fdea8ba1bb59a0056f6a5eabd443d47ec78](https://goerli.etherscan.io/address/0xe2e28fdea8ba1bb59a0056f6a5eabd443d47ec78) + ### Step 3: Verify implementation contract on etherscan (each time after upgrade) + Open `.openzeppelin/.json` file and find `[impls..address]` value which is implementation smart contract address. -We use [UUPS Proxy Upgrade pattern](https://docs.openzeppelin.com/contracts/4.x/api/proxy) for smart contracts to have an ability to upgrade them later. -To deploy the contract we will use a Hardhat script. Inside `scripts/` you will find `ssv-network-deploy.ts` file. -Run this: +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. + + + +To verify an implementation contract, run this: + ```sh -npx hardhat verify --network +npx hardhat verify --network ``` -### Step 4: Link proxy contract with implementation on etherscan (each time after upgrade) -Go to `https://.etherscan.io/address/` and click on `Contract` tab. -On a right side click `More Options` dropbox and select `Is this a proxy?`. On a verification page enter proxy address inside field and click `Verify` button. As result you will see the message: +Output of this action will be: ```sh -The proxy contract verification completed with the message: -The proxy\'s ( +Nothing to compile +No need to generate any newer typings. +Successfully submitted source code for contract +contracts/SSVNetwork.sol:SSVNetwork at 0x2279B7... +for verification on the block explorer. Waiting for verification result... + +Successfully verified contract SSVNetwork on Etherscan. +https://goerli.etherscan.io/address/0x2279b7dea8ba1bb59a0056f6a5eabd443d47ec78#code ``` -To be sure that values are correct and click `Save` button. As result on etherscan proxy address page in `Contract` tab you will find two new buttons: -`Write as Proxy` and `Read as Proxy` which will represent implementation smart contract functions interface and the actual state. -### Step 5: Upgrade SSVNetwork contract -Once we have tested our new implementation, for example `contracts/SSVNetwork.sol` we can prepare the upgrade. +After this action, you can go to the proxy contract in Etherscan and start interacting with it. + +## Upgrade process +### Upgrade SSVNetwork contract -In `.env` file, remember to set `PROXY_ADDRESS`. +Once we have tested our new implementation, for example `contracts/SSVNetwork_V2.sol` we can prepare the upgrade. -**Important** -Pay special attention when changing storage layout, for example adding new storage variables -in `SSVNetwork` (base) contract. -There is a state variable `uint256[50] __gap;` that you should reduce the size according to -the size of the new variables added. More info: [Storage Gaps](https://docs.openzeppelin.com/upgrades-plugins/1.x/writing-upgradeable#storage-gaps) + +In `.env` file, remember to set `SSVNETWORK_PROXY_ADDRESS` with the address of the `SSVNetwork` proxy contract. To validate the upgrade before running it: + ```sh -npx hardhat run --network scripts/ssv-network-validate-upgrade.ts +npx hardhat run --network scripts/validate-upgrade-ssv-network.ts ``` + To fire the upgrade process: + ```sh -npx hardhat run --network scripts/ssv-network-upgrade.ts +npx hardhat run --network scripts/upgrade-ssv-network.ts ``` If you get the error: + ` Error: invalid hex string ... reason: 'invalid hex string', code: 'INVALID_ARGUMENT', ` + Set or change the parameters `GAS_PRICE` and `GAS` in `.env` file. -### dApp UI to interact with smart contract + +### Upgrade SSVNetworkViews contract + +Once we have tested our new implementation, for example `contracts/SSVNetworkViews_V2.sol` we can prepare the upgrade. + +In `.env` file, remember to set `SSVNETWORKVIEWS_PROXY_ADDRESS` with the address of the `SSVNetworkViews` proxy . + +To validate the upgrade before running it: + +```sh +npx hardhat run --network scripts/validate-upgrade-ssv-network-views.ts +``` + +To fire the upgrade process: ```sh -https://eth95.dev/?network=1&address=0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0 +npx hardhat run --network scripts/upgrade-ssv-network-views.ts ``` -UI dApp [direct link](https://eth95.dev/?network=1&address=0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0) +**Important note on upgrades** + +Pay special attention when changing storage layout, for example adding new storage variables in `SSVNetwork` and `SSVNetworkViews` (base) contracts. + +There is a state variable `uint256[50] __gap;` that you should reduce the size according to the size of the new variables added. More info: [Storage Gaps](https://docs.openzeppelin.com/upgrades-plugins/1.x/writing-upgradeable#storage-gaps) diff --git a/contracts/ISSVNetwork.sol b/contracts/ISSVNetwork.sol index 2a252701..f55c693b 100644 --- a/contracts/ISSVNetwork.sol +++ b/contracts/ISSVNetwork.sol @@ -2,18 +2,9 @@ // SPDX-License-Identifier: GPL-3.0-or-later pragma solidity 0.8.16; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "./ISSVNetworkCore.sol"; -interface ISSVNetwork { - - struct Cluster { - uint32 validatorCount; - uint64 networkFee; - uint64 networkFeeIndex; - uint64 index; - uint64 balance; - bool disabled; - } - +interface ISSVNetwork is ISSVNetworkCore { /**********/ /* Events */ /**********/ @@ -73,7 +64,10 @@ interface ISSVNetwork { uint256 fee ); - event OperatorFeeCancelationDeclared(address indexed owner, uint64 operatorId); + event OperatorFeeCancelationDeclared( + address indexed owner, + uint64 operatorId + ); /** * @dev Emitted when an operator's fee is updated. @@ -88,9 +82,17 @@ interface ISSVNetwork { uint256 fee ); - event ClusterLiquidated(address indexed owner, uint64[] operatorIds, Cluster cluster); + event ClusterLiquidated( + address owner, + uint64[] operatorIds, + Cluster cluster + ); - event ClusterReactivated(address indexed owner, uint64[] operatorIds, Cluster cluster); + event ClusterReactivated( + address owner, + uint64[] operatorIds, + Cluster cluster + ); event OperatorFeeIncreaseLimitUpdated(uint64 value); @@ -114,7 +116,12 @@ interface ISSVNetwork { */ event NetworkEarningsWithdrawn(uint256 value, address recipient); - event ClusterWithdrawn(address indexed owner, uint64[] operatorIds, uint256 value, Cluster cluster); + event ClusterWithdrawn( + address owner, + uint64[] operatorIds, + uint256 value, + Cluster cluster + ); event OperatorWithdrawn(uint256 value, uint64 operatorId, address owner); event ClusterDeposited( @@ -124,37 +131,7 @@ interface ISSVNetwork { Cluster cluster ); - event FeeRecipientAddressUpdated( - address owner, - address recipientAddress - ); - - /**********/ - /* Errors */ - /**********/ - - error CallerNotOwner(); - error FeeTooLow(); - error FeeExceedsIncreaseLimit(); - error NoFeeDelcared(); - error ApprovalNotWithinTimeframe(); - error OperatorDoesNotExist(); - error InsufficientBalance(); - error ValidatorAlreadyExists(); - error ValidatorDoesNotExist(); - error ClusterLiquidatable(); - error ClusterNotLiquidatable(); - error InvalidPublicKeyLength(); - error InvalidOperatorIdsLength(); - error ValidatorOwnedByOtherAddress(); - error InsufficientFunds(); - error ClusterAlreadyEnabled(); - error ClusterIsLiquidated(); - error ClusterDoesNotExists(); - error IncorrectClusterState(); - error UnsortedOperatorsList(); - error NewBlockPeriodIsBelowMinimum(); - error ExceedValidatorLimit(); + event FeeRecipientAddressUpdated(address owner, address recipientAddress); /****************/ /* Initializers */ @@ -248,7 +225,10 @@ interface ISSVNetwork { Cluster memory cluster ) external; - function withdrawOperatorEarnings(uint64 operatorId, uint256 tokenAmount) external; + function withdrawOperatorEarnings( + uint64 operatorId, + uint256 tokenAmount + ) external; function withdrawOperatorEarnings(uint64 operatorId) external; @@ -279,69 +259,4 @@ interface ISSVNetwork { ) external; function updateLiquidationThresholdPeriod(uint64 blocks) external; - - /************************************/ - /* Operator External View Functions */ - /************************************/ - - function getOperatorFee(uint64 operatorId) external view returns (uint256); - - function getOperatorDeclaredFee( - uint64 operatorId - ) external view returns (uint256, uint256, uint256); - - function getOperatorById( - uint64 operatorId - ) external view returns (address owner, uint256 fee, uint32 validatorCount); - - /*******************************/ - /* Cluster External View Functions */ - /*******************************/ - - function isLiquidatable( - address owner, - uint64[] memory operatorIds, - Cluster memory cluster - ) external view returns(bool); - - function isLiquidated( - address owner, - uint64[] memory operatorIds, - Cluster memory cluster - ) external view returns(bool); - - function getClusterBurnRate(uint64[] memory operatorIds) external view returns (uint256); - - /***********************************/ - /* Balance External View Functions */ - /***********************************/ - - /** - * @dev Gets the operators current snapshot. - * @param id Operator's id. - * @return balance the current balance of the operator. - */ - function getOperatorEarnings(uint64 id) external view returns (uint256 balance); - - function getBalance( - address owner, - uint64[] memory operatorIds, - Cluster memory cluster - ) external view returns (uint256); - - /*******************************/ - /* DAO External View Functions */ - /*******************************/ - - function getNetworkFee() external view returns (uint256); - - function getNetworkEarnings() external view returns (uint256); - - function getOperatorFeeIncreaseLimit() external view returns (uint64); - - function getExecuteOperatorFeePeriod() external view returns (uint64); - - function getDeclaredOperatorFeePeriod() external view returns (uint64); - - function getLiquidationThresholdPeriod() external view returns (uint64); } diff --git a/contracts/ISSVNetworkCore.sol b/contracts/ISSVNetworkCore.sol new file mode 100644 index 00000000..9f8671e6 --- /dev/null +++ b/contracts/ISSVNetworkCore.sol @@ -0,0 +1,84 @@ +// File: contracts/ISSVNetwork.sol +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity 0.8.16; +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; + +interface ISSVNetworkCore { + /***********/ + /* Structs */ + /***********/ + + struct Validator { + address owner; + bool active; + } + struct Snapshot { + /// @dev block is the last block in which last index was set + uint64 block; + /// @dev index is the last index calculated by index += (currentBlock - block) * fee + uint64 index; + /// @dev accumulated is all the accumulated earnings, calculated by accumulated + lastIndex * validatorCount + uint64 balance; + } + + struct Operator { + address owner; + uint64 fee; + uint32 validatorCount; + Snapshot snapshot; + } + + struct OperatorFeeChangeRequest { + uint64 fee; + uint64 approvalBeginTime; + uint64 approvalEndTime; + } + + struct Cluster { + uint32 validatorCount; + uint64 networkFee; + uint64 networkFeeIndex; + uint64 index; + uint64 balance; + bool disabled; + } + + struct DAO { + uint32 validatorCount; + uint64 withdrawn; + Snapshot earnings; + } + + struct Network { + uint64 networkFee; + uint64 networkFeeIndex; + uint64 networkFeeIndexBlockNumber; + } + + /**********/ + /* Errors */ + /**********/ + + error CallerNotOwner(); + error FeeTooLow(); + error FeeExceedsIncreaseLimit(); + error NoFeeDelcared(); + error ApprovalNotWithinTimeframe(); + error OperatorDoesNotExist(); + error InsufficientBalance(); + error ValidatorAlreadyExists(); + error ValidatorDoesNotExist(); + error ClusterNotLiquidatable(); + error InvalidPublicKeyLength(); + error InvalidOperatorIdsLength(); + error ValidatorOwnedByOtherAddress(); + error InsufficientFunds(); + error ClusterAlreadyEnabled(); + error ClusterIsLiquidated(); + error ClusterDoesNotExists(); + error IncorrectClusterState(); + error UnsortedOperatorsList(); + error NewBlockPeriodIsBelowMinimum(); + error ExceedValidatorLimit(); + error TokenTransferFailed(); +} diff --git a/contracts/ISSVNetworkViews.sol b/contracts/ISSVNetworkViews.sol new file mode 100644 index 00000000..1dc2635f --- /dev/null +++ b/contracts/ISSVNetworkViews.sol @@ -0,0 +1,82 @@ +// File: contracts/ISSVNetwork.sol +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity 0.8.16; +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "./ISSVNetworkCore.sol"; +import "./SSVNetwork.sol"; + +interface ISSVNetworkViews is ISSVNetworkCore { + /****************/ + /* Initializers */ + /****************/ + + /** + * @dev Initializes the contract. + * @param ssvNetwork_ The SSVNetwork contract. + */ + function initialize(SSVNetwork ssvNetwork_) external; + + /************************************/ + /* Operator External View Functions */ + /************************************/ + + function getOperatorFee(uint64 operatorId) external view returns (uint256); + + function getOperatorDeclaredFee( + uint64 operatorId + ) external view returns (uint256, uint256, uint256); + + function getOperatorById( + uint64 operatorId + ) external view returns (address owner, uint256 fee, uint32 validatorCount); + + /*******************************/ + /* Cluster External View Functions */ + /*******************************/ + + function isLiquidatable( + address owner, + uint64[] memory operatorIds, + ISSVNetwork.Cluster memory cluster + ) external view returns (bool); + + function isLiquidated( + address owner, + uint64[] memory operatorIds, + ISSVNetwork.Cluster memory cluster + ) external view returns (bool); + + function getClusterBurnRate( + uint64[] memory operatorIds + ) external view returns (uint256); + + /***********************************/ + /* Balance External View Functions */ + /***********************************/ + + function getOperatorEarnings( + uint64 id + ) external view returns (uint256 balance); + + function getBalance( + address owner, + uint64[] memory operatorIds, + ISSVNetwork.Cluster memory cluster + ) external view returns (uint256); + + /*******************************/ + /* DAO External View Functions */ + /*******************************/ + + function getNetworkFee() external view returns (uint256); + + function getNetworkEarnings() external view returns (uint256); + + function getOperatorFeeIncreaseLimit() external view returns (uint64); + + function getExecuteOperatorFeePeriod() external view returns (uint64); + + function getDeclaredOperatorFeePeriod() external view returns (uint64); + + function getLiquidationThresholdPeriod() external view returns (uint64); +} diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index 27994195..9edc0691 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -8,66 +8,30 @@ import "@openzeppelin/contracts/utils/Counters.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; -import "./utils/Types.sol"; +import "./libraries/Types.sol"; +import "./libraries/ClusterLib.sol"; +import "./libraries/OperatorLib.sol"; +import "./libraries/NetworkLib.sol"; -contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { +contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { /*************/ /* Libraries */ /*************/ using Types256 for uint256; using Types64 for uint64; + using ClusterLib for Cluster; + using OperatorLib for Operator; + using NetworkLib for DAO; using Counters for Counters.Counter; - /***********/ - /* Structs */ - /***********/ - - struct Snapshot { - /// @dev block is the last block in which last index was set - uint64 block; - /// @dev index is the last index calculated by index += (currentBlock - block) * fee - uint64 index; - /// @dev accumulated is all the accumulated earnings, calculated by accumulated + lastIndex * validatorCount - uint64 balance; - } - - struct Operator { - address owner; - uint64 fee; - uint32 validatorCount; - Snapshot snapshot; - } - - struct OperatorFeeChangeRequest { - uint64 fee; - uint64 approvalBeginTime; - uint64 approvalEndTime; - } - - struct DAO { - uint32 validatorCount; - uint64 withdrawn; - Snapshot earnings; - } - /* - struct Cluster { - uint64[] operatorIds; - } - */ - - struct Validator { - address owner; - bool active; - } - /*************/ /* Constants */ /*************/ uint64 constant MINIMAL_LIQUIDATION_THRESHOLD = 6570; - uint64 constant MINIMAL_OPERATOR_FEE = 1e8; + uint64 constant MINIMAL_OPERATOR_FEE = 100_000_000; uint32 constant VALIDATORS_PER_OPERATOR_LIMIT = 2000; /********************/ @@ -80,24 +44,20 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { /* Variables */ /*************/ - mapping(uint64 => Operator) private _operators; + mapping(uint64 => Operator) public operators; mapping(uint64 => OperatorFeeChangeRequest) - private _operatorFeeChangeRequests; - // mapping(bytes32 => Cluster) private _clusters; - mapping(bytes32 => bytes32) private _clusters; - mapping(bytes32 => Validator) _validatorPKs; - - uint64 private _networkFee; - uint64 private _networkFeeIndex; - uint64 private _networkFeeIndexBlockNumber; + public operatorFeeChangeRequests; + mapping(bytes32 => bytes32) public clusters; + mapping(bytes32 => Validator) private _validatorPKs; - uint64 private _declareOperatorFeePeriod; - uint64 private _executeOperatorFeePeriod; - uint64 private _operatorMaxFeeIncrease; - uint64 private _minimumBlocksBeforeLiquidation; + uint64 public declareOperatorFeePeriod; + uint64 public executeOperatorFeePeriod; + uint64 public operatorMaxFeeIncrease; + uint64 public minimumBlocksBeforeLiquidation; - DAO private _dao; + DAO public dao; IERC20 private _token; + Network public network; // @dev reserve storage space for future new state variables in base contract uint256[50] __gap; @@ -124,7 +84,13 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { ) external override initializer onlyProxy { __UUPSUpgradeable_init(); __Ownable_init_unchained(); - __SSVNetwork_init_unchained(token_, operatorMaxFeeIncrease_, declareOperatorFeePeriod_, executeOperatorFeePeriod_, minimumBlocksBeforeLiquidation_); + __SSVNetwork_init_unchained( + token_, + operatorMaxFeeIncrease_, + declareOperatorFeePeriod_, + executeOperatorFeePeriod_, + minimumBlocksBeforeLiquidation_ + ); } function __SSVNetwork_init_unchained( @@ -135,10 +101,10 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { uint64 minimumBlocksBeforeLiquidation_ ) internal onlyInitializing { _token = token_; - _operatorMaxFeeIncrease = operatorMaxFeeIncrease_; - _declareOperatorFeePeriod = declareOperatorFeePeriod_; - _executeOperatorFeePeriod = executeOperatorFeePeriod_; - _minimumBlocksBeforeLiquidation = minimumBlocksBeforeLiquidation_; + operatorMaxFeeIncrease = operatorMaxFeeIncrease_; + declareOperatorFeePeriod = declareOperatorFeePeriod_; + executeOperatorFeePeriod = executeOperatorFeePeriod_; + minimumBlocksBeforeLiquidation = minimumBlocksBeforeLiquidation_; } /*****************/ @@ -161,15 +127,24 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { lastOperatorId.increment(); id = uint64(lastOperatorId.current()); - _operators[id] = Operator({ owner: msg.sender, snapshot: Snapshot({ block: uint64(block.number), index: 0, balance: 0}), validatorCount: 0, fee: fee.shrink()}); + operators[id] = Operator({ + owner: msg.sender, + snapshot: Snapshot({ + block: uint64(block.number), + index: 0, + balance: 0 + }), + validatorCount: 0, + fee: fee.shrink() + }); emit OperatorAdded(id, msg.sender, publicKey, fee); } function removeOperator(uint64 id) external override { - Operator memory operator = _operators[id]; + Operator memory operator = operators[id]; if (operator.owner != msg.sender) revert CallerNotOwner(); - operator.snapshot = _getSnapshot(operator, uint64(block.number)); + operator.getSnapshot(); uint64 currentBalance = operator.snapshot.balance; operator.snapshot.block = 0; @@ -177,7 +152,7 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { operator.validatorCount = 0; operator.fee = 0; - _operators[id] = operator; + operators[id] = operator; if (currentBalance > 0) { _transferOperatorBalanceUnsafe(id, currentBalance.expand()); @@ -194,17 +169,17 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { uint64 shrunkFee = fee.shrink(); // @dev 100% = 10000, 10% = 1000 - using 10000 to represent 2 digit precision - uint64 maxAllowedFee = (_operators[operatorId].fee * - (10000 + _operatorMaxFeeIncrease)) / 10000; + uint64 maxAllowedFee = (operators[operatorId].fee * + (10000 + operatorMaxFeeIncrease)) / 10000; if (shrunkFee > maxAllowedFee) revert FeeExceedsIncreaseLimit(); - _operatorFeeChangeRequests[operatorId] = OperatorFeeChangeRequest( + operatorFeeChangeRequests[operatorId] = OperatorFeeChangeRequest( shrunkFee, - uint64(block.timestamp) + _declareOperatorFeePeriod, + uint64(block.timestamp) + declareOperatorFeePeriod, uint64(block.timestamp) + - _declareOperatorFeePeriod + - _executeOperatorFeePeriod + declareOperatorFeePeriod + + executeOperatorFeePeriod ); emit OperatorFeeDeclared(msg.sender, operatorId, block.number, fee); } @@ -213,9 +188,9 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { uint64 operatorId ) external override onlyOperatorOwnerOrContractOwner(operatorId) { OperatorFeeChangeRequest - memory feeChangeRequest = _operatorFeeChangeRequests[operatorId]; + memory feeChangeRequest = operatorFeeChangeRequests[operatorId]; - if(feeChangeRequest.fee == 0) revert NoFeeDelcared(); + if (feeChangeRequest.fee == 0) revert NoFeeDelcared(); if ( block.timestamp < feeChangeRequest.approvalBeginTime || @@ -224,20 +199,37 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { revert ApprovalNotWithinTimeframe(); } - _updateOperatorFeeUnsafe(operatorId, feeChangeRequest.fee); + Operator memory operator = operators[operatorId]; + + operator.getSnapshot(); + operator.fee = feeChangeRequest.fee; + + operators[operatorId] = operator; - delete _operatorFeeChangeRequests[operatorId]; + delete operatorFeeChangeRequests[operatorId]; + + emit OperatorFeeExecuted( + msg.sender, + operatorId, + block.number, + feeChangeRequest.fee.expand() + ); } - function cancelDeclaredOperatorFee(uint64 operatorId) onlyOperatorOwnerOrContractOwner(operatorId) external override { - if(_operatorFeeChangeRequests[operatorId].fee == 0) revert NoFeeDelcared(); + function cancelDeclaredOperatorFee( + uint64 operatorId + ) external override onlyOperatorOwnerOrContractOwner(operatorId) { + if (operatorFeeChangeRequests[operatorId].fee == 0) + revert NoFeeDelcared(); - delete _operatorFeeChangeRequests[operatorId]; + delete operatorFeeChangeRequests[operatorId]; emit OperatorFeeCancelationDeclared(msg.sender, operatorId); } - function setFeeRecipientAddress(address recipientAddress) external override { + function setFeeRecipientAddress( + address recipientAddress + ) external override { emit FeeRecipientAddressUpdated(msg.sender, recipientAddress); } @@ -250,7 +242,8 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { bytes calldata sharesEncrypted, uint256 amount, Cluster memory cluster - ) external override { + ) external { + // TODO override uint operatorsLength = operatorIds.length; { @@ -268,27 +261,52 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { }); } + bytes32 hashedCluster = keccak256( + abi.encodePacked(msg.sender, operatorIds) + ); + { + bytes32 hashedClusterData = keccak256( + abi.encodePacked( + cluster.validatorCount, + cluster.networkFee, + cluster.networkFeeIndex, + cluster.index, + cluster.balance, + cluster.disabled + ) + ); + if ( + clusters[hashedCluster] != bytes32(0) && + clusters[hashedCluster] != hashedClusterData + ) { + revert IncorrectClusterState(); + } + } + uint64 clusterIndex; uint64 burnRate; { if (!cluster.disabled) { - for (uint i; i < operatorsLength;) { - if (i+1 < operatorsLength) { - if (operatorIds[i] > operatorIds[i+1]) { + for (uint i; i < operatorsLength; ) { + if (i + 1 < operatorsLength) { + if (operatorIds[i] > operatorIds[i + 1]) { revert UnsortedOperatorsList(); } } - Operator memory operator = _operators[operatorIds[i]]; + Operator memory operator = operators[operatorIds[i]]; if (operator.snapshot.block == 0) { revert OperatorDoesNotExist(); } - operator.snapshot = _getSnapshot(operator, uint64(block.number)); - if (++operator.validatorCount > VALIDATORS_PER_OPERATOR_LIMIT) { + operator.getSnapshot(); + if ( + ++operator.validatorCount > + VALIDATORS_PER_OPERATOR_LIMIT + ) { revert ExceedValidatorLimit(); } clusterIndex += operator.snapshot.index; burnRate += operator.fee; - _operators[operatorIds[i]] = operator; + operators[operatorIds[i]] = operator; unchecked { ++i; } @@ -296,54 +314,71 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { } } - bytes32 hashedCluster = keccak256(abi.encodePacked(msg.sender, operatorIds)); - { - bytes32 hashedClusterData = keccak256(abi.encodePacked(cluster.validatorCount, cluster.networkFee, cluster.networkFeeIndex, cluster.index, cluster.balance, cluster.disabled )); - if (_clusters[hashedCluster] == bytes32(0)) { - cluster = Cluster({ validatorCount: 0, networkFee: 0, networkFeeIndex: 0, index: 0, balance: 0, disabled: false }); - } else if (_clusters[hashedCluster] != hashedClusterData) { - revert IncorrectClusterState(); - } - } + Network memory network_ = network; + uint64 currentNetworkFeeIndex = NetworkLib.currentNetworkFeeIndex( + network_ + ); cluster.balance += amount.shrink(); - cluster = _updateClusterData(cluster, clusterIndex, 1); + cluster.updateClusterData(clusterIndex, currentNetworkFeeIndex, 1); - if (_liquidatable(_clusterBalance(cluster, clusterIndex), cluster.validatorCount, burnRate)) { + if ( + cluster.liquidatable( + burnRate, + network_.networkFee, + minimumBlocksBeforeLiquidation + ) + ) { revert InsufficientBalance(); } { if (!cluster.disabled) { - DAO memory dao = _dao; - dao = _updateDAOEarnings(dao); - ++dao.validatorCount; - _dao = dao; + DAO memory dao_ = dao; + dao_ = dao_.updateDAOEarnings(network_.networkFee); + ++dao_.validatorCount; + dao = dao_; } } - _clusters[hashedCluster] = keccak256(abi.encodePacked(cluster.validatorCount, cluster.networkFee, cluster.networkFeeIndex, cluster.index, cluster.balance, cluster.disabled )); + clusters[hashedCluster] = keccak256( + abi.encodePacked( + cluster.validatorCount, + cluster.networkFee, + cluster.networkFeeIndex, + cluster.index, + cluster.balance, + cluster.disabled + ) + ); if (amount > 0) { _deposit(amount.shrink()); } - emit ValidatorAdded(msg.sender, operatorIds, publicKey, sharesEncrypted, cluster); + emit ValidatorAdded( + msg.sender, + operatorIds, + publicKey, + sharesEncrypted, + cluster + ); } function removeValidator( bytes calldata publicKey, uint64[] memory operatorIds, Cluster memory cluster - ) external override { + ) external { + // TODO override uint operatorsLength = operatorIds.length; bytes32 hashedValidator = keccak256(publicKey); - address owner = _validatorPKs[hashedValidator].owner; - if (owner == address(0)) { + address validatorOwner = _validatorPKs[hashedValidator].owner; + if (validatorOwner == address(0)) { revert ValidatorDoesNotExist(); } - if (owner != msg.sender) { + if (validatorOwner != msg.sender) { revert ValidatorOwnedByOtherAddress(); } @@ -355,38 +390,54 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { uint64 clusterIndex; { if (!cluster.disabled) { - for (uint i; i < operatorsLength;) { - Operator memory operator = _operators[operatorIds[i]]; + for (uint i; i < operatorsLength; ) { + Operator memory operator = operators[operatorIds[i]]; if (operator.snapshot.block != 0) { - operator.snapshot = _getSnapshot( - operator, - uint64(block.number) - ); + operator.getSnapshot(); --operator.validatorCount; - _operators[operatorIds[i]] = operator; + operators[operatorIds[i]] = operator; } - + clusterIndex += operator.snapshot.index; - unchecked { ++i; } + unchecked { + ++i; + } } } } - bytes32 hashedCluster = _validateHashedCluster(msg.sender, operatorIds, cluster); + bytes32 hashedCluster = cluster.validateHashedCluster( + msg.sender, + operatorIds, + this + ); - cluster = _updateClusterData(cluster, clusterIndex, -1); + cluster.updateClusterData( + clusterIndex, + NetworkLib.currentNetworkFeeIndex(network), + -1 + ); { if (!cluster.disabled) { - DAO memory dao = _dao; - dao = _updateDAOEarnings(dao); - --dao.validatorCount; - _dao = dao; + DAO memory dao_ = dao; + dao_ = dao_.updateDAOEarnings(network.networkFee); + --dao_.validatorCount; + dao = dao_; } } delete _validatorPKs[hashedValidator]; - _clusters[hashedCluster] = keccak256(abi.encodePacked(cluster.validatorCount, cluster.networkFee, cluster.networkFeeIndex, cluster.index, cluster.balance, cluster.disabled )); + clusters[hashedCluster] = keccak256( + abi.encodePacked( + cluster.validatorCount, + cluster.networkFee, + cluster.networkFeeIndex, + cluster.index, + cluster.balance, + cluster.disabled + ) + ); emit ValidatorRemoved(msg.sender, operatorIds, publicKey, cluster); } @@ -396,31 +447,48 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { uint64[] memory operatorIds, Cluster memory cluster ) external override { - _validateClusterIsNotLiquidated(cluster); + cluster.validateClusterIsNotLiquidated(); - bytes32 hashedCluster = _validateHashedCluster(owner, operatorIds, cluster); + bytes32 hashedCluster = cluster.validateHashedCluster( + owner, + operatorIds, + this + ); uint64 clusterIndex; uint64 burnRate; { uint operatorsLength = operatorIds.length; for (uint i; i < operatorsLength; ) { - Operator memory operator = _operators[operatorIds[i]]; - uint64 currentBlock = uint64(block.number); + Operator memory operator = operators[operatorIds[i]]; + if (operator.snapshot.block != 0) { - operator.snapshot = _getSnapshot(operator, currentBlock); + operator.getSnapshot(); operator.validatorCount -= cluster.validatorCount; burnRate += operator.fee; - _operators[operatorIds[i]] = operator; + operators[operatorIds[i]] = operator; } - + clusterIndex += operator.snapshot.index; - unchecked { ++i; } + unchecked { + ++i; + } } } - uint64 clusterBalance = _clusterBalance(cluster, clusterIndex); - if (!_liquidatable(clusterBalance, cluster.validatorCount, burnRate)) { + cluster.balance = cluster.clusterBalance( + clusterIndex, + NetworkLib.currentNetworkFeeIndex(network) + ); + + uint64 networkFee = network.networkFee; + if ( + !cluster.liquidatable( + burnRate, + networkFee, + minimumBlocksBeforeLiquidation + ) + ) { revert ClusterNotLiquidatable(); } @@ -428,17 +496,27 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { cluster.balance = 0; cluster.index = 0; - { - DAO memory dao = _dao; - dao = _updateDAOEarnings(dao); - dao.validatorCount -= cluster.validatorCount; - _dao = dao; - } - - _clusters[hashedCluster] = keccak256(abi.encodePacked(cluster.validatorCount, cluster.networkFee, cluster.networkFeeIndex, cluster.index, cluster.balance, cluster.disabled )); + DAO memory dao_ = dao; + dao_ = dao_.updateDAOEarnings(networkFee); + dao_.validatorCount -= cluster.validatorCount; + dao = dao_; + } + + clusters[hashedCluster] = keccak256( + abi.encodePacked( + cluster.validatorCount, + cluster.networkFee, + cluster.networkFeeIndex, + cluster.index, + cluster.balance, + cluster.disabled + ) + ); - _token.transfer(msg.sender, clusterBalance.expand()); + if (!_token.transfer(msg.sender, cluster.balance.expand())) { + revert TokenTransferFailed(); + } emit ClusterLiquidated(owner, operatorIds, cluster); } @@ -448,7 +526,6 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { uint256 amount, Cluster memory cluster ) external override { - if (!cluster.disabled) { revert ClusterAlreadyEnabled(); } @@ -458,39 +535,66 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { { uint operatorsLength = operatorIds.length; for (uint i; i < operatorsLength; ) { - Operator memory operator = _operators[operatorIds[i]]; + Operator memory operator = operators[operatorIds[i]]; if (operator.snapshot.block != 0) { - operator.snapshot = _getSnapshot(operator, uint64(block.number)); + operator.getSnapshot(); operator.validatorCount += cluster.validatorCount; burnRate += operator.fee; - _operators[operatorIds[i]] = operator; + operators[operatorIds[i]] = operator; } clusterIndex += operator.snapshot.index; - unchecked { ++i; } + unchecked { + ++i; + } } } - bytes32 hashedCluster = _validateHashedCluster(msg.sender, operatorIds, cluster); + bytes32 hashedCluster = cluster.validateHashedCluster( + msg.sender, + operatorIds, + this + ); + + uint64 currentNetworkFeeIndex = NetworkLib.currentNetworkFeeIndex( + network + ); cluster.balance += amount.shrink(); cluster.disabled = false; cluster.index = clusterIndex; - cluster = _updateClusterData(cluster, clusterIndex, 0); + cluster.updateClusterData(clusterIndex, currentNetworkFeeIndex, 0); + + uint64 networkFee = network.networkFee; { - DAO memory dao = _dao; - dao = _updateDAOEarnings(dao); - dao.validatorCount += cluster.validatorCount; - _dao = dao; + DAO memory dao_ = dao; + dao_ = dao_.updateDAOEarnings(networkFee); + dao_.validatorCount += cluster.validatorCount; + dao = dao_; } - if (_liquidatable(_clusterBalance(cluster, clusterIndex), cluster.validatorCount, burnRate)) { + if ( + cluster.liquidatable( + burnRate, + networkFee, + minimumBlocksBeforeLiquidation + ) + ) { revert InsufficientBalance(); } - _clusters[hashedCluster] = keccak256(abi.encodePacked(cluster.validatorCount, cluster.networkFee, cluster.networkFeeIndex, cluster.index, cluster.balance, cluster.disabled )); + clusters[hashedCluster] = keccak256( + abi.encodePacked( + cluster.validatorCount, + cluster.networkFee, + cluster.networkFeeIndex, + cluster.index, + cluster.balance, + cluster.disabled + ) + ); if (amount > 0) { _deposit(amount.shrink()); @@ -509,35 +613,49 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { uint256 amount, Cluster memory cluster ) external override { - _validateClusterIsNotLiquidated(cluster); + cluster.validateClusterIsNotLiquidated(); uint64 shrunkAmount = amount.shrink(); - bytes32 hashedCluster = _validateHashedCluster(owner, operatorIds, cluster); + bytes32 hashedCluster = cluster.validateHashedCluster( + owner, + operatorIds, + this + ); cluster.balance += shrunkAmount; - _clusters[hashedCluster] = keccak256(abi.encodePacked(cluster.validatorCount, cluster.networkFee, cluster.networkFeeIndex, cluster.index, cluster.balance, cluster.disabled )); + clusters[hashedCluster] = keccak256( + abi.encodePacked( + cluster.validatorCount, + cluster.networkFee, + cluster.networkFeeIndex, + cluster.index, + cluster.balance, + cluster.disabled + ) + ); _deposit(shrunkAmount); emit ClusterDeposited(owner, operatorIds, amount, cluster); } - - function _withdrawOperatorEarnings(uint64 operatorId, uint256 amount) private { - - Operator memory operator = _operators[operatorId]; + function _withdrawOperatorEarnings( + uint64 operatorId, + uint256 amount + ) private { + Operator memory operator = operators[operatorId]; if (operator.owner != msg.sender) revert CallerNotOwner(); - operator.snapshot = _getSnapshot(operator, uint64(block.number)); + operator.getSnapshot(); uint64 shrunkAmount; - if(amount == 0 && operator.snapshot.balance > 0) { + if (amount == 0 && operator.snapshot.balance > 0) { shrunkAmount = operator.snapshot.balance; - } else if(amount > 0 && operator.snapshot.balance >= amount.shrink()) { + } else if (amount > 0 && operator.snapshot.balance >= amount.shrink()) { shrunkAmount = amount.shrink(); } else { revert InsufficientBalance(); @@ -545,14 +663,15 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { operator.snapshot.balance -= shrunkAmount; - _operators[operatorId] = operator; + operators[operatorId] = operator; _transferOperatorBalanceUnsafe(operatorId, shrunkAmount.expand()); - } - - function withdrawOperatorEarnings(uint64 operatorId, uint256 amount) external override { + function withdrawOperatorEarnings( + uint64 operatorId, + uint256 amount + ) external override { _withdrawOperatorEarnings(operatorId, amount); } @@ -565,7 +684,7 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { uint256 amount, Cluster memory cluster ) external override { - _validateClusterIsNotLiquidated(cluster); + cluster.validateClusterIsNotLiquidated(); uint64 shrunkAmount = amount.shrink(); @@ -574,8 +693,11 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { { uint operatorsLength = operatorIds.length; for (uint i; i < operatorsLength; ) { - Operator memory operator = _operators[operatorIds[i]]; - clusterIndex += operator.snapshot.index + (uint64(block.number) - operator.snapshot.block) * operator.fee; + Operator memory operator = operators[operatorIds[i]]; + clusterIndex += + operator.snapshot.index + + (uint64(block.number) - operator.snapshot.block) * + operator.fee; burnRate += operator.fee; unchecked { ++i; @@ -583,19 +705,44 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { } } - bytes32 hashedCluster = _validateHashedCluster(msg.sender, operatorIds, cluster); + bytes32 hashedCluster = cluster.validateHashedCluster( + msg.sender, + operatorIds, + this + ); - uint64 clusterBalance = _clusterBalance(cluster, clusterIndex); + cluster.balance = cluster.clusterBalance( + clusterIndex, + NetworkLib.currentNetworkFeeIndex(network) + ); - if (clusterBalance < shrunkAmount || _liquidatable(clusterBalance, cluster.validatorCount, burnRate)) { + if ( + cluster.balance < shrunkAmount || + cluster.liquidatable( + burnRate, + network.networkFee, + minimumBlocksBeforeLiquidation + ) + ) { revert InsufficientBalance(); } cluster.balance -= shrunkAmount; - _clusters[hashedCluster] = keccak256(abi.encodePacked(cluster.validatorCount, cluster.networkFee, cluster.networkFeeIndex, cluster.index, cluster.balance, cluster.disabled )); + clusters[hashedCluster] = keccak256( + abi.encodePacked( + cluster.validatorCount, + cluster.networkFee, + cluster.networkFeeIndex, + cluster.index, + cluster.balance, + cluster.disabled + ) + ); - _token.transfer(msg.sender, amount); + if (!_token.transfer(msg.sender, amount)) { + revert TokenTransferFailed(); + } emit ClusterWithdrawn(msg.sender, operatorIds, amount, cluster); } @@ -605,32 +752,38 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { /**************************/ function updateNetworkFee(uint256 fee) external override onlyOwner { - DAO memory dao = _dao; - dao = _updateDAOEarnings(dao); - _dao = dao; + Network memory network_ = network; - _updateNetworkFeeIndex(); + DAO memory dao_ = dao; + dao_ = dao_.updateDAOEarnings(network.networkFee); + dao = dao_; - emit NetworkFeeUpdated(_networkFee.expand(), fee); + network_.networkFeeIndex = NetworkLib.currentNetworkFeeIndex(network_); + network_.networkFeeIndexBlockNumber = uint64(block.number); - _networkFee = fee.shrink(); + emit NetworkFeeUpdated(network_.networkFee.expand(), fee); + + network_.networkFee = fee.shrink(); + network = network_; } function withdrawNetworkEarnings( uint256 amount ) external override onlyOwner { - DAO memory dao = _dao; + DAO memory dao_ = dao; uint64 shrunkAmount = amount.shrink(); - if(shrunkAmount > _networkBalance(dao)) { + if (shrunkAmount > dao_.networkBalance(network.networkFee)) { revert InsufficientBalance(); } - dao.withdrawn += shrunkAmount; - _dao = dao; + dao_.withdrawn += shrunkAmount; + dao = dao_; - _token.transfer(msg.sender, amount); + if (!_token.transfer(msg.sender, amount)) { + revert TokenTransferFailed(); + } emit NetworkEarningsWithdrawn(amount, msg.sender); } @@ -638,209 +791,43 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { function updateOperatorFeeIncreaseLimit( uint64 newOperatorMaxFeeIncrease ) external override onlyOwner { - _operatorMaxFeeIncrease = newOperatorMaxFeeIncrease; - emit OperatorFeeIncreaseLimitUpdated(_operatorMaxFeeIncrease); + operatorMaxFeeIncrease = newOperatorMaxFeeIncrease; + emit OperatorFeeIncreaseLimitUpdated(operatorMaxFeeIncrease); } function updateDeclareOperatorFeePeriod( uint64 newDeclareOperatorFeePeriod ) external override onlyOwner { - _declareOperatorFeePeriod = newDeclareOperatorFeePeriod; + declareOperatorFeePeriod = newDeclareOperatorFeePeriod; emit DeclareOperatorFeePeriodUpdated(newDeclareOperatorFeePeriod); } function updateExecuteOperatorFeePeriod( uint64 newExecuteOperatorFeePeriod ) external override onlyOwner { - _executeOperatorFeePeriod = newExecuteOperatorFeePeriod; + executeOperatorFeePeriod = newExecuteOperatorFeePeriod; emit ExecuteOperatorFeePeriodUpdated(newExecuteOperatorFeePeriod); } - function updateLiquidationThresholdPeriod(uint64 blocks) external onlyOwner override { - if(blocks < MINIMAL_LIQUIDATION_THRESHOLD) { + function updateLiquidationThresholdPeriod( + uint64 blocks + ) external override onlyOwner { + if (blocks < MINIMAL_LIQUIDATION_THRESHOLD) { revert NewBlockPeriodIsBelowMinimum(); } - _minimumBlocksBeforeLiquidation = blocks; + minimumBlocksBeforeLiquidation = blocks; emit LiquidationThresholdPeriodUpdated(blocks); } - /************************************/ - /* Operator External View Functions */ - /************************************/ - - function getOperatorFee(uint64 operatorId) external view override returns (uint256) { - if (_operators[operatorId].snapshot.block == 0) revert OperatorDoesNotExist(); - - return _operators[operatorId].fee.expand(); - } - - function getOperatorDeclaredFee( - uint64 operatorId - ) external view override returns (uint256, uint256, uint256) { - OperatorFeeChangeRequest - memory feeChangeRequest = _operatorFeeChangeRequests[operatorId]; - - if(feeChangeRequest.fee == 0) { - revert NoFeeDelcared(); - } - - return ( - feeChangeRequest.fee.expand(), - feeChangeRequest.approvalBeginTime, - feeChangeRequest.approvalEndTime - ); - } - - function getOperatorById(uint64 operatorId) external view override returns (address owner, uint256 fee, uint32 validatorCount) { - if (_operators[operatorId].owner == address(0)) revert OperatorDoesNotExist(); - - return ( - _operators[operatorId].owner, - _operators[operatorId].fee.expand(), - _operators[operatorId].validatorCount - ); - } - - /***********************************/ - /* Cluster External View Functions */ - /***********************************/ - - function isLiquidatable( - address owner, - uint64[] calldata operatorIds, - Cluster memory cluster - ) external view override returns (bool) { - uint64 clusterIndex; - uint64 burnRate; - uint operatorsLength = operatorIds.length; - for (uint i; i < operatorsLength; ) { - Operator memory operator = _operators[operatorIds[i]]; - clusterIndex += operator.snapshot.index + (uint64(block.number) - operator.snapshot.block) * operator.fee; - burnRate += operator.fee; - unchecked { - ++i; - } - } - - _validateHashedCluster(owner, operatorIds, cluster); - - return _liquidatable(_clusterBalance(cluster, clusterIndex), cluster.validatorCount, burnRate); - } - - function isLiquidated( - address owner, - uint64[] calldata operatorIds, - Cluster memory cluster - ) external view override returns (bool) { - _validateHashedCluster(owner, operatorIds, cluster); - - return cluster.disabled; - } - - function getClusterBurnRate(uint64[] calldata operatorIds) external view override returns (uint256) { - uint64 burnRate; - uint operatorsLength = operatorIds.length; - for (uint i; i < operatorsLength; ) { - Operator memory operator = _operators[operatorIds[i]]; - if (operator.owner != address(0)) { - burnRate += operator.fee; - } - unchecked { - ++i; - } - } - return burnRate.expand(); - } - - /***********************************/ - /* Balance External View Functions */ - /***********************************/ - - function getOperatorEarnings(uint64 id) external view override returns (uint256) { - Snapshot memory s = _getSnapshot(_operators[id], uint64(block.number)); - return s.balance.expand(); - } - - function getBalance( - address owner, - uint64[] calldata operatorIds, - Cluster memory cluster - ) external view override returns (uint256) { - _validateClusterIsNotLiquidated(cluster); - - uint64 clusterIndex; - { - uint operatorsLength = operatorIds.length; - for (uint i; i < operatorsLength; ) { - Operator memory operator = _operators[operatorIds[i]]; - clusterIndex += operator.snapshot.index + (uint64(block.number) - operator.snapshot.block) * operator.fee; - unchecked { ++i; } - } - } - - _validateHashedCluster(owner, operatorIds, cluster); - - return _clusterBalance(cluster, clusterIndex).expand(); - } - - /*******************************/ - /* DAO External View Functions */ - /*******************************/ - - function getNetworkFee() external view override returns (uint256) { - return _networkFee.expand(); - } - - function getNetworkEarnings() external view override returns (uint256) { - DAO memory dao = _dao; - return _networkBalance(dao).expand(); - } - - function getOperatorFeeIncreaseLimit() - external - view - override - returns (uint64) - { - return _operatorMaxFeeIncrease; - } - - function getExecuteOperatorFeePeriod() - external - view - override - returns (uint64) - { - return _executeOperatorFeePeriod; - } - - function getDeclaredOperatorFeePeriod() - external - view - override - returns (uint64) - { - return _declareOperatorFeePeriod; - } - - function getLiquidationThresholdPeriod() - external - view - override - returns (uint64) - { - return _minimumBlocksBeforeLiquidation; - } - /********************************/ /* Validation Private Functions */ /********************************/ function _onlyOperatorOwnerOrContractOwner(uint64 operatorId) private view { - Operator memory operator = _operators[operatorId]; + Operator memory operator = operators[operatorId]; - if(operator.snapshot.block == 0) { + if (operator.snapshot.block == 0) { revert OperatorDoesNotExist(); } @@ -856,112 +843,27 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { } function _validateOperatorIds(uint operatorsLength) private pure { - if (operatorsLength < 4 || operatorsLength > 13 || operatorsLength % 3 != 1) { + if ( + operatorsLength < 4 || + operatorsLength > 13 || + operatorsLength % 3 != 1 + ) { revert InvalidOperatorIdsLength(); } } - function _validateClusterIsNotLiquidated(Cluster memory cluster) private pure { - if (cluster.disabled) { - revert ClusterIsLiquidated(); - } - } - /******************************/ /* Operator Private Functions */ /******************************/ - function _setFee( - Operator memory operator, - uint64 fee - ) private view returns (Operator memory) { - operator.snapshot = _getSnapshot(operator, uint64(block.number)); - operator.fee = fee; - - return operator; - } - - function _updateOperatorFeeUnsafe(uint64 operatorId, uint64 fee) private { - Operator memory operator = _operators[operatorId]; - - _operators[operatorId] = _setFee(operator, fee); - - emit OperatorFeeExecuted( - msg.sender, - operatorId, - block.number, - fee.expand() - ); - } - - function _getSnapshot( - Operator memory operator, - uint64 currentBlock - ) private pure returns (Snapshot memory) { - uint64 blockDiffFee = (currentBlock - operator.snapshot.block) * - operator.fee; - - operator.snapshot.index += blockDiffFee; - operator.snapshot.balance += blockDiffFee * operator.validatorCount; - operator.snapshot.block = currentBlock; - - return operator.snapshot; - } - function _transferOperatorBalanceUnsafe( uint64 operatorId, uint256 amount ) private { - _token.transfer(msg.sender, amount); - emit OperatorWithdrawn(amount, operatorId, msg.sender); - } - - /*****************************/ - /* Cluster Private Functions */ - /*****************************/ - - function _validateHashedCluster(address owner, uint64[] memory operatorIds, Cluster memory cluster) private view returns (bytes32) { - bytes32 hashedCluster = keccak256(abi.encodePacked(owner, operatorIds)); - { - bytes32 hashedClusterData = keccak256(abi.encodePacked(cluster.validatorCount, cluster.networkFee, cluster.networkFeeIndex, cluster.index, cluster.balance, cluster.disabled )); - if (_clusters[hashedCluster] == bytes32(0)) { - revert ClusterDoesNotExists(); - } else if (_clusters[hashedCluster] != hashedClusterData) { - revert IncorrectClusterState(); - } + if (!_token.transfer(msg.sender, amount)) { + revert TokenTransferFailed(); } - - return hashedCluster; - } - - function _updateClusterData(Cluster memory cluster, uint64 clusterIndex, int8 changedTo) private view returns (Cluster memory) { - if (!cluster.disabled) { - cluster.balance = _clusterBalance(cluster, clusterIndex); - cluster.index = clusterIndex; - - cluster.networkFee = _clusterNetworkFee(cluster.networkFee, cluster.networkFeeIndex, cluster.validatorCount); - cluster.networkFeeIndex = _currentNetworkFeeIndex(); - } - - if (changedTo == 1) { - ++cluster.validatorCount; - } else if (changedTo == -1) { - --cluster.validatorCount; - } - - return cluster; - } - - function _liquidatable( - uint64 balance, - uint64 validatorCount, - uint64 burnRate - ) private view returns (bool) { - return - balance < - _minimumBlocksBeforeLiquidation * - (burnRate + _networkFee) * - validatorCount; + emit OperatorWithdrawn(amount, operatorId, msg.sender); } /*****************************/ @@ -969,55 +871,8 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { /*****************************/ function _deposit(uint64 amount) private { - _token.transferFrom(msg.sender, address(this), amount.expand()); - } - - function _updateNetworkFeeIndex() private { - _networkFeeIndex = _currentNetworkFeeIndex(); - _networkFeeIndexBlockNumber = uint64(block.number); - } - - function _updateDAOEarnings( - DAO memory dao - ) private view returns (DAO memory) { - dao.earnings.balance = _networkTotalEarnings(dao); - dao.earnings.block = uint64(block.number); - - return dao; - } - - function _currentNetworkFeeIndex() private view returns (uint64) { - return - _networkFeeIndex + - uint64(block.number - _networkFeeIndexBlockNumber) * - _networkFee; - } - - function _networkTotalEarnings( - DAO memory dao - ) private view returns (uint64) { - return - dao.earnings.balance + - (uint64(block.number) - dao.earnings.block) * - _networkFee * - dao.validatorCount; - } - - function _networkBalance(DAO memory dao) private view returns (uint64) { - return _networkTotalEarnings(dao) - dao.withdrawn; - } - - function _clusterBalance(Cluster memory cluster, uint64 newIndex) private view returns (uint64) { - uint64 usage = (newIndex - cluster.index) * cluster.validatorCount + _clusterNetworkFee(cluster.networkFee, cluster.networkFeeIndex, cluster.validatorCount); - - if (usage > cluster.balance) { - revert InsufficientFunds(); + if (!_token.transferFrom(msg.sender, address(this), amount.expand())) { + revert TokenTransferFailed(); } - - return cluster.balance - usage; - } - - function _clusterNetworkFee(uint64 networkFee, uint64 networkFeeIndex, uint32 validatorCount) private view returns (uint64) { - return networkFee + uint64(_currentNetworkFeeIndex() - networkFeeIndex) * validatorCount; } } diff --git a/contracts/SSVNetworkViews.sol b/contracts/SSVNetworkViews.sol new file mode 100644 index 00000000..1eb95136 --- /dev/null +++ b/contracts/SSVNetworkViews.sol @@ -0,0 +1,287 @@ +// File: contracts/SSVRegistry.sol +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity 0.8.16; + +import "./SSVNetwork.sol"; +import "./ISSVNetworkViews.sol"; +import "./libraries/Types.sol"; +import "./libraries/ClusterLib.sol"; +import "./libraries/OperatorLib.sol"; +import "./libraries/NetworkLib.sol"; + +import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; + +contract SSVNetworkViews is + UUPSUpgradeable, + OwnableUpgradeable, + ISSVNetworkViews +{ + using Types256 for uint256; + using Types64 for uint64; + using ClusterLib for Cluster; + using OperatorLib for Operator; + using NetworkLib for DAO; + + SSVNetwork _ssvNetwork; + + // @dev reserve storage space for future new state variables in base contract + uint256[50] __gap; + + function _authorizeUpgrade(address) internal override onlyOwner {} + + function initialize(SSVNetwork ssvNetwork_) external initializer onlyProxy { + __UUPSUpgradeable_init(); + __Ownable_init_unchained(); + _ssvNetwork = ssvNetwork_; + } + + /************************************/ + /* Operator External View Functions */ + /************************************/ + + function getOperatorFee( + uint64 operatorId + ) external view override returns (uint256) { + (, uint64 fee, , Snapshot memory snapshot) = _ssvNetwork.operators( + operatorId + ); + if (snapshot.block == 0) revert OperatorDoesNotExist(); + + return fee.expand(); + } + + function getOperatorDeclaredFee( + uint64 operatorId + ) external view override returns (uint256, uint256, uint256) { + ( + uint64 fee, + uint64 approvalBeginTime, + uint64 approvalEndTime + ) = _ssvNetwork.operatorFeeChangeRequests(operatorId); + + if (fee == 0) { + revert NoFeeDelcared(); + } + + return (fee.expand(), approvalBeginTime, approvalEndTime); + } + + function getOperatorById( + uint64 operatorId + ) external view override returns (address, uint256, uint32) { + ( + address operatorOwner, + uint64 fee, + uint32 validatorCount, + + ) = _ssvNetwork.operators(operatorId); + if (operatorOwner == address(0)) revert OperatorDoesNotExist(); + + return (operatorOwner, fee.expand(), validatorCount); + } + + /***********************************/ + /* Cluster External View Functions */ + /***********************************/ + + function isLiquidatable( + address owner, + uint64[] calldata operatorIds, + Cluster memory cluster + ) external view override returns (bool) { + uint64 clusterIndex; + uint64 burnRate; + uint operatorsLength = operatorIds.length; + for (uint i; i < operatorsLength; ++i) { + (, uint64 fee, , Snapshot memory snapshot) = _ssvNetwork.operators( + operatorIds[i] + ); + clusterIndex += + snapshot.index + + (uint64(block.number) - snapshot.block) * + fee; + burnRate += fee; + } + + cluster.validateHashedCluster(owner, operatorIds, _ssvNetwork); + + ( + uint64 networkFee, + uint64 networkFeeIndex, + uint64 networkFeeIndexBlockNumber + ) = _ssvNetwork.network(); + + cluster.balance = cluster.clusterBalance( + clusterIndex, + NetworkLib.currentNetworkFeeIndex( + Network(networkFee, networkFeeIndex, networkFeeIndexBlockNumber) + ) + ); + return + cluster.liquidatable( + burnRate, + networkFee, + _ssvNetwork.minimumBlocksBeforeLiquidation() + ); + } + + function isLiquidated( + address owner, + uint64[] calldata operatorIds, + Cluster memory cluster + ) external view override returns (bool) { + cluster.validateHashedCluster(owner, operatorIds, _ssvNetwork); + + return cluster.disabled; + } + + function getClusterBurnRate( + uint64[] calldata operatorIds + ) external view returns (uint256) { + uint64 burnRate; + uint operatorsLength = operatorIds.length; + for (uint i; i < operatorsLength; ++i) { + (address operatorOwner, uint64 fee, , ) = _ssvNetwork.operators( + operatorIds[i] + ); + if (operatorOwner != address(0)) { + burnRate += fee; + } + } + return burnRate.expand(); + } + + /***********************************/ + /* Balance External View Functions */ + /***********************************/ + + function getOperatorEarnings( + uint64 id + ) external view override returns (uint256) { + ( + address operatorOwner, + uint64 fee, + uint32 validatorCount, + Snapshot memory snapshot + ) = _ssvNetwork.operators(id); + + Operator memory operator = Operator({ + owner: operatorOwner, + fee: fee, + snapshot: Snapshot({ + block: snapshot.block, + index: snapshot.index, + balance: snapshot.balance + }), + validatorCount: validatorCount + }); + + operator.getSnapshot(); + return operator.snapshot.balance.expand(); + } + + function getBalance( + address owner, + uint64[] calldata operatorIds, + Cluster memory cluster + ) external view override returns (uint256) { + cluster.validateClusterIsNotLiquidated(); + + uint64 clusterIndex; + { + uint operatorsLength = operatorIds.length; + for (uint i; i < operatorsLength; ++i) { + (, uint64 fee, , Snapshot memory snapshot) = _ssvNetwork + .operators(operatorIds[i]); + clusterIndex += + snapshot.index + + (uint64(block.number) - snapshot.block) * + fee; + } + } + + cluster.validateHashedCluster(owner, operatorIds, _ssvNetwork); + + ( + uint64 networkFee, + uint64 networkFeeIndex, + uint64 networkFeeIndexBlockNumber + ) = _ssvNetwork.network(); + + uint64 currrentNetworkFeeIndex = NetworkLib.currentNetworkFeeIndex( + Network(networkFee, networkFeeIndex, networkFeeIndexBlockNumber) + ); + + return + cluster + .clusterBalance(clusterIndex, currrentNetworkFeeIndex) + .expand(); + } + + /*******************************/ + /* DAO External View Functions */ + /*******************************/ + + function getNetworkFee() external view override returns (uint256) { + (uint64 networkFee, , ) = _ssvNetwork.network(); + return networkFee.expand(); + } + + function getNetworkEarnings() external view override returns (uint256) { + ( + uint32 validatorCount, + uint64 withdrawn, + Snapshot memory snapshot + ) = _ssvNetwork.dao(); + + DAO memory dao = DAO({ + validatorCount: validatorCount, + withdrawn: withdrawn, + earnings: Snapshot({ + block: snapshot.block, + index: snapshot.index, + balance: snapshot.balance + }) + }); + (uint64 networkFee, , ) = _ssvNetwork.network(); + + return dao.networkBalance(networkFee).expand(); + } + + function getOperatorFeeIncreaseLimit() + external + view + override + returns (uint64) + { + return _ssvNetwork.operatorMaxFeeIncrease(); + } + + function getExecuteOperatorFeePeriod() + external + view + override + returns (uint64) + { + return _ssvNetwork.executeOperatorFeePeriod(); + } + + function getDeclaredOperatorFeePeriod() + external + view + override + returns (uint64) + { + return _ssvNetwork.declareOperatorFeePeriod(); + } + + function getLiquidationThresholdPeriod() + external + view + override + returns (uint64) + { + return _ssvNetwork.minimumBlocksBeforeLiquidation(); + } +} diff --git a/contracts/libraries/ClusterLib.sol b/contracts/libraries/ClusterLib.sol new file mode 100644 index 00000000..aeebe8c6 --- /dev/null +++ b/contracts/libraries/ClusterLib.sol @@ -0,0 +1,103 @@ +// File: contracts/SSVNetwork.sol +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity 0.8.16; + +import "../ISSVNetworkCore.sol"; +import "../SSVNetwork.sol"; + +library ClusterLib { + function clusterBalance( + ISSVNetworkCore.Cluster memory cluster, + uint64 newIndex, + uint64 currentNetworkFeeIndex + ) internal pure returns (uint64 balance) { + uint64 networkFee = cluster.networkFee + + uint64(currentNetworkFeeIndex - cluster.networkFeeIndex) * + cluster.validatorCount; + uint64 usage = (newIndex - cluster.index) * + cluster.validatorCount + + networkFee; + + if (usage > cluster.balance) { + revert ISSVNetworkCore.InsufficientFunds(); + } + + balance = cluster.balance - usage; + } + + function liquidatable( + ISSVNetworkCore.Cluster memory cluster, + uint64 burnRate, + uint64 networkFee, + uint64 minimumBlocksBeforeLiquidation + ) internal pure returns (bool) { + return + cluster.balance < + minimumBlocksBeforeLiquidation * + (burnRate + networkFee) * + cluster.validatorCount; + } + + function validateClusterIsNotLiquidated( + ISSVNetworkCore.Cluster memory cluster + ) internal pure { + if (cluster.disabled) { + revert ISSVNetworkCore.ClusterIsLiquidated(); + } + } + + function validateHashedCluster( + ISSVNetworkCore.Cluster memory cluster, + address owner, + uint64[] memory operatorIds, + SSVNetwork ssvNetwork + ) internal view returns (bytes32) { + bytes32 hashedCluster = keccak256(abi.encodePacked(owner, operatorIds)); + bytes32 hashedClusterData = keccak256( + abi.encodePacked( + cluster.validatorCount, + cluster.networkFee, + cluster.networkFeeIndex, + cluster.index, + cluster.balance, + cluster.disabled + ) + ); + + if (ssvNetwork.clusters(hashedCluster) == bytes32(0)) { + revert ISSVNetworkCore.ClusterDoesNotExists(); + } else if (ssvNetwork.clusters(hashedCluster) != hashedClusterData) { + revert ISSVNetworkCore.IncorrectClusterState(); + } + + return hashedCluster; + } + + function updateClusterData( + ISSVNetworkCore.Cluster memory cluster, + uint64 clusterIndex, + uint64 currentNetworkFeeIndex, + int8 changedTo + ) internal pure { + if (!cluster.disabled) { + cluster.balance = clusterBalance( + cluster, + clusterIndex, + currentNetworkFeeIndex + ); + cluster.index = clusterIndex; + + cluster.networkFee = + cluster.networkFee + + uint64(currentNetworkFeeIndex - cluster.networkFeeIndex) * + cluster.validatorCount; + cluster.networkFeeIndex = currentNetworkFeeIndex; + } + + if (changedTo == 1) { + ++cluster.validatorCount; + } else if (changedTo == -1) { + --cluster.validatorCount; + } + } +} diff --git a/contracts/libraries/NetworkLib.sol b/contracts/libraries/NetworkLib.sol new file mode 100644 index 00000000..c7128c83 --- /dev/null +++ b/contracts/libraries/NetworkLib.sol @@ -0,0 +1,45 @@ +// File: contracts/SSVNetwork.sol +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity 0.8.16; + +import "../ISSVNetworkCore.sol"; +import "../SSVNetwork.sol"; + +library NetworkLib { + function networkBalance( + ISSVNetworkCore.DAO memory dao, + uint64 networkFee + ) internal view returns (uint64) { + return networkTotalEarnings(dao, networkFee) - dao.withdrawn; + } + + function updateDAOEarnings( + ISSVNetworkCore.DAO memory dao, + uint64 networkFee + ) internal view returns (ISSVNetworkCore.DAO memory) { + dao.earnings.balance = networkTotalEarnings(dao, networkFee); + dao.earnings.block = uint64(block.number); + + return dao; + } + + function networkTotalEarnings( + ISSVNetworkCore.DAO memory dao, + uint64 networkFee + ) internal view returns (uint64) { + return + dao.earnings.balance + + (uint64(block.number) - dao.earnings.block) * + networkFee * + dao.validatorCount; + } + + function currentNetworkFeeIndex( + ISSVNetworkCore.Network memory network + ) internal view returns (uint64) { + return + network.networkFeeIndex + + uint64(block.number - network.networkFeeIndexBlockNumber) * + network.networkFee; + } +} diff --git a/contracts/libraries/OperatorLib.sol b/contracts/libraries/OperatorLib.sol new file mode 100644 index 00000000..771e3607 --- /dev/null +++ b/contracts/libraries/OperatorLib.sol @@ -0,0 +1,18 @@ +// File: contracts/SSVNetwork.sol +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity 0.8.16; + +import "../ISSVNetworkCore.sol"; + +library OperatorLib { + function getSnapshot( + ISSVNetworkCore.Operator memory operator + ) internal view { + uint64 blockDiffFee = (uint64(block.number) - operator.snapshot.block) * + operator.fee; + + operator.snapshot.index += blockDiffFee; + operator.snapshot.balance += blockDiffFee * operator.validatorCount; + operator.snapshot.block = uint64(block.number); + } +} diff --git a/contracts/utils/Types.sol b/contracts/libraries/Types.sol similarity index 76% rename from contracts/utils/Types.sol rename to contracts/libraries/Types.sol index ae6fe43f..690ad753 100644 --- a/contracts/utils/Types.sol +++ b/contracts/libraries/Types.sol @@ -2,7 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later pragma solidity 0.8.16; -uint256 constant DEDUCTED_DIGITS = 10000000; +uint256 constant DEDUCTED_DIGITS = 10_000_000; library Types64 { function expand(uint64 value) internal pure returns (uint256) { @@ -16,10 +16,7 @@ library Types256 { } function shrinkable(uint256 value) internal pure returns (uint256) { - require( - value % DEDUCTED_DIGITS == 0, - "Max precision exceeded" - ); + require(value % DEDUCTED_DIGITS == 0, "Max precision exceeded"); return value; } } diff --git a/contracts/mocks/SSVNetworkBasicUpgrade.sol b/contracts/mocks/SSVNetworkBasicUpgrade.sol new file mode 100644 index 00000000..8efbf0c1 --- /dev/null +++ b/contracts/mocks/SSVNetworkBasicUpgrade.sol @@ -0,0 +1,17 @@ +// File: contracts/SSVRegistry.sol +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity 0.8.16; + +import "../SSVNetwork.sol"; + +contract SSVNetworkBasicUpgrade is SSVNetwork { + uint256 public operatorsUpdated; + + function resetOperatorFee(uint64 operatorId) external { + if (operators[operatorId].snapshot.block != 0) { + operators[operatorId].fee = 0; + + ++operatorsUpdated; + } + } +} diff --git a/contracts/mocks/SSVNetworkLibUpgrade.sol b/contracts/mocks/SSVNetworkLibUpgrade.sol new file mode 100644 index 00000000..5141ae0d --- /dev/null +++ b/contracts/mocks/SSVNetworkLibUpgrade.sol @@ -0,0 +1,24 @@ +// File: contracts/SSVRegistry.sol +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity 0.8.16; + +import "../SSVNetwork.sol"; +import "./libraries/NetworkLibUpgrade.sol"; + +contract SSVNetworkLibUpgrade is SSVNetwork { + using NetworkLibUpgrade for DAO; + + function getFixedNetworkRawBalance() external view returns (uint64) { + DAO memory dao = ISSVNetworkCore.DAO({ + validatorCount: 0, + withdrawn: 0, + earnings: ISSVNetworkCore.Snapshot({ + block: uint64(block.number), + index: 0, + balance: 100 + }) + }); + + return dao.networkRawBalance(); + } +} diff --git a/contracts/mocks/SSVNetworkReinitializable.sol b/contracts/mocks/SSVNetworkReinitializable.sol new file mode 100644 index 00000000..b14ff526 --- /dev/null +++ b/contracts/mocks/SSVNetworkReinitializable.sol @@ -0,0 +1,13 @@ +// File: contracts/SSVRegistry.sol +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity 0.8.16; + +import "../SSVNetwork.sol"; + +contract SSVNetworkReinitializable is SSVNetwork { + uint256 public count; + + function initializeV2() reinitializer(2) public { + count = 100; + } +} diff --git a/contracts/mocks/SSVNetworkViewsBasicUpgrade.sol b/contracts/mocks/SSVNetworkViewsBasicUpgrade.sol new file mode 100644 index 00000000..24b0f928 --- /dev/null +++ b/contracts/mocks/SSVNetworkViewsBasicUpgrade.sol @@ -0,0 +1,16 @@ +// File: contracts/SSVRegistry.sol +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity 0.8.16; + +import "../SSVNetworkViews.sol"; + +contract SSVNetworkViewsBasicUpgrade is SSVNetworkViews { + function getOperatorOwnerdById( + uint64 operatorId + ) external view returns (address) { + (address operatorOwner, , , ) = _ssvNetwork.operators(operatorId); + if (operatorOwner == address(0)) revert ISSVNetworkCore.OperatorDoesNotExist(); + + return operatorOwner; + } +} diff --git a/contracts/mocks/SSVNetworkViewsLibUpgrade.sol b/contracts/mocks/SSVNetworkViewsLibUpgrade.sol new file mode 100644 index 00000000..c3fc716c --- /dev/null +++ b/contracts/mocks/SSVNetworkViewsLibUpgrade.sol @@ -0,0 +1,25 @@ +// File: contracts/SSVRegistry.sol +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity 0.8.16; + +import "../SSVNetworkViews.sol"; +import "../ISSVNetworkCore.sol"; +import "./libraries/NetworkLibUpgrade.sol"; + +contract SSVNetworkViewsLibUpgrade is SSVNetworkViews { + using NetworkLibUpgrade for ISSVNetworkCore.DAO; + + function getFixedNetworkRawBalance() external view returns (uint64) { + ISSVNetworkCore.DAO memory dao = ISSVNetworkCore.DAO({ + validatorCount: 0, + withdrawn: 0, + earnings: ISSVNetworkCore.Snapshot({ + block: uint64(block.number), + index: 0, + balance: 100 + }) + }); + + return dao.networkRawBalance(); + } +} diff --git a/contracts/mocks/SSVNetworkViewsReinitializable.sol b/contracts/mocks/SSVNetworkViewsReinitializable.sol new file mode 100644 index 00000000..d2a68120 --- /dev/null +++ b/contracts/mocks/SSVNetworkViewsReinitializable.sol @@ -0,0 +1,13 @@ +// File: contracts/SSVRegistry.sol +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity 0.8.16; + +import "../SSVNetworkViews.sol"; + +contract SSVNetworkViewsReinitializable is SSVNetworkViews { + uint64 public validatorsPerOperatorListed; + + function initializeV2(uint64 newValidatorsPerOperatorListed) reinitializer(2) public { + validatorsPerOperatorListed = newValidatorsPerOperatorListed; + } +} diff --git a/contracts/mocks/libraries/NetworkLibUpgrade.sol b/contracts/mocks/libraries/NetworkLibUpgrade.sol new file mode 100644 index 00000000..b68c85fe --- /dev/null +++ b/contracts/mocks/libraries/NetworkLibUpgrade.sol @@ -0,0 +1,51 @@ +// File: contracts/SSVNetwork.sol +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity 0.8.16; + +import "../../ISSVNetwork.sol"; +import "../../SSVNetwork.sol"; + +library NetworkLibUpgrade { + + function networkRawBalance( + ISSVNetwork.DAO memory dao + ) internal pure returns (uint64) { + return dao.earnings.balance; + } + function networkBalance( + ISSVNetwork.DAO memory dao, + uint64 networkFee + ) internal view returns (uint64) { + return networkTotalEarnings(dao, networkFee) - dao.withdrawn; + } + + function updateDAOEarnings( + ISSVNetwork.DAO memory dao, + uint64 networkFee + ) internal view returns (ISSVNetwork.DAO memory) { + dao.earnings.balance = networkTotalEarnings(dao, networkFee); + dao.earnings.block = uint64(block.number); + + return dao; + } + + function networkTotalEarnings( + ISSVNetwork.DAO memory dao, + uint64 networkFee + ) internal view returns (uint64) { + return + dao.earnings.balance + + (uint64(block.number) - dao.earnings.block) * + networkFee * + dao.validatorCount; + } + + function currentNetworkFeeIndex( + ISSVNetwork.Network memory network + ) internal view returns (uint64) { + return + network.networkFeeIndex + + uint64(block.number - network.networkFeeIndexBlockNumber) * + network.networkFee; + } +} diff --git a/hardhat.config.ts b/hardhat.config.ts index 053a163d..cf68cacc 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -6,6 +6,7 @@ import '@openzeppelin/hardhat-upgrades'; import 'hardhat-tracer'; import '@nomiclabs/hardhat-solhint'; import 'hardhat-contract-sizer'; +import 'hardhat-storage-layout-changes'; const config: HardhatUserConfig = { // Your type-safe config goes here @@ -19,7 +20,7 @@ const config: HardhatUserConfig = { settings: { optimizer: { enabled: true, - runs: 1000 + runs: 2000 } } } diff --git a/package.json b/package.json index 28fb91ba..c1a8cf84 100644 --- a/package.json +++ b/package.json @@ -5,9 +5,11 @@ "lint:fix": "eslint --fix . --ext .ts", "solidity-coverage": "NO_GAS_ENFORCE=1 npx hardhat coverage", "test": "npx hardhat test", - "deploy-goerli": "npx hardhat run --network goerli scripts/ssv-network-deploy.ts", - "validate-upgrade-goerli": "npx hardhat run --network goerli scripts/ssv-network-validate-upgrade.ts", - "upgrade-goerli": "npx hardhat run --network goerli scripts/ssv-network-upgrade.ts", + "deploy-testnet": "npx hardhat run --network goerli scripts/deploy-all.ts", + "validate-upgrade-ssv-network-testnet": "npx hardhat run --network goerli scripts/validate-upgrade-ssv-network.ts", + "validate-upgrade-ssv-network-views-testnet": "npx hardhat run --network goerli scripts/validate-upgrade-ssv-network-views.ts", + "upgrade-ssv-network-testnet": "npx hardhat run --network goerli scripts/upgrade-ssv-network.ts", + "upgrade-ssv-network-views-testnet": "npx hardhat run --network goerli scripts/upgrade-ssv-network-views.ts", "slither": "slither contracts --solc-remaps @openzeppelin=node_modules/@openzeppelin" }, "devDependencies": { @@ -29,6 +31,7 @@ "gh-pages": "^3.2.3", "hardhat": "^2.12.5", "hardhat-contract-sizer": "^2.6.1", + "hardhat-storage-layout-changes": "^0.1.2", "hardhat-tracer": "^1.2.1", "prompts": "^2.4.2", "simple-git": "^3.10.0", diff --git a/scripts/deploy-all.ts b/scripts/deploy-all.ts new file mode 100644 index 00000000..ae30a513 --- /dev/null +++ b/scripts/deploy-all.ts @@ -0,0 +1,49 @@ +import { ethers, upgrades } from 'hardhat'; + +async function deploy() { + const ssvTokenAddress = process.env.SSVTOKEN_ADDRESS; + + const [deployer] = await ethers.getSigners(); + console.log(`Deploying contracts with the account:${deployer.address}`); + + // deploy SSVNetwork + const ssvNetworkFactory = await ethers.getContractFactory('SSVNetwork'); + console.log(`Deploying SSVNetwork with ssvToken ${ssvTokenAddress}`); + const ssvNetwork = await upgrades.deployProxy(ssvNetworkFactory, [ + ssvTokenAddress, + process.env.OPERATOR_MAX_FEE_INCREASE, + process.env.DECLARE_OPERATOR_FEE_PERIOD, + process.env.EXECUTE_OPERATOR_FEE_PERIOD, + process.env.MINIMUM_BLOCKS_BEFORE_LIQUIDATION + ], + { + kind: "uups" + }); + await ssvNetwork.deployed(); + console.log(`SSVNetwork proxy deployed to: ${ssvNetwork.address}`); + + let implAddress = await upgrades.erc1967.getImplementationAddress(ssvNetwork.address); + console.log(`SSVNetwork implementation deployed to: ${implAddress}`); + + // deploy SSVNetworkViews + const ssvViewsFactory = await ethers.getContractFactory('SSVNetworkViews'); + console.log(`Deploying SSVNetworkViews with SSVNetwork ${ssvNetwork.address}...`); + const viewsContract = await upgrades.deployProxy(ssvViewsFactory, [ + ssvNetwork.address + ], + { + kind: "uups" + }); + await viewsContract.deployed(); + console.log(`SSVNetworkViews proxy deployed to: ${viewsContract.address}`); + + implAddress = await upgrades.erc1967.getImplementationAddress(viewsContract.address); + console.log(`SSVNetworkViews implementation deployed to: ${implAddress}`); +} + +deploy() + .then(() => process.exit(0)) + .catch(error => { + console.error(error); + process.exit(1); + }); diff --git a/scripts/ssv-network-deploy.ts b/scripts/ssv-network-deploy.ts deleted file mode 100644 index b5264950..00000000 --- a/scripts/ssv-network-deploy.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { ethers, upgrades } from 'hardhat'; - -async function main() { - const ssvTokenAddress = process.env.SSVTOKEN_ADDRESS; - const ssvNetworkFactory = await ethers.getContractFactory('SSVNetwork'); - console.log(`Deploying SSVNetwork with ssvToken ${ssvTokenAddress}...`); - const contract = await upgrades.deployProxy(ssvNetworkFactory, [ - ssvTokenAddress, - process.env.OPERATOR_MAX_FEE_INCREASE, - process.env.DECLARE_OPERATOR_FEE_PERIOD, - process.env.EXECUTE_OPERATOR_FEE_PERIOD, - process.env.MINIMUM_BLOCKS_BEFORE_LIQUIDATION - ], - { - kind: "uups" - }); - await contract.deployed(); - console.log(`SSVNetwork deployed to: ${contract.address}`); -} - -main() - .then(() => process.exit(0)) - .catch(error => { - console.error(error); - process.exit(1); - }); diff --git a/scripts/upgrade-ssv-network-views.ts b/scripts/upgrade-ssv-network-views.ts new file mode 100644 index 00000000..77487839 --- /dev/null +++ b/scripts/upgrade-ssv-network-views.ts @@ -0,0 +1,19 @@ +const { ethers, upgrades } = require("hardhat"); + +async function upgradeSSVNetworkViews() { + const proxyAddress = process.env.SSVNETWORKVIEWS_PROXY_ADDRESS; + const [deployer] = await ethers.getSigners(); + console.log("Upgading contract with the account:", deployer.address); + + const SSVNetworkViews = await ethers.getContractFactory("SSVNetworkViews_V2"); + + await upgrades.upgradeProxy(proxyAddress, SSVNetworkViews, { kind: 'uups' }); + console.log("SSVNetworkViews upgraded successfully"); +} + +upgradeSSVNetworkViews() + .then(() => process.exit(0)) + .catch(error => { + console.error(error); + process.exit(1); + }); \ No newline at end of file diff --git a/scripts/ssv-network-upgrade.ts b/scripts/upgrade-ssv-network.ts similarity index 53% rename from scripts/ssv-network-upgrade.ts rename to scripts/upgrade-ssv-network.ts index ccd7a156..1dd8e31a 100644 --- a/scripts/ssv-network-upgrade.ts +++ b/scripts/upgrade-ssv-network.ts @@ -1,17 +1,15 @@ -const { ethers, upgrades } = require("hardhat"); +async function upgradeSSVNetwork() { + const proxyAddress = process.env.SSVNETWORK_PROXY_ADDRESS; + const [deployer] = await ethers.getSigners(); + console.log("Upgading contract with the account:", deployer.address); -async function main() { - const proxyAddress = process.env.PROXY_ADDRESS; - const SSVNetwork = await ethers.getContractFactory("SSVNetwork"); - - await upgrades.validateUpgrade(proxyAddress, SSVNetwork, { kind: 'uups' }); - console.log("Upgrading SSVNetwork..."); + const SSVNetwork = await ethers.getContractFactory("SSVNetwork_V2"); await upgrades.upgradeProxy(proxyAddress, SSVNetwork, { kind: 'uups' }); console.log("SSVNetwork upgraded successfully"); } -main() +upgradeSSVNetwork() .then(() => process.exit(0)) .catch(error => { console.error(error); diff --git a/scripts/validate-upgrade-ssv-network-views.ts b/scripts/validate-upgrade-ssv-network-views.ts new file mode 100644 index 00000000..6c488c04 --- /dev/null +++ b/scripts/validate-upgrade-ssv-network-views.ts @@ -0,0 +1,14 @@ +async function validateUpgradeSSVNetworkViews() { + const proxyAddress = process.env.SSVNETWORKVIEWS_PROXY_ADDRESS; + const SSVNetworkViews = await ethers.getContractFactory("SSVNetworkViews_V2"); + + await upgrades.validateUpgrade(proxyAddress, SSVNetworkViews, { kind: 'uups' }); + console.log("Contract validation finished"); +} + +validateUpgradeSSVNetworkViews() + .then(() => process.exit(0)) + .catch(error => { + console.error(error); + process.exit(1); + }); \ No newline at end of file diff --git a/scripts/ssv-network-validate-upgrade.ts b/scripts/validate-upgrade-ssv-network.ts similarity index 67% rename from scripts/ssv-network-validate-upgrade.ts rename to scripts/validate-upgrade-ssv-network.ts index 283839df..da3b8bfd 100644 --- a/scripts/ssv-network-validate-upgrade.ts +++ b/scripts/validate-upgrade-ssv-network.ts @@ -1,14 +1,12 @@ -const { ethers, upgrades } = require("hardhat"); - -async function main() { - const proxyAddress = process.env.PROXY_ADDRESS; - const SSVNetwork = await ethers.getContractFactory("SSVNetwork"); +async function validateUpgradeSSVNetwork() { + const proxyAddress = process.env.SSVNETWORK_PROXY_ADDRESS; + const SSVNetwork = await ethers.getContractFactory("SSVNetwork_V2"); await upgrades.validateUpgrade(proxyAddress, SSVNetwork, { kind: 'uups' }); console.log("Contract validation finished"); } -main() +validateUpgradeSSVNetwork() .then(() => process.exit(0)) .catch(error => { console.error(error); diff --git a/test/dao/liquidation-threshold.ts b/test/dao/liquidation-threshold.ts index 154f9db1..8e31e0a1 100644 --- a/test/dao/liquidation-threshold.ts +++ b/test/dao/liquidation-threshold.ts @@ -3,12 +3,14 @@ import * as helpers from '../helpers/contract-helpers'; import { expect } from 'chai'; // Declare globals -let ssvNetworkContract: any, networkFee: any; +let ssvNetworkContract: any, ssvViews: any, networkFee: any; describe('Liquidation Threshold Tests', () => { beforeEach(async () => { // Initialize contract - ssvNetworkContract = (await helpers.initializeContract()).contract; + const metadata = (await helpers.initializeContract()); + ssvNetworkContract = metadata.contract; + ssvViews = metadata.ssvViews; // Define minumum allowed network fee to pass shrinkable validation networkFee = helpers.CONFIG.minimalOperatorFee / 10; @@ -19,11 +21,11 @@ describe('Liquidation Threshold Tests', () => { }); it('Get liquidation threshold period', async () => { - expect(await ssvNetworkContract.getLiquidationThresholdPeriod()).to.equal(helpers.CONFIG.minimalBlocksBeforeLiquidation); + expect(await ssvViews.getLiquidationThresholdPeriod()).to.equal(helpers.CONFIG.minimalBlocksBeforeLiquidation); }); it('Change liquidation threshold period reverts "NewBlockPeriodIsBelowMinimum"', async () => { - await expect(ssvNetworkContract.updateLiquidationThresholdPeriod(helpers.CONFIG.minimalBlocksBeforeLiquidation - 10)).to.be.revertedWithCustomError(ssvNetworkContract,'NewBlockPeriodIsBelowMinimum'); + await expect(ssvNetworkContract.updateLiquidationThresholdPeriod(helpers.CONFIG.minimalBlocksBeforeLiquidation - 10)).to.be.revertedWithCustomError(ssvNetworkContract, 'NewBlockPeriodIsBelowMinimum'); }); it('Change liquidation threshold period reverts "caller is not the owner"', async () => { diff --git a/test/dao/network-fee-change.ts b/test/dao/network-fee-change.ts index c7319f15..a649a5a2 100644 --- a/test/dao/network-fee-change.ts +++ b/test/dao/network-fee-change.ts @@ -3,12 +3,14 @@ import * as helpers from '../helpers/contract-helpers'; import { expect } from 'chai'; // Declare globals -let ssvNetworkContract: any, networkFee: any; +let ssvNetworkContract: any, ssvViews: any, networkFee: any; describe('Network Fee Tests', () => { beforeEach(async () => { // Initialize contract - ssvNetworkContract = (await helpers.initializeContract()).contract; + const metadata = (await helpers.initializeContract()); + ssvNetworkContract = metadata.contract; + ssvViews = metadata.ssvViews; // Define minumum allowed network fee to pass shrinkable validation networkFee = helpers.CONFIG.minimalOperatorFee / 10; @@ -20,7 +22,7 @@ describe('Network Fee Tests', () => { }); it('Get network fee', async () => { - expect(await ssvNetworkContract.getNetworkFee()).to.equal(0); + expect(await ssvViews.getNetworkFee()).to.equal(0); }); it('Change the network fee to a number below the minimum fee reverts "Max precision exceeded"', async () => { diff --git a/test/dao/network-fee-withdraw.ts b/test/dao/network-fee-withdraw.ts index 494960a4..2fb19fdc 100644 --- a/test/dao/network-fee-withdraw.ts +++ b/test/dao/network-fee-withdraw.ts @@ -5,12 +5,14 @@ import { expect } from 'chai'; import { GasGroup } from '../helpers/gas-usage'; // Declare globals -let ssvNetworkContract: any, minDepositAmount: any, burnPerBlock: any, networkFee: any; +let ssvNetworkContract: any, ssvViews: any, minDepositAmount: any, burnPerBlock: any, networkFee: any; describe('DAO Network Fee Withdraw Tests', () => { beforeEach(async () => { // Initialize contract - ssvNetworkContract = (await helpers.initializeContract()).contract; + const metadata = (await helpers.initializeContract()); + ssvNetworkContract = metadata.contract; + ssvViews = metadata.ssvViews; // Define minumum allowed network fee to pass shrinkable validation networkFee = helpers.CONFIG.minimalOperatorFee; @@ -54,27 +56,27 @@ describe('DAO Network Fee Withdraw Tests', () => { }); it('Withdraw network earnings emits "NetworkEarningsWithdrawn"', async () => { - const amount = await ssvNetworkContract.getNetworkEarnings(); + const amount = await ssvViews.getNetworkEarnings(); await expect(ssvNetworkContract.withdrawNetworkEarnings(amount )).to.emit(ssvNetworkContract, 'NetworkEarningsWithdrawn').withArgs(amount, helpers.DB.owners[0].address); }); it('Get withdrawable network earnings', async () => { - expect(await ssvNetworkContract.getNetworkEarnings()).to.above(0); + expect(await ssvViews.getNetworkEarnings()).to.above(0); }); it('Get withdrawable network earnings as not owner', async () => { - await ssvNetworkContract.connect(helpers.DB.owners[3]).getNetworkEarnings(); + await ssvViews.connect(helpers.DB.owners[3]).getNetworkEarnings(); }); it('Withdraw network earnings with not enough balance reverts "InsufficientBalance"', async () => { - const amount = await ssvNetworkContract.getNetworkEarnings() * 2; + 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 ssvNetworkContract.getNetworkEarnings(); + const amount = await ssvViews.getNetworkEarnings(); await expect(ssvNetworkContract.connect(helpers.DB.owners[3]).withdrawNetworkEarnings(amount )).to.be.revertedWith('Ownable: caller is not the owner'); }); diff --git a/test/deployment/deploy.ts b/test/deployment/deploy.ts new file mode 100644 index 00000000..e7ab52da --- /dev/null +++ b/test/deployment/deploy.ts @@ -0,0 +1,153 @@ +// Imports +import { CONFIG, DB, initializeContract, DataGenerator } from '../helpers/contract-helpers'; +import { expect } from 'chai'; + +describe('Deployment tests', () => { + let ssvNetworkContract: any, ssvNetworkViews: any; + + beforeEach(async () => { + const metadata = (await initializeContract()); + ssvNetworkContract = metadata.contract; + ssvNetworkViews = metadata.ssvViews; + }); + + + it('Test initial deployment of SSVNetwork and SSVNetworkViews', async () => { + await ssvNetworkContract.connect(DB.owners[1]).registerOperator( + DataGenerator.publicKey(0), + CONFIG.minimalOperatorFee, + ); + + expect((await ssvNetworkViews.getOperatorById(1))[0]).to.equal(DB.owners[1].address); // owner + expect((await ssvNetworkViews.getOperatorById(1))[1]).to.equal(CONFIG.minimalOperatorFee); // fee + expect((await ssvNetworkViews.getOperatorById(1))[2]).to.equal(0); // validatorCount + }); + + it('Upgrade SSVNetwork contract failed when using not owner account', async () => { + const BasicUpgrade = await ethers.getContractFactory("SSVNetworkBasicUpgrade", DB.owners[2]); + await expect(upgrades.upgradeProxy(ssvNetworkContract.address, BasicUpgrade, { kind: 'uups' })).to.be.revertedWith('Ownable: caller is not the owner'); + }); + + 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' }); + await ssvNetworkUpgrade.deployed(); + + await ssvNetworkUpgrade.connect(DB.owners[1]).resetOperatorFee(1); + expect((await ssvNetworkViews.getOperatorById(1))[1]).to.equal(0); // fee + expect((await ssvNetworkUpgrade.operatorsUpdated())).to.equal(1); + }); + + 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' }); + 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', + 2000000, + 2000000, + 2000000, + 2000000)).to.be.revertedWith('Function must be called through delegatecall'); + }); + + it('Upgrade SSVNetwork contract with a new initializer', async () => { + const SSVNetworkReinitializable = await ethers.getContractFactory("SSVNetworkReinitializable"); + const ssvNetworkUpgrade = await upgrades.upgradeProxy(ssvNetworkContract.address, SSVNetworkReinitializable, { + kind: 'uups', + call: 'initializeV2' + }); + await ssvNetworkUpgrade.deployed(); + + expect((await ssvNetworkUpgrade.count())).to.equal(100); + }); + + it('Upgrade SSVNetwork contract reusing initializer version', async () => { + const SSVNetworkReinitializable = await ethers.getContractFactory("SSVNetworkReinitializable"); + let ssvNetworkUpgrade = await upgrades.upgradeProxy(ssvNetworkContract.address, SSVNetworkReinitializable, { + kind: 'uups', + call: 'initializeV2' + }); + await ssvNetworkUpgrade.deployed(); + + await expect(upgrades.upgradeProxy(ssvNetworkContract.address, SSVNetworkReinitializable, { + kind: 'uups', + call: 'initializeV2' + })).to.be.revertedWith('Initializable: contract is already initialized'); + + }); + + it('Upgrade SSVNetworkViews contract failed when using not owner account', async () => { + const SSVNetworkViewsBasicUpgrade = await ethers.getContractFactory("SSVNetworkViewsBasicUpgrade", DB.owners[2]); + await expect(upgrades.upgradeProxy(ssvNetworkViews.address, SSVNetworkViewsBasicUpgrade, { kind: 'uups' })).to.be.revertedWith('Ownable: caller is not the owner'); + }); + + it('Upgrade SSVNetworkViews contract. Check new function execution', async () => { + await ssvNetworkContract.connect(DB.owners[1]).registerOperator( + DataGenerator.publicKey(0), + CONFIG.minimalOperatorFee, + ); + + const SSVNetworkViewsBasicUpgrade = await ethers.getContractFactory("SSVNetworkViewsBasicUpgrade"); + const ssvNetworkUpgrade = await upgrades.upgradeProxy(ssvNetworkViews.address, SSVNetworkViewsBasicUpgrade, { kind: 'uups' }); + await ssvNetworkUpgrade.deployed(); + + expect(await ssvNetworkUpgrade.connect(DB.owners[0]).getOperatorOwnerdById(1)).to.equal(DB.owners[1].address); + }); + + it('Upgrade SSVNetworkViews contract with a new initializer', async () => { + const SSVNetworkViewsReinitializable = await ethers.getContractFactory("SSVNetworkViewsReinitializable"); + const ssvNetworkUpgrade = await upgrades.upgradeProxy(ssvNetworkViews.address, SSVNetworkViewsReinitializable, { + kind: 'uups', + call: { + fn: 'initializeV2', + args: [4000] + } + }); + await ssvNetworkUpgrade.deployed(); + + expect((await ssvNetworkUpgrade.validatorsPerOperatorListed())).to.equal(4000); + }); + + it('Upgrade SSVNetworkViews contract reusing initializer version', async () => { + const SSVNetworkViewsReinitializable = await ethers.getContractFactory("SSVNetworkViewsReinitializable"); + let ssvNetworkUpgrade = await upgrades.upgradeProxy(ssvNetworkViews.address, SSVNetworkViewsReinitializable, { + kind: 'uups', + call: { + fn: 'initializeV2', + args: [4000] + } + }); + await ssvNetworkUpgrade.deployed(); + + await expect(upgrades.upgradeProxy(ssvNetworkViews.address, SSVNetworkViewsReinitializable, { + kind: 'uups', + call: { + fn: 'initializeV2', + args: [4000] + } + })).to.be.revertedWith('Initializable: contract is already initialized'); + + }); + + it('Update NetworkLib and updgrade SSVNetwork and SSVNetworkViews', async () => { + const SSVNetworkLibUpgrade = await ethers.getContractFactory("SSVNetworkLibUpgrade"); + const ssvNetworkUpgrade = await upgrades.upgradeProxy(ssvNetworkContract.address, SSVNetworkLibUpgrade, { kind: 'uups' }); + await ssvNetworkUpgrade.deployed(); + + const SSVNetworkViewsLibUpgrade = await ethers.getContractFactory("SSVNetworkViewsLibUpgrade"); + const ssvNetworkViewsUpgrade = await upgrades.upgradeProxy(ssvNetworkViews.address, SSVNetworkViewsLibUpgrade, { kind: 'uups' }); + await ssvNetworkViewsUpgrade.deployed(); + + expect(await ssvNetworkUpgrade.connect(DB.owners[0]).getFixedNetworkRawBalance()).to.equal(100); + expect(await ssvNetworkViewsUpgrade.connect(DB.owners[0]).getFixedNetworkRawBalance()).to.equal(100); + + }); +}); diff --git a/test/helpers/contract-helpers.ts b/test/helpers/contract-helpers.ts index 4067001e..80be0af5 100644 --- a/test/helpers/contract-helpers.ts +++ b/test/helpers/contract-helpers.ts @@ -76,6 +76,7 @@ export const initializeContract = async () => { operators: [], clusters: [], ssvNetwork: {}, + ssvViews: {}, ssvToken: {}, }; @@ -84,6 +85,7 @@ export const initializeContract = async () => { // Initialize contract const ssvNetwork = await ethers.getContractFactory('SSVNetwork'); + const ssvViews = await ethers.getContractFactory('SSVNetworkViews'); const ssvToken = await ethers.getContractFactory('SSVTokenMock'); DB.ssvToken = await ssvToken.deploy(); @@ -102,6 +104,15 @@ export const initializeContract = async () => { await DB.ssvNetwork.contract.deployed(); + DB.ssvViews.contract = await upgrades.deployProxy(ssvViews, [ + DB.ssvNetwork.contract.address + ], + { + kind: 'uups' + }); + + await DB.ssvViews.contract.deployed(); + DB.ssvNetwork.owner = DB.owners[0]; await DB.ssvToken.mint(DB.owners[1].address, '10000000000000000000'); @@ -111,7 +122,7 @@ export const initializeContract = async () => { await DB.ssvToken.mint(DB.owners[5].address, '10000000000000000000'); await DB.ssvToken.mint(DB.owners[6].address, '10000000000000000000'); - return { contract: DB.ssvNetwork.contract, owner: DB.ssvNetwork.owner, ssvToken: DB.ssvToken }; + 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]) => { diff --git a/test/helpers/gas-usage.ts b/test/helpers/gas-usage.ts index 098fa452..f67a236b 100644 --- a/test/helpers/gas-usage.ts +++ b/test/helpers/gas-usage.ts @@ -36,17 +36,17 @@ const MAX_GAS_PER_GROUP: any = { [GasGroup.REMOVE_OPERATOR]: 62000, [GasGroup.REMOVE_OPERATOR_WITH_WITHDRAW]: 62000, - [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]: 195000, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE]: 211500, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT]: 173750, + [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]: 196000, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE]: 213000, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT]: 175000, - [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_7]: 258000, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]: 275000, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_7]: 237000, + [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_7]: 259000, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]: 276500, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_7]: 238500, - [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_13]: 385000, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]: 402000, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_13]: 365000, + [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_13]: 386500, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]: 403500, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_13]: 365500, [GasGroup.REMOVE_VALIDATOR]: 120000, [GasGroup.TRANSFER_VALIDATOR_NEW_CLUSTER]: 400000, diff --git a/test/liquidate/liquidate.ts b/test/liquidate/liquidate.ts index dace376f..f3f619fb 100644 --- a/test/liquidate/liquidate.ts +++ b/test/liquidate/liquidate.ts @@ -4,13 +4,15 @@ import * as utils from '../helpers/utils'; import { expect } from 'chai'; import { trackGas, GasGroup } from '../helpers/gas-usage'; -let ssvNetworkContract: any, minDepositAmount: any, firstCluster: any; +let ssvNetworkContract: any, ssvViews: any, minDepositAmount: any, firstCluster: any; // Declare globals describe('Liquidate Tests', () => { beforeEach(async () => { // Initialize contract - ssvNetworkContract = (await helpers.initializeContract()).contract; + const metadata = (await helpers.initializeContract()); + ssvNetworkContract = metadata.contract; + ssvViews = metadata.ssvViews; // Register operators await helpers.registerOperators(0, 12, helpers.CONFIG.minimalOperatorFee); @@ -66,7 +68,7 @@ describe('Liquidate Tests', () => { it('Liquidatable with removed operator', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); await ssvNetworkContract.removeOperator(1); - expect(await ssvNetworkContract.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 () => { @@ -107,12 +109,16 @@ describe('Liquidate Tests', () => { ), [GasGroup.LIQUIDATE_POD]); const updatedCluster = liquidatedCluster.eventsByName.ClusterLiquidated[0].args; - expect(await ssvNetworkContract.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 ssvNetworkContract.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); }); it('Liquidate a cluster that is not liquidatable reverts "ClusterNotLiquidatable"', async () => { @@ -163,6 +169,6 @@ describe('Liquidate Tests', () => { ), [GasGroup.LIQUIDATE_POD]); const updatedCluster = liquidatedCluster.eventsByName.ClusterLiquidated[0].args; - await expect(ssvNetworkContract.isLiquidated(helpers.DB.owners[0].address, firstCluster.operatorIds, updatedCluster.cluster)).to.be.revertedWithCustomError(ssvNetworkContract,'ClusterDoesNotExists'); + await expect(ssvViews.isLiquidated(helpers.DB.owners[0].address, firstCluster.operatorIds, updatedCluster.cluster)).to.be.revertedWithCustomError(ssvNetworkContract,'ClusterDoesNotExists'); }); }); \ No newline at end of file diff --git a/test/operators/register.ts b/test/operators/register.ts index 86c1e711..bb449cb1 100644 --- a/test/operators/register.ts +++ b/test/operators/register.ts @@ -4,11 +4,13 @@ import { expect } from 'chai'; import { trackGas, GasGroup } from '../helpers/gas-usage'; // Declare globals -let ssvNetworkContract: any; +let ssvNetworkContract: any, ssvViews: any; describe('Register Operator Tests', () => { beforeEach(async () => { - ssvNetworkContract = (await helpers.initializeContract()).contract; + const metadata = (await helpers.initializeContract()); + ssvNetworkContract = metadata.contract; + ssvViews = metadata.ssvViews; }); it('Register operator emits "OperatorAdded"', async () => { @@ -32,9 +34,9 @@ describe('Register Operator Tests', () => { helpers.CONFIG.minimalOperatorFee, ), [GasGroup.REGISTER_OPERATOR]); - expect((await ssvNetworkContract.getOperatorById(1)).owner).to.equal(helpers.DB.owners[1].address); - expect((await ssvNetworkContract.getOperatorById(1)).fee).to.equal(helpers.CONFIG.minimalOperatorFee); - expect((await ssvNetworkContract.getOperatorById(1)).validatorCount).to.equal(0); + expect((await ssvViews.getOperatorById(1))[0]).to.equal(helpers.DB.owners[1].address); // owner + expect((await ssvViews.getOperatorById(1))[1]).to.equal(helpers.CONFIG.minimalOperatorFee); // fee + expect((await ssvViews.getOperatorById(1))[2]).to.equal(0); // validatorCount }); it('Get operator by id reverts "OperatorDoesNotExist"', async () => { @@ -43,7 +45,7 @@ describe('Register Operator Tests', () => { helpers.CONFIG.minimalOperatorFee, ), [GasGroup.REGISTER_OPERATOR]); - await expect(ssvNetworkContract.getOperatorById(3)).to.be.revertedWithCustomError(ssvNetworkContract,'OperatorDoesNotExist'); + await expect(ssvViews.getOperatorById(3)).to.be.revertedWithCustomError(ssvNetworkContract,'OperatorDoesNotExist'); }); it('Register an operator with a fee thats too low reverts "FeeTooLow"', async () => { diff --git a/test/operators/update-fee.ts b/test/operators/update-fee.ts index c9de0685..ebcedbbb 100644 --- a/test/operators/update-fee.ts +++ b/test/operators/update-fee.ts @@ -5,11 +5,14 @@ import { progressTime } from '../helpers/utils'; import { trackGas, GasGroup } from '../helpers/gas-usage'; // Declare globals -let ssvNetworkContract: any, initialFee: any; +let ssvNetworkContract: any, ssvViews: any, initialFee: any; describe('Operator Fee Tests', () => { beforeEach(async () => { - ssvNetworkContract = (await helpers.initializeContract()).contract; + const metadata = (await helpers.initializeContract()); + ssvNetworkContract = metadata.contract; + ssvViews = metadata.ssvViews; + initialFee = helpers.CONFIG.minimalOperatorFee * 10; await helpers.registerOperators(2, 1, initialFee); }); @@ -52,11 +55,11 @@ describe('Operator Fee Tests', () => { }); it('Get operator fee', async () => { - expect(await ssvNetworkContract.getOperatorFee(1)).to.equal(initialFee); + expect(await ssvViews.getOperatorFee(1)).to.equal(initialFee); }); it('Get fee from operator that does not exist reverts "OperatorDoesNotExist"', async () => { - await expect(ssvNetworkContract.getOperatorFee(12 + await expect(ssvViews.getOperatorFee(12 )).to.be.revertedWithCustomError(ssvNetworkContract,'OperatorDoesNotExist'); }); @@ -133,22 +136,22 @@ describe('Operator Fee Tests', () => { }); it('DAO get fee increase limit', async () => { - expect(await ssvNetworkContract.getOperatorFeeIncreaseLimit()).to.equal(helpers.CONFIG.operatorMaxFeeIncrease); + expect(await ssvViews.getOperatorFeeIncreaseLimit()).to.equal(helpers.CONFIG.operatorMaxFeeIncrease); }); it('DAO get declared fee', async () => { const newFee = initialFee + initialFee / 10; await trackGas(ssvNetworkContract.declareOperatorFee(1, newFee), [GasGroup.REGISTER_OPERATOR]); - const [feeDeclaredInContract] = await ssvNetworkContract.getOperatorDeclaredFee(1); + const [feeDeclaredInContract] = await ssvViews.getOperatorDeclaredFee(1); expect(feeDeclaredInContract).to.equal(newFee); }); it('DAO get declared fee period', async () => { - expect(await ssvNetworkContract.getDeclaredOperatorFeePeriod()).to.equal(helpers.CONFIG.declareOperatorFeePeriod); + expect(await ssvViews.getDeclaredOperatorFeePeriod()).to.equal(helpers.CONFIG.declareOperatorFeePeriod); }); it('DAO get execute fee period', async () => { - expect(await ssvNetworkContract.getExecuteOperatorFeePeriod()).to.equal(helpers.CONFIG.executeOperatorFeePeriod); + expect(await ssvViews.getExecuteOperatorFeePeriod()).to.equal(helpers.CONFIG.executeOperatorFeePeriod); }); it('Increase fee from an address thats not the DAO reverts "caller is not the owner"', async () => { @@ -168,7 +171,7 @@ describe('Operator Fee Tests', () => { it('DAO declared fee without a pending request reverts "NoFeeDelcared"', async () => { await trackGas(ssvNetworkContract.declareOperatorFee(1, initialFee + initialFee / 10), [GasGroup.REGISTER_OPERATOR]); - await expect(ssvNetworkContract.getOperatorDeclaredFee(2 + await expect(ssvViews.getOperatorDeclaredFee(2 )).to.be.revertedWithCustomError(ssvNetworkContract,'NoFeeDelcared'); }); }); \ No newline at end of file diff --git a/test/sanity/balances.ts b/test/sanity/balances.ts index aa4d06ee..904edfc3 100644 --- a/test/sanity/balances.ts +++ b/test/sanity/balances.ts @@ -4,13 +4,15 @@ import * as utils from '../helpers/utils'; import { expect } from 'chai'; import { GasGroup } from '../helpers/gas-usage'; -let ssvNetworkContract: 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 - ssvNetworkContract = (await helpers.initializeContract()).contract; + const metadata = (await helpers.initializeContract()); + ssvNetworkContract = metadata.contract; + ssvViews = metadata.ssvViews; // Register operators await helpers.registerOperators(0, 12, helpers.CONFIG.minimalOperatorFee); @@ -44,78 +46,78 @@ describe('Balance Tests', () => { ); cluster1 = await helpers.registerValidators(4, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); - initNetworkFeeBalance = await ssvNetworkContract.getNetworkEarnings(); + initNetworkFeeBalance = await ssvViews.getNetworkEarnings(); }); it('Check cluster balance in three blocks, one after the other', async () => { await utils.progressBlocks(1); - expect(await ssvNetworkContract.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 ssvNetworkContract.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 ssvNetworkContract.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 ssvNetworkContract.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 ssvNetworkContract.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 ssvNetworkContract.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 ssvNetworkContract.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 ssvNetworkContract.getNetworkEarnings() - initNetworkFeeBalance).to.equal(networkFee * 2); + expect(await ssvViews.getNetworkEarnings() - initNetworkFeeBalance).to.equal(networkFee * 2); await utils.progressBlocks(1); - expect(await ssvNetworkContract.getNetworkEarnings() - initNetworkFeeBalance).to.equal(networkFee * 4); + expect(await ssvViews.getNetworkEarnings() - initNetworkFeeBalance).to.equal(networkFee * 4); await utils.progressBlocks(1); - expect(await ssvNetworkContract.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 ssvNetworkContract.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 ssvNetworkContract.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 ssvNetworkContract.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 ssvNetworkContract.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 ssvNetworkContract.getOperatorEarnings(1)).to.equal(helpers.CONFIG.minimalOperatorFee * 2 + helpers.CONFIG.minimalOperatorFee * 2); - expect(await ssvNetworkContract.getOperatorEarnings(2)).to.equal(helpers.CONFIG.minimalOperatorFee * 2 + helpers.CONFIG.minimalOperatorFee * 2); - expect(await ssvNetworkContract.getOperatorEarnings(3)).to.equal(helpers.CONFIG.minimalOperatorFee * 2 + helpers.CONFIG.minimalOperatorFee * 2); - expect(await ssvNetworkContract.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 ssvNetworkContract.getOperatorEarnings(1)).to.equal(helpers.CONFIG.minimalOperatorFee * 4 + helpers.CONFIG.minimalOperatorFee * 2); - expect(await ssvNetworkContract.getOperatorEarnings(2)).to.equal(helpers.CONFIG.minimalOperatorFee * 4 + helpers.CONFIG.minimalOperatorFee * 2); - expect(await ssvNetworkContract.getOperatorEarnings(3)).to.equal(helpers.CONFIG.minimalOperatorFee * 4 + helpers.CONFIG.minimalOperatorFee * 2); - expect(await ssvNetworkContract.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 ssvNetworkContract.getOperatorEarnings(1)).to.equal(helpers.CONFIG.minimalOperatorFee * 6 + helpers.CONFIG.minimalOperatorFee * 2); - expect(await ssvNetworkContract.getOperatorEarnings(2)).to.equal(helpers.CONFIG.minimalOperatorFee * 6 + helpers.CONFIG.minimalOperatorFee * 2); - expect(await ssvNetworkContract.getOperatorEarnings(3)).to.equal(helpers.CONFIG.minimalOperatorFee * 6 + helpers.CONFIG.minimalOperatorFee * 2); - expect(await ssvNetworkContract.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 ssvNetworkContract.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 reverts "InsufficientFunds"', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation + 10); - await expect(ssvNetworkContract.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster)).to.be.revertedWithCustomError(ssvNetworkContract,'InsufficientFunds'); + await expect(ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster)).to.be.revertedWithCustomError(ssvNetworkContract,'InsufficientFunds'); }); }); \ No newline at end of file diff --git a/test/validators/register.ts b/test/validators/register.ts index 0f6487fe..fcba4b62 100644 --- a/test/validators/register.ts +++ b/test/validators/register.ts @@ -3,13 +3,14 @@ import * as helpers from '../helpers/contract-helpers'; import { expect } from 'chai'; import { trackGas, GasGroup } from '../helpers/gas-usage'; -// Declare globals -let ssvNetworkContract: any, minDepositAmount: any; +let ssvNetworkContract: any, ssvViews: any, minDepositAmount: any; describe('Register Validator Tests', () => { beforeEach(async () => { // Initialize contract - ssvNetworkContract = (await helpers.initializeContract()).contract; + const metadata = (await helpers.initializeContract()); + ssvNetworkContract = metadata.contract; + ssvViews = metadata.ssvViews; // Register operators await helpers.registerOperators(0, 14, helpers.CONFIG.minimalOperatorFee); @@ -414,11 +415,11 @@ describe('Register Validator Tests', () => { }); it('Get cluster burn rate', async () => { - expect(await ssvNetworkContract.getClusterBurnRate([1,2,3,4])).to.equal(helpers.CONFIG.minimalOperatorFee * 4); + expect(await ssvViews.getClusterBurnRate([1,2,3,4])).to.equal(helpers.CONFIG.minimalOperatorFee * 4); }); it('Get cluster burn rate when one of the operators does not exsit', async () => { - expect(await ssvNetworkContract.getClusterBurnRate([1,2,3,41])).to.equal(helpers.CONFIG.minimalOperatorFee * 3); + expect(await ssvViews.getClusterBurnRate([1,2,3,41])).to.equal(helpers.CONFIG.minimalOperatorFee * 3); }); it('Register validator with incorrect input data reverts "IncorrectClusterState"', async () => { @@ -557,4 +558,12 @@ describe('Register Validator Tests', () => { } )).to.be.revertedWithCustomError(ssvNetworkContract,'ValidatorAlreadyExists'); }); -}); \ No newline at end of file + + it('Get cluster burn rate', async () => { + expect(await ssvViews.getClusterBurnRate([1,2,3,4])).to.equal(helpers.CONFIG.minimalOperatorFee * 4); + }); + + it('Get cluster burn rate by not existed operator in the list', async () => { + expect(await ssvViews.getClusterBurnRate([1,2,3,41])).to.equal(helpers.CONFIG.minimalOperatorFee * 3); + }); +}); From da229c46013855a5381ba6cb936c90031d5fefe1 Mon Sep 17 00:00:00 2001 From: mtabasco Date: Thu, 9 Feb 2023 02:30:29 +0100 Subject: [PATCH 120/149] Add slither to CI pipeline - IO1-2233 (#177) add slither to CI pipeline --- .github/workflows/slither.yml | 16 ++++++++++++++++ contracts/SSVNetwork.sol | 23 +++++++++++------------ contracts/SSVNetworkViews.sol | 1 + package-lock.json | 17 +++++++++++++++++ 4 files changed, 45 insertions(+), 12 deletions(-) create mode 100644 .github/workflows/slither.yml diff --git a/.github/workflows/slither.yml b/.github/workflows/slither.yml new file mode 100644 index 00000000..9940415f --- /dev/null +++ b/.github/workflows/slither.yml @@ -0,0 +1,16 @@ +name: Slither Analysis +on: [push] +jobs: + analyze: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Run Slither + uses: crytic/slither-action@v0.2.0 + id: slither + with: + node-version: 16 + fail-on: high + slither-args: --exclude controlled-delegatecall \ No newline at end of file diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index 9edc0691..bb7dde07 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -60,6 +60,7 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { Network public network; // @dev reserve storage space for future new state variables in base contract + // slither-disable-next-line shadowing-state uint256[50] __gap; /*************/ @@ -514,9 +515,7 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { ) ); - if (!_token.transfer(msg.sender, cluster.balance.expand())) { - revert TokenTransferFailed(); - } + _transfer(msg.sender, cluster.balance.expand()); emit ClusterLiquidated(owner, operatorIds, cluster); } @@ -740,9 +739,7 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { ) ); - if (!_token.transfer(msg.sender, amount)) { - revert TokenTransferFailed(); - } + _transfer(msg.sender, amount); emit ClusterWithdrawn(msg.sender, operatorIds, amount, cluster); } @@ -781,9 +778,7 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { dao_.withdrawn += shrunkAmount; dao = dao_; - if (!_token.transfer(msg.sender, amount)) { - revert TokenTransferFailed(); - } + _transfer(msg.sender, amount); emit NetworkEarningsWithdrawn(amount, msg.sender); } @@ -860,9 +855,7 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { uint64 operatorId, uint256 amount ) private { - if (!_token.transfer(msg.sender, amount)) { - revert TokenTransferFailed(); - } + _transfer(msg.sender, amount); emit OperatorWithdrawn(amount, operatorId, msg.sender); } @@ -875,4 +868,10 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { revert TokenTransferFailed(); } } + + function _transfer(address to, uint256 amount) private { + if(!_token.transfer(to, amount)) { + revert TokenTransferFailed(); + } + } } diff --git a/contracts/SSVNetworkViews.sol b/contracts/SSVNetworkViews.sol index 1eb95136..3f6d9fdd 100644 --- a/contracts/SSVNetworkViews.sol +++ b/contracts/SSVNetworkViews.sol @@ -26,6 +26,7 @@ contract SSVNetworkViews is SSVNetwork _ssvNetwork; // @dev reserve storage space for future new state variables in base contract + // slither-disable-next-line shadowing-state uint256[50] __gap; function _authorizeUpgrade(address) internal override onlyOwner {} diff --git a/package-lock.json b/package-lock.json index ac8d21df..e7e2430f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,6 +24,7 @@ "gh-pages": "^3.2.3", "hardhat": "^2.12.5", "hardhat-contract-sizer": "^2.6.1", + "hardhat-storage-layout-changes": "^0.1.2", "hardhat-tracer": "^1.2.1", "prompts": "^2.4.2", "simple-git": "^3.10.0", @@ -6426,6 +6427,15 @@ "hardhat": "^2.0.2" } }, + "node_modules/hardhat-storage-layout-changes": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/hardhat-storage-layout-changes/-/hardhat-storage-layout-changes-0.1.2.tgz", + "integrity": "sha512-fWX2jykXoRha6vCDD21NkbrrjKJ8U9juCodf8PTMEDjTjpb+rfUzgZdFOVHpo9DHQTnobMGY5HlrmtEdwgFlTw==", + "dev": true, + "peerDependencies": { + "hardhat": "^2.0.0" + } + }, "node_modules/hardhat-tracer": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/hardhat-tracer/-/hardhat-tracer-1.2.1.tgz", @@ -16956,6 +16966,13 @@ "sha1": "^1.1.1" } }, + "hardhat-storage-layout-changes": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/hardhat-storage-layout-changes/-/hardhat-storage-layout-changes-0.1.2.tgz", + "integrity": "sha512-fWX2jykXoRha6vCDD21NkbrrjKJ8U9juCodf8PTMEDjTjpb+rfUzgZdFOVHpo9DHQTnobMGY5HlrmtEdwgFlTw==", + "dev": true, + "requires": {} + }, "hardhat-tracer": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/hardhat-tracer/-/hardhat-tracer-1.2.1.tgz", From 8a92030e2b78118b7eee06b3ea4552a568c75aba Mon Sep 17 00:00:00 2001 From: mtabasco Date: Thu, 9 Feb 2023 09:40:02 +0100 Subject: [PATCH 121/149] Limit max # validators per operator - IO1-2160 (#178) Allow to change max number of validators per operator via upgrade process --- README.md | 19 +++ contracts/ISSVNetwork.sol | 14 ++- contracts/SSVNetwork.sol | 10 +- contracts/libraries/Types.sol | 1 - .../mocks/SSVNetworkValidatorsPerOperator.sol | 11 ++ test/helpers/contract-helpers.ts | 65 +++++++--- test/operators/others.ts | 17 +++ test/validators/register.ts | 117 +++++++++++------- 8 files changed, 189 insertions(+), 65 deletions(-) create mode 100644 contracts/mocks/SSVNetworkValidatorsPerOperator.sol diff --git a/README.md b/README.md index f25e9b07..1a8ef1b0 100644 --- a/README.md +++ b/README.md @@ -240,3 +240,22 @@ npx hardhat run --network scripts/upgrade-ssv-network-views.ts Pay special attention when changing storage layout, for example adding new storage variables in `SSVNetwork` and `SSVNetworkViews` (base) contracts. There is a state variable `uint256[50] __gap;` that you should reduce the size according to the size of the new variables added. More info: [Storage Gaps](https://docs.openzeppelin.com/upgrades-plugins/1.x/writing-upgradeable#storage-gaps) + +### Modify the limit of validators that an operator can manage +In `SSVNetwork` contract, the state variable `validatorsPerOperatorLimit` is used to represent the máximum number of validators that can be registered per operator. Its default value is `2000`. + +To change it, the upgrade process should be fired. The assignement to a new value must be in a new initializer function. Pay special attention to the `reinitializer` modifier where there should be a number higher than the one consumed in previous initialized contracts. More info [here](https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-reinitializer-uint8-) +Example upgrade contract: +``` +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity 0.8.16; + +import "../SSVNetwork.sol"; + +contract SSVNetwork_v2 is SSVNetwork { + + function initializev2(uint32 validatorsPerOperatorLimit_) reinitializer(2) external { + validatorsPerOperatorLimit = validatorsPerOperatorLimit_; + } +} +``` \ No newline at end of file diff --git a/contracts/ISSVNetwork.sol b/contracts/ISSVNetwork.sol index f55c693b..22169936 100644 --- a/contracts/ISSVNetwork.sol +++ b/contracts/ISSVNetwork.sol @@ -1,4 +1,3 @@ -// File: contracts/ISSVNetwork.sol // SPDX-License-Identifier: GPL-3.0-or-later pragma solidity 0.8.16; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; @@ -83,15 +82,23 @@ interface ISSVNetwork is ISSVNetworkCore { ); event ClusterLiquidated( + address owner, + uint64[] operatorIds, + Cluster cluster + ); event ClusterReactivated( + address owner, + uint64[] operatorIds, + Cluster cluster + ); event OperatorFeeIncreaseLimitUpdated(uint64 value); @@ -117,10 +124,15 @@ interface ISSVNetwork is ISSVNetworkCore { event NetworkEarningsWithdrawn(uint256 value, address recipient); event ClusterWithdrawn( + address owner, + uint64[] operatorIds, + uint256 value, + Cluster cluster + ); event OperatorWithdrawn(uint256 value, uint64 operatorId, address owner); diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index bb7dde07..cd791d33 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -30,9 +30,8 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { /* Constants */ /*************/ - uint64 constant MINIMAL_LIQUIDATION_THRESHOLD = 6570; + uint64 constant MINIMAL_LIQUIDATION_THRESHOLD = 6_570; uint64 constant MINIMAL_OPERATOR_FEE = 100_000_000; - uint32 constant VALIDATORS_PER_OPERATOR_LIMIT = 2000; /********************/ /* Global Variables */ @@ -50,6 +49,7 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { mapping(bytes32 => bytes32) public clusters; mapping(bytes32 => Validator) private _validatorPKs; + uint32 public validatorsPerOperatorLimit; uint64 public declareOperatorFeePeriod; uint64 public executeOperatorFeePeriod; uint64 public operatorMaxFeeIncrease; @@ -106,6 +106,7 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { declareOperatorFeePeriod = declareOperatorFeePeriod_; executeOperatorFeePeriod = executeOperatorFeePeriod_; minimumBlocksBeforeLiquidation = minimumBlocksBeforeLiquidation_; + validatorsPerOperatorLimit = 2000; } /*****************/ @@ -299,10 +300,7 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { revert OperatorDoesNotExist(); } operator.getSnapshot(); - if ( - ++operator.validatorCount > - VALIDATORS_PER_OPERATOR_LIMIT - ) { + if (++operator.validatorCount > validatorsPerOperatorLimit) { revert ExceedValidatorLimit(); } clusterIndex += operator.snapshot.index; diff --git a/contracts/libraries/Types.sol b/contracts/libraries/Types.sol index 690ad753..20c1628f 100644 --- a/contracts/libraries/Types.sol +++ b/contracts/libraries/Types.sol @@ -1,4 +1,3 @@ -// File: contracts/SSVNetwork.sol // SPDX-License-Identifier: GPL-3.0-or-later pragma solidity 0.8.16; diff --git a/contracts/mocks/SSVNetworkValidatorsPerOperator.sol b/contracts/mocks/SSVNetworkValidatorsPerOperator.sol new file mode 100644 index 00000000..693b0a95 --- /dev/null +++ b/contracts/mocks/SSVNetworkValidatorsPerOperator.sol @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity 0.8.16; + +import "../SSVNetwork.sol"; + +contract SSVNetworkValidatorsPerOperator is SSVNetwork { + + function initializev2(uint32 validatorsPerOperatorLimit_) reinitializer(2) external { + validatorsPerOperatorLimit = validatorsPerOperatorLimit_; + } +} diff --git a/test/helpers/contract-helpers.ts b/test/helpers/contract-helpers.ts index 80be0af5..54a7cbab 100644 --- a/test/helpers/contract-helpers.ts +++ b/test/helpers/contract-helpers.ts @@ -19,17 +19,17 @@ const SHARES_RSA = [ ]; export const DataGenerator = { - publicKey: (index: number) => `0x${index.toString(16).padStart(96, '1')}`, + 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]; + case 7: + return SHARES_RSA[1]; + case 10: + return SHARES_RSA[2]; + case 13: + return SHARES_RSA[3]; + default: + return SHARES_RSA[0]; } }, cluster: { @@ -98,9 +98,9 @@ export const initializeContract = async () => { CONFIG.executeOperatorFeePeriod, CONFIG.minimalBlocksBeforeLiquidation ], - { - kind: 'uups' - }); + { + kind: 'uups' + }); await DB.ssvNetwork.contract.deployed(); @@ -167,7 +167,6 @@ export const registerValidators = async (ownerId: number, numberOfValidators: nu } ), gasGroups); args = result.eventsByName.ValidatorAdded[0].args; - DB.validators.push({ publicKey, operatorIds, shares }); validators.push({ publicKey, shares }); } @@ -175,9 +174,47 @@ export const registerValidators = async (ownerId: number, numberOfValidators: nu return { validators, args }; }; +export const registerValidatorsRaw = async (ownerId: number, numberOfValidators: number, amount: string, operatorIds: number[]) => { + + let cluster: any = { + validatorCount: 0, + networkFee: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + disabled: false + }; + + for (let i = 0; i < numberOfValidators; i++) { + const shares = DataGenerator.shares(4); + const publicKey = DataGenerator.publicKey(i); + + 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 + )); + + const clusterData = result.eventsByName.ValidatorAdded[0].args.cluster; + cluster = { + validatorCount: clusterData.validatorCount, + networkFee: clusterData.networkFee, + networkFeeIndex: clusterData.networkFeeIndex, + index: clusterData.index, + balance: clusterData.balance, + disabled: false + }; + + } +} + + export const getCluster = (payload: any) => ethers.utils.AbiCoder.prototype.encode( ['tuple(uint32 validatorCount, uint64 networkFee, uint64 networkFeeIndex, uint64 index, uint64 balance, bool disabled) cluster'], - [ payload ] + [payload] ); /* diff --git a/test/operators/others.ts b/test/operators/others.ts index 24eccad6..958002bd 100644 --- a/test/operators/others.ts +++ b/test/operators/others.ts @@ -17,4 +17,21 @@ describe('Others Operator Tests', () => { .to.emit(ssvNetworkContract, 'FeeRecipientAddressUpdated') .withArgs(helpers.DB.owners[1].address, helpers.DB.owners[2].address); }); + + it('Update max number of validators per operator', async () => { + expect((await ssvNetworkContract.validatorsPerOperatorLimit())).to.equal(2000); + + const SSVNetworkValidatorsPerOperator = await ethers.getContractFactory("SSVNetworkValidatorsPerOperator"); + const ssvNetwork = await upgrades.upgradeProxy(ssvNetworkContract.address, SSVNetworkValidatorsPerOperator, { + kind: 'uups', + call: { + fn: 'initializev2', + args: [50] + } + }); + await ssvNetwork.deployed(); + + expect((await ssvNetwork.validatorsPerOperatorLimit())).to.equal(50); + }); + }); \ No newline at end of file diff --git a/test/validators/register.ts b/test/validators/register.ts index fcba4b62..c9a8d6b2 100644 --- a/test/validators/register.ts +++ b/test/validators/register.ts @@ -20,8 +20,8 @@ describe('Register Validator Tests', () => { // cold register await helpers.DB.ssvToken.connect(helpers.DB.owners[6]).approve(helpers.DB.ssvNetwork.contract.address, '1000000000000000'); await ssvNetworkContract.connect(helpers.DB.owners[6]).registerValidator( - '0x221111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111119', - [1,2,3,4], + helpers.DataGenerator.publicKey(90), + [1, 2, 3, 4], helpers.DataGenerator.shares(4), '1000000000000000', { @@ -34,7 +34,7 @@ describe('Register Validator Tests', () => { } ); }); - + it('Register validator with 4 operators emits "ValidatorAdded"', async () => { await helpers.DB.ssvToken.approve(ssvNetworkContract.address, minDepositAmount); await expect(ssvNetworkContract.registerValidator( @@ -75,7 +75,7 @@ describe('Register Validator Tests', () => { 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], + [1, 2, 3, 4], helpers.DataGenerator.shares(4), minDepositAmount, { @@ -93,7 +93,7 @@ describe('Register Validator Tests', () => { 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], + [1, 2, 3, 4], helpers.DataGenerator.shares(4), minDepositAmount, args.cluster @@ -104,7 +104,7 @@ describe('Register Validator Tests', () => { 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], + [1, 2, 3, 4], helpers.DataGenerator.shares(4), minDepositAmount, { @@ -122,7 +122,7 @@ describe('Register Validator Tests', () => { 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], + [1, 2, 3, 4], helpers.DataGenerator.shares(4), minDepositAmount, args.cluster @@ -131,7 +131,7 @@ describe('Register Validator Tests', () => { 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], + [2, 3, 4, 5], helpers.DataGenerator.shares(4), minDepositAmount, { @@ -146,12 +146,12 @@ describe('Register Validator Tests', () => { }); 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}`); + 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], + [1, 2, 3, 4], helpers.DataGenerator.shares(4), - `${minDepositAmount*2}`, + `${minDepositAmount * 2}`, { validatorCount: 0, networkFee: 0, @@ -165,7 +165,7 @@ describe('Register Validator Tests', () => { const args = eventsByName.ValidatorAdded[0].args; await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( helpers.DataGenerator.publicKey(2), - [1,2,3,4], + [1, 2, 3, 4], helpers.DataGenerator.shares(4), 0, args.cluster @@ -196,7 +196,7 @@ describe('Register Validator Tests', () => { 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], + [1, 2, 3, 4, 5, 6, 7], helpers.DataGenerator.shares(7), minDepositAmount, { @@ -214,7 +214,7 @@ describe('Register Validator Tests', () => { 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], + [1, 2, 3, 4, 5, 6, 7], helpers.DataGenerator.shares(7), minDepositAmount, args.cluster @@ -225,7 +225,7 @@ describe('Register Validator Tests', () => { 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], + [1, 2, 3, 4, 5, 6, 7], helpers.DataGenerator.shares(7), minDepositAmount, { @@ -243,7 +243,7 @@ describe('Register Validator Tests', () => { 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], + [1, 2, 3, 4, 5, 6, 7], helpers.DataGenerator.shares(7), minDepositAmount, args.cluster @@ -252,7 +252,7 @@ describe('Register Validator Tests', () => { 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], + [2, 3, 4, 5, 6, 7, 8], helpers.DataGenerator.shares(7), minDepositAmount, { @@ -267,12 +267,12 @@ describe('Register Validator Tests', () => { }); 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}`); + 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], + [1, 2, 3, 4, 5, 6, 7], helpers.DataGenerator.shares(7), - `${minDepositAmount*2}`, + `${minDepositAmount * 2}`, { validatorCount: 0, networkFee: 0, @@ -286,7 +286,7 @@ describe('Register Validator Tests', () => { 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], + [1, 2, 3, 4, 5, 6, 7], helpers.DataGenerator.shares(7), 0, args.cluster @@ -317,7 +317,7 @@ describe('Register Validator Tests', () => { 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], + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], helpers.DataGenerator.shares(13), minDepositAmount, { @@ -335,7 +335,7 @@ describe('Register Validator Tests', () => { 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], + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], helpers.DataGenerator.shares(13), minDepositAmount, args.cluster @@ -346,7 +346,7 @@ describe('Register Validator Tests', () => { 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], + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], helpers.DataGenerator.shares(13), minDepositAmount, { @@ -364,7 +364,7 @@ describe('Register Validator Tests', () => { 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], + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], helpers.DataGenerator.shares(13), minDepositAmount, args.cluster @@ -373,7 +373,7 @@ describe('Register Validator Tests', () => { 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], + [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], helpers.DataGenerator.shares(13), minDepositAmount, { @@ -388,12 +388,12 @@ describe('Register Validator Tests', () => { }); 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}`); + 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], + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], helpers.DataGenerator.shares(13), - `${minDepositAmount*2}`, + `${minDepositAmount * 2}`, { validatorCount: 0, networkFee: 0, @@ -407,7 +407,7 @@ describe('Register Validator Tests', () => { 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], + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], helpers.DataGenerator.shares(13), 0, args.cluster @@ -423,7 +423,7 @@ describe('Register Validator Tests', () => { }); 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 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], @@ -452,7 +452,7 @@ describe('Register Validator Tests', () => { balance: 0, disabled: false } - )).to.be.revertedWithCustomError(ssvNetworkContract,'IncorrectClusterState'); + )).to.be.revertedWithCustomError(ssvNetworkContract, 'IncorrectClusterState'); }); it('Register validator when an operator does not exsit in the cluster reverts "OperatorDoesNotExist"', async () => { @@ -469,7 +469,7 @@ describe('Register Validator Tests', () => { balance: 0, disabled: false } - )).to.be.revertedWithCustomError(ssvNetworkContract,'OperatorDoesNotExist'); + )).to.be.revertedWithCustomError(ssvNetworkContract, 'OperatorDoesNotExist'); }); it('Register validator with a removed operator in the cluster reverts "OperatorDoesNotExist"', async () => { @@ -487,23 +487,23 @@ describe('Register Validator Tests', () => { balance: 0, disabled: false } - )).to.be.revertedWithCustomError(ssvNetworkContract,'OperatorDoesNotExist'); + )).to.be.revertedWithCustomError(ssvNetworkContract, 'OperatorDoesNotExist'); }); it('Register cluster with unsorted operators reverts "The operators list should be in ascending order"', async () => { - await expect(helpers.registerValidators(2, 1, minDepositAmount, [3, 2, 1, 4])).to.be.revertedWithCustomError(ssvNetworkContract,'UnsortedOperatorsList'); + await expect(helpers.registerValidators(2, 1, minDepositAmount, [3, 2, 1, 4])).to.be.revertedWithCustomError(ssvNetworkContract, 'UnsortedOperatorsList'); }); 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'); + 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'); + 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'); + 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 invalild public key reverts "InvalidPublicKeyLength"', async () => { @@ -520,7 +520,7 @@ describe('Register Validator Tests', () => { balance: 0, disabled: false } - )).to.be.revertedWithCustomError(ssvNetworkContract,'InvalidPublicKeyLength'); + )).to.be.revertedWithCustomError(ssvNetworkContract, 'InvalidPublicKeyLength'); }); it('Register validator with not enough balance reverts "InsufficientBalance"', async () => { @@ -538,14 +538,14 @@ describe('Register Validator Tests', () => { balance: 0, disabled: false } - )).to.be.revertedWithCustomError(ssvNetworkContract,'InsufficientBalance'); + )).to.be.revertedWithCustomError(ssvNetworkContract, 'InsufficientBalance'); }); it('Register an existing validator reverts "ValidatorAlreadyExists"', async () => { await helpers.DB.ssvToken.approve(ssvNetworkContract.address, helpers.CONFIG.minimalOperatorFee); await expect(ssvNetworkContract.connect(helpers.DB.owners[6]).registerValidator( - '0x221111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111119', - [1,2,3,4], + helpers.DataGenerator.publicKey(90), + [1, 2, 3, 4], helpers.DataGenerator.shares(4), minDepositAmount, { @@ -556,7 +556,38 @@ describe('Register Validator Tests', () => { balance: 0, disabled: false } - )).to.be.revertedWithCustomError(ssvNetworkContract,'ValidatorAlreadyExists'); + )).to.be.revertedWithCustomError(ssvNetworkContract, 'ValidatorAlreadyExists'); + }); + + it('Surpassing max number of validators per operator reverts "ExceedValidatorLimit"', async () => { + helpers.registerValidatorsRaw(2, 50, minDepositAmount, [8, 9, 10, 11]); + + const SSVNetworkValidatorsPerOperator = await ethers.getContractFactory("SSVNetworkValidatorsPerOperator"); + 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, + networkFee: 0, + networkFeeIndex: 0, + index: 0, + balance: 0, + disabled: false + } + )).to.be.revertedWithCustomError(ssvNetwork, 'ExceedValidatorLimit'); + }); it('Get cluster burn rate', async () => { From 4c4a9dc3d58c3b50bdbe3f40bf837d4c0da70072 Mon Sep 17 00:00:00 2001 From: Marco Date: Wed, 15 Feb 2023 11:22:53 +0100 Subject: [PATCH 122/149] emit uint256 cluster balance --- contracts/ISSVNetworkCore.sol | 2 +- contracts/ISSVNetworkViews.sol | 2 +- contracts/SSVNetwork.sol | 26 +++++++++++--------------- contracts/SSVNetworkViews.sol | 3 +-- contracts/libraries/ClusterLib.sol | 18 ++++++++++-------- test/account/deposit.ts | 12 ++++++------ 6 files changed, 30 insertions(+), 33 deletions(-) diff --git a/contracts/ISSVNetworkCore.sol b/contracts/ISSVNetworkCore.sol index 9f8671e6..576a74e9 100644 --- a/contracts/ISSVNetworkCore.sol +++ b/contracts/ISSVNetworkCore.sol @@ -39,7 +39,7 @@ interface ISSVNetworkCore { uint64 networkFee; uint64 networkFeeIndex; uint64 index; - uint64 balance; + uint256 balance; bool disabled; } diff --git a/contracts/ISSVNetworkViews.sol b/contracts/ISSVNetworkViews.sol index 1dc2635f..39709fd1 100644 --- a/contracts/ISSVNetworkViews.sol +++ b/contracts/ISSVNetworkViews.sol @@ -56,7 +56,7 @@ interface ISSVNetworkViews is ISSVNetworkCore { function getOperatorEarnings( uint64 id - ) external view returns (uint256 balance); + ) external view returns (uint256); function getBalance( address owner, diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index cd791d33..1074941c 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -318,7 +318,7 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { network_ ); - cluster.balance += amount.shrink(); + cluster.balance += amount; cluster.updateClusterData(clusterIndex, currentNetworkFeeIndex, 1); if ( @@ -352,7 +352,7 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { ); if (amount > 0) { - _deposit(amount.shrink()); + _deposit(amount); } emit ValidatorAdded( @@ -513,7 +513,7 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { ) ); - _transfer(msg.sender, cluster.balance.expand()); + _transfer(msg.sender, cluster.balance); emit ClusterLiquidated(owner, operatorIds, cluster); } @@ -557,7 +557,7 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { network ); - cluster.balance += amount.shrink(); + cluster.balance += amount; cluster.disabled = false; cluster.index = clusterIndex; @@ -594,7 +594,7 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { ); if (amount > 0) { - _deposit(amount.shrink()); + _deposit(amount); } emit ClusterReactivated(msg.sender, operatorIds, cluster); @@ -612,15 +612,13 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { ) external override { cluster.validateClusterIsNotLiquidated(); - uint64 shrunkAmount = amount.shrink(); - bytes32 hashedCluster = cluster.validateHashedCluster( owner, operatorIds, this ); - cluster.balance += shrunkAmount; + cluster.balance += amount; clusters[hashedCluster] = keccak256( abi.encodePacked( @@ -633,7 +631,7 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { ) ); - _deposit(shrunkAmount); + _deposit(amount); emit ClusterDeposited(owner, operatorIds, amount, cluster); } @@ -683,8 +681,6 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { ) external override { cluster.validateClusterIsNotLiquidated(); - uint64 shrunkAmount = amount.shrink(); - uint64 clusterIndex; uint64 burnRate; { @@ -714,7 +710,7 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { ); if ( - cluster.balance < shrunkAmount || + cluster.balance < amount || cluster.liquidatable( burnRate, network.networkFee, @@ -724,7 +720,7 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { revert InsufficientBalance(); } - cluster.balance -= shrunkAmount; + cluster.balance -= amount; clusters[hashedCluster] = keccak256( abi.encodePacked( @@ -861,8 +857,8 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { /* Balance Private Functions */ /*****************************/ - function _deposit(uint64 amount) private { - if (!_token.transferFrom(msg.sender, address(this), amount.expand())) { + function _deposit(uint256 amount) private { + if (!_token.transferFrom(msg.sender, address(this), amount)) { revert TokenTransferFailed(); } } diff --git a/contracts/SSVNetworkViews.sol b/contracts/SSVNetworkViews.sol index 3f6d9fdd..06ecd9dd 100644 --- a/contracts/SSVNetworkViews.sol +++ b/contracts/SSVNetworkViews.sol @@ -216,8 +216,7 @@ contract SSVNetworkViews is return cluster - .clusterBalance(clusterIndex, currrentNetworkFeeIndex) - .expand(); + .clusterBalance(clusterIndex, currrentNetworkFeeIndex); } /*******************************/ diff --git a/contracts/libraries/ClusterLib.sol b/contracts/libraries/ClusterLib.sol index aeebe8c6..8ba7e873 100644 --- a/contracts/libraries/ClusterLib.sol +++ b/contracts/libraries/ClusterLib.sol @@ -4,13 +4,16 @@ pragma solidity 0.8.16; import "../ISSVNetworkCore.sol"; import "../SSVNetwork.sol"; +import "./Types.sol"; library ClusterLib { + using Types64 for uint64; + function clusterBalance( ISSVNetworkCore.Cluster memory cluster, uint64 newIndex, uint64 currentNetworkFeeIndex - ) internal pure returns (uint64 balance) { + ) internal pure returns (uint256 balance) { uint64 networkFee = cluster.networkFee + uint64(currentNetworkFeeIndex - cluster.networkFeeIndex) * cluster.validatorCount; @@ -18,11 +21,11 @@ library ClusterLib { cluster.validatorCount + networkFee; - if (usage > cluster.balance) { + if (usage.expand() > cluster.balance) { revert ISSVNetworkCore.InsufficientFunds(); } - balance = cluster.balance - usage; + balance = cluster.balance - usage.expand(); } function liquidatable( @@ -31,11 +34,10 @@ library ClusterLib { uint64 networkFee, uint64 minimumBlocksBeforeLiquidation ) internal pure returns (bool) { - return - cluster.balance < - minimumBlocksBeforeLiquidation * - (burnRate + networkFee) * - cluster.validatorCount; + uint64 liquidationThreshold = minimumBlocksBeforeLiquidation * + (burnRate + networkFee) * + cluster.validatorCount; + return cluster.balance < liquidationThreshold.expand(); } function validateClusterIsNotLiquidated( diff --git a/test/account/deposit.ts b/test/account/deposit.ts index 321d6849..ac1446c4 100644 --- a/test/account/deposit.ts +++ b/test/account/deposit.ts @@ -39,29 +39,29 @@ describe('Deposit Tests', () => { it('Deposit to a cluster I own emits "ClusterDeposited', async () => { await helpers.DB.ssvToken.connect(helpers.DB.owners[4]).approve(ssvNetworkContract.address, minDepositAmount); - await expect(ssvNetworkContract.connect(helpers.DB.owners[4])['deposit(address,uint64[],uint256,(uint32,uint64,uint64,uint64,uint64,bool))'](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(address,uint64[],uint256,(uint32,uint64,uint64,uint64,uint256,bool))'](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(address,uint64[],uint256,(uint32,uint64,uint64,uint64,uint64,bool))'](helpers.DB.owners[4].address, cluster1.args.operatorIds, minDepositAmount, cluster1.args.cluster), [GasGroup.DEPOSIT]); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4])['deposit(address,uint64[],uint256,(uint32,uint64,uint64,uint64,uint256,bool))'](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(address,uint64[],uint256,(uint32,uint64,uint64,uint64,uint64,bool))'](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(address,uint64[],uint256,(uint32,uint64,uint64,uint64,uint256,bool))'](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(address,uint64[],uint256,(uint32,uint64,uint64,uint64,uint64,bool))'](helpers.DB.owners[4].address, cluster1.args.operatorIds, minDepositAmount, cluster1.args.cluster), [GasGroup.DEPOSIT]); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[0])['deposit(address,uint64[],uint256,(uint32,uint64,uint64,uint64,uint256,bool))'](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(address,uint64[],uint256,(uint32,uint64,uint64,uint64,uint64,bool))'](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(address,uint64[],uint256,(uint32,uint64,uint64,uint64,uint256,bool))'](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(address,uint64[],uint256,(uint32,uint64,uint64,uint64,uint64,bool))'](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(address,uint64[],uint256,(uint32,uint64,uint64,uint64,uint256,bool))'](helpers.DB.owners[1].address,[1,2,4,5], minDepositAmount, cluster1.args.cluster)).to.be.revertedWithCustomError(ssvNetworkContract,'ClusterDoesNotExists'); }); }); \ No newline at end of file From 7d368ec632716a4f0f29da4dd6108594187b594d Mon Sep 17 00:00:00 2001 From: mtabasco Date: Wed, 15 Feb 2023 15:40:09 +0100 Subject: [PATCH 123/149] Versioned contract - IO1-1818 (#179) --- .env.example | 1 + .gitignore | 2 +- README.md | 72 +++++++------------- contracts/ISSVNetwork.sol | 14 +--- contracts/SSVNetwork.sol | 8 ++- contracts/SSVNetworkViews.sol | 10 +++ contracts/mocks/SSVNetworkVersionUpgrade.sol | 10 +++ scripts/deploy-all.ts | 1 + test/deployment/deploy.ts | 4 +- test/deployment/version.ts | 29 ++++++++ test/helpers/contract-helpers.ts | 2 + 11 files changed, 89 insertions(+), 64 deletions(-) create mode 100644 contracts/mocks/SSVNetworkVersionUpgrade.sol create mode 100644 test/deployment/version.ts diff --git a/.env.example b/.env.example index 4723b6f9..5852e35a 100644 --- a/.env.example +++ b/.env.example @@ -14,3 +14,4 @@ VALIDATORS_PER_OPERATOR_LIMIT=2000 REGISTERED_OPERATORS_PER_ACCOUNT_LIMIT=10 SSVNETWORK_PROXY_ADDRESS= SSVNETWORKVIEWS_PROXY_ADDRESS= +INITIAL_VERSION="0.0.1" diff --git a/.gitignore b/.gitignore index 8937453a..7ab021d3 100644 --- a/.gitignore +++ b/.gitignore @@ -7,7 +7,7 @@ cache coverage coverage.json artifacts -.openzeppelin/unknown-* +.openzeppelin/ subgraph/build .idea /incentivized_testnet/operators* diff --git a/README.md b/README.md index 1a8ef1b0..88cedb56 100644 --- a/README.md +++ b/README.md @@ -1,47 +1,29 @@ # SSV Network Project - This repository contains a SSVNetwork smart contacts project. - - ## Quick start - - The first things you need to do are cloning this repository and installing its dependencies: - ```sh - git clone git@github.com:bloxapp/ssv-network.git - cd ssv-network - npm install - ``` - - ### Run locally HardHat TestNetwork node Once installed, to run Hardhat's testing network: - ```sh - npx hardhat node - ``` - - For more details about it and how to use MainNet forking you can find [here](https://hardhat.org/hardhat-network/). - ### Compile contracts @@ -51,23 +33,13 @@ Take a look at `contracts/` folder, you should be able to find: - `SSVNetworkViews.sol`: Contract with view functions only to retrive information from SSVNetwork contract. - `libraries`: Folder which contains library contracts that implement operators, clusters and network functionalities. - - To compile them, simply run: - - ```sh - npx hardhat compile - ``` - - - -## CI/CD Workflow - +## CI/CD Workflow ### Step 1: Test contracts @@ -76,16 +48,11 @@ Take a look at `test/` folder, you should be able to find tests related to speci It comes with tests that use [Ethers.js](https://github.com/ethers-io/ethers.js/). To run tests, run: - - - + ```sh - npx hardhat test - ``` - ### Step 2: Deploy new contracts @@ -99,18 +66,13 @@ To deploy the contract we will use a Hardhat script. Inside `scripts/` you will - `upgrade-ssv-network-views`: Upgrades `SSVNetworkViews` contract. As general rule, you can target any network configured in the `hardhat.config.ts`, specifying the right [network]_ETH_NODE_URL and [network]_OWNER_PRIVATE_KEY in `.env` file. - #### Deploy SSV Network - - Before run the cli command, in `.env` need to add the following seetings: - ```sh - [NETWORK]_ETH_NODE_URL=# RPC URL of the node [NETWORK]_OWNER_PRIVATE_KEY=# Private key of the deployer account, without 0x prefix GAS_PRICE=# example 30000000000 @@ -125,14 +87,12 @@ VALIDATORS_PER_OPERATOR_LIMIT=# custom param REGISTERED_OPERATORS_PER_ACCOUNT_LIMIT=# custom param SSVNETWORK_PROXY_ADDRESS=# SSVNetwork proxy address, set it when runnning upgrade-ssv-network.ts script SSVNETWORKVIEWS_PROXY_ADDRESS=# SSVNetworkViews proxy address, set it when runnning upgrade-ssv-network-views.ts script +INITIAL_VERSION=# SSVNetwork initial version, example: "1.0.0" ``` Then run: - ```sh - npx hardhat run --network scripts/deploy-all.ts - ``` Output of this action will be: @@ -155,7 +115,6 @@ You can now go to Etherscan and see: Example: [https://goerli.etherscan.io/address/0xe2e28fdea8ba1bb59a0056f6a5eabd443d47ec78](https://goerli.etherscan.io/address/0xe2e28fdea8ba1bb59a0056f6a5eabd443d47ec78) - ### Step 3: Verify implementation contract on etherscan (each time after upgrade) Open `.openzeppelin/.json` file and find `[impls..address]` value which is implementation smart contract address. @@ -163,8 +122,7 @@ You will find 2 `[impls.]` entries, one for `SSVNetwork` and another for ` Run this verification process for both. You can take it from the output of the `deploy-all.ts` script. - - + To verify an implementation contract, run this: @@ -216,7 +174,6 @@ code: 'INVALID_ARGUMENT', Set or change the parameters `GAS_PRICE` and `GAS` in `.env` file. - ### Upgrade SSVNetworkViews contract Once we have tested our new implementation, for example `contracts/SSVNetworkViews_V2.sol` we can prepare the upgrade. @@ -258,4 +215,23 @@ contract SSVNetwork_v2 is SSVNetwork { validatorsPerOperatorLimit = validatorsPerOperatorLimit_; } } -``` \ No newline at end of file +``` + +#### Version tracking + +`SSVNetwork` contract keeps its version number using the state variable `version`, which can be queried at any time but is only updated via the upgrade process. The assignement of the new version number takes place in the initializer function of the new contract. We follow [SemVer](https://semver.org/) spec. + +Example upgrade contract: +``` +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity 0.8.16; + +import "./SSVNetwork.sol"; + +contract SSVNetworkVersionUpgrade is SSVNetwork { + function initializev2(string calldata _version) external reinitializer(_getInitializedVersion() + 1) { + version = bytes32(abi.encodePacked((_version))); + } +} +``` +Here a new `_version` is passed to the `initializev2` function that is executed in the upgrade process. The `Initializable._getInitializedVersion()` call picks the latest version of previously initialized contracts and is increased by 1. diff --git a/contracts/ISSVNetwork.sol b/contracts/ISSVNetwork.sol index 22169936..4d5800c7 100644 --- a/contracts/ISSVNetwork.sol +++ b/contracts/ISSVNetwork.sol @@ -82,23 +82,15 @@ interface ISSVNetwork is ISSVNetworkCore { ); event ClusterLiquidated( - address owner, - uint64[] operatorIds, - Cluster cluster - ); event ClusterReactivated( - address owner, - uint64[] operatorIds, - Cluster cluster - ); event OperatorFeeIncreaseLimitUpdated(uint64 value); @@ -124,15 +116,10 @@ interface ISSVNetwork is ISSVNetworkCore { event NetworkEarningsWithdrawn(uint256 value, address recipient); event ClusterWithdrawn( - address owner, - uint64[] operatorIds, - uint256 value, - Cluster cluster - ); event OperatorWithdrawn(uint256 value, uint64 operatorId, address owner); @@ -157,6 +144,7 @@ interface ISSVNetwork is ISSVNetworkCore { * @param executeOperatorFeePeriod_ The length of the period in which an operator can approve their fee. */ function initialize( + string calldata initialVersion_, IERC20 token_, uint64 operatorMaxFeeIncrease_, uint64 declareOperatorFeePeriod_, diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index cd791d33..c70fcd27 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -49,6 +49,8 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { mapping(bytes32 => bytes32) public clusters; mapping(bytes32 => Validator) private _validatorPKs; + bytes32 public version; + uint32 public validatorsPerOperatorLimit; uint64 public declareOperatorFeePeriod; uint64 public executeOperatorFeePeriod; @@ -77,6 +79,7 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { /****************/ function initialize( + string calldata initialVersion_, IERC20 token_, uint64 operatorMaxFeeIncrease_, uint64 declareOperatorFeePeriod_, @@ -86,6 +89,7 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { __UUPSUpgradeable_init(); __Ownable_init_unchained(); __SSVNetwork_init_unchained( + initialVersion_, token_, operatorMaxFeeIncrease_, declareOperatorFeePeriod_, @@ -95,18 +99,20 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { } function __SSVNetwork_init_unchained( + string calldata initialVersion_, IERC20 token_, uint64 operatorMaxFeeIncrease_, uint64 declareOperatorFeePeriod_, uint64 executeOperatorFeePeriod_, uint64 minimumBlocksBeforeLiquidation_ ) internal onlyInitializing { + version = bytes32(abi.encodePacked(initialVersion_)); _token = token_; operatorMaxFeeIncrease = operatorMaxFeeIncrease_; declareOperatorFeePeriod = declareOperatorFeePeriod_; executeOperatorFeePeriod = executeOperatorFeePeriod_; minimumBlocksBeforeLiquidation = minimumBlocksBeforeLiquidation_; - validatorsPerOperatorLimit = 2000; + validatorsPerOperatorLimit = 2_000; } /*****************/ diff --git a/contracts/SSVNetworkViews.sol b/contracts/SSVNetworkViews.sol index 3f6d9fdd..b9eb2708 100644 --- a/contracts/SSVNetworkViews.sol +++ b/contracts/SSVNetworkViews.sol @@ -285,4 +285,14 @@ contract SSVNetworkViews is { return _ssvNetwork.minimumBlocksBeforeLiquidation(); } + + function getVersion() external view returns(string memory version) { + bytes memory currentVersion = abi.encodePacked(_ssvNetwork.version()); + + uint8 i; + while(i < 32 && currentVersion[i] != 0) { + version = string(abi.encodePacked(version, currentVersion[i])); + i++; + } + } } diff --git a/contracts/mocks/SSVNetworkVersionUpgrade.sol b/contracts/mocks/SSVNetworkVersionUpgrade.sol new file mode 100644 index 00000000..94ad0224 --- /dev/null +++ b/contracts/mocks/SSVNetworkVersionUpgrade.sol @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity 0.8.16; + +import "../SSVNetwork.sol"; + +contract SSVNetworkVersionUpgrade is SSVNetwork { + function initializev2(string calldata _version) external reinitializer(_getInitializedVersion() + 1) { + version = bytes32(abi.encodePacked((_version))); + } +} diff --git a/scripts/deploy-all.ts b/scripts/deploy-all.ts index ae30a513..348c965d 100644 --- a/scripts/deploy-all.ts +++ b/scripts/deploy-all.ts @@ -10,6 +10,7 @@ async function deploy() { const ssvNetworkFactory = await ethers.getContractFactory('SSVNetwork'); console.log(`Deploying SSVNetwork with ssvToken ${ssvTokenAddress}`); const ssvNetwork = await upgrades.deployProxy(ssvNetworkFactory, [ + process.env.INITIAL_VERSION, ssvTokenAddress, process.env.OPERATOR_MAX_FEE_INCREASE, process.env.DECLARE_OPERATOR_FEE_PERIOD, diff --git a/test/deployment/deploy.ts b/test/deployment/deploy.ts index e7ab52da..cb4beb1a 100644 --- a/test/deployment/deploy.ts +++ b/test/deployment/deploy.ts @@ -51,7 +51,9 @@ describe('Deployment tests', () => { const address = await upgrades.erc1967.getImplementationAddress(ssvNetworkUpgrade.address); const instance = await ssvNetworkUpgrade.attach(address); - await expect(instance.connect(DB.owners[1]).initialize('0x6471F70b932390f527c6403773D082A0Db8e8A9F', + await expect(instance.connect(DB.owners[1]).initialize( + "0.0.2", + '0x6471F70b932390f527c6403773D082A0Db8e8A9F', 2000000, 2000000, 2000000, diff --git a/test/deployment/version.ts b/test/deployment/version.ts new file mode 100644 index 00000000..afb02092 --- /dev/null +++ b/test/deployment/version.ts @@ -0,0 +1,29 @@ +// Declare imports +import * as helpers from '../helpers/contract-helpers'; +import { expect } from 'chai'; +// Declare globals +let ssvNetworkContract: any, ssvNetworkViews: any; +describe('Version upgrade tests', () => { + beforeEach(async () => { + const metadata = await helpers.initializeContract(); + ssvNetworkContract = metadata.contract; + ssvNetworkViews = metadata.ssvViews; + }); + + it('Upgrade contract version number', async () => { + expect(await ssvNetworkViews.getVersion()).to.equal(helpers.CONFIG.initialVersion); + + const SSVNetworkVersionUpgrade = await ethers.getContractFactory("SSVNetworkVersionUpgrade"); + const ssvNetwork = await upgrades.upgradeProxy(ssvNetworkContract.address, SSVNetworkVersionUpgrade, { + kind: 'uups', + call: { + fn: 'initializev2', + args: ["0.0.2"] + } + }); + await ssvNetwork.deployed(); + + expect(await ssvNetworkViews.getVersion()).to.equal("0.0.2"); + }); + +}); \ No newline at end of file diff --git a/test/helpers/contract-helpers.ts b/test/helpers/contract-helpers.ts index 54a7cbab..d21dfcac 100644 --- a/test/helpers/contract-helpers.ts +++ b/test/helpers/contract-helpers.ts @@ -63,6 +63,7 @@ export const DataGenerator = { export const initializeContract = async () => { CONFIG = { + initialVersion: "0.0.1", operatorMaxFeeIncrease: 1000, declareOperatorFeePeriod: 3600, // HOUR executeOperatorFeePeriod: 86400, // DAY @@ -92,6 +93,7 @@ export const initializeContract = async () => { await DB.ssvToken.deployed(); DB.ssvNetwork.contract = await upgrades.deployProxy(ssvNetwork, [ + CONFIG.initialVersion, DB.ssvToken.address, CONFIG.operatorMaxFeeIncrease, CONFIG.declareOperatorFeePeriod, From 5a0bb1b092dd643cb6ef96824e3b2b3b7fd2a480 Mon Sep 17 00:00:00 2001 From: mtabasco Date: Tue, 21 Feb 2023 12:19:23 +0100 Subject: [PATCH 124/149] 2 step transfer ownership - IO1-434 (#180) * use Ownable2StepUpgradeable to support 2-step transfer --- README.md | 9 ++++++++- contracts/ISSVNetworkCore.sol | 2 +- contracts/ISSVNetworkViews.sol | 2 +- contracts/SSVNetwork.sol | 30 +++++++++++++----------------- contracts/SSVNetworkViews.sol | 7 +++---- contracts/libraries/ClusterLib.sol | 18 ++++++++++-------- scripts/deploy-all.ts | 11 ++++++----- test/account/deposit.ts | 12 ++++++------ test/dao/operational.ts | 27 +++++++++++++++++++++++++++ 9 files changed, 75 insertions(+), 43 deletions(-) create mode 100644 test/dao/operational.ts diff --git a/README.md b/README.md index 88cedb56..aa8cb349 100644 --- a/README.md +++ b/README.md @@ -198,7 +198,8 @@ Pay special attention when changing storage layout, for example adding new stora There is a state variable `uint256[50] __gap;` that you should reduce the size according to the size of the new variables added. More info: [Storage Gaps](https://docs.openzeppelin.com/upgrades-plugins/1.x/writing-upgradeable#storage-gaps) -### Modify the limit of validators that an operator can manage + +## Modify the limit of validators that an operator can manage In `SSVNetwork` contract, the state variable `validatorsPerOperatorLimit` is used to represent the máximum number of validators that can be registered per operator. Its default value is `2000`. To change it, the upgrade process should be fired. The assignement to a new value must be in a new initializer function. Pay special attention to the `reinitializer` modifier where there should be a number higher than the one consumed in previous initialized contracts. More info [here](https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-reinitializer-uint8-) @@ -217,6 +218,12 @@ contract SSVNetwork_v2 is SSVNetwork { } ``` + +## Transfer the ownership of the contract +The process of transferring the ownership of the SSVNetwork contract is implemented using OpenZeppelin's `Ownable2StepUpgradeable` contract, and consists of the following steps: +1. Current owner calls `SSVNetwork`'s `transferOwnership` function with the new owner address as parameter. +2. The new owner calls `SSVNetwork`'s `acceptOwnership` fucntion and the ownership of the contract is transferred. + #### Version tracking `SSVNetwork` contract keeps its version number using the state variable `version`, which can be queried at any time but is only updated via the upgrade process. The assignement of the new version number takes place in the initializer function of the new contract. We follow [SemVer](https://semver.org/) spec. diff --git a/contracts/ISSVNetworkCore.sol b/contracts/ISSVNetworkCore.sol index 9f8671e6..576a74e9 100644 --- a/contracts/ISSVNetworkCore.sol +++ b/contracts/ISSVNetworkCore.sol @@ -39,7 +39,7 @@ interface ISSVNetworkCore { uint64 networkFee; uint64 networkFeeIndex; uint64 index; - uint64 balance; + uint256 balance; bool disabled; } diff --git a/contracts/ISSVNetworkViews.sol b/contracts/ISSVNetworkViews.sol index 1dc2635f..39709fd1 100644 --- a/contracts/ISSVNetworkViews.sol +++ b/contracts/ISSVNetworkViews.sol @@ -56,7 +56,7 @@ interface ISSVNetworkViews is ISSVNetworkCore { function getOperatorEarnings( uint64 id - ) external view returns (uint256 balance); + ) external view returns (uint256); function getBalance( address owner, diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index c70fcd27..bdcfe1da 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -7,13 +7,13 @@ import "./ISSVNetwork.sol"; import "@openzeppelin/contracts/utils/Counters.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; -import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol"; import "./libraries/Types.sol"; import "./libraries/ClusterLib.sol"; import "./libraries/OperatorLib.sol"; import "./libraries/NetworkLib.sol"; -contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { +contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { /*************/ /* Libraries */ /*************/ @@ -324,7 +324,7 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { network_ ); - cluster.balance += amount.shrink(); + cluster.balance += amount; cluster.updateClusterData(clusterIndex, currentNetworkFeeIndex, 1); if ( @@ -358,7 +358,7 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { ); if (amount > 0) { - _deposit(amount.shrink()); + _deposit(amount); } emit ValidatorAdded( @@ -519,7 +519,7 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { ) ); - _transfer(msg.sender, cluster.balance.expand()); + _transfer(msg.sender, cluster.balance); emit ClusterLiquidated(owner, operatorIds, cluster); } @@ -563,7 +563,7 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { network ); - cluster.balance += amount.shrink(); + cluster.balance += amount; cluster.disabled = false; cluster.index = clusterIndex; @@ -600,7 +600,7 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { ); if (amount > 0) { - _deposit(amount.shrink()); + _deposit(amount); } emit ClusterReactivated(msg.sender, operatorIds, cluster); @@ -618,15 +618,13 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { ) external override { cluster.validateClusterIsNotLiquidated(); - uint64 shrunkAmount = amount.shrink(); - bytes32 hashedCluster = cluster.validateHashedCluster( owner, operatorIds, this ); - cluster.balance += shrunkAmount; + cluster.balance += amount; clusters[hashedCluster] = keccak256( abi.encodePacked( @@ -639,7 +637,7 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { ) ); - _deposit(shrunkAmount); + _deposit(amount); emit ClusterDeposited(owner, operatorIds, amount, cluster); } @@ -689,8 +687,6 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { ) external override { cluster.validateClusterIsNotLiquidated(); - uint64 shrunkAmount = amount.shrink(); - uint64 clusterIndex; uint64 burnRate; { @@ -720,7 +716,7 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { ); if ( - cluster.balance < shrunkAmount || + cluster.balance < amount || cluster.liquidatable( burnRate, network.networkFee, @@ -730,7 +726,7 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { revert InsufficientBalance(); } - cluster.balance -= shrunkAmount; + cluster.balance -= amount; clusters[hashedCluster] = keccak256( abi.encodePacked( @@ -867,8 +863,8 @@ contract SSVNetwork is UUPSUpgradeable, OwnableUpgradeable, ISSVNetwork { /* Balance Private Functions */ /*****************************/ - function _deposit(uint64 amount) private { - if (!_token.transferFrom(msg.sender, address(this), amount.expand())) { + function _deposit(uint256 amount) private { + if (!_token.transferFrom(msg.sender, address(this), amount)) { revert TokenTransferFailed(); } } diff --git a/contracts/SSVNetworkViews.sol b/contracts/SSVNetworkViews.sol index b9eb2708..bb4a8e62 100644 --- a/contracts/SSVNetworkViews.sol +++ b/contracts/SSVNetworkViews.sol @@ -10,11 +10,11 @@ import "./libraries/OperatorLib.sol"; import "./libraries/NetworkLib.sol"; import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; -import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol"; contract SSVNetworkViews is UUPSUpgradeable, - OwnableUpgradeable, + Ownable2StepUpgradeable, ISSVNetworkViews { using Types256 for uint256; @@ -216,8 +216,7 @@ contract SSVNetworkViews is return cluster - .clusterBalance(clusterIndex, currrentNetworkFeeIndex) - .expand(); + .clusterBalance(clusterIndex, currrentNetworkFeeIndex); } /*******************************/ diff --git a/contracts/libraries/ClusterLib.sol b/contracts/libraries/ClusterLib.sol index aeebe8c6..8ba7e873 100644 --- a/contracts/libraries/ClusterLib.sol +++ b/contracts/libraries/ClusterLib.sol @@ -4,13 +4,16 @@ pragma solidity 0.8.16; import "../ISSVNetworkCore.sol"; import "../SSVNetwork.sol"; +import "./Types.sol"; library ClusterLib { + using Types64 for uint64; + function clusterBalance( ISSVNetworkCore.Cluster memory cluster, uint64 newIndex, uint64 currentNetworkFeeIndex - ) internal pure returns (uint64 balance) { + ) internal pure returns (uint256 balance) { uint64 networkFee = cluster.networkFee + uint64(currentNetworkFeeIndex - cluster.networkFeeIndex) * cluster.validatorCount; @@ -18,11 +21,11 @@ library ClusterLib { cluster.validatorCount + networkFee; - if (usage > cluster.balance) { + if (usage.expand() > cluster.balance) { revert ISSVNetworkCore.InsufficientFunds(); } - balance = cluster.balance - usage; + balance = cluster.balance - usage.expand(); } function liquidatable( @@ -31,11 +34,10 @@ library ClusterLib { uint64 networkFee, uint64 minimumBlocksBeforeLiquidation ) internal pure returns (bool) { - return - cluster.balance < - minimumBlocksBeforeLiquidation * - (burnRate + networkFee) * - cluster.validatorCount; + uint64 liquidationThreshold = minimumBlocksBeforeLiquidation * + (burnRate + networkFee) * + cluster.validatorCount; + return cluster.balance < liquidationThreshold.expand(); } function validateClusterIsNotLiquidated( diff --git a/scripts/deploy-all.ts b/scripts/deploy-all.ts index 348c965d..fdebe8b3 100644 --- a/scripts/deploy-all.ts +++ b/scripts/deploy-all.ts @@ -1,7 +1,8 @@ import { ethers, upgrades } from 'hardhat'; +import { getEnvVar } from './utils'; async function deploy() { - const ssvTokenAddress = process.env.SSVTOKEN_ADDRESS; + const ssvTokenAddress = getEnvVar('SSVTOKEN_ADDRESS'); const [deployer] = await ethers.getSigners(); console.log(`Deploying contracts with the account:${deployer.address}`); @@ -12,10 +13,10 @@ async function deploy() { const ssvNetwork = await upgrades.deployProxy(ssvNetworkFactory, [ process.env.INITIAL_VERSION, ssvTokenAddress, - process.env.OPERATOR_MAX_FEE_INCREASE, - process.env.DECLARE_OPERATOR_FEE_PERIOD, - process.env.EXECUTE_OPERATOR_FEE_PERIOD, - process.env.MINIMUM_BLOCKS_BEFORE_LIQUIDATION + getEnvVar('OPERATOR_MAX_FEE_INCREASE'), + getEnvVar('DECLARE_OPERATOR_FEE_PERIOD'), + getEnvVar('EXECUTE_OPERATOR_FEE_PERIOD'), + getEnvVar('MINIMUM_BLOCKS_BEFORE_LIQUIDATION') ], { kind: "uups" diff --git a/test/account/deposit.ts b/test/account/deposit.ts index 321d6849..ac1446c4 100644 --- a/test/account/deposit.ts +++ b/test/account/deposit.ts @@ -39,29 +39,29 @@ describe('Deposit Tests', () => { it('Deposit to a cluster I own emits "ClusterDeposited', async () => { await helpers.DB.ssvToken.connect(helpers.DB.owners[4]).approve(ssvNetworkContract.address, minDepositAmount); - await expect(ssvNetworkContract.connect(helpers.DB.owners[4])['deposit(address,uint64[],uint256,(uint32,uint64,uint64,uint64,uint64,bool))'](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(address,uint64[],uint256,(uint32,uint64,uint64,uint64,uint256,bool))'](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(address,uint64[],uint256,(uint32,uint64,uint64,uint64,uint64,bool))'](helpers.DB.owners[4].address, cluster1.args.operatorIds, minDepositAmount, cluster1.args.cluster), [GasGroup.DEPOSIT]); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4])['deposit(address,uint64[],uint256,(uint32,uint64,uint64,uint64,uint256,bool))'](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(address,uint64[],uint256,(uint32,uint64,uint64,uint64,uint64,bool))'](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(address,uint64[],uint256,(uint32,uint64,uint64,uint64,uint256,bool))'](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(address,uint64[],uint256,(uint32,uint64,uint64,uint64,uint64,bool))'](helpers.DB.owners[4].address, cluster1.args.operatorIds, minDepositAmount, cluster1.args.cluster), [GasGroup.DEPOSIT]); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[0])['deposit(address,uint64[],uint256,(uint32,uint64,uint64,uint64,uint256,bool))'](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(address,uint64[],uint256,(uint32,uint64,uint64,uint64,uint64,bool))'](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(address,uint64[],uint256,(uint32,uint64,uint64,uint64,uint256,bool))'](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(address,uint64[],uint256,(uint32,uint64,uint64,uint64,uint64,bool))'](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(address,uint64[],uint256,(uint32,uint64,uint64,uint64,uint256,bool))'](helpers.DB.owners[1].address,[1,2,4,5], minDepositAmount, cluster1.args.cluster)).to.be.revertedWithCustomError(ssvNetworkContract,'ClusterDoesNotExists'); }); }); \ No newline at end of file diff --git a/test/dao/operational.ts b/test/dao/operational.ts new file mode 100644 index 00000000..88969e35 --- /dev/null +++ b/test/dao/operational.ts @@ -0,0 +1,27 @@ +// Declare imports +import * as helpers from '../helpers/contract-helpers'; +import { expect } from 'chai'; + +let ssvNetworkContract: any; + +// Declare globals +describe('DAO operational Tests', () => { + beforeEach(async () => { + // Initialize contract + ssvNetworkContract = (await helpers.initializeContract()).contract; + }); + + 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); + }); + +}); \ No newline at end of file From 1b6409860578e73c82e45297457ba939878e3d4f Mon Sep 17 00:00:00 2001 From: mtabasco Date: Tue, 21 Feb 2023 16:16:19 +0100 Subject: [PATCH 125/149] Indexed events - IO1-2153 (#183) * emit uint256 cluster balance --- contracts/ISSVNetwork.sol | 24 ++++++++++++++---------- contracts/SSVNetwork.sol | 2 +- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/contracts/ISSVNetwork.sol b/contracts/ISSVNetwork.sol index 4d5800c7..9baabf3d 100644 --- a/contracts/ISSVNetwork.sol +++ b/contracts/ISSVNetwork.sol @@ -16,7 +16,7 @@ interface ISSVNetwork is ISSVNetworkCore { * @param fee Operator's fee. */ event OperatorAdded( - uint64 id, + uint64 indexed id, address indexed owner, bytes publicKey, uint256 fee @@ -26,7 +26,7 @@ interface ISSVNetwork is ISSVNetworkCore { * @dev Emitted when operator has been removed. * @param id operator's ID. */ - event OperatorRemoved(uint64 id); + event OperatorRemoved(uint64 indexed id); /** * @dev Emitted when the validator has been added. @@ -58,14 +58,14 @@ interface ISSVNetwork is ISSVNetworkCore { event OperatorFeeDeclared( address indexed owner, - uint64 operatorId, + uint64 indexed operatorId, uint256 blockNumber, uint256 fee ); event OperatorFeeCancelationDeclared( address indexed owner, - uint64 operatorId + uint64 indexed operatorId ); /** @@ -76,19 +76,19 @@ interface ISSVNetwork is ISSVNetworkCore { */ event OperatorFeeExecuted( address indexed owner, - uint64 operatorId, + uint64 indexed operatorId, uint256 blockNumber, uint256 fee ); event ClusterLiquidated( - address owner, + address indexed owner, uint64[] operatorIds, Cluster cluster ); event ClusterReactivated( - address owner, + address indexed owner, uint64[] operatorIds, Cluster cluster ); @@ -116,12 +116,16 @@ interface ISSVNetwork is ISSVNetworkCore { event NetworkEarningsWithdrawn(uint256 value, address recipient); event ClusterWithdrawn( - address owner, + address indexed owner, uint64[] operatorIds, uint256 value, Cluster cluster ); - event OperatorWithdrawn(uint256 value, uint64 operatorId, address owner); + event OperatorWithdrawn( + address indexed owner, + uint64 indexed operatorId, + uint256 value + ); event ClusterDeposited( address indexed owner, @@ -130,7 +134,7 @@ interface ISSVNetwork is ISSVNetworkCore { Cluster cluster ); - event FeeRecipientAddressUpdated(address owner, address recipientAddress); + event FeeRecipientAddressUpdated(address indexed owner, address recipientAddress); /****************/ /* Initializers */ diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index bdcfe1da..05a5b117 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -856,7 +856,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { uint256 amount ) private { _transfer(msg.sender, amount); - emit OperatorWithdrawn(amount, operatorId, msg.sender); + emit OperatorWithdrawn(msg.sender, operatorId, amount); } /*****************************/ From 79744c837aa4a0a5e7983485a6c93d2ca54fcd1a Mon Sep 17 00:00:00 2001 From: mtabasco Date: Thu, 23 Feb 2023 12:26:59 +0100 Subject: [PATCH 126/149] Operator can have 0 fee - IO1-2305 (#182) * operator fee=0 allowed, getOperatorById returns active state --- contracts/ISSVNetwork.sol | 2 +- contracts/ISSVNetworkCore.sol | 5 +- contracts/ISSVNetworkViews.sol | 2 +- contracts/SSVNetwork.sol | 244 +++++++++++++++++---------------- contracts/SSVNetworkViews.sol | 9 +- test/liquidate/liquidate.ts | 23 ++++ test/operators/register.ts | 28 +++- test/operators/remove.ts | 14 +- test/operators/update-fee.ts | 89 +++++++----- 9 files changed, 246 insertions(+), 170 deletions(-) diff --git a/contracts/ISSVNetwork.sol b/contracts/ISSVNetwork.sol index 9baabf3d..710d842a 100644 --- a/contracts/ISSVNetwork.sol +++ b/contracts/ISSVNetwork.sol @@ -163,7 +163,7 @@ interface ISSVNetwork is ISSVNetworkCore { /** * @dev Registers a new operator. * @param publicKey Operator's public key. Used to encrypt secret shares of validators keys. - * @param fee operator's fee. + * @param fee operator's fee. When fee is set to zero (mostly for private operators), it can not be increased. */ function registerOperator( bytes calldata publicKey, diff --git a/contracts/ISSVNetworkCore.sol b/contracts/ISSVNetworkCore.sol index 576a74e9..180bfd34 100644 --- a/contracts/ISSVNetworkCore.sol +++ b/contracts/ISSVNetworkCore.sol @@ -13,7 +13,7 @@ interface ISSVNetworkCore { bool active; } struct Snapshot { - /// @dev block is the last block in which last index was set + /// @dev block is the last block in which last index was set. For Operator, it's also used to identify an active / inactive one. uint64 block; /// @dev index is the last index calculated by index += (currentBlock - block) * fee uint64 index; @@ -23,6 +23,7 @@ interface ISSVNetworkCore { struct Operator { address owner; + /// @dev when fee is set to zero (mostly for private operators), it can not be increased uint64 fee; uint32 validatorCount; Snapshot snapshot; @@ -81,4 +82,6 @@ interface ISSVNetworkCore { error NewBlockPeriodIsBelowMinimum(); error ExceedValidatorLimit(); error TokenTransferFailed(); + error SameFeeChangeNotAllowed(); + error ZeroFeeIncreaseNotAllowed(); } diff --git a/contracts/ISSVNetworkViews.sol b/contracts/ISSVNetworkViews.sol index 39709fd1..b885f3e6 100644 --- a/contracts/ISSVNetworkViews.sol +++ b/contracts/ISSVNetworkViews.sol @@ -28,7 +28,7 @@ interface ISSVNetworkViews is ISSVNetworkCore { function getOperatorById( uint64 operatorId - ) external view returns (address owner, uint256 fee, uint32 validatorCount); + ) external view returns (address owner, uint256 fee, uint32 validatorCount, bool active); /*******************************/ /* Cluster External View Functions */ diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index 05a5b117..aa867300 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -69,8 +69,8 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { /* Modifiers */ /*************/ - modifier onlyOperatorOwnerOrContractOwner(uint64 operatorId) { - _onlyOperatorOwnerOrContractOwner(operatorId); + modifier onlyOperatorOwner(Operator memory operator) { + _onlyOperatorOwner(operator); _; } @@ -129,7 +129,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { bytes calldata publicKey, uint256 fee ) external override returns (uint64 id) { - if (fee < MINIMAL_OPERATOR_FEE) { + if (fee != 0 && fee < MINIMAL_OPERATOR_FEE) { revert FeeTooLow(); } @@ -148,91 +148,27 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { emit OperatorAdded(id, msg.sender, publicKey, fee); } - function removeOperator(uint64 id) external override { - Operator memory operator = operators[id]; - if (operator.owner != msg.sender) revert CallerNotOwner(); - - operator.getSnapshot(); - uint64 currentBalance = operator.snapshot.balance; - - operator.snapshot.block = 0; - operator.snapshot.balance = 0; - operator.validatorCount = 0; - operator.fee = 0; - - operators[id] = operator; - - if (currentBalance > 0) { - _transferOperatorBalanceUnsafe(id, currentBalance.expand()); - } - emit OperatorRemoved(id); + function removeOperator(uint64 operatorId) external override { + _removeOperator(operatorId, operators[operatorId]); } function declareOperatorFee( uint64 operatorId, uint256 fee - ) external override onlyOperatorOwnerOrContractOwner(operatorId) { - if (fee < MINIMAL_OPERATOR_FEE) revert FeeTooLow(); - - uint64 shrunkFee = fee.shrink(); - - // @dev 100% = 10000, 10% = 1000 - using 10000 to represent 2 digit precision - uint64 maxAllowedFee = (operators[operatorId].fee * - (10000 + operatorMaxFeeIncrease)) / 10000; - - if (shrunkFee > maxAllowedFee) revert FeeExceedsIncreaseLimit(); - - operatorFeeChangeRequests[operatorId] = OperatorFeeChangeRequest( - shrunkFee, - uint64(block.timestamp) + declareOperatorFeePeriod, - uint64(block.timestamp) + - declareOperatorFeePeriod + - executeOperatorFeePeriod - ); - emit OperatorFeeDeclared(msg.sender, operatorId, block.number, fee); + ) external override { + _declareOperatorFee(operatorId, operators[operatorId], fee); } function executeOperatorFee( uint64 operatorId - ) external override onlyOperatorOwnerOrContractOwner(operatorId) { - OperatorFeeChangeRequest - memory feeChangeRequest = operatorFeeChangeRequests[operatorId]; - - if (feeChangeRequest.fee == 0) revert NoFeeDelcared(); - - if ( - block.timestamp < feeChangeRequest.approvalBeginTime || - block.timestamp > feeChangeRequest.approvalEndTime - ) { - revert ApprovalNotWithinTimeframe(); - } - - Operator memory operator = operators[operatorId]; - - operator.getSnapshot(); - operator.fee = feeChangeRequest.fee; - - operators[operatorId] = operator; - - delete operatorFeeChangeRequests[operatorId]; - - emit OperatorFeeExecuted( - msg.sender, - operatorId, - block.number, - feeChangeRequest.fee.expand() - ); + ) external override { + _executeOperatorFee(operatorId, operators[operatorId]); } function cancelDeclaredOperatorFee( uint64 operatorId - ) external override onlyOperatorOwnerOrContractOwner(operatorId) { - if (operatorFeeChangeRequests[operatorId].fee == 0) - revert NoFeeDelcared(); - - delete operatorFeeChangeRequests[operatorId]; - - emit OperatorFeeCancelationDeclared(msg.sender, operatorId); + ) external override { + _cancelDeclaredOperatorFee(operatorId, operators[operatorId]); } function setFeeRecipientAddress( @@ -487,13 +423,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { ); uint64 networkFee = network.networkFee; - if ( - !cluster.liquidatable( - burnRate, - networkFee, - minimumBlocksBeforeLiquidation - ) - ) { + if (owner != msg.sender && !cluster.liquidatable(burnRate, networkFee, minimumBlocksBeforeLiquidation)) { revert ClusterNotLiquidatable(); } @@ -642,42 +572,15 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { emit ClusterDeposited(owner, operatorIds, amount, cluster); } - function _withdrawOperatorEarnings( - uint64 operatorId, - uint256 amount - ) private { - Operator memory operator = operators[operatorId]; - - if (operator.owner != msg.sender) revert CallerNotOwner(); - - operator.getSnapshot(); - - uint64 shrunkAmount; - - if (amount == 0 && operator.snapshot.balance > 0) { - shrunkAmount = operator.snapshot.balance; - } else if (amount > 0 && operator.snapshot.balance >= amount.shrink()) { - shrunkAmount = amount.shrink(); - } else { - revert InsufficientBalance(); - } - - operator.snapshot.balance -= shrunkAmount; - - operators[operatorId] = operator; - - _transferOperatorBalanceUnsafe(operatorId, shrunkAmount.expand()); - } - function withdrawOperatorEarnings( uint64 operatorId, uint256 amount ) external override { - _withdrawOperatorEarnings(operatorId, amount); + _withdrawOperatorEarnings(operatorId, operators[operatorId], amount); } function withdrawOperatorEarnings(uint64 operatorId) external override { - _withdrawOperatorEarnings(operatorId, 0); + _withdrawOperatorEarnings(operatorId, operators[operatorId], 0); } function withdraw( @@ -819,16 +722,9 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { /* Validation Private Functions */ /********************************/ - function _onlyOperatorOwnerOrContractOwner(uint64 operatorId) private view { - Operator memory operator = operators[operatorId]; - - if (operator.snapshot.block == 0) { - revert OperatorDoesNotExist(); - } - - if (msg.sender != operator.owner && msg.sender != owner()) { - revert CallerNotOwner(); - } + function _onlyOperatorOwner(Operator memory operator) private view { + if (operator.snapshot.block == 0) revert OperatorDoesNotExist(); + if (operator.owner != msg.sender) revert CallerNotOwner(); } function _validatePublicKey(bytes calldata publicKey) private pure { @@ -859,6 +755,112 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { emit OperatorWithdrawn(msg.sender, operatorId, amount); } + function _withdrawOperatorEarnings( + uint64 operatorId, + Operator memory operator, + uint256 amount + ) private onlyOperatorOwner(operator) { + operator.getSnapshot(); + + uint64 shrunkAmount; + + if (amount == 0 && operator.snapshot.balance > 0) { + shrunkAmount = operator.snapshot.balance; + } else if (amount > 0 && operator.snapshot.balance >= amount.shrink()) { + shrunkAmount = amount.shrink(); + } else { + revert InsufficientBalance(); + } + + operator.snapshot.balance -= shrunkAmount; + + operators[operatorId] = operator; + + _transferOperatorBalanceUnsafe(operatorId, shrunkAmount.expand()); + } + + + function _removeOperator(uint64 operatorId, Operator memory operator) private onlyOperatorOwner(operator) { + operator.getSnapshot(); + uint64 currentBalance = operator.snapshot.balance; + + operator.snapshot.block = 0; + operator.snapshot.balance = 0; + operator.validatorCount = 0; + operator.fee = 0; + + operators[operatorId] = operator; + + if (currentBalance > 0) { + _transferOperatorBalanceUnsafe(operatorId, currentBalance.expand()); + } + emit OperatorRemoved(operatorId); + } + + function _declareOperatorFee(uint64 operatorId, Operator memory operator, uint256 fee) private onlyOperatorOwner(operator) { + if (fee != 0 && fee < MINIMAL_OPERATOR_FEE) revert FeeTooLow(); + uint64 operatorFee = operators[operatorId].fee; + uint64 shrunkFee = fee.shrink(); + + if(operatorFee == shrunkFee) { + revert SameFeeChangeNotAllowed(); + } else if (shrunkFee != 0 && operatorFee == 0) { + revert ZeroFeeIncreaseNotAllowed(); + } + + // @dev 100% = 10000, 10% = 1000 - using 10000 to represent 2 digit precision + uint64 maxAllowedFee = (operatorFee * + (10000 + operatorMaxFeeIncrease)) / 10000; + + if (shrunkFee > maxAllowedFee) revert FeeExceedsIncreaseLimit(); + + operatorFeeChangeRequests[operatorId] = OperatorFeeChangeRequest( + shrunkFee, + uint64(block.timestamp) + declareOperatorFeePeriod, + uint64(block.timestamp) + + declareOperatorFeePeriod + + executeOperatorFeePeriod + ); + emit OperatorFeeDeclared(msg.sender, operatorId, block.number, fee); + } + + function _executeOperatorFee(uint64 operatorId, Operator memory operator) private onlyOperatorOwner(operator) { + OperatorFeeChangeRequest + memory feeChangeRequest = operatorFeeChangeRequests[operatorId]; + + if(feeChangeRequest.approvalBeginTime == 0) revert NoFeeDelcared(); + + if ( + block.timestamp < feeChangeRequest.approvalBeginTime || + block.timestamp > feeChangeRequest.approvalEndTime + ) { + revert ApprovalNotWithinTimeframe(); + } + + operator.getSnapshot(); + operator.fee = feeChangeRequest.fee; + + operators[operatorId] = operator; + + delete operatorFeeChangeRequests[operatorId]; + + emit OperatorFeeExecuted( + msg.sender, + operatorId, + block.number, + feeChangeRequest.fee.expand() + ); + } + + function _cancelDeclaredOperatorFee(uint64 operatorId, Operator memory operator) private onlyOperatorOwner(operator) { + if (operatorFeeChangeRequests[operatorId].approvalBeginTime == 0) + revert NoFeeDelcared(); + + delete operatorFeeChangeRequests[operatorId]; + + emit OperatorFeeCancelationDeclared(msg.sender, operatorId); + } + /*****************************/ /* Balance Private Functions */ /*****************************/ diff --git a/contracts/SSVNetworkViews.sol b/contracts/SSVNetworkViews.sol index bb4a8e62..125c67c2 100644 --- a/contracts/SSVNetworkViews.sol +++ b/contracts/SSVNetworkViews.sol @@ -70,16 +70,17 @@ contract SSVNetworkViews is function getOperatorById( uint64 operatorId - ) external view override returns (address, uint256, uint32) { + ) external view override returns (address, uint256, uint32, bool) { ( address operatorOwner, uint64 fee, uint32 validatorCount, - + Snapshot memory snapshot ) = _ssvNetwork.operators(operatorId); - if (operatorOwner == address(0)) revert OperatorDoesNotExist(); + bool active; + if (snapshot.block != 0) active = true; - return (operatorOwner, fee.expand(), validatorCount); + return (operatorOwner, fee.expand(), validatorCount, active); } /***********************************/ diff --git a/test/liquidate/liquidate.ts b/test/liquidate/liquidate.ts index f3f619fb..fe1160ab 100644 --- a/test/liquidate/liquidate.ts +++ b/test/liquidate/liquidate.ts @@ -112,6 +112,29 @@ describe('Liquidate Tests', () => { expect(await ssvViews.isLiquidated(firstCluster.owner, firstCluster.operatorIds, updatedCluster.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_POD]); + const updatedCluster = liquidatedCluster.eventsByName.ClusterLiquidated[0].args; + + 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_POD]); + const updatedCluster = liquidatedCluster.eventsByName.ClusterLiquidated[0].args; + + 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); diff --git a/test/operators/register.ts b/test/operators/register.ts index bb449cb1..defe1dea 100644 --- a/test/operators/register.ts +++ b/test/operators/register.ts @@ -29,29 +29,45 @@ describe('Register Operator Tests', () => { }); it('Get operator by id', async () => { - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerOperator( + await ssvNetworkContract.connect(helpers.DB.owners[1]).registerOperator( helpers.DataGenerator.publicKey(0), - helpers.CONFIG.minimalOperatorFee, - ), [GasGroup.REGISTER_OPERATOR]); + helpers.CONFIG.minimalOperatorFee); expect((await ssvViews.getOperatorById(1))[0]).to.equal(helpers.DB.owners[1].address); // owner expect((await ssvViews.getOperatorById(1))[1]).to.equal(helpers.CONFIG.minimalOperatorFee); // fee expect((await ssvViews.getOperatorById(1))[2]).to.equal(0); // validatorCount + expect((await ssvViews.getOperatorById(1))[3]).to.equal(true); // active }); - it('Get operator by id reverts "OperatorDoesNotExist"', async () => { + it('Get non-existent operator by id', async () => { await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerOperator( helpers.DataGenerator.publicKey(0), helpers.CONFIG.minimalOperatorFee, ), [GasGroup.REGISTER_OPERATOR]); - await expect(ssvViews.getOperatorById(3)).to.be.revertedWithCustomError(ssvNetworkContract,'OperatorDoesNotExist'); + expect((await ssvViews.getOperatorById(3))[0]).to.equal(ethers.constants.AddressZero); // owner + expect((await ssvViews.getOperatorById(3))[1]).to.equal(0); // fee + expect((await ssvViews.getOperatorById(3))[2]).to.equal(0); // validatorCount + expect((await ssvViews.getOperatorById(3))[3]).to.equal(false); // active + }); + + it('Get operator removed by id', async () => { + await ssvNetworkContract.connect(helpers.DB.owners[1]).registerOperator( + helpers.DataGenerator.publicKey(0), + helpers.CONFIG.minimalOperatorFee, + ); + await ssvNetworkContract.connect(helpers.DB.owners[1]).removeOperator(1); + + expect((await ssvViews.getOperatorById(1))[0]).to.equal(helpers.DB.owners[1].address); // owner + expect((await ssvViews.getOperatorById(1))[1]).to.equal(0); // fee + expect((await ssvViews.getOperatorById(1))[2]).to.equal(0); // validatorCount + expect((await ssvViews.getOperatorById(1))[3]).to.equal(false); // active }); it('Register an operator with a fee thats too low reverts "FeeTooLow"', async () => { await expect(ssvNetworkContract.registerOperator( helpers.DataGenerator.publicKey(0), '10' - )).to.be.revertedWithCustomError(ssvNetworkContract,'FeeTooLow'); + )).to.be.revertedWithCustomError(ssvNetworkContract, 'FeeTooLow'); }); }); \ No newline at end of file diff --git a/test/operators/remove.ts b/test/operators/remove.ts index 95d497cd..263577c7 100644 --- a/test/operators/remove.ts +++ b/test/operators/remove.ts @@ -17,7 +17,7 @@ describe('Remove Operator Tests', () => { await helpers.DB.ssvToken.connect(helpers.DB.owners[6]).approve(helpers.DB.ssvNetwork.contract.address, '1000000000000000'); await ssvNetworkContract.connect(helpers.DB.owners[6]).registerValidator( '0x221111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111119', - [1,2,3,4], + [1, 2, 3, 4], helpers.DataGenerator.shares(4), '1000000000000000', { @@ -45,17 +45,23 @@ describe('Remove Operator Tests', () => { }); 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, 1, `${helpers.CONFIG.minimalBlocksBeforeLiquidation * helpers.CONFIG.minimalOperatorFee * 4}`, [1, 2, 3, 4], [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, 1, `${helpers.CONFIG.minimalBlocksBeforeLiquidation * helpers.CONFIG.minimalOperatorFee * 4}`, [1, 2, 3, 4], [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'); + .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'); }); }); \ No newline at end of file diff --git a/test/operators/update-fee.ts b/test/operators/update-fee.ts index ebcedbbb..a3c40721 100644 --- a/test/operators/update-fee.ts +++ b/test/operators/update-fee.ts @@ -22,36 +22,41 @@ describe('Operator Fee Tests', () => { )).to.emit(ssvNetworkContract, 'OperatorFeeDeclared'); }); + it('Declare fee with zero value emits "OperatorFeeDeclared"', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[2]).declareOperatorFee(1, 0 + )).to.emit(ssvNetworkContract, 'OperatorFeeDeclared'); + }); + it('Declare a lower fee gas limits', async () => { - await trackGas(ssvNetworkContract.declareOperatorFee(1, initialFee + initialFee / 10), [GasGroup.REGISTER_OPERATOR]); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[2]).declareOperatorFee(1, initialFee - initialFee / 10), [GasGroup.REGISTER_OPERATOR]); }); it('Declare a higher fee gas limit', async () => { - await trackGas(ssvNetworkContract.declareOperatorFee(1, initialFee - initialFee / 20), [GasGroup.REGISTER_OPERATOR]); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[2]).declareOperatorFee(1, initialFee + initialFee / 10), [GasGroup.REGISTER_OPERATOR]); }); it('Cancel declared fee emits "OperatorFeeCancelationDeclared"', async () => { - await ssvNetworkContract.declareOperatorFee(1, initialFee + initialFee / 10); + await ssvNetworkContract.connect(helpers.DB.owners[2]).declareOperatorFee(1, initialFee + initialFee / 10); await expect(ssvNetworkContract.connect(helpers.DB.owners[2]).cancelDeclaredOperatorFee(1 )).to.emit(ssvNetworkContract, 'OperatorFeeCancelationDeclared'); }); it('Cancel declared fee gas limits', async () => { - await trackGas(ssvNetworkContract.declareOperatorFee(1, initialFee + initialFee / 10), [GasGroup.REGISTER_OPERATOR]); - await trackGas(ssvNetworkContract.cancelDeclaredOperatorFee(1), [GasGroup.REGISTER_OPERATOR]); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[2]).declareOperatorFee(1, initialFee + initialFee / 10), [GasGroup.REGISTER_OPERATOR]); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[2]).cancelDeclaredOperatorFee(1), [GasGroup.REGISTER_OPERATOR]); }); it('Execute declared fee emits "OperatorFeeExecuted"', async () => { - await ssvNetworkContract.declareOperatorFee(1, initialFee + initialFee / 10); + await ssvNetworkContract.connect(helpers.DB.owners[2]).declareOperatorFee(1, initialFee + initialFee / 10); await progressTime(helpers.CONFIG.declareOperatorFeePeriod); await expect(ssvNetworkContract.connect(helpers.DB.owners[2]).executeOperatorFee(1 )).to.emit(ssvNetworkContract, 'OperatorFeeExecuted'); }); it('Execute declared fee gas limits', async () => { - await trackGas(ssvNetworkContract.declareOperatorFee(1, initialFee + initialFee / 10), [GasGroup.REGISTER_OPERATOR]); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[2]).declareOperatorFee(1, initialFee + initialFee / 10), [GasGroup.REGISTER_OPERATOR]); await progressTime(helpers.CONFIG.declareOperatorFeePeriod); - await trackGas(ssvNetworkContract.executeOperatorFee(1), [GasGroup.REGISTER_OPERATOR]); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[2]).executeOperatorFee(1), [GasGroup.REGISTER_OPERATOR]); }); it('Get operator fee', async () => { @@ -60,63 +65,83 @@ describe('Operator Fee Tests', () => { it('Get fee from operator that does not exist reverts "OperatorDoesNotExist"', async () => { await expect(ssvViews.getOperatorFee(12 - )).to.be.revertedWithCustomError(ssvNetworkContract,'OperatorDoesNotExist'); + )).to.be.revertedWithCustomError(ssvNetworkContract, 'OperatorDoesNotExist'); }); it('Declare fee of operator I do not own reverts "CallerNotOwner"', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).declareOperatorFee(1, initialFee + initialFee / 10 - )).to.be.revertedWithCustomError(ssvNetworkContract,'CallerNotOwner'); + )).to.be.revertedWithCustomError(ssvNetworkContract, 'CallerNotOwner'); }); it('Declare fee with a wrong Publickey reverts "OperatorDoesNotExist"', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).declareOperatorFee(12, initialFee + initialFee / 10 - )).to.be.revertedWithCustomError(ssvNetworkContract,'OperatorDoesNotExist'); + )).to.be.revertedWithCustomError(ssvNetworkContract, 'OperatorDoesNotExist'); + }); + + it('Declare fee when previously set to zero reverts "ZeroFeeIncreaseNotAllowed"', async () => { + await ssvNetworkContract.connect(helpers.DB.owners[2]).declareOperatorFee(1, 0); + await progressTime(helpers.CONFIG.declareOperatorFeePeriod); + await ssvNetworkContract.connect(helpers.DB.owners[2]).executeOperatorFee(1); + await expect(ssvNetworkContract.connect(helpers.DB.owners[2]).declareOperatorFee(1, initialFee + initialFee / 10 + )).to.be.revertedWithCustomError(ssvNetworkContract, 'ZeroFeeIncreaseNotAllowed'); }); - it('Declare fee with too low of a fee reverts "FeeTooLow"', async () => { - await expect(ssvNetworkContract.connect(helpers.DB.owners[2]).declareOperatorFee(1, helpers.CONFIG.minimalOperatorFee - 1 - )).to.be.revertedWithCustomError(ssvNetworkContract,'FeeTooLow'); + it('Declare same fee value as actual reverts "SameFeeChangeNotAllowed"', async () => { + await ssvNetworkContract.connect(helpers.DB.owners[2]).declareOperatorFee(1, initialFee / 10); + await progressTime(helpers.CONFIG.declareOperatorFeePeriod); + await ssvNetworkContract.connect(helpers.DB.owners[2]).executeOperatorFee(1); + await expect(ssvNetworkContract.connect(helpers.DB.owners[2]).declareOperatorFee(1, initialFee / 10 + )).to.be.revertedWithCustomError(ssvNetworkContract, 'SameFeeChangeNotAllowed'); + }); + + it('Declare fee after registering an operator with zero fee reverts "ZeroFeeIncreaseNotAllowed"', async () => { + await ssvNetworkContract.connect(helpers.DB.owners[2]).registerOperator( + helpers.DataGenerator.publicKey(0), + 0, + ); + await expect(ssvNetworkContract.connect(helpers.DB.owners[2]).declareOperatorFee(2, initialFee + initialFee / 10 + )).to.be.revertedWithCustomError(ssvNetworkContract, 'ZeroFeeIncreaseNotAllowed'); }); it('Declare fee above the operators max fee increase limit reverts "FeeExceedsIncreaseLimit"', async () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[2]).declareOperatorFee(1, initialFee + initialFee / 5 - )).to.be.revertedWithCustomError(ssvNetworkContract,'FeeExceedsIncreaseLimit'); + )).to.be.revertedWithCustomError(ssvNetworkContract, 'FeeExceedsIncreaseLimit'); }); it('Cancel declared fee without a pending request reverts "NoFeeDelcared"', async () => { - await expect(ssvNetworkContract.cancelDeclaredOperatorFee(1 - )).to.be.revertedWithCustomError(ssvNetworkContract,'NoFeeDelcared'); + await expect(ssvNetworkContract.connect(helpers.DB.owners[2]).cancelDeclaredOperatorFee(1 + )).to.be.revertedWithCustomError(ssvNetworkContract, 'NoFeeDelcared'); }); it('Cancel declared fee of an operator I do not own reverts "CallerNotOwner"', async () => { - await trackGas(ssvNetworkContract.declareOperatorFee(1, initialFee + initialFee / 10), [GasGroup.REGISTER_OPERATOR]); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[2]).declareOperatorFee(1, initialFee + initialFee / 10), [GasGroup.REGISTER_OPERATOR]); await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).cancelDeclaredOperatorFee(1 - )).to.be.revertedWithCustomError(ssvNetworkContract,'CallerNotOwner'); + )).to.be.revertedWithCustomError(ssvNetworkContract, 'CallerNotOwner'); }); it('Execute declared fee of an operator I do not own reverts "CallerNotOwner"', async () => { - await trackGas(ssvNetworkContract.declareOperatorFee(1, initialFee + initialFee / 10), [GasGroup.REGISTER_OPERATOR]); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[2]).declareOperatorFee(1, initialFee + initialFee / 10), [GasGroup.REGISTER_OPERATOR]); await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).executeOperatorFee(1 - )).to.be.revertedWithCustomError(ssvNetworkContract,'CallerNotOwner'); + )).to.be.revertedWithCustomError(ssvNetworkContract, 'CallerNotOwner'); }); it('Execute declared fee without a pending request reverts "NoFeeDelcared"', async () => { - await expect(ssvNetworkContract.executeOperatorFee(1 - )).to.be.revertedWithCustomError(ssvNetworkContract,'NoFeeDelcared'); + await expect(ssvNetworkContract.connect(helpers.DB.owners[2]).executeOperatorFee(1 + )).to.be.revertedWithCustomError(ssvNetworkContract, 'NoFeeDelcared'); }); it('Execute declared fee too early reverts "ApprovalNotWithinTimeframe"', async () => { - await trackGas(ssvNetworkContract.declareOperatorFee(1, initialFee + initialFee / 10), [GasGroup.REGISTER_OPERATOR]); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[2]).declareOperatorFee(1, initialFee + initialFee / 10), [GasGroup.REGISTER_OPERATOR]); await progressTime(helpers.CONFIG.declareOperatorFeePeriod - 10); - await expect(ssvNetworkContract.executeOperatorFee(1 - )).to.be.revertedWithCustomError(ssvNetworkContract,'ApprovalNotWithinTimeframe'); + await expect(ssvNetworkContract.connect(helpers.DB.owners[2]).executeOperatorFee(1 + )).to.be.revertedWithCustomError(ssvNetworkContract, 'ApprovalNotWithinTimeframe'); }); it('Execute declared fee too late reverts "ApprovalNotWithinTimeframe"', async () => { - await trackGas(ssvNetworkContract.declareOperatorFee(1, initialFee + initialFee / 10), [GasGroup.REGISTER_OPERATOR]); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[2]).declareOperatorFee(1, initialFee + initialFee / 10), [GasGroup.REGISTER_OPERATOR]); await progressTime(helpers.CONFIG.declareOperatorFeePeriod + helpers.CONFIG.executeOperatorFeePeriod + 1); - await expect(ssvNetworkContract.executeOperatorFee(1 - )).to.be.revertedWithCustomError(ssvNetworkContract,'ApprovalNotWithinTimeframe'); + await expect(ssvNetworkContract.connect(helpers.DB.owners[2]).executeOperatorFee(1 + )).to.be.revertedWithCustomError(ssvNetworkContract, 'ApprovalNotWithinTimeframe'); }); //Dao @@ -141,7 +166,7 @@ describe('Operator Fee Tests', () => { it('DAO get declared fee', async () => { const newFee = initialFee + initialFee / 10; - await trackGas(ssvNetworkContract.declareOperatorFee(1, newFee), [GasGroup.REGISTER_OPERATOR]); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[2]).declareOperatorFee(1, newFee), [GasGroup.REGISTER_OPERATOR]); const [feeDeclaredInContract] = await ssvViews.getOperatorDeclaredFee(1); expect(feeDeclaredInContract).to.equal(newFee); }); @@ -170,8 +195,8 @@ describe('Operator Fee Tests', () => { }); it('DAO declared fee without a pending request reverts "NoFeeDelcared"', async () => { - await trackGas(ssvNetworkContract.declareOperatorFee(1, initialFee + initialFee / 10), [GasGroup.REGISTER_OPERATOR]); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[2]).declareOperatorFee(1, initialFee + initialFee / 10), [GasGroup.REGISTER_OPERATOR]); await expect(ssvViews.getOperatorDeclaredFee(2 - )).to.be.revertedWithCustomError(ssvNetworkContract,'NoFeeDelcared'); + )).to.be.revertedWithCustomError(ssvNetworkContract, 'NoFeeDelcared'); }); }); \ No newline at end of file From 390c9af972d2f2d813c2776a25190548c999d7d3 Mon Sep 17 00:00:00 2001 From: mtabasco Date: Mon, 27 Feb 2023 16:11:40 +0100 Subject: [PATCH 127/149] Network fee math - IO1-2028 (#185) * DAO struct simplified * update gas numbers * add balances test --- contracts/ISSVNetworkCore.sol | 4 +- contracts/SSVNetwork.sol | 16 +++--- contracts/SSVNetworkViews.sol | 16 ++---- contracts/libraries/NetworkLib.sol | 19 ++----- contracts/mocks/SSVNetworkLibUpgrade.sol | 8 +-- contracts/mocks/SSVNetworkViewsLibUpgrade.sol | 8 +-- .../mocks/libraries/NetworkLibUpgrade.sol | 24 ++++----- test/helpers/gas-usage.ts | 18 +++---- test/sanity/balances.ts | 54 ++++++++++++++++++- 9 files changed, 96 insertions(+), 71 deletions(-) diff --git a/contracts/ISSVNetworkCore.sol b/contracts/ISSVNetworkCore.sol index 180bfd34..dcef1ac4 100644 --- a/contracts/ISSVNetworkCore.sol +++ b/contracts/ISSVNetworkCore.sol @@ -46,8 +46,8 @@ interface ISSVNetworkCore { struct DAO { uint32 validatorCount; - uint64 withdrawn; - Snapshot earnings; + uint64 balance; + uint64 block; } struct Network { diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index aa867300..ef8e1e76 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -276,7 +276,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { { if (!cluster.disabled) { DAO memory dao_ = dao; - dao_ = dao_.updateDAOEarnings(network_.networkFee); + dao_.updateDAOEarnings(network_.networkFee); ++dao_.validatorCount; dao = dao_; } @@ -362,7 +362,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { { if (!cluster.disabled) { DAO memory dao_ = dao; - dao_ = dao_.updateDAOEarnings(network.networkFee); + dao_.updateDAOEarnings(network.networkFee); --dao_.validatorCount; dao = dao_; } @@ -433,7 +433,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { { DAO memory dao_ = dao; - dao_ = dao_.updateDAOEarnings(networkFee); + dao_.updateDAOEarnings(networkFee); dao_.validatorCount -= cluster.validatorCount; dao = dao_; } @@ -503,7 +503,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { { DAO memory dao_ = dao; - dao_ = dao_.updateDAOEarnings(networkFee); + dao_.updateDAOEarnings(networkFee); dao_.validatorCount += cluster.validatorCount; dao = dao_; } @@ -655,7 +655,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { Network memory network_ = network; DAO memory dao_ = dao; - dao_ = dao_.updateDAOEarnings(network.networkFee); + dao_.updateDAOEarnings(network.networkFee); dao = dao_; network_.networkFeeIndex = NetworkLib.currentNetworkFeeIndex(network_); @@ -674,11 +674,13 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { uint64 shrunkAmount = amount.shrink(); - if (shrunkAmount > dao_.networkBalance(network.networkFee)) { + uint64 networkBalance = dao_.networkTotalEarnings(network.networkFee); + + if (shrunkAmount > networkBalance) { revert InsufficientBalance(); } - dao_.withdrawn += shrunkAmount; + dao_.balance = networkBalance - shrunkAmount; dao = dao_; _transfer(msg.sender, amount); diff --git a/contracts/SSVNetworkViews.sol b/contracts/SSVNetworkViews.sol index 125c67c2..6b6aa4dd 100644 --- a/contracts/SSVNetworkViews.sol +++ b/contracts/SSVNetworkViews.sol @@ -230,24 +230,16 @@ contract SSVNetworkViews is } function getNetworkEarnings() external view override returns (uint256) { - ( - uint32 validatorCount, - uint64 withdrawn, - Snapshot memory snapshot - ) = _ssvNetwork.dao(); + (uint32 validatorCount, uint64 balance, uint64 block) = _ssvNetwork.dao(); DAO memory dao = DAO({ validatorCount: validatorCount, - withdrawn: withdrawn, - earnings: Snapshot({ - block: snapshot.block, - index: snapshot.index, - balance: snapshot.balance - }) + balance: balance, + block: block }); (uint64 networkFee, , ) = _ssvNetwork.network(); - return dao.networkBalance(networkFee).expand(); + return dao.networkTotalEarnings(networkFee).expand(); } function getOperatorFeeIncreaseLimit() diff --git a/contracts/libraries/NetworkLib.sol b/contracts/libraries/NetworkLib.sol index c7128c83..e96203ec 100644 --- a/contracts/libraries/NetworkLib.sol +++ b/contracts/libraries/NetworkLib.sol @@ -6,21 +6,12 @@ import "../ISSVNetworkCore.sol"; import "../SSVNetwork.sol"; library NetworkLib { - function networkBalance( - ISSVNetworkCore.DAO memory dao, - uint64 networkFee - ) internal view returns (uint64) { - return networkTotalEarnings(dao, networkFee) - dao.withdrawn; - } - function updateDAOEarnings( ISSVNetworkCore.DAO memory dao, uint64 networkFee - ) internal view returns (ISSVNetworkCore.DAO memory) { - dao.earnings.balance = networkTotalEarnings(dao, networkFee); - dao.earnings.block = uint64(block.number); - - return dao; + ) internal view { + dao.balance = networkTotalEarnings(dao, networkFee); + dao.block = uint64(block.number); } function networkTotalEarnings( @@ -28,8 +19,8 @@ library NetworkLib { uint64 networkFee ) internal view returns (uint64) { return - dao.earnings.balance + - (uint64(block.number) - dao.earnings.block) * + dao.balance + + (uint64(block.number) - dao.block) * networkFee * dao.validatorCount; } diff --git a/contracts/mocks/SSVNetworkLibUpgrade.sol b/contracts/mocks/SSVNetworkLibUpgrade.sol index 5141ae0d..e9e7ae22 100644 --- a/contracts/mocks/SSVNetworkLibUpgrade.sol +++ b/contracts/mocks/SSVNetworkLibUpgrade.sol @@ -11,12 +11,8 @@ contract SSVNetworkLibUpgrade is SSVNetwork { function getFixedNetworkRawBalance() external view returns (uint64) { DAO memory dao = ISSVNetworkCore.DAO({ validatorCount: 0, - withdrawn: 0, - earnings: ISSVNetworkCore.Snapshot({ - block: uint64(block.number), - index: 0, - balance: 100 - }) + balance: 100, + block: uint64(block.number) }); return dao.networkRawBalance(); diff --git a/contracts/mocks/SSVNetworkViewsLibUpgrade.sol b/contracts/mocks/SSVNetworkViewsLibUpgrade.sol index c3fc716c..b3ecaae3 100644 --- a/contracts/mocks/SSVNetworkViewsLibUpgrade.sol +++ b/contracts/mocks/SSVNetworkViewsLibUpgrade.sol @@ -12,12 +12,8 @@ contract SSVNetworkViewsLibUpgrade is SSVNetworkViews { function getFixedNetworkRawBalance() external view returns (uint64) { ISSVNetworkCore.DAO memory dao = ISSVNetworkCore.DAO({ validatorCount: 0, - withdrawn: 0, - earnings: ISSVNetworkCore.Snapshot({ - block: uint64(block.number), - index: 0, - balance: 100 - }) + balance: 100, + block: uint64(block.number) }); return dao.networkRawBalance(); diff --git a/contracts/mocks/libraries/NetworkLibUpgrade.sol b/contracts/mocks/libraries/NetworkLibUpgrade.sol index b68c85fe..2aacf181 100644 --- a/contracts/mocks/libraries/NetworkLibUpgrade.sol +++ b/contracts/mocks/libraries/NetworkLibUpgrade.sol @@ -10,38 +10,36 @@ library NetworkLibUpgrade { function networkRawBalance( ISSVNetwork.DAO memory dao ) internal pure returns (uint64) { - return dao.earnings.balance; + return dao.balance; } function networkBalance( - ISSVNetwork.DAO memory dao, + ISSVNetworkCore.DAO memory dao, uint64 networkFee ) internal view returns (uint64) { - return networkTotalEarnings(dao, networkFee) - dao.withdrawn; + return networkTotalEarnings(dao, networkFee); } function updateDAOEarnings( - ISSVNetwork.DAO memory dao, + ISSVNetworkCore.DAO memory dao, uint64 networkFee - ) internal view returns (ISSVNetwork.DAO memory) { - dao.earnings.balance = networkTotalEarnings(dao, networkFee); - dao.earnings.block = uint64(block.number); - - return dao; + ) internal view { + dao.balance = networkTotalEarnings(dao, networkFee); + //dao.earnings.block = uint64(block.number); } function networkTotalEarnings( - ISSVNetwork.DAO memory dao, + ISSVNetworkCore.DAO memory dao, uint64 networkFee ) internal view returns (uint64) { return - dao.earnings.balance + - (uint64(block.number) - dao.earnings.block) * + dao.balance + + (uint64(block.number) - dao.block) * networkFee * dao.validatorCount; } function currentNetworkFeeIndex( - ISSVNetwork.Network memory network + ISSVNetworkCore.Network memory network ) internal view returns (uint64) { return network.networkFeeIndex + diff --git a/test/helpers/gas-usage.ts b/test/helpers/gas-usage.ts index f67a236b..d7d5dd9b 100644 --- a/test/helpers/gas-usage.ts +++ b/test/helpers/gas-usage.ts @@ -36,17 +36,17 @@ const MAX_GAS_PER_GROUP: any = { [GasGroup.REMOVE_OPERATOR]: 62000, [GasGroup.REMOVE_OPERATOR_WITH_WITHDRAW]: 62000, - [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]: 196000, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE]: 213000, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT]: 175000, + [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]: 187000, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE]: 204000, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT]: 166000, - [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_7]: 259000, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]: 276500, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_7]: 238500, + [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_7]: 250000, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]: 267000, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_7]: 229500, - [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_13]: 386500, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]: 403500, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_13]: 365500, + [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_13]: 377000, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]: 394000, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_13]: 357000, [GasGroup.REMOVE_VALIDATOR]: 120000, [GasGroup.TRANSFER_VALIDATOR_NEW_CLUSTER]: 400000, diff --git a/test/sanity/balances.ts b/test/sanity/balances.ts index 904edfc3..5e577fc8 100644 --- a/test/sanity/balances.ts +++ b/test/sanity/balances.ts @@ -32,7 +32,7 @@ describe('Balance Tests', () => { await helpers.DB.ssvToken.connect(helpers.DB.owners[6]).approve(helpers.DB.ssvNetwork.contract.address, '1000000000000000'); await ssvNetworkContract.connect(helpers.DB.owners[6]).registerValidator( '0x221111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111119', - [1,2,3,4], + [1, 2, 3, 4], helpers.DataGenerator.shares(4), '1000000000000000', { @@ -118,6 +118,56 @@ describe('Balance Tests', () => { it('Check cluster balance with not enough balance reverts "InsufficientFunds"', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation + 10); - await expect(ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster)).to.be.revertedWithCustomError(ssvNetworkContract,'InsufficientFunds'); + await expect(ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster)).to.be.revertedWithCustomError(ssvNetworkContract, 'InsufficientFunds'); + }); + + it('Check operator earnings, cluster balances and network earnings"', async () => { + // 2 exisiting clusters + // update network fee + // register a new validator with some shared operators + // update network fee + // 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); + + const newNetworkFee = networkFee * 2; + await ssvNetworkContract.updateNetworkFee(newNetworkFee); + + 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); + + 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 * 9 + helpers.CONFIG.minimalOperatorFee * 7); + expect(await ssvViews.getOperatorEarnings(3)).to.equal(helpers.CONFIG.minimalOperatorFee * 9 + helpers.CONFIG.minimalOperatorFee * 7 + helpers.CONFIG.minimalOperatorFee * 2); + + expect(await ssvViews.getOperatorEarnings(5)).to.equal(helpers.CONFIG.minimalOperatorFee * 2); + 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 * 5 + newNetworkFee * 2); + + 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 * 7); + + // 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); + }); }); \ No newline at end of file From 8709e3d60c818ae29e07e5abe110c0a109b710d9 Mon Sep 17 00:00:00 2001 From: mtabasco Date: Mon, 27 Feb 2023 16:18:21 +0100 Subject: [PATCH 128/149] Can't add active validator to liquidated pod - IO1-2005 + IO1-2367 (#188) --- contracts/SSVNetwork.sol | 11 +++++------ contracts/libraries/ClusterLib.sol | 4 +--- test/liquidate/liquidate.ts | 6 +++--- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index ef8e1e76..059bfa8d 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -183,11 +183,10 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { function registerValidator( bytes calldata publicKey, uint64[] memory operatorIds, - bytes calldata sharesEncrypted, + bytes calldata shares, uint256 amount, Cluster memory cluster - ) external { - // TODO override + ) external override { uint operatorsLength = operatorIds.length; { @@ -225,6 +224,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { ) { revert IncorrectClusterState(); } + cluster.validateClusterIsNotLiquidated(); } uint64 clusterIndex; @@ -301,7 +301,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { msg.sender, operatorIds, publicKey, - sharesEncrypted, + shares, cluster ); } @@ -310,8 +310,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { bytes calldata publicKey, uint64[] memory operatorIds, Cluster memory cluster - ) external { - // TODO override + ) external override { uint operatorsLength = operatorIds.length; bytes32 hashedValidator = keccak256(publicKey); diff --git a/contracts/libraries/ClusterLib.sol b/contracts/libraries/ClusterLib.sol index 8ba7e873..639696dd 100644 --- a/contracts/libraries/ClusterLib.sol +++ b/contracts/libraries/ClusterLib.sol @@ -43,9 +43,7 @@ library ClusterLib { function validateClusterIsNotLiquidated( ISSVNetworkCore.Cluster memory cluster ) internal pure { - if (cluster.disabled) { - revert ISSVNetworkCore.ClusterIsLiquidated(); - } + if (cluster.disabled) revert ISSVNetworkCore.ClusterIsLiquidated(); } function validateHashedCluster( diff --git a/test/liquidate/liquidate.ts b/test/liquidate/liquidate.ts index fe1160ab..b7b0a7d6 100644 --- a/test/liquidate/liquidate.ts +++ b/test/liquidate/liquidate.ts @@ -81,7 +81,7 @@ describe('Liquidate Tests', () => { ), [GasGroup.LIQUIDATE_POD]); }); - it('Liquidate and register validator in a disabled cluster', async () => { + 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, @@ -91,13 +91,13 @@ describe('Liquidate Tests', () => { 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 trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( + await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).registerValidator( helpers.DataGenerator.publicKey(2), updatedCluster.operatorIds, helpers.DataGenerator.shares(4), `${minDepositAmount*2}`, updatedCluster.cluster - ), [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]); + )).to.be.revertedWithCustomError(ssvNetworkContract,'ClusterIsLiquidated'); }); it('Liquidate cluster and check isLiquidated true', async () => { From 80a12a7504baa162fe4838763f6ae9b7f8ddf525 Mon Sep 17 00:00:00 2001 From: mtabasco Date: Mon, 27 Feb 2023 16:26:47 +0100 Subject: [PATCH 129/149] Liquidation update + getClusterBurnRate fixed (#189) * liquidate cluster I own + views.getClusterBurnRate --- contracts/ISSVNetworkViews.sol | 4 +++- contracts/SSVNetwork.sol | 10 ++++++++-- contracts/SSVNetworkViews.sol | 22 ++++++++++++++-------- test/validators/register.ts | 34 +++++++++++++++++++++------------- 4 files changed, 46 insertions(+), 24 deletions(-) diff --git a/contracts/ISSVNetworkViews.sol b/contracts/ISSVNetworkViews.sol index b885f3e6..7ce98def 100644 --- a/contracts/ISSVNetworkViews.sol +++ b/contracts/ISSVNetworkViews.sol @@ -47,7 +47,9 @@ interface ISSVNetworkViews is ISSVNetworkCore { ) external view returns (bool); function getClusterBurnRate( - uint64[] memory operatorIds + address owner, + uint64[] memory operatorIds, + ISSVNetwork.Cluster memory cluster ) external view returns (uint256); /***********************************/ diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index 059bfa8d..52c25ecb 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -422,7 +422,13 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { ); uint64 networkFee = network.networkFee; - if (owner != msg.sender && !cluster.liquidatable(burnRate, networkFee, minimumBlocksBeforeLiquidation)) { + + if (owner != msg.sender && + !cluster.liquidatable( + burnRate, + networkFee, + minimumBlocksBeforeLiquidation)) + { revert ClusterNotLiquidatable(); } @@ -873,7 +879,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { } function _transfer(address to, uint256 amount) private { - if(!_token.transfer(to, amount)) { + if (!_token.transfer(to, amount)) { revert TokenTransferFailed(); } } diff --git a/contracts/SSVNetworkViews.sol b/contracts/SSVNetworkViews.sol index 6b6aa4dd..515d7080 100644 --- a/contracts/SSVNetworkViews.sol +++ b/contracts/SSVNetworkViews.sol @@ -139,18 +139,26 @@ contract SSVNetworkViews is } function getClusterBurnRate( - uint64[] calldata operatorIds + address owner, + uint64[] calldata operatorIds, + Cluster memory cluster ) external view returns (uint256) { - uint64 burnRate; + cluster.validateHashedCluster(owner, operatorIds, _ssvNetwork); + + uint64 aggregateFee; uint operatorsLength = operatorIds.length; for (uint i; i < operatorsLength; ++i) { (address operatorOwner, uint64 fee, , ) = _ssvNetwork.operators( operatorIds[i] ); if (operatorOwner != address(0)) { - burnRate += fee; + aggregateFee += fee; } } + + (uint64 networkFee, , ) = _ssvNetwork.network(); + + uint64 burnRate = (aggregateFee + networkFee) * cluster.validatorCount; return burnRate.expand(); } @@ -215,9 +223,7 @@ contract SSVNetworkViews is Network(networkFee, networkFeeIndex, networkFeeIndexBlockNumber) ); - return - cluster - .clusterBalance(clusterIndex, currrentNetworkFeeIndex); + return cluster.clusterBalance(clusterIndex, currrentNetworkFeeIndex); } /*******************************/ @@ -278,11 +284,11 @@ contract SSVNetworkViews is return _ssvNetwork.minimumBlocksBeforeLiquidation(); } - function getVersion() external view returns(string memory version) { + function getVersion() external view returns (string memory version) { bytes memory currentVersion = abi.encodePacked(_ssvNetwork.version()); uint8 i; - while(i < 32 && currentVersion[i] != 0) { + while (i < 32 && currentVersion[i] != 0) { version = string(abi.encodePacked(version, currentVersion[i])); i++; } diff --git a/test/validators/register.ts b/test/validators/register.ts index c9a8d6b2..141dc13a 100644 --- a/test/validators/register.ts +++ b/test/validators/register.ts @@ -3,7 +3,7 @@ import * as helpers from '../helpers/contract-helpers'; import { expect } from 'chai'; import { trackGas, GasGroup } from '../helpers/gas-usage'; -let ssvNetworkContract: any, ssvViews: any, minDepositAmount: any; +let ssvNetworkContract: any, ssvViews: any, minDepositAmount: any, cluster1: any; describe('Register Validator Tests', () => { beforeEach(async () => { @@ -19,7 +19,7 @@ describe('Register Validator Tests', () => { // cold register await helpers.DB.ssvToken.connect(helpers.DB.owners[6]).approve(helpers.DB.ssvNetwork.contract.address, '1000000000000000'); - await ssvNetworkContract.connect(helpers.DB.owners[6]).registerValidator( + cluster1 = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[6]).registerValidator( helpers.DataGenerator.publicKey(90), [1, 2, 3, 4], helpers.DataGenerator.shares(4), @@ -32,7 +32,7 @@ describe('Register Validator Tests', () => { balance: 0, disabled: false } - ); + )); }); it('Register validator with 4 operators emits "ValidatorAdded"', async () => { @@ -415,11 +415,27 @@ describe('Register Validator Tests', () => { }); it('Get cluster burn rate', async () => { - expect(await ssvViews.getClusterBurnRate([1,2,3,4])).to.equal(helpers.CONFIG.minimalOperatorFee * 4); + const networkFee = helpers.CONFIG.minimalOperatorFee; + await ssvNetworkContract.updateNetworkFee(networkFee); + + let clusterData = cluster1.eventsByName.ValidatorAdded[0].args.cluster; + expect(await ssvViews.getClusterBurnRate(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 + )); + clusterData = validator2.eventsByName.ValidatorAdded[0].args.cluster; + expect(await ssvViews.getClusterBurnRate(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 exsit', async () => { - expect(await ssvViews.getClusterBurnRate([1,2,3,41])).to.equal(helpers.CONFIG.minimalOperatorFee * 3); + const clusterData = cluster1.eventsByName.ValidatorAdded[0].args.cluster; + await expect(ssvViews.getClusterBurnRate(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 () => { @@ -589,12 +605,4 @@ describe('Register Validator Tests', () => { )).to.be.revertedWithCustomError(ssvNetwork, 'ExceedValidatorLimit'); }); - - it('Get cluster burn rate', async () => { - expect(await ssvViews.getClusterBurnRate([1,2,3,4])).to.equal(helpers.CONFIG.minimalOperatorFee * 4); - }); - - it('Get cluster burn rate by not existed operator in the list', async () => { - expect(await ssvViews.getClusterBurnRate([1,2,3,41])).to.equal(helpers.CONFIG.minimalOperatorFee * 3); - }); }); From f447f90ce34766636f05e3a028167d0d44b5ff64 Mon Sep 17 00:00:00 2001 From: Marco Date: Tue, 28 Feb 2023 14:29:24 +0100 Subject: [PATCH 130/149] fix cluster balance calculation --- contracts/ISSVNetworkCore.sol | 1 - contracts/SSVNetwork.sol | 21 ++++++--------------- contracts/libraries/ClusterLib.sol | 21 ++++----------------- test/account/deposit.ts | 12 ++++++------ 4 files changed, 16 insertions(+), 39 deletions(-) diff --git a/contracts/ISSVNetworkCore.sol b/contracts/ISSVNetworkCore.sol index dcef1ac4..6b766e59 100644 --- a/contracts/ISSVNetworkCore.sol +++ b/contracts/ISSVNetworkCore.sol @@ -37,7 +37,6 @@ interface ISSVNetworkCore { struct Cluster { uint32 validatorCount; - uint64 networkFee; uint64 networkFeeIndex; uint64 index; uint256 balance; diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index 52c25ecb..7cb477d0 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -211,7 +211,6 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { bytes32 hashedClusterData = keccak256( abi.encodePacked( cluster.validatorCount, - cluster.networkFee, cluster.networkFeeIndex, cluster.index, cluster.balance, @@ -261,7 +260,8 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { ); cluster.balance += amount; - cluster.updateClusterData(clusterIndex, currentNetworkFeeIndex, 1); + cluster.updateClusterData(clusterIndex, currentNetworkFeeIndex); + ++cluster.validatorCount; if ( cluster.liquidatable( @@ -285,7 +285,6 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { clusters[hashedCluster] = keccak256( abi.encodePacked( cluster.validatorCount, - cluster.networkFee, cluster.networkFeeIndex, cluster.index, cluster.balance, @@ -354,9 +353,9 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { cluster.updateClusterData( clusterIndex, - NetworkLib.currentNetworkFeeIndex(network), - -1 + NetworkLib.currentNetworkFeeIndex(network) ); + --cluster.validatorCount; { if (!cluster.disabled) { @@ -371,7 +370,6 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { clusters[hashedCluster] = keccak256( abi.encodePacked( cluster.validatorCount, - cluster.networkFee, cluster.networkFeeIndex, cluster.index, cluster.balance, @@ -446,7 +444,6 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { clusters[hashedCluster] = keccak256( abi.encodePacked( cluster.validatorCount, - cluster.networkFee, cluster.networkFeeIndex, cluster.index, cluster.balance, @@ -502,7 +499,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { cluster.disabled = false; cluster.index = clusterIndex; - cluster.updateClusterData(clusterIndex, currentNetworkFeeIndex, 0); + cluster.updateClusterData(clusterIndex, currentNetworkFeeIndex); uint64 networkFee = network.networkFee; @@ -526,7 +523,6 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { clusters[hashedCluster] = keccak256( abi.encodePacked( cluster.validatorCount, - cluster.networkFee, cluster.networkFeeIndex, cluster.index, cluster.balance, @@ -564,7 +560,6 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { clusters[hashedCluster] = keccak256( abi.encodePacked( cluster.validatorCount, - cluster.networkFee, cluster.networkFeeIndex, cluster.index, cluster.balance, @@ -618,10 +613,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { this ); - cluster.balance = cluster.clusterBalance( - clusterIndex, - NetworkLib.currentNetworkFeeIndex(network) - ); + cluster.updateClusterData(clusterIndex, NetworkLib.currentNetworkFeeIndex(network)); if ( cluster.balance < amount || @@ -639,7 +631,6 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { clusters[hashedCluster] = keccak256( abi.encodePacked( cluster.validatorCount, - cluster.networkFee, cluster.networkFeeIndex, cluster.index, cluster.balance, diff --git a/contracts/libraries/ClusterLib.sol b/contracts/libraries/ClusterLib.sol index 639696dd..4845a201 100644 --- a/contracts/libraries/ClusterLib.sol +++ b/contracts/libraries/ClusterLib.sol @@ -14,9 +14,9 @@ library ClusterLib { uint64 newIndex, uint64 currentNetworkFeeIndex ) internal pure returns (uint256 balance) { - uint64 networkFee = cluster.networkFee + - uint64(currentNetworkFeeIndex - cluster.networkFeeIndex) * - cluster.validatorCount; + uint64 networkFee = uint64( + currentNetworkFeeIndex - cluster.networkFeeIndex + ) * cluster.validatorCount; uint64 usage = (newIndex - cluster.index) * cluster.validatorCount + networkFee; @@ -56,7 +56,6 @@ library ClusterLib { bytes32 hashedClusterData = keccak256( abi.encodePacked( cluster.validatorCount, - cluster.networkFee, cluster.networkFeeIndex, cluster.index, cluster.balance, @@ -76,8 +75,7 @@ library ClusterLib { function updateClusterData( ISSVNetworkCore.Cluster memory cluster, uint64 clusterIndex, - uint64 currentNetworkFeeIndex, - int8 changedTo + uint64 currentNetworkFeeIndex ) internal pure { if (!cluster.disabled) { cluster.balance = clusterBalance( @@ -86,18 +84,7 @@ library ClusterLib { currentNetworkFeeIndex ); cluster.index = clusterIndex; - - cluster.networkFee = - cluster.networkFee + - uint64(currentNetworkFeeIndex - cluster.networkFeeIndex) * - cluster.validatorCount; cluster.networkFeeIndex = currentNetworkFeeIndex; } - - if (changedTo == 1) { - ++cluster.validatorCount; - } else if (changedTo == -1) { - --cluster.validatorCount; - } } } diff --git a/test/account/deposit.ts b/test/account/deposit.ts index ac1446c4..c44ffa3b 100644 --- a/test/account/deposit.ts +++ b/test/account/deposit.ts @@ -39,29 +39,29 @@ describe('Deposit Tests', () => { it('Deposit to a cluster I own emits "ClusterDeposited', async () => { await helpers.DB.ssvToken.connect(helpers.DB.owners[4]).approve(ssvNetworkContract.address, minDepositAmount); - await expect(ssvNetworkContract.connect(helpers.DB.owners[4])['deposit(address,uint64[],uint256,(uint32,uint64,uint64,uint64,uint256,bool))'](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(address,uint64[],uint256,(uint32,uint64,uint64,uint256,bool))'](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(address,uint64[],uint256,(uint32,uint64,uint64,uint64,uint256,bool))'](helpers.DB.owners[4].address, cluster1.args.operatorIds, minDepositAmount, cluster1.args.cluster), [GasGroup.DEPOSIT]); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4])['deposit(address,uint64[],uint256,(uint32,uint64,uint64,uint256,bool))'](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(address,uint64[],uint256,(uint32,uint64,uint64,uint64,uint256,bool))'](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(address,uint64[],uint256,(uint32,uint64,uint64,uint256,bool))'](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(address,uint64[],uint256,(uint32,uint64,uint64,uint64,uint256,bool))'](helpers.DB.owners[4].address, cluster1.args.operatorIds, minDepositAmount, cluster1.args.cluster), [GasGroup.DEPOSIT]); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[0])['deposit(address,uint64[],uint256,(uint32,uint64,uint64,uint256,bool))'](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(address,uint64[],uint256,(uint32,uint64,uint64,uint64,uint256,bool))'](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(address,uint64[],uint256,(uint32,uint64,uint64,uint256,bool))'](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(address,uint64[],uint256,(uint32,uint64,uint64,uint64,uint256,bool))'](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(address,uint64[],uint256,(uint32,uint64,uint64,uint256,bool))'](helpers.DB.owners[1].address,[1,2,4,5], minDepositAmount, cluster1.args.cluster)).to.be.revertedWithCustomError(ssvNetworkContract,'ClusterDoesNotExists'); }); }); \ No newline at end of file From 5f7ad48fd6307200e2e31c8845ad4d6966838fbf Mon Sep 17 00:00:00 2001 From: Marco Date: Tue, 28 Feb 2023 14:49:19 +0100 Subject: [PATCH 131/149] add test --- test/sanity/balances.ts | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/test/sanity/balances.ts b/test/sanity/balances.ts index 5e577fc8..1e836cdc 100644 --- a/test/sanity/balances.ts +++ b/test/sanity/balances.ts @@ -2,7 +2,7 @@ import * as helpers from '../helpers/contract-helpers'; import * as utils from '../helpers/utils'; import { expect } from 'chai'; -import { GasGroup } from '../helpers/gas-usage'; +import { GasGroup, trackGas } from '../helpers/gas-usage'; let ssvNetworkContract: any, ssvViews: any, cluster1: any, minDepositAmount: any, burnPerBlock: any, networkFee: any, initNetworkFeeBalance: any; @@ -170,4 +170,33 @@ describe('Balance Tests', () => { expect(await ssvViews.getNetworkEarnings() - initNetworkFeeBalance).to.equal(networkFee * 4 + newNetworkFee * 6 + newNetworkFee * 6 + newNetworkFee * 3 + networkFee * 12); }); + + 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 + )); + 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); + + 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)); + 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); + }); }); \ No newline at end of file From 1920b32abcc7628b0d2c6dc62009e2eeccd3e3cf Mon Sep 17 00:00:00 2001 From: Marco Date: Tue, 28 Feb 2023 15:56:23 +0100 Subject: [PATCH 132/149] cluster.disabled -> cluster.active --- contracts/ISSVNetworkCore.sol | 2 +- contracts/SSVNetwork.sol | 28 ++++++++--------- contracts/SSVNetworkViews.sol | 2 +- contracts/libraries/ClusterLib.sol | 6 ++-- test-e2e/register-validator-gas.ts | 10 +++--- test-e2e/stress.ts | 26 ++++++++-------- test/account/deposit.ts | 2 +- test/account/withdraw.ts | 2 +- test/dao/network-fee-withdraw.ts | 2 +- test/helpers/contract-helpers.ts | 8 ++--- test/helpers/gas-usage.ts | 2 +- test/liquidate/liquidate.ts | 6 ++-- test/liquidate/reactivate.ts | 4 +-- test/operators/remove.ts | 2 +- test/sanity/balances.ts | 2 +- test/validators/register.ts | 50 +++++++++++++++--------------- test/validators/remove.ts | 4 +-- 17 files changed, 79 insertions(+), 79 deletions(-) diff --git a/contracts/ISSVNetworkCore.sol b/contracts/ISSVNetworkCore.sol index dcef1ac4..e1866d84 100644 --- a/contracts/ISSVNetworkCore.sol +++ b/contracts/ISSVNetworkCore.sol @@ -41,7 +41,7 @@ interface ISSVNetworkCore { uint64 networkFeeIndex; uint64 index; uint256 balance; - bool disabled; + bool active; } struct DAO { diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index 52c25ecb..444dd334 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -215,7 +215,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { cluster.networkFeeIndex, cluster.index, cluster.balance, - cluster.disabled + cluster.active ) ); if ( @@ -230,7 +230,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { uint64 clusterIndex; uint64 burnRate; { - if (!cluster.disabled) { + if (cluster.active) { for (uint i; i < operatorsLength; ) { if (i + 1 < operatorsLength) { if (operatorIds[i] > operatorIds[i + 1]) { @@ -274,7 +274,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { } { - if (!cluster.disabled) { + if (cluster.active) { DAO memory dao_ = dao; dao_.updateDAOEarnings(network_.networkFee); ++dao_.validatorCount; @@ -289,7 +289,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { cluster.networkFeeIndex, cluster.index, cluster.balance, - cluster.disabled + cluster.active ) ); @@ -329,7 +329,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { uint64 clusterIndex; { - if (!cluster.disabled) { + if (cluster.active) { for (uint i; i < operatorsLength; ) { Operator memory operator = operators[operatorIds[i]]; if (operator.snapshot.block != 0) { @@ -359,7 +359,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { ); { - if (!cluster.disabled) { + if (cluster.active) { DAO memory dao_ = dao; dao_.updateDAOEarnings(network.networkFee); --dao_.validatorCount; @@ -375,7 +375,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { cluster.networkFeeIndex, cluster.index, cluster.balance, - cluster.disabled + cluster.active ) ); @@ -432,7 +432,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { revert ClusterNotLiquidatable(); } - cluster.disabled = true; + cluster.active = false; cluster.balance = 0; cluster.index = 0; @@ -450,7 +450,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { cluster.networkFeeIndex, cluster.index, cluster.balance, - cluster.disabled + cluster.active ) ); @@ -464,7 +464,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { uint256 amount, Cluster memory cluster ) external override { - if (!cluster.disabled) { + if (cluster.active) { revert ClusterAlreadyEnabled(); } @@ -499,7 +499,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { ); cluster.balance += amount; - cluster.disabled = false; + cluster.active = true; cluster.index = clusterIndex; cluster.updateClusterData(clusterIndex, currentNetworkFeeIndex, 0); @@ -530,7 +530,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { cluster.networkFeeIndex, cluster.index, cluster.balance, - cluster.disabled + cluster.active ) ); @@ -568,7 +568,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { cluster.networkFeeIndex, cluster.index, cluster.balance, - cluster.disabled + cluster.active ) ); @@ -643,7 +643,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { cluster.networkFeeIndex, cluster.index, cluster.balance, - cluster.disabled + cluster.active ) ); diff --git a/contracts/SSVNetworkViews.sol b/contracts/SSVNetworkViews.sol index 515d7080..b584668a 100644 --- a/contracts/SSVNetworkViews.sol +++ b/contracts/SSVNetworkViews.sol @@ -135,7 +135,7 @@ contract SSVNetworkViews is ) external view override returns (bool) { cluster.validateHashedCluster(owner, operatorIds, _ssvNetwork); - return cluster.disabled; + return !cluster.active; } function getClusterBurnRate( diff --git a/contracts/libraries/ClusterLib.sol b/contracts/libraries/ClusterLib.sol index 639696dd..0b3520af 100644 --- a/contracts/libraries/ClusterLib.sol +++ b/contracts/libraries/ClusterLib.sol @@ -43,7 +43,7 @@ library ClusterLib { function validateClusterIsNotLiquidated( ISSVNetworkCore.Cluster memory cluster ) internal pure { - if (cluster.disabled) revert ISSVNetworkCore.ClusterIsLiquidated(); + if (!cluster.active) revert ISSVNetworkCore.ClusterIsLiquidated(); } function validateHashedCluster( @@ -60,7 +60,7 @@ library ClusterLib { cluster.networkFeeIndex, cluster.index, cluster.balance, - cluster.disabled + cluster.active ) ); @@ -79,7 +79,7 @@ library ClusterLib { uint64 currentNetworkFeeIndex, int8 changedTo ) internal pure { - if (!cluster.disabled) { + if (cluster.active) { cluster.balance = clusterBalance( cluster, clusterIndex, diff --git a/test-e2e/register-validator-gas.ts b/test-e2e/register-validator-gas.ts index d83783af..603f16e9 100644 --- a/test-e2e/register-validator-gas.ts +++ b/test-e2e/register-validator-gas.ts @@ -36,7 +36,7 @@ describe('Register Validator Gas Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ); @@ -61,7 +61,7 @@ describe('Register Validator Gas Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ); const receipt1 = await tx1.wait(); @@ -105,7 +105,7 @@ describe('Register Validator Gas Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ); const receipt1 = await tx1.wait(); @@ -149,7 +149,7 @@ describe('Register Validator Gas Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ); const receipt1 = await tx1.wait(); @@ -193,7 +193,7 @@ describe('Register Validator Gas Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ); const receipt1 = await tx1.wait(); diff --git a/test-e2e/stress.ts b/test-e2e/stress.ts index 820d148b..82ee3900 100644 --- a/test-e2e/stress.ts +++ b/test-e2e/stress.ts @@ -39,11 +39,11 @@ describe('Stress Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true }; // Loop through all created validators to see if the pod you chose is created or not - for (let j = validatorData.length-1; j >= 0; j--) { + for (let j = validatorData.length - 1; j >= 0; j--) { if (validatorData[j].operatorPoint === randomOperatorPoint && validatorData[j].owner === randomOwner) { podData = validatorData[j].pod; break; @@ -53,7 +53,7 @@ describe('Stress Tests', () => { // Register a validator const tx = await ssvNetworkContract.connect(helpers.DB.owners[randomOwner]).registerValidator( validatorPublicKey, - [randomOperatorPoint,randomOperatorPoint+1,randomOperatorPoint+2,randomOperatorPoint+3], + [randomOperatorPoint, randomOperatorPoint + 1, randomOperatorPoint + 2, randomOperatorPoint + 3], helpers.DataGenerator.shares(0), minDepositAmount, podData @@ -65,17 +65,17 @@ describe('Stress Tests', () => { const args = (receipt.events[3].args[4]); // Break the pod event to a struct - const pod = { + const pod = { validatorCount: args.validatorCount, networkFee: args.networkFee, networkFeeIndex: args.networkFeeIndex, index: args.index, balance: args.balance, - disabled: args.disabled + active: args.active }; // Push the validator to an array - validatorData.push({publicKey: validatorPublicKey, operatorPoint: randomOperatorPoint, owner: randomOwner, pod: pod}); + validatorData.push({ publicKey: validatorPublicKey, operatorPoint: randomOperatorPoint, owner: randomOwner, pod: pod }); } }); @@ -101,12 +101,12 @@ describe('Stress Tests', () => { it('Remove 1000 validators', async () => { const newValidatorData: any = []; - for (let i = 0; i < validatorData.length-1; i++) { + for (let i = 0; i < validatorData.length - 1; i++) { let podData: any; // Loop and get latest pod - for (let j = validatorData.length-1; j >= 0; j--) { + for (let j = validatorData.length - 1; j >= 0; j--) { if (validatorData[j].operatorPoint === validatorData[i].operatorPoint && validatorData[j].owner === validatorData[i].owner) { podData = validatorData[j].pod; break; @@ -114,7 +114,7 @@ describe('Stress Tests', () => { } // Loop through new emits to get even more up to date pod if neeeded - for (let j = newValidatorData.length-1; j >= 0; j--) { + for (let j = newValidatorData.length - 1; j >= 0; j--) { if (newValidatorData[j].operatorPoint === validatorData[i].operatorPoint && newValidatorData[j].owner === validatorData[i].owner) { podData = newValidatorData[j].pod; break; @@ -124,7 +124,7 @@ describe('Stress Tests', () => { // Remove a validator const { eventsByName } = await trackGas(await ssvNetworkContract.connect(helpers.DB.owners[validatorData[i].owner]).removeValidator( validatorData[i].publicKey, - [validatorData[i].operatorPoint, validatorData[i].operatorPoint+1, validatorData[i].operatorPoint+2, validatorData[i].operatorPoint+3], + [validatorData[i].operatorPoint, validatorData[i].operatorPoint + 1, validatorData[i].operatorPoint + 2, validatorData[i].operatorPoint + 3], podData ), [GasGroup.REMOVE_VALIDATOR]); @@ -132,17 +132,17 @@ describe('Stress Tests', () => { const args = (eventsByName.ValidatorRemoved[0].args).pod; // Form a pod struct - const pod = { + const pod = { validatorCount: args.validatorCount, networkFee: args.networkFee, networkFeeIndex: args.networkFeeIndex, index: args.index, balance: args.balance, - disabled: args.disabled + active: args.active }; // Save new validator data - newValidatorData.push({publicKey: validatorData[i].validatorPublicKey, operatorPoint: validatorData[i].operatorPoint, owner: validatorData[i].owner, pod: pod}); + newValidatorData.push({ publicKey: validatorData[i].validatorPublicKey, operatorPoint: validatorData[i].operatorPoint, owner: validatorData[i].owner, pod: pod }); } }); diff --git a/test/account/deposit.ts b/test/account/deposit.ts index ac1446c4..0ddc6b45 100644 --- a/test/account/deposit.ts +++ b/test/account/deposit.ts @@ -29,7 +29,7 @@ describe('Deposit Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ); diff --git a/test/account/withdraw.ts b/test/account/withdraw.ts index cd765522..a3593676 100644 --- a/test/account/withdraw.ts +++ b/test/account/withdraw.ts @@ -31,7 +31,7 @@ describe('Withdraw Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ); diff --git a/test/dao/network-fee-withdraw.ts b/test/dao/network-fee-withdraw.ts index 2fb19fdc..ecf6dbf1 100644 --- a/test/dao/network-fee-withdraw.ts +++ b/test/dao/network-fee-withdraw.ts @@ -43,7 +43,7 @@ describe('DAO Network Fee Withdraw Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ); diff --git a/test/helpers/contract-helpers.ts b/test/helpers/contract-helpers.ts index d21dfcac..8901cece 100644 --- a/test/helpers/contract-helpers.ts +++ b/test/helpers/contract-helpers.ts @@ -165,7 +165,7 @@ export const registerValidators = async (ownerId: number, numberOfValidators: nu networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ), gasGroups); args = result.eventsByName.ValidatorAdded[0].args; @@ -184,7 +184,7 @@ export const registerValidatorsRaw = async (ownerId: number, numberOfValidators: networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true }; for (let i = 0; i < numberOfValidators; i++) { @@ -207,7 +207,7 @@ export const registerValidatorsRaw = async (ownerId: number, numberOfValidators: networkFeeIndex: clusterData.networkFeeIndex, index: clusterData.index, balance: clusterData.balance, - disabled: false + active: true }; } @@ -215,7 +215,7 @@ export const registerValidatorsRaw = async (ownerId: number, numberOfValidators: export const getCluster = (payload: any) => ethers.utils.AbiCoder.prototype.encode( - ['tuple(uint32 validatorCount, uint64 networkFee, uint64 networkFeeIndex, uint64 index, uint64 balance, bool disabled) cluster'], + ['tuple(uint32 validatorCount, uint64 networkFee, uint64 networkFeeIndex, uint64 index, uint64 balance, bool active) cluster'], [payload] ); diff --git a/test/helpers/gas-usage.ts b/test/helpers/gas-usage.ts index d7d5dd9b..7c977ab7 100644 --- a/test/helpers/gas-usage.ts +++ b/test/helpers/gas-usage.ts @@ -38,7 +38,7 @@ const MAX_GAS_PER_GROUP: any = { [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]: 187000, [GasGroup.REGISTER_VALIDATOR_NEW_STATE]: 204000, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT]: 166000, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT]: 166100, [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_7]: 250000, [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]: 267000, diff --git a/test/liquidate/liquidate.ts b/test/liquidate/liquidate.ts index b7b0a7d6..837f7be7 100644 --- a/test/liquidate/liquidate.ts +++ b/test/liquidate/liquidate.ts @@ -32,7 +32,7 @@ describe('Liquidate Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ); @@ -49,7 +49,7 @@ describe('Liquidate Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); firstCluster = register.eventsByName.ValidatorAdded[0].args; @@ -162,7 +162,7 @@ describe('Liquidate Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } )).to.be.revertedWithCustomError(ssvNetworkContract,'IncorrectClusterState'); }); diff --git a/test/liquidate/reactivate.ts b/test/liquidate/reactivate.ts index 9f88857d..daed3ed7 100644 --- a/test/liquidate/reactivate.ts +++ b/test/liquidate/reactivate.ts @@ -31,7 +31,7 @@ describe('Reactivate Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ); @@ -48,7 +48,7 @@ describe('Reactivate Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); firstCluster = register.eventsByName.ValidatorAdded[0].args; diff --git a/test/operators/remove.ts b/test/operators/remove.ts index 263577c7..f2eaa51e 100644 --- a/test/operators/remove.ts +++ b/test/operators/remove.ts @@ -26,7 +26,7 @@ describe('Remove Operator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ); }); diff --git a/test/sanity/balances.ts b/test/sanity/balances.ts index 5e577fc8..759df192 100644 --- a/test/sanity/balances.ts +++ b/test/sanity/balances.ts @@ -41,7 +41,7 @@ describe('Balance Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ); diff --git a/test/validators/register.ts b/test/validators/register.ts index 141dc13a..4425bc3a 100644 --- a/test/validators/register.ts +++ b/test/validators/register.ts @@ -30,7 +30,7 @@ describe('Register Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } )); }); @@ -48,7 +48,7 @@ describe('Register Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } )).to.emit(ssvNetworkContract, 'ValidatorAdded'); }); @@ -66,7 +66,7 @@ describe('Register Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); }); @@ -84,7 +84,7 @@ describe('Register Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); @@ -113,7 +113,7 @@ describe('Register Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); @@ -140,7 +140,7 @@ describe('Register Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); }); @@ -158,7 +158,7 @@ describe('Register Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); @@ -187,7 +187,7 @@ describe('Register Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]); }); @@ -205,7 +205,7 @@ describe('Register Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]); @@ -234,7 +234,7 @@ describe('Register Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]); @@ -261,7 +261,7 @@ describe('Register Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]); }); @@ -279,7 +279,7 @@ describe('Register Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]); @@ -308,7 +308,7 @@ describe('Register Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]); }); @@ -326,7 +326,7 @@ describe('Register Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]); @@ -355,7 +355,7 @@ describe('Register Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]); @@ -382,7 +382,7 @@ describe('Register Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]); }); @@ -400,7 +400,7 @@ describe('Register Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]); @@ -451,7 +451,7 @@ describe('Register Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ); @@ -466,7 +466,7 @@ describe('Register Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } )).to.be.revertedWithCustomError(ssvNetworkContract, 'IncorrectClusterState'); }); @@ -483,7 +483,7 @@ describe('Register Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } )).to.be.revertedWithCustomError(ssvNetworkContract, 'OperatorDoesNotExist'); }); @@ -501,7 +501,7 @@ describe('Register Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } )).to.be.revertedWithCustomError(ssvNetworkContract, 'OperatorDoesNotExist'); }); @@ -534,7 +534,7 @@ describe('Register Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } )).to.be.revertedWithCustomError(ssvNetworkContract, 'InvalidPublicKeyLength'); }); @@ -552,7 +552,7 @@ describe('Register Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } )).to.be.revertedWithCustomError(ssvNetworkContract, 'InsufficientBalance'); }); @@ -570,7 +570,7 @@ describe('Register Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } )).to.be.revertedWithCustomError(ssvNetworkContract, 'ValidatorAlreadyExists'); }); @@ -600,7 +600,7 @@ describe('Register Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } )).to.be.revertedWithCustomError(ssvNetwork, 'ExceedValidatorLimit'); diff --git a/test/validators/remove.ts b/test/validators/remove.ts index 28a10538..9294957b 100644 --- a/test/validators/remove.ts +++ b/test/validators/remove.ts @@ -31,7 +31,7 @@ describe('Remove Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ); @@ -48,7 +48,7 @@ describe('Remove Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); firstCluster = register.eventsByName.ValidatorAdded[0].args; From a6f9b62c7d08ecb9c47d8f0908a9c1cb6fa535e9 Mon Sep 17 00:00:00 2001 From: Marco Date: Tue, 28 Feb 2023 16:34:55 +0100 Subject: [PATCH 133/149] optimize flow when checking cluster.active --- contracts/SSVNetwork.sol | 112 +++++++++++++++-------------- contracts/libraries/ClusterLib.sol | 16 ++--- test/helpers/gas-usage.ts | 20 +++--- 3 files changed, 75 insertions(+), 73 deletions(-) diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index ef5c4525..db5edba9 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -148,26 +148,22 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { emit OperatorAdded(id, msg.sender, publicKey, fee); } - function removeOperator(uint64 operatorId) external override { - _removeOperator(operatorId, operators[operatorId]); + function removeOperator(uint64 operatorId) external override { + _removeOperator(operatorId, operators[operatorId]); } function declareOperatorFee( uint64 operatorId, uint256 fee - ) external override { + ) external override { _declareOperatorFee(operatorId, operators[operatorId], fee); } - function executeOperatorFee( - uint64 operatorId - ) external override { + function executeOperatorFee(uint64 operatorId) external override { _executeOperatorFee(operatorId, operators[operatorId]); } - function cancelDeclaredOperatorFee( - uint64 operatorId - ) external override { + function cancelDeclaredOperatorFee(uint64 operatorId) external override { _cancelDeclaredOperatorFee(operatorId, operators[operatorId]); } @@ -228,7 +224,15 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { uint64 clusterIndex; uint64 burnRate; + + Network memory network_ = network; + uint64 currentNetworkFeeIndex = NetworkLib.currentNetworkFeeIndex( + network_ + ); + { + cluster.balance += amount; + if (cluster.active) { for (uint i; i < operatorsLength; ) { if (i + 1 < operatorsLength) { @@ -251,16 +255,14 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { ++i; } } + cluster.updateClusterData(clusterIndex, currentNetworkFeeIndex); + + DAO memory dao_ = dao; + dao_.updateDAOEarnings(network_.networkFee); + ++dao_.validatorCount; + dao = dao_; } } - - Network memory network_ = network; - uint64 currentNetworkFeeIndex = NetworkLib.currentNetworkFeeIndex( - network_ - ); - - cluster.balance += amount; - cluster.updateClusterData(clusterIndex, currentNetworkFeeIndex); ++cluster.validatorCount; if ( @@ -273,15 +275,6 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { revert InsufficientBalance(); } - { - if (cluster.active) { - DAO memory dao_ = dao; - dao_.updateDAOEarnings(network_.networkFee); - ++dao_.validatorCount; - dao = dao_; - } - } - clusters[hashedCluster] = keccak256( abi.encodePacked( cluster.validatorCount, @@ -326,6 +319,12 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { _validatePublicKey(publicKey); } + bytes32 hashedCluster = cluster.validateHashedCluster( + msg.sender, + operatorIds, + this + ); + uint64 clusterIndex; { if (cluster.active) { @@ -342,29 +341,20 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { ++i; } } - } - } - - bytes32 hashedCluster = cluster.validateHashedCluster( - msg.sender, - operatorIds, - this - ); - - cluster.updateClusterData( - clusterIndex, - NetworkLib.currentNetworkFeeIndex(network) - ); - --cluster.validatorCount; + cluster.updateClusterData( + clusterIndex, + NetworkLib.currentNetworkFeeIndex(network) + ); - { - if (cluster.active) { DAO memory dao_ = dao; dao_.updateDAOEarnings(network.networkFee); --dao_.validatorCount; dao = dao_; } } + + --cluster.validatorCount; + delete _validatorPKs[hashedValidator]; clusters[hashedCluster] = keccak256( @@ -421,12 +411,14 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { uint64 networkFee = network.networkFee; - if (owner != msg.sender && + if ( + owner != msg.sender && !cluster.liquidatable( burnRate, networkFee, - minimumBlocksBeforeLiquidation)) - { + minimumBlocksBeforeLiquidation + ) + ) { revert ClusterNotLiquidatable(); } @@ -777,8 +769,10 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { _transferOperatorBalanceUnsafe(operatorId, shrunkAmount.expand()); } - - function _removeOperator(uint64 operatorId, Operator memory operator) private onlyOperatorOwner(operator) { + function _removeOperator( + uint64 operatorId, + Operator memory operator + ) private onlyOperatorOwner(operator) { operator.getSnapshot(); uint64 currentBalance = operator.snapshot.balance; @@ -795,16 +789,20 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { emit OperatorRemoved(operatorId); } - function _declareOperatorFee(uint64 operatorId, Operator memory operator, uint256 fee) private onlyOperatorOwner(operator) { + function _declareOperatorFee( + uint64 operatorId, + Operator memory operator, + uint256 fee + ) private onlyOperatorOwner(operator) { if (fee != 0 && fee < MINIMAL_OPERATOR_FEE) revert FeeTooLow(); uint64 operatorFee = operators[operatorId].fee; uint64 shrunkFee = fee.shrink(); - - if(operatorFee == shrunkFee) { + + if (operatorFee == shrunkFee) { revert SameFeeChangeNotAllowed(); } else if (shrunkFee != 0 && operatorFee == 0) { revert ZeroFeeIncreaseNotAllowed(); - } + } // @dev 100% = 10000, 10% = 1000 - using 10000 to represent 2 digit precision uint64 maxAllowedFee = (operatorFee * @@ -822,11 +820,14 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { emit OperatorFeeDeclared(msg.sender, operatorId, block.number, fee); } - function _executeOperatorFee(uint64 operatorId, Operator memory operator) private onlyOperatorOwner(operator) { + function _executeOperatorFee( + uint64 operatorId, + Operator memory operator + ) private onlyOperatorOwner(operator) { OperatorFeeChangeRequest memory feeChangeRequest = operatorFeeChangeRequests[operatorId]; - if(feeChangeRequest.approvalBeginTime == 0) revert NoFeeDelcared(); + if (feeChangeRequest.approvalBeginTime == 0) revert NoFeeDelcared(); if ( block.timestamp < feeChangeRequest.approvalBeginTime || @@ -850,7 +851,10 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { ); } - function _cancelDeclaredOperatorFee(uint64 operatorId, Operator memory operator) private onlyOperatorOwner(operator) { + function _cancelDeclaredOperatorFee( + uint64 operatorId, + Operator memory operator + ) private onlyOperatorOwner(operator) { if (operatorFeeChangeRequests[operatorId].approvalBeginTime == 0) revert NoFeeDelcared(); diff --git a/contracts/libraries/ClusterLib.sol b/contracts/libraries/ClusterLib.sol index 59e44069..ee169097 100644 --- a/contracts/libraries/ClusterLib.sol +++ b/contracts/libraries/ClusterLib.sol @@ -77,14 +77,12 @@ library ClusterLib { uint64 clusterIndex, uint64 currentNetworkFeeIndex ) internal pure { - if (cluster.active) { - cluster.balance = clusterBalance( - cluster, - clusterIndex, - currentNetworkFeeIndex - ); - cluster.index = clusterIndex; - cluster.networkFeeIndex = currentNetworkFeeIndex; - } + cluster.balance = clusterBalance( + cluster, + clusterIndex, + currentNetworkFeeIndex + ); + cluster.index = clusterIndex; + cluster.networkFeeIndex = currentNetworkFeeIndex; } } diff --git a/test/helpers/gas-usage.ts b/test/helpers/gas-usage.ts index 7c977ab7..3f6977d6 100644 --- a/test/helpers/gas-usage.ts +++ b/test/helpers/gas-usage.ts @@ -36,19 +36,19 @@ const MAX_GAS_PER_GROUP: any = { [GasGroup.REMOVE_OPERATOR]: 62000, [GasGroup.REMOVE_OPERATOR_WITH_WITHDRAW]: 62000, - [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]: 187000, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE]: 204000, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT]: 166100, + [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]: 185300, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE]: 202200, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT]: 164800, - [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_7]: 250000, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]: 267000, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_7]: 229500, + [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_7]: 248500, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]: 265400, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_7]: 228000, - [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_13]: 377000, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]: 394000, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_13]: 357000, + [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_13]: 375500, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]: 392300, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_13]: 355000, - [GasGroup.REMOVE_VALIDATOR]: 120000, + [GasGroup.REMOVE_VALIDATOR]: 106300, [GasGroup.TRANSFER_VALIDATOR_NEW_CLUSTER]: 400000, [GasGroup.TRANSFER_VALIDATOR]: 260000, [GasGroup.TRANSFER_VALIDATOR_NON_EXISTING_POD]: 290000, From 82f8a1e097fa0ab9d63db2c79300f59ad6f4f47c Mon Sep 17 00:00:00 2001 From: Marco Tabasco Date: Tue, 28 Feb 2023 18:09:28 +0100 Subject: [PATCH 134/149] Cluster balance fix (#193) --- contracts/ISSVNetworkCore.sol | 1 - contracts/SSVNetwork.sol | 21 ++++++-------------- contracts/libraries/ClusterLib.sol | 21 ++++---------------- test/account/deposit.ts | 12 ++++++------ test/sanity/balances.ts | 31 +++++++++++++++++++++++++++++- 5 files changed, 46 insertions(+), 40 deletions(-) diff --git a/contracts/ISSVNetworkCore.sol b/contracts/ISSVNetworkCore.sol index dcef1ac4..6b766e59 100644 --- a/contracts/ISSVNetworkCore.sol +++ b/contracts/ISSVNetworkCore.sol @@ -37,7 +37,6 @@ interface ISSVNetworkCore { struct Cluster { uint32 validatorCount; - uint64 networkFee; uint64 networkFeeIndex; uint64 index; uint256 balance; diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index 52c25ecb..7cb477d0 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -211,7 +211,6 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { bytes32 hashedClusterData = keccak256( abi.encodePacked( cluster.validatorCount, - cluster.networkFee, cluster.networkFeeIndex, cluster.index, cluster.balance, @@ -261,7 +260,8 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { ); cluster.balance += amount; - cluster.updateClusterData(clusterIndex, currentNetworkFeeIndex, 1); + cluster.updateClusterData(clusterIndex, currentNetworkFeeIndex); + ++cluster.validatorCount; if ( cluster.liquidatable( @@ -285,7 +285,6 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { clusters[hashedCluster] = keccak256( abi.encodePacked( cluster.validatorCount, - cluster.networkFee, cluster.networkFeeIndex, cluster.index, cluster.balance, @@ -354,9 +353,9 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { cluster.updateClusterData( clusterIndex, - NetworkLib.currentNetworkFeeIndex(network), - -1 + NetworkLib.currentNetworkFeeIndex(network) ); + --cluster.validatorCount; { if (!cluster.disabled) { @@ -371,7 +370,6 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { clusters[hashedCluster] = keccak256( abi.encodePacked( cluster.validatorCount, - cluster.networkFee, cluster.networkFeeIndex, cluster.index, cluster.balance, @@ -446,7 +444,6 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { clusters[hashedCluster] = keccak256( abi.encodePacked( cluster.validatorCount, - cluster.networkFee, cluster.networkFeeIndex, cluster.index, cluster.balance, @@ -502,7 +499,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { cluster.disabled = false; cluster.index = clusterIndex; - cluster.updateClusterData(clusterIndex, currentNetworkFeeIndex, 0); + cluster.updateClusterData(clusterIndex, currentNetworkFeeIndex); uint64 networkFee = network.networkFee; @@ -526,7 +523,6 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { clusters[hashedCluster] = keccak256( abi.encodePacked( cluster.validatorCount, - cluster.networkFee, cluster.networkFeeIndex, cluster.index, cluster.balance, @@ -564,7 +560,6 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { clusters[hashedCluster] = keccak256( abi.encodePacked( cluster.validatorCount, - cluster.networkFee, cluster.networkFeeIndex, cluster.index, cluster.balance, @@ -618,10 +613,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { this ); - cluster.balance = cluster.clusterBalance( - clusterIndex, - NetworkLib.currentNetworkFeeIndex(network) - ); + cluster.updateClusterData(clusterIndex, NetworkLib.currentNetworkFeeIndex(network)); if ( cluster.balance < amount || @@ -639,7 +631,6 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { clusters[hashedCluster] = keccak256( abi.encodePacked( cluster.validatorCount, - cluster.networkFee, cluster.networkFeeIndex, cluster.index, cluster.balance, diff --git a/contracts/libraries/ClusterLib.sol b/contracts/libraries/ClusterLib.sol index 639696dd..4845a201 100644 --- a/contracts/libraries/ClusterLib.sol +++ b/contracts/libraries/ClusterLib.sol @@ -14,9 +14,9 @@ library ClusterLib { uint64 newIndex, uint64 currentNetworkFeeIndex ) internal pure returns (uint256 balance) { - uint64 networkFee = cluster.networkFee + - uint64(currentNetworkFeeIndex - cluster.networkFeeIndex) * - cluster.validatorCount; + uint64 networkFee = uint64( + currentNetworkFeeIndex - cluster.networkFeeIndex + ) * cluster.validatorCount; uint64 usage = (newIndex - cluster.index) * cluster.validatorCount + networkFee; @@ -56,7 +56,6 @@ library ClusterLib { bytes32 hashedClusterData = keccak256( abi.encodePacked( cluster.validatorCount, - cluster.networkFee, cluster.networkFeeIndex, cluster.index, cluster.balance, @@ -76,8 +75,7 @@ library ClusterLib { function updateClusterData( ISSVNetworkCore.Cluster memory cluster, uint64 clusterIndex, - uint64 currentNetworkFeeIndex, - int8 changedTo + uint64 currentNetworkFeeIndex ) internal pure { if (!cluster.disabled) { cluster.balance = clusterBalance( @@ -86,18 +84,7 @@ library ClusterLib { currentNetworkFeeIndex ); cluster.index = clusterIndex; - - cluster.networkFee = - cluster.networkFee + - uint64(currentNetworkFeeIndex - cluster.networkFeeIndex) * - cluster.validatorCount; cluster.networkFeeIndex = currentNetworkFeeIndex; } - - if (changedTo == 1) { - ++cluster.validatorCount; - } else if (changedTo == -1) { - --cluster.validatorCount; - } } } diff --git a/test/account/deposit.ts b/test/account/deposit.ts index ac1446c4..c44ffa3b 100644 --- a/test/account/deposit.ts +++ b/test/account/deposit.ts @@ -39,29 +39,29 @@ describe('Deposit Tests', () => { it('Deposit to a cluster I own emits "ClusterDeposited', async () => { await helpers.DB.ssvToken.connect(helpers.DB.owners[4]).approve(ssvNetworkContract.address, minDepositAmount); - await expect(ssvNetworkContract.connect(helpers.DB.owners[4])['deposit(address,uint64[],uint256,(uint32,uint64,uint64,uint64,uint256,bool))'](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(address,uint64[],uint256,(uint32,uint64,uint64,uint256,bool))'](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(address,uint64[],uint256,(uint32,uint64,uint64,uint64,uint256,bool))'](helpers.DB.owners[4].address, cluster1.args.operatorIds, minDepositAmount, cluster1.args.cluster), [GasGroup.DEPOSIT]); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[4])['deposit(address,uint64[],uint256,(uint32,uint64,uint64,uint256,bool))'](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(address,uint64[],uint256,(uint32,uint64,uint64,uint64,uint256,bool))'](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(address,uint64[],uint256,(uint32,uint64,uint64,uint256,bool))'](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(address,uint64[],uint256,(uint32,uint64,uint64,uint64,uint256,bool))'](helpers.DB.owners[4].address, cluster1.args.operatorIds, minDepositAmount, cluster1.args.cluster), [GasGroup.DEPOSIT]); + await trackGas(ssvNetworkContract.connect(helpers.DB.owners[0])['deposit(address,uint64[],uint256,(uint32,uint64,uint64,uint256,bool))'](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(address,uint64[],uint256,(uint32,uint64,uint64,uint64,uint256,bool))'](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(address,uint64[],uint256,(uint32,uint64,uint64,uint256,bool))'](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(address,uint64[],uint256,(uint32,uint64,uint64,uint64,uint256,bool))'](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(address,uint64[],uint256,(uint32,uint64,uint64,uint256,bool))'](helpers.DB.owners[1].address,[1,2,4,5], minDepositAmount, cluster1.args.cluster)).to.be.revertedWithCustomError(ssvNetworkContract,'ClusterDoesNotExists'); }); }); \ No newline at end of file diff --git a/test/sanity/balances.ts b/test/sanity/balances.ts index 5e577fc8..1e836cdc 100644 --- a/test/sanity/balances.ts +++ b/test/sanity/balances.ts @@ -2,7 +2,7 @@ import * as helpers from '../helpers/contract-helpers'; import * as utils from '../helpers/utils'; import { expect } from 'chai'; -import { GasGroup } from '../helpers/gas-usage'; +import { GasGroup, trackGas } from '../helpers/gas-usage'; let ssvNetworkContract: any, ssvViews: any, cluster1: any, minDepositAmount: any, burnPerBlock: any, networkFee: any, initNetworkFeeBalance: any; @@ -170,4 +170,33 @@ describe('Balance Tests', () => { expect(await ssvViews.getNetworkEarnings() - initNetworkFeeBalance).to.equal(networkFee * 4 + newNetworkFee * 6 + newNetworkFee * 6 + newNetworkFee * 3 + networkFee * 12); }); + + 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 + )); + 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); + + 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)); + 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); + }); }); \ No newline at end of file From 33c26be69da017d7d5c061354fe66f574303247e Mon Sep 17 00:00:00 2001 From: Marco Tabasco Date: Tue, 28 Feb 2023 19:50:45 +0100 Subject: [PATCH 135/149] Cluster active - IO1-2371 (#194) * cluster.disabled -> cluster.active * optimize flow when checking cluster.active --- contracts/ISSVNetworkCore.sol | 2 +- contracts/SSVNetwork.sol | 135 +++++++++++++++-------------- contracts/SSVNetworkViews.sol | 2 +- contracts/libraries/ClusterLib.sol | 20 ++--- test-e2e/register-validator-gas.ts | 10 +-- test-e2e/stress.ts | 26 +++--- test/account/deposit.ts | 2 +- test/account/withdraw.ts | 2 +- test/dao/network-fee-withdraw.ts | 2 +- test/helpers/contract-helpers.ts | 8 +- test/helpers/gas-usage.ts | 20 ++--- test/liquidate/liquidate.ts | 6 +- test/liquidate/reactivate.ts | 4 +- test/operators/remove.ts | 2 +- test/sanity/balances.ts | 2 +- test/validators/register.ts | 50 +++++------ test/validators/remove.ts | 4 +- 17 files changed, 150 insertions(+), 147 deletions(-) diff --git a/contracts/ISSVNetworkCore.sol b/contracts/ISSVNetworkCore.sol index 6b766e59..466f0dc2 100644 --- a/contracts/ISSVNetworkCore.sol +++ b/contracts/ISSVNetworkCore.sol @@ -40,7 +40,7 @@ interface ISSVNetworkCore { uint64 networkFeeIndex; uint64 index; uint256 balance; - bool disabled; + bool active; } struct DAO { diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index 7cb477d0..973b0bd7 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -148,26 +148,22 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { emit OperatorAdded(id, msg.sender, publicKey, fee); } - function removeOperator(uint64 operatorId) external override { - _removeOperator(operatorId, operators[operatorId]); + function removeOperator(uint64 operatorId) external override { + _removeOperator(operatorId, operators[operatorId]); } function declareOperatorFee( uint64 operatorId, uint256 fee - ) external override { + ) external override { _declareOperatorFee(operatorId, operators[operatorId], fee); } - function executeOperatorFee( - uint64 operatorId - ) external override { + function executeOperatorFee(uint64 operatorId) external override { _executeOperatorFee(operatorId, operators[operatorId]); } - function cancelDeclaredOperatorFee( - uint64 operatorId - ) external override { + function cancelDeclaredOperatorFee(uint64 operatorId) external override { _cancelDeclaredOperatorFee(operatorId, operators[operatorId]); } @@ -214,7 +210,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { cluster.networkFeeIndex, cluster.index, cluster.balance, - cluster.disabled + cluster.active ) ); if ( @@ -228,8 +224,16 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { uint64 clusterIndex; uint64 burnRate; + + Network memory network_ = network; + uint64 currentNetworkFeeIndex = NetworkLib.currentNetworkFeeIndex( + network_ + ); + { - if (!cluster.disabled) { + cluster.balance += amount; + + if (cluster.active) { for (uint i; i < operatorsLength; ) { if (i + 1 < operatorsLength) { if (operatorIds[i] > operatorIds[i + 1]) { @@ -251,16 +255,15 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { ++i; } } + cluster.updateClusterData(clusterIndex, currentNetworkFeeIndex); + + DAO memory dao_ = dao; + dao_.updateDAOEarnings(network_.networkFee); + ++dao_.validatorCount; + dao = dao_; } } - Network memory network_ = network; - uint64 currentNetworkFeeIndex = NetworkLib.currentNetworkFeeIndex( - network_ - ); - - cluster.balance += amount; - cluster.updateClusterData(clusterIndex, currentNetworkFeeIndex); ++cluster.validatorCount; if ( @@ -273,22 +276,13 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { revert InsufficientBalance(); } - { - if (!cluster.disabled) { - DAO memory dao_ = dao; - dao_.updateDAOEarnings(network_.networkFee); - ++dao_.validatorCount; - dao = dao_; - } - } - clusters[hashedCluster] = keccak256( abi.encodePacked( cluster.validatorCount, cluster.networkFeeIndex, cluster.index, cluster.balance, - cluster.disabled + cluster.active ) ); @@ -326,9 +320,15 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { _validatePublicKey(publicKey); } + bytes32 hashedCluster = cluster.validateHashedCluster( + msg.sender, + operatorIds, + this + ); + uint64 clusterIndex; { - if (!cluster.disabled) { + if (cluster.active) { for (uint i; i < operatorsLength; ) { Operator memory operator = operators[operatorIds[i]]; if (operator.snapshot.block != 0) { @@ -342,29 +342,20 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { ++i; } } - } - } - - bytes32 hashedCluster = cluster.validateHashedCluster( - msg.sender, - operatorIds, - this - ); - - cluster.updateClusterData( - clusterIndex, - NetworkLib.currentNetworkFeeIndex(network) - ); - --cluster.validatorCount; + cluster.updateClusterData( + clusterIndex, + NetworkLib.currentNetworkFeeIndex(network) + ); - { - if (!cluster.disabled) { DAO memory dao_ = dao; dao_.updateDAOEarnings(network.networkFee); --dao_.validatorCount; dao = dao_; } } + + --cluster.validatorCount; + delete _validatorPKs[hashedValidator]; clusters[hashedCluster] = keccak256( @@ -373,7 +364,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { cluster.networkFeeIndex, cluster.index, cluster.balance, - cluster.disabled + cluster.active ) ); @@ -421,16 +412,18 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { uint64 networkFee = network.networkFee; - if (owner != msg.sender && + if ( + owner != msg.sender && !cluster.liquidatable( burnRate, networkFee, - minimumBlocksBeforeLiquidation)) - { + minimumBlocksBeforeLiquidation + ) + ) { revert ClusterNotLiquidatable(); } - cluster.disabled = true; + cluster.active = false; cluster.balance = 0; cluster.index = 0; @@ -447,7 +440,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { cluster.networkFeeIndex, cluster.index, cluster.balance, - cluster.disabled + cluster.active ) ); @@ -461,7 +454,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { uint256 amount, Cluster memory cluster ) external override { - if (!cluster.disabled) { + if (cluster.active) { revert ClusterAlreadyEnabled(); } @@ -496,7 +489,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { ); cluster.balance += amount; - cluster.disabled = false; + cluster.active = true; cluster.index = clusterIndex; cluster.updateClusterData(clusterIndex, currentNetworkFeeIndex); @@ -526,7 +519,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { cluster.networkFeeIndex, cluster.index, cluster.balance, - cluster.disabled + cluster.active ) ); @@ -563,7 +556,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { cluster.networkFeeIndex, cluster.index, cluster.balance, - cluster.disabled + cluster.active ) ); @@ -634,7 +627,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { cluster.networkFeeIndex, cluster.index, cluster.balance, - cluster.disabled + cluster.active ) ); @@ -777,8 +770,10 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { _transferOperatorBalanceUnsafe(operatorId, shrunkAmount.expand()); } - - function _removeOperator(uint64 operatorId, Operator memory operator) private onlyOperatorOwner(operator) { + function _removeOperator( + uint64 operatorId, + Operator memory operator + ) private onlyOperatorOwner(operator) { operator.getSnapshot(); uint64 currentBalance = operator.snapshot.balance; @@ -795,16 +790,20 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { emit OperatorRemoved(operatorId); } - function _declareOperatorFee(uint64 operatorId, Operator memory operator, uint256 fee) private onlyOperatorOwner(operator) { + function _declareOperatorFee( + uint64 operatorId, + Operator memory operator, + uint256 fee + ) private onlyOperatorOwner(operator) { if (fee != 0 && fee < MINIMAL_OPERATOR_FEE) revert FeeTooLow(); uint64 operatorFee = operators[operatorId].fee; uint64 shrunkFee = fee.shrink(); - - if(operatorFee == shrunkFee) { + + if (operatorFee == shrunkFee) { revert SameFeeChangeNotAllowed(); } else if (shrunkFee != 0 && operatorFee == 0) { revert ZeroFeeIncreaseNotAllowed(); - } + } // @dev 100% = 10000, 10% = 1000 - using 10000 to represent 2 digit precision uint64 maxAllowedFee = (operatorFee * @@ -822,11 +821,14 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { emit OperatorFeeDeclared(msg.sender, operatorId, block.number, fee); } - function _executeOperatorFee(uint64 operatorId, Operator memory operator) private onlyOperatorOwner(operator) { + function _executeOperatorFee( + uint64 operatorId, + Operator memory operator + ) private onlyOperatorOwner(operator) { OperatorFeeChangeRequest memory feeChangeRequest = operatorFeeChangeRequests[operatorId]; - if(feeChangeRequest.approvalBeginTime == 0) revert NoFeeDelcared(); + if (feeChangeRequest.approvalBeginTime == 0) revert NoFeeDelcared(); if ( block.timestamp < feeChangeRequest.approvalBeginTime || @@ -850,7 +852,10 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { ); } - function _cancelDeclaredOperatorFee(uint64 operatorId, Operator memory operator) private onlyOperatorOwner(operator) { + function _cancelDeclaredOperatorFee( + uint64 operatorId, + Operator memory operator + ) private onlyOperatorOwner(operator) { if (operatorFeeChangeRequests[operatorId].approvalBeginTime == 0) revert NoFeeDelcared(); diff --git a/contracts/SSVNetworkViews.sol b/contracts/SSVNetworkViews.sol index 515d7080..b584668a 100644 --- a/contracts/SSVNetworkViews.sol +++ b/contracts/SSVNetworkViews.sol @@ -135,7 +135,7 @@ contract SSVNetworkViews is ) external view override returns (bool) { cluster.validateHashedCluster(owner, operatorIds, _ssvNetwork); - return cluster.disabled; + return !cluster.active; } function getClusterBurnRate( diff --git a/contracts/libraries/ClusterLib.sol b/contracts/libraries/ClusterLib.sol index 4845a201..ee169097 100644 --- a/contracts/libraries/ClusterLib.sol +++ b/contracts/libraries/ClusterLib.sol @@ -43,7 +43,7 @@ library ClusterLib { function validateClusterIsNotLiquidated( ISSVNetworkCore.Cluster memory cluster ) internal pure { - if (cluster.disabled) revert ISSVNetworkCore.ClusterIsLiquidated(); + if (!cluster.active) revert ISSVNetworkCore.ClusterIsLiquidated(); } function validateHashedCluster( @@ -59,7 +59,7 @@ library ClusterLib { cluster.networkFeeIndex, cluster.index, cluster.balance, - cluster.disabled + cluster.active ) ); @@ -77,14 +77,12 @@ library ClusterLib { uint64 clusterIndex, uint64 currentNetworkFeeIndex ) internal pure { - if (!cluster.disabled) { - cluster.balance = clusterBalance( - cluster, - clusterIndex, - currentNetworkFeeIndex - ); - cluster.index = clusterIndex; - cluster.networkFeeIndex = currentNetworkFeeIndex; - } + cluster.balance = clusterBalance( + cluster, + clusterIndex, + currentNetworkFeeIndex + ); + cluster.index = clusterIndex; + cluster.networkFeeIndex = currentNetworkFeeIndex; } } diff --git a/test-e2e/register-validator-gas.ts b/test-e2e/register-validator-gas.ts index d83783af..603f16e9 100644 --- a/test-e2e/register-validator-gas.ts +++ b/test-e2e/register-validator-gas.ts @@ -36,7 +36,7 @@ describe('Register Validator Gas Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ); @@ -61,7 +61,7 @@ describe('Register Validator Gas Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ); const receipt1 = await tx1.wait(); @@ -105,7 +105,7 @@ describe('Register Validator Gas Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ); const receipt1 = await tx1.wait(); @@ -149,7 +149,7 @@ describe('Register Validator Gas Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ); const receipt1 = await tx1.wait(); @@ -193,7 +193,7 @@ describe('Register Validator Gas Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ); const receipt1 = await tx1.wait(); diff --git a/test-e2e/stress.ts b/test-e2e/stress.ts index 820d148b..82ee3900 100644 --- a/test-e2e/stress.ts +++ b/test-e2e/stress.ts @@ -39,11 +39,11 @@ describe('Stress Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true }; // Loop through all created validators to see if the pod you chose is created or not - for (let j = validatorData.length-1; j >= 0; j--) { + for (let j = validatorData.length - 1; j >= 0; j--) { if (validatorData[j].operatorPoint === randomOperatorPoint && validatorData[j].owner === randomOwner) { podData = validatorData[j].pod; break; @@ -53,7 +53,7 @@ describe('Stress Tests', () => { // Register a validator const tx = await ssvNetworkContract.connect(helpers.DB.owners[randomOwner]).registerValidator( validatorPublicKey, - [randomOperatorPoint,randomOperatorPoint+1,randomOperatorPoint+2,randomOperatorPoint+3], + [randomOperatorPoint, randomOperatorPoint + 1, randomOperatorPoint + 2, randomOperatorPoint + 3], helpers.DataGenerator.shares(0), minDepositAmount, podData @@ -65,17 +65,17 @@ describe('Stress Tests', () => { const args = (receipt.events[3].args[4]); // Break the pod event to a struct - const pod = { + const pod = { validatorCount: args.validatorCount, networkFee: args.networkFee, networkFeeIndex: args.networkFeeIndex, index: args.index, balance: args.balance, - disabled: args.disabled + active: args.active }; // Push the validator to an array - validatorData.push({publicKey: validatorPublicKey, operatorPoint: randomOperatorPoint, owner: randomOwner, pod: pod}); + validatorData.push({ publicKey: validatorPublicKey, operatorPoint: randomOperatorPoint, owner: randomOwner, pod: pod }); } }); @@ -101,12 +101,12 @@ describe('Stress Tests', () => { it('Remove 1000 validators', async () => { const newValidatorData: any = []; - for (let i = 0; i < validatorData.length-1; i++) { + for (let i = 0; i < validatorData.length - 1; i++) { let podData: any; // Loop and get latest pod - for (let j = validatorData.length-1; j >= 0; j--) { + for (let j = validatorData.length - 1; j >= 0; j--) { if (validatorData[j].operatorPoint === validatorData[i].operatorPoint && validatorData[j].owner === validatorData[i].owner) { podData = validatorData[j].pod; break; @@ -114,7 +114,7 @@ describe('Stress Tests', () => { } // Loop through new emits to get even more up to date pod if neeeded - for (let j = newValidatorData.length-1; j >= 0; j--) { + for (let j = newValidatorData.length - 1; j >= 0; j--) { if (newValidatorData[j].operatorPoint === validatorData[i].operatorPoint && newValidatorData[j].owner === validatorData[i].owner) { podData = newValidatorData[j].pod; break; @@ -124,7 +124,7 @@ describe('Stress Tests', () => { // Remove a validator const { eventsByName } = await trackGas(await ssvNetworkContract.connect(helpers.DB.owners[validatorData[i].owner]).removeValidator( validatorData[i].publicKey, - [validatorData[i].operatorPoint, validatorData[i].operatorPoint+1, validatorData[i].operatorPoint+2, validatorData[i].operatorPoint+3], + [validatorData[i].operatorPoint, validatorData[i].operatorPoint + 1, validatorData[i].operatorPoint + 2, validatorData[i].operatorPoint + 3], podData ), [GasGroup.REMOVE_VALIDATOR]); @@ -132,17 +132,17 @@ describe('Stress Tests', () => { const args = (eventsByName.ValidatorRemoved[0].args).pod; // Form a pod struct - const pod = { + const pod = { validatorCount: args.validatorCount, networkFee: args.networkFee, networkFeeIndex: args.networkFeeIndex, index: args.index, balance: args.balance, - disabled: args.disabled + active: args.active }; // Save new validator data - newValidatorData.push({publicKey: validatorData[i].validatorPublicKey, operatorPoint: validatorData[i].operatorPoint, owner: validatorData[i].owner, pod: pod}); + newValidatorData.push({ publicKey: validatorData[i].validatorPublicKey, operatorPoint: validatorData[i].operatorPoint, owner: validatorData[i].owner, pod: pod }); } }); diff --git a/test/account/deposit.ts b/test/account/deposit.ts index c44ffa3b..7dde8925 100644 --- a/test/account/deposit.ts +++ b/test/account/deposit.ts @@ -29,7 +29,7 @@ describe('Deposit Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ); diff --git a/test/account/withdraw.ts b/test/account/withdraw.ts index cd765522..a3593676 100644 --- a/test/account/withdraw.ts +++ b/test/account/withdraw.ts @@ -31,7 +31,7 @@ describe('Withdraw Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ); diff --git a/test/dao/network-fee-withdraw.ts b/test/dao/network-fee-withdraw.ts index 2fb19fdc..ecf6dbf1 100644 --- a/test/dao/network-fee-withdraw.ts +++ b/test/dao/network-fee-withdraw.ts @@ -43,7 +43,7 @@ describe('DAO Network Fee Withdraw Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ); diff --git a/test/helpers/contract-helpers.ts b/test/helpers/contract-helpers.ts index d21dfcac..8901cece 100644 --- a/test/helpers/contract-helpers.ts +++ b/test/helpers/contract-helpers.ts @@ -165,7 +165,7 @@ export const registerValidators = async (ownerId: number, numberOfValidators: nu networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ), gasGroups); args = result.eventsByName.ValidatorAdded[0].args; @@ -184,7 +184,7 @@ export const registerValidatorsRaw = async (ownerId: number, numberOfValidators: networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true }; for (let i = 0; i < numberOfValidators; i++) { @@ -207,7 +207,7 @@ export const registerValidatorsRaw = async (ownerId: number, numberOfValidators: networkFeeIndex: clusterData.networkFeeIndex, index: clusterData.index, balance: clusterData.balance, - disabled: false + active: true }; } @@ -215,7 +215,7 @@ export const registerValidatorsRaw = async (ownerId: number, numberOfValidators: export const getCluster = (payload: any) => ethers.utils.AbiCoder.prototype.encode( - ['tuple(uint32 validatorCount, uint64 networkFee, uint64 networkFeeIndex, uint64 index, uint64 balance, bool disabled) cluster'], + ['tuple(uint32 validatorCount, uint64 networkFee, uint64 networkFeeIndex, uint64 index, uint64 balance, bool active) cluster'], [payload] ); diff --git a/test/helpers/gas-usage.ts b/test/helpers/gas-usage.ts index d7d5dd9b..3f6977d6 100644 --- a/test/helpers/gas-usage.ts +++ b/test/helpers/gas-usage.ts @@ -36,19 +36,19 @@ const MAX_GAS_PER_GROUP: any = { [GasGroup.REMOVE_OPERATOR]: 62000, [GasGroup.REMOVE_OPERATOR_WITH_WITHDRAW]: 62000, - [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]: 187000, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE]: 204000, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT]: 166000, + [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]: 185300, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE]: 202200, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT]: 164800, - [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_7]: 250000, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]: 267000, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_7]: 229500, + [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_7]: 248500, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]: 265400, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_7]: 228000, - [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_13]: 377000, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]: 394000, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_13]: 357000, + [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_13]: 375500, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]: 392300, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_13]: 355000, - [GasGroup.REMOVE_VALIDATOR]: 120000, + [GasGroup.REMOVE_VALIDATOR]: 106300, [GasGroup.TRANSFER_VALIDATOR_NEW_CLUSTER]: 400000, [GasGroup.TRANSFER_VALIDATOR]: 260000, [GasGroup.TRANSFER_VALIDATOR_NON_EXISTING_POD]: 290000, diff --git a/test/liquidate/liquidate.ts b/test/liquidate/liquidate.ts index b7b0a7d6..837f7be7 100644 --- a/test/liquidate/liquidate.ts +++ b/test/liquidate/liquidate.ts @@ -32,7 +32,7 @@ describe('Liquidate Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ); @@ -49,7 +49,7 @@ describe('Liquidate Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); firstCluster = register.eventsByName.ValidatorAdded[0].args; @@ -162,7 +162,7 @@ describe('Liquidate Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } )).to.be.revertedWithCustomError(ssvNetworkContract,'IncorrectClusterState'); }); diff --git a/test/liquidate/reactivate.ts b/test/liquidate/reactivate.ts index 9f88857d..daed3ed7 100644 --- a/test/liquidate/reactivate.ts +++ b/test/liquidate/reactivate.ts @@ -31,7 +31,7 @@ describe('Reactivate Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ); @@ -48,7 +48,7 @@ describe('Reactivate Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); firstCluster = register.eventsByName.ValidatorAdded[0].args; diff --git a/test/operators/remove.ts b/test/operators/remove.ts index 263577c7..f2eaa51e 100644 --- a/test/operators/remove.ts +++ b/test/operators/remove.ts @@ -26,7 +26,7 @@ describe('Remove Operator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ); }); diff --git a/test/sanity/balances.ts b/test/sanity/balances.ts index 1e836cdc..52e9f649 100644 --- a/test/sanity/balances.ts +++ b/test/sanity/balances.ts @@ -41,7 +41,7 @@ describe('Balance Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ); diff --git a/test/validators/register.ts b/test/validators/register.ts index 141dc13a..4425bc3a 100644 --- a/test/validators/register.ts +++ b/test/validators/register.ts @@ -30,7 +30,7 @@ describe('Register Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } )); }); @@ -48,7 +48,7 @@ describe('Register Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } )).to.emit(ssvNetworkContract, 'ValidatorAdded'); }); @@ -66,7 +66,7 @@ describe('Register Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); }); @@ -84,7 +84,7 @@ describe('Register Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); @@ -113,7 +113,7 @@ describe('Register Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); @@ -140,7 +140,7 @@ describe('Register Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); }); @@ -158,7 +158,7 @@ describe('Register Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); @@ -187,7 +187,7 @@ describe('Register Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]); }); @@ -205,7 +205,7 @@ describe('Register Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]); @@ -234,7 +234,7 @@ describe('Register Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]); @@ -261,7 +261,7 @@ describe('Register Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]); }); @@ -279,7 +279,7 @@ describe('Register Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]); @@ -308,7 +308,7 @@ describe('Register Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]); }); @@ -326,7 +326,7 @@ describe('Register Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]); @@ -355,7 +355,7 @@ describe('Register Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]); @@ -382,7 +382,7 @@ describe('Register Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]); }); @@ -400,7 +400,7 @@ describe('Register Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]); @@ -451,7 +451,7 @@ describe('Register Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ); @@ -466,7 +466,7 @@ describe('Register Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } )).to.be.revertedWithCustomError(ssvNetworkContract, 'IncorrectClusterState'); }); @@ -483,7 +483,7 @@ describe('Register Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } )).to.be.revertedWithCustomError(ssvNetworkContract, 'OperatorDoesNotExist'); }); @@ -501,7 +501,7 @@ describe('Register Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } )).to.be.revertedWithCustomError(ssvNetworkContract, 'OperatorDoesNotExist'); }); @@ -534,7 +534,7 @@ describe('Register Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } )).to.be.revertedWithCustomError(ssvNetworkContract, 'InvalidPublicKeyLength'); }); @@ -552,7 +552,7 @@ describe('Register Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } )).to.be.revertedWithCustomError(ssvNetworkContract, 'InsufficientBalance'); }); @@ -570,7 +570,7 @@ describe('Register Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } )).to.be.revertedWithCustomError(ssvNetworkContract, 'ValidatorAlreadyExists'); }); @@ -600,7 +600,7 @@ describe('Register Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } )).to.be.revertedWithCustomError(ssvNetwork, 'ExceedValidatorLimit'); diff --git a/test/validators/remove.ts b/test/validators/remove.ts index 28a10538..9294957b 100644 --- a/test/validators/remove.ts +++ b/test/validators/remove.ts @@ -31,7 +31,7 @@ describe('Remove Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ); @@ -48,7 +48,7 @@ describe('Remove Validator Tests', () => { networkFeeIndex: 0, index: 0, balance: 0, - disabled: false + active: true } ), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); firstCluster = register.eventsByName.ValidatorAdded[0].args; From 1ec7c8245319d9c14bec4eb00b48d3fc97bde980 Mon Sep 17 00:00:00 2001 From: Marco Tabasco Date: Thu, 2 Mar 2023 13:51:17 +0100 Subject: [PATCH 136/149] Fix liquidate transfer (#197) * fix transfer when liquidating --- contracts/SSVNetwork.sol | 17 ++++++++--------- test/liquidate/liquidate.ts | 27 ++++++++++++++++----------- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index 973b0bd7..82985ab2 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -409,8 +409,9 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { clusterIndex, NetworkLib.currentNetworkFeeIndex(network) ); - + uint64 networkFee = network.networkFee; + uint256 balanceLiquidatable = cluster.balance; if ( owner != msg.sender && @@ -423,17 +424,15 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { revert ClusterNotLiquidatable(); } + DAO memory dao_ = dao; + dao_.updateDAOEarnings(networkFee); + dao_.validatorCount -= cluster.validatorCount; + dao = dao_; + cluster.active = false; cluster.balance = 0; cluster.index = 0; - { - DAO memory dao_ = dao; - dao_.updateDAOEarnings(networkFee); - dao_.validatorCount -= cluster.validatorCount; - dao = dao_; - } - clusters[hashedCluster] = keccak256( abi.encodePacked( cluster.validatorCount, @@ -444,7 +443,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { ) ); - _transfer(msg.sender, cluster.balance); + _transfer(msg.sender, balanceLiquidatable); emit ClusterLiquidated(owner, operatorIds, cluster); } diff --git a/test/liquidate/liquidate.ts b/test/liquidate/liquidate.ts index 837f7be7..dd928125 100644 --- a/test/liquidate/liquidate.ts +++ b/test/liquidate/liquidate.ts @@ -23,7 +23,7 @@ describe('Liquidate Tests', () => { await helpers.DB.ssvToken.connect(helpers.DB.owners[6]).approve(helpers.DB.ssvNetwork.contract.address, '1000000000000000'); await ssvNetworkContract.connect(helpers.DB.owners[6]).registerValidator( '0x221111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111119', - [1,2,3,4], + [1, 2, 3, 4], helpers.DataGenerator.shares(4), '1000000000000000', { @@ -40,7 +40,7 @@ describe('Liquidate Tests', () => { 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], + [1, 2, 3, 4], helpers.DataGenerator.shares(4), minDepositAmount, { @@ -62,7 +62,12 @@ describe('Liquidate Tests', () => { firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster - )).to.emit(ssvNetworkContract, 'ClusterLiquidated'); + )).to.emit(ssvNetworkContract, 'ClusterLiquidated') + .to.emit(helpers.DB.ssvToken, 'Transfer').withArgs( + ssvNetworkContract.address, + helpers.DB.owners[0].address, + minDepositAmount - (helpers.CONFIG.minimalOperatorFee * 4 * 6571) + ); }); it('Liquidatable with removed operator', async () => { @@ -90,16 +95,16 @@ describe('Liquidate Tests', () => { ), [GasGroup.LIQUIDATE_POD]); 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 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}`, + `${minDepositAmount * 2}`, updatedCluster.cluster - )).to.be.revertedWithCustomError(ssvNetworkContract,'ClusterIsLiquidated'); + )).to.be.revertedWithCustomError(ssvNetworkContract, 'ClusterIsLiquidated'); }); - + it('Liquidate cluster and check isLiquidated true', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); const liquidatedCluster = await trackGas(ssvNetworkContract.liquidate( @@ -149,7 +154,7 @@ describe('Liquidate Tests', () => { firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster - )).to.be.revertedWithCustomError(ssvNetworkContract,'ClusterNotLiquidatable'); + )).to.be.revertedWithCustomError(ssvNetworkContract, 'ClusterNotLiquidatable'); }); it('Liquidate a cluster that is not liquidatable reverts "IncorrectClusterState"', async () => { @@ -164,7 +169,7 @@ describe('Liquidate Tests', () => { balance: 0, active: true } - )).to.be.revertedWithCustomError(ssvNetworkContract,'IncorrectClusterState'); + )).to.be.revertedWithCustomError(ssvNetworkContract, 'IncorrectClusterState'); }); it('Liquidate already liquidated cluster reverts "ClusterIsLiquidated"', async () => { @@ -180,7 +185,7 @@ describe('Liquidate Tests', () => { firstCluster.owner, updatedCluster.operatorIds, updatedCluster.cluster - )).to.be.revertedWithCustomError(ssvNetworkContract,'ClusterIsLiquidated'); + )).to.be.revertedWithCustomError(ssvNetworkContract, 'ClusterIsLiquidated'); }); it('Is liquidated reverts "ClusterDoesNotExists"', async () => { @@ -192,6 +197,6 @@ describe('Liquidate Tests', () => { ), [GasGroup.LIQUIDATE_POD]); const updatedCluster = liquidatedCluster.eventsByName.ClusterLiquidated[0].args; - await expect(ssvViews.isLiquidated(helpers.DB.owners[0].address, firstCluster.operatorIds, updatedCluster.cluster)).to.be.revertedWithCustomError(ssvNetworkContract,'ClusterDoesNotExists'); + await expect(ssvViews.isLiquidated(helpers.DB.owners[0].address, firstCluster.operatorIds, updatedCluster.cluster)).to.be.revertedWithCustomError(ssvNetworkContract, 'ClusterDoesNotExists'); }); }); \ No newline at end of file From 141e125820b8f1fe9d9ae6f5c71e1da157f2a958 Mon Sep 17 00:00:00 2001 From: Marco Date: Wed, 8 Mar 2023 16:06:15 +0100 Subject: [PATCH 137/149] push goerli deployment info --- .gitignore | 2 +- .openzeppelin/goerli.json | 1393 +++++++++++++++++++++++++++++++++++++ 2 files changed, 1394 insertions(+), 1 deletion(-) create mode 100644 .openzeppelin/goerli.json diff --git a/.gitignore b/.gitignore index 7ab021d3..083546ce 100644 --- a/.gitignore +++ b/.gitignore @@ -7,7 +7,7 @@ cache coverage coverage.json artifacts -.openzeppelin/ +.openzeppelin/dev-*.json subgraph/build .idea /incentivized_testnet/operators* diff --git a/.openzeppelin/goerli.json b/.openzeppelin/goerli.json new file mode 100644 index 00000000..777629d5 --- /dev/null +++ b/.openzeppelin/goerli.json @@ -0,0 +1,1393 @@ +{ + "manifestVersion": "3.2", + "proxies": [ + { + "address": "0x3A23a7F455E853058d900f5dc86f1Bb1589b54F9", + "txHash": "0x9802d184ef00cd873e770ecabe377fb98e5fd7c422946c5d46a2866f42dc93d2", + "kind": "uups" + }, + { + "address": "0x4ddfE2966f7Cdfe1F7d4f7d48949b3AB16BCc6B5", + "txHash": "0x7f46d97d62a3f25fe62473d9839871949408b23a07bd4541b52eb4a03090523f", + "kind": "uups" + } + ], + "impls": { + "84c23f7724698de84eb813dbfda03172032dfda80fc9218f7edeef2aa8404809": { + "address": "0xC3f92f9F001De4Fe36f9aF7A093842d7fc1a8718", + "txHash": "0x7206af5ce75169aac83dcaf88d81a0744f58834e456cf984a89af704e1a57ea5", + "layout": { + "solcVersion": "0.8.16", + "storage": [ + { + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_uint8", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:62", + "retypedFrom": "bool" + }, + { + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:67" + }, + { + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)50_storage", + "contract": "ERC1967UpgradeUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol:211" + }, + { + "label": "__gap", + "offset": 0, + "slot": "51", + "type": "t_array(t_uint256)50_storage", + "contract": "UUPSUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol:107" + }, + { + "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": "lastOperatorId", + "offset": 0, + "slot": "251", + "type": "t_struct(Counter)1401_storage", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:40" + }, + { + "label": "operators", + "offset": 0, + "slot": "252", + "type": "t_mapping(t_uint64,t_struct(Operator)1833_storage)", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:46" + }, + { + "label": "operatorFeeChangeRequests", + "offset": 0, + "slot": "253", + "type": "t_mapping(t_uint64,t_struct(OperatorFeeChangeRequest)1840_storage)", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:47" + }, + { + "label": "clusters", + "offset": 0, + "slot": "254", + "type": "t_mapping(t_bytes32,t_bytes32)", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:49" + }, + { + "label": "_validatorPKs", + "offset": 0, + "slot": "255", + "type": "t_mapping(t_bytes32,t_struct(Validator)1812_storage)", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:50" + }, + { + "label": "version", + "offset": 0, + "slot": "256", + "type": "t_bytes32", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:52" + }, + { + "label": "validatorsPerOperatorLimit", + "offset": 0, + "slot": "257", + "type": "t_uint32", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:54" + }, + { + "label": "declareOperatorFeePeriod", + "offset": 4, + "slot": "257", + "type": "t_uint64", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:55" + }, + { + "label": "executeOperatorFeePeriod", + "offset": 12, + "slot": "257", + "type": "t_uint64", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:56" + }, + { + "label": "operatorMaxFeeIncrease", + "offset": 20, + "slot": "257", + "type": "t_uint64", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:57" + }, + { + "label": "minimumBlocksBeforeLiquidation", + "offset": 0, + "slot": "258", + "type": "t_uint64", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:58" + }, + { + "label": "dao", + "offset": 0, + "slot": "259", + "type": "t_struct(DAO)1858_storage", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:60" + }, + { + "label": "_token", + "offset": 0, + "slot": "260", + "type": "t_contract(IERC20)1395", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:61" + }, + { + "label": "network", + "offset": 0, + "slot": "261", + "type": "t_struct(Network)1865_storage", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:62" + }, + { + "label": "__gap", + "offset": 0, + "slot": "262", + "type": "t_array(t_uint256)50_storage", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:66" + } + ], + "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_bytes32": { + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_contract(IERC20)1395": { + "label": "contract IERC20", + "numberOfBytes": "20" + }, + "t_mapping(t_bytes32,t_bytes32)": { + "label": "mapping(bytes32 => bytes32)", + "numberOfBytes": "32" + }, + "t_mapping(t_bytes32,t_struct(Validator)1812_storage)": { + "label": "mapping(bytes32 => struct ISSVNetworkCore.Validator)", + "numberOfBytes": "32" + }, + "t_mapping(t_uint64,t_struct(Operator)1833_storage)": { + "label": "mapping(uint64 => struct ISSVNetworkCore.Operator)", + "numberOfBytes": "32" + }, + "t_mapping(t_uint64,t_struct(OperatorFeeChangeRequest)1840_storage)": { + "label": "mapping(uint64 => struct ISSVNetworkCore.OperatorFeeChangeRequest)", + "numberOfBytes": "32" + }, + "t_struct(Counter)1401_storage": { + "label": "struct Counters.Counter", + "members": [ + { + "label": "_value", + "type": "t_uint256", + "offset": 0, + "slot": "0" + } + ], + "numberOfBytes": "32" + }, + "t_struct(DAO)1858_storage": { + "label": "struct ISSVNetworkCore.DAO", + "members": [ + { + "label": "validatorCount", + "type": "t_uint32", + "offset": 0, + "slot": "0" + }, + { + "label": "balance", + "type": "t_uint64", + "offset": 4, + "slot": "0" + }, + { + "label": "block", + "type": "t_uint64", + "offset": 12, + "slot": "0" + } + ], + "numberOfBytes": "32" + }, + "t_struct(Network)1865_storage": { + "label": "struct ISSVNetworkCore.Network", + "members": [ + { + "label": "networkFee", + "type": "t_uint64", + "offset": 0, + "slot": "0" + }, + { + "label": "networkFeeIndex", + "type": "t_uint64", + "offset": 8, + "slot": "0" + }, + { + "label": "networkFeeIndexBlockNumber", + "type": "t_uint64", + "offset": 16, + "slot": "0" + } + ], + "numberOfBytes": "32" + }, + "t_struct(Operator)1833_storage": { + "label": "struct ISSVNetworkCore.Operator", + "members": [ + { + "label": "owner", + "type": "t_address", + "offset": 0, + "slot": "0" + }, + { + "label": "fee", + "type": "t_uint64", + "offset": 20, + "slot": "0" + }, + { + "label": "validatorCount", + "type": "t_uint32", + "offset": 28, + "slot": "0" + }, + { + "label": "snapshot", + "type": "t_struct(Snapshot)1822_storage", + "offset": 0, + "slot": "1" + } + ], + "numberOfBytes": "64" + }, + "t_struct(OperatorFeeChangeRequest)1840_storage": { + "label": "struct ISSVNetworkCore.OperatorFeeChangeRequest", + "members": [ + { + "label": "fee", + "type": "t_uint64", + "offset": 0, + "slot": "0" + }, + { + "label": "approvalBeginTime", + "type": "t_uint64", + "offset": 8, + "slot": "0" + }, + { + "label": "approvalEndTime", + "type": "t_uint64", + "offset": 16, + "slot": "0" + } + ], + "numberOfBytes": "32" + }, + "t_struct(Snapshot)1822_storage": { + "label": "struct ISSVNetworkCore.Snapshot", + "members": [ + { + "label": "block", + "type": "t_uint64", + "offset": 0, + "slot": "0" + }, + { + "label": "index", + "type": "t_uint64", + "offset": 8, + "slot": "0" + }, + { + "label": "balance", + "type": "t_uint64", + "offset": 16, + "slot": "0" + } + ], + "numberOfBytes": "32" + }, + "t_struct(Validator)1812_storage": { + "label": "struct ISSVNetworkCore.Validator", + "members": [ + { + "label": "owner", + "type": "t_address", + "offset": 0, + "slot": "0" + }, + { + "label": "active", + "type": "t_bool", + "offset": 20, + "slot": "0" + } + ], + "numberOfBytes": "32" + }, + "t_uint256": { + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint32": { + "label": "uint32", + "numberOfBytes": "4" + }, + "t_uint64": { + "label": "uint64", + "numberOfBytes": "8" + }, + "t_uint8": { + "label": "uint8", + "numberOfBytes": "1" + } + } + } + }, + "660ed01ee43f3f2af646276a03204bac7cb226ab7013ef4ca1a2a5900bd9b6c2": { + "address": "0xE858F79E4220fC552522563aE2C55Be6f5d661f4", + "txHash": "0xbbedf6dd62602c37ad101e4575336fa1bc815365581c3d1dc0e79490c9da3b5b", + "layout": { + "solcVersion": "0.8.16", + "storage": [ + { + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_uint8", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:62", + "retypedFrom": "bool" + }, + { + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:67" + }, + { + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)50_storage", + "contract": "ERC1967UpgradeUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol:211" + }, + { + "label": "__gap", + "offset": 0, + "slot": "51", + "type": "t_array(t_uint256)50_storage", + "contract": "UUPSUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol:107" + }, + { + "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(SSVNetwork)5018", + "contract": "SSVNetworkViews", + "src": "contracts/SSVNetworkViews.sol:26" + }, + { + "label": "__gap", + "offset": 0, + "slot": "252", + "type": "t_array(t_uint256)50_storage", + "contract": "SSVNetworkViews", + "src": "contracts/SSVNetworkViews.sol:30" + } + ], + "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(SSVNetwork)5018": { + "label": "contract SSVNetwork", + "numberOfBytes": "20" + }, + "t_uint256": { + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint8": { + "label": "uint8", + "numberOfBytes": "1" + } + } + } + }, + "1e164419e5042d71372eda74f4b4650521a5473bbd51b5c1e1cee4b82afe94b7": { + "address": "0xe7A57a7a489d884C30946573A61C173928e03F9B", + "txHash": "0x50f9eca193ce521eecbdd47b73cb5718767b23db6f85d93c363df8f0ed5b5deb", + "layout": { + "solcVersion": "0.8.16", + "storage": [ + { + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_uint8", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:62", + "retypedFrom": "bool" + }, + { + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:67" + }, + { + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)50_storage", + "contract": "ERC1967UpgradeUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol:211" + }, + { + "label": "__gap", + "offset": 0, + "slot": "51", + "type": "t_array(t_uint256)50_storage", + "contract": "UUPSUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol:107" + }, + { + "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": "lastOperatorId", + "offset": 0, + "slot": "251", + "type": "t_struct(Counter)1401_storage", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:40" + }, + { + "label": "operators", + "offset": 0, + "slot": "252", + "type": "t_mapping(t_uint64,t_struct(Operator)1833_storage)", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:46" + }, + { + "label": "operatorFeeChangeRequests", + "offset": 0, + "slot": "253", + "type": "t_mapping(t_uint64,t_struct(OperatorFeeChangeRequest)1840_storage)", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:47" + }, + { + "label": "clusters", + "offset": 0, + "slot": "254", + "type": "t_mapping(t_bytes32,t_bytes32)", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:49" + }, + { + "label": "_validatorPKs", + "offset": 0, + "slot": "255", + "type": "t_mapping(t_bytes32,t_struct(Validator)1812_storage)", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:50" + }, + { + "label": "version", + "offset": 0, + "slot": "256", + "type": "t_bytes32", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:52" + }, + { + "label": "validatorsPerOperatorLimit", + "offset": 0, + "slot": "257", + "type": "t_uint32", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:54" + }, + { + "label": "declareOperatorFeePeriod", + "offset": 4, + "slot": "257", + "type": "t_uint64", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:55" + }, + { + "label": "executeOperatorFeePeriod", + "offset": 12, + "slot": "257", + "type": "t_uint64", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:56" + }, + { + "label": "operatorMaxFeeIncrease", + "offset": 20, + "slot": "257", + "type": "t_uint64", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:57" + }, + { + "label": "minimumBlocksBeforeLiquidation", + "offset": 0, + "slot": "258", + "type": "t_uint64", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:58" + }, + { + "label": "dao", + "offset": 0, + "slot": "259", + "type": "t_struct(DAO)1858_storage", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:60" + }, + { + "label": "_token", + "offset": 0, + "slot": "260", + "type": "t_contract(IERC20)1395", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:61" + }, + { + "label": "network", + "offset": 0, + "slot": "261", + "type": "t_struct(Network)1865_storage", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:62" + }, + { + "label": "__gap", + "offset": 0, + "slot": "262", + "type": "t_array(t_uint256)50_storage", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:66" + } + ], + "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_bytes32": { + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_contract(IERC20)1395": { + "label": "contract IERC20", + "numberOfBytes": "20" + }, + "t_mapping(t_bytes32,t_bytes32)": { + "label": "mapping(bytes32 => bytes32)", + "numberOfBytes": "32" + }, + "t_mapping(t_bytes32,t_struct(Validator)1812_storage)": { + "label": "mapping(bytes32 => struct ISSVNetworkCore.Validator)", + "numberOfBytes": "32" + }, + "t_mapping(t_uint64,t_struct(Operator)1833_storage)": { + "label": "mapping(uint64 => struct ISSVNetworkCore.Operator)", + "numberOfBytes": "32" + }, + "t_mapping(t_uint64,t_struct(OperatorFeeChangeRequest)1840_storage)": { + "label": "mapping(uint64 => struct ISSVNetworkCore.OperatorFeeChangeRequest)", + "numberOfBytes": "32" + }, + "t_struct(Counter)1401_storage": { + "label": "struct Counters.Counter", + "members": [ + { + "label": "_value", + "type": "t_uint256", + "offset": 0, + "slot": "0" + } + ], + "numberOfBytes": "32" + }, + "t_struct(DAO)1858_storage": { + "label": "struct ISSVNetworkCore.DAO", + "members": [ + { + "label": "validatorCount", + "type": "t_uint32", + "offset": 0, + "slot": "0" + }, + { + "label": "balance", + "type": "t_uint64", + "offset": 4, + "slot": "0" + }, + { + "label": "block", + "type": "t_uint64", + "offset": 12, + "slot": "0" + } + ], + "numberOfBytes": "32" + }, + "t_struct(Network)1865_storage": { + "label": "struct ISSVNetworkCore.Network", + "members": [ + { + "label": "networkFee", + "type": "t_uint64", + "offset": 0, + "slot": "0" + }, + { + "label": "networkFeeIndex", + "type": "t_uint64", + "offset": 8, + "slot": "0" + }, + { + "label": "networkFeeIndexBlockNumber", + "type": "t_uint64", + "offset": 16, + "slot": "0" + } + ], + "numberOfBytes": "32" + }, + "t_struct(Operator)1833_storage": { + "label": "struct ISSVNetworkCore.Operator", + "members": [ + { + "label": "owner", + "type": "t_address", + "offset": 0, + "slot": "0" + }, + { + "label": "fee", + "type": "t_uint64", + "offset": 20, + "slot": "0" + }, + { + "label": "validatorCount", + "type": "t_uint32", + "offset": 28, + "slot": "0" + }, + { + "label": "snapshot", + "type": "t_struct(Snapshot)1822_storage", + "offset": 0, + "slot": "1" + } + ], + "numberOfBytes": "64" + }, + "t_struct(OperatorFeeChangeRequest)1840_storage": { + "label": "struct ISSVNetworkCore.OperatorFeeChangeRequest", + "members": [ + { + "label": "fee", + "type": "t_uint64", + "offset": 0, + "slot": "0" + }, + { + "label": "approvalBeginTime", + "type": "t_uint64", + "offset": 8, + "slot": "0" + }, + { + "label": "approvalEndTime", + "type": "t_uint64", + "offset": 16, + "slot": "0" + } + ], + "numberOfBytes": "32" + }, + "t_struct(Snapshot)1822_storage": { + "label": "struct ISSVNetworkCore.Snapshot", + "members": [ + { + "label": "block", + "type": "t_uint64", + "offset": 0, + "slot": "0" + }, + { + "label": "index", + "type": "t_uint64", + "offset": 8, + "slot": "0" + }, + { + "label": "balance", + "type": "t_uint64", + "offset": 16, + "slot": "0" + } + ], + "numberOfBytes": "32" + }, + "t_struct(Validator)1812_storage": { + "label": "struct ISSVNetworkCore.Validator", + "members": [ + { + "label": "owner", + "type": "t_address", + "offset": 0, + "slot": "0" + }, + { + "label": "active", + "type": "t_bool", + "offset": 20, + "slot": "0" + } + ], + "numberOfBytes": "32" + }, + "t_uint256": { + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint32": { + "label": "uint32", + "numberOfBytes": "4" + }, + "t_uint64": { + "label": "uint64", + "numberOfBytes": "8" + }, + "t_uint8": { + "label": "uint8", + "numberOfBytes": "1" + } + } + } + }, + "c7f446c2126eeceebac6ff1bbb1cc583a527079acd7f8929332ade86b5852b55": { + "address": "0x2fe8da61509Fd14a1ac00ad589Ffd0Bf1145956D", + "txHash": "0x740ae16c8cf791324207db865b65aceb45ecacb2bcb75306c57fa410de574589", + "layout": { + "solcVersion": "0.8.16", + "storage": [ + { + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_uint8", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:62", + "retypedFrom": "bool" + }, + { + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:67" + }, + { + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)50_storage", + "contract": "ERC1967UpgradeUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol:211" + }, + { + "label": "__gap", + "offset": 0, + "slot": "51", + "type": "t_array(t_uint256)50_storage", + "contract": "UUPSUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol:107" + }, + { + "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": "lastOperatorId", + "offset": 0, + "slot": "251", + "type": "t_struct(Counter)1401_storage", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:40" + }, + { + "label": "operators", + "offset": 0, + "slot": "252", + "type": "t_mapping(t_uint64,t_struct(Operator)1833_storage)", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:46" + }, + { + "label": "operatorFeeChangeRequests", + "offset": 0, + "slot": "253", + "type": "t_mapping(t_uint64,t_struct(OperatorFeeChangeRequest)1840_storage)", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:47" + }, + { + "label": "clusters", + "offset": 0, + "slot": "254", + "type": "t_mapping(t_bytes32,t_bytes32)", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:49" + }, + { + "label": "_validatorPKs", + "offset": 0, + "slot": "255", + "type": "t_mapping(t_bytes32,t_struct(Validator)1812_storage)", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:50" + }, + { + "label": "version", + "offset": 0, + "slot": "256", + "type": "t_bytes32", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:52" + }, + { + "label": "validatorsPerOperatorLimit", + "offset": 0, + "slot": "257", + "type": "t_uint32", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:54" + }, + { + "label": "declareOperatorFeePeriod", + "offset": 4, + "slot": "257", + "type": "t_uint64", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:55" + }, + { + "label": "executeOperatorFeePeriod", + "offset": 12, + "slot": "257", + "type": "t_uint64", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:56" + }, + { + "label": "operatorMaxFeeIncrease", + "offset": 20, + "slot": "257", + "type": "t_uint64", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:57" + }, + { + "label": "minimumBlocksBeforeLiquidation", + "offset": 0, + "slot": "258", + "type": "t_uint64", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:58" + }, + { + "label": "dao", + "offset": 0, + "slot": "259", + "type": "t_struct(DAO)1858_storage", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:60" + }, + { + "label": "_token", + "offset": 0, + "slot": "260", + "type": "t_contract(IERC20)1395", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:61" + }, + { + "label": "network", + "offset": 0, + "slot": "261", + "type": "t_struct(Network)1865_storage", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:62" + }, + { + "label": "__gap", + "offset": 0, + "slot": "262", + "type": "t_array(t_uint256)50_storage", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:66" + } + ], + "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_bytes32": { + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_contract(IERC20)1395": { + "label": "contract IERC20", + "numberOfBytes": "20" + }, + "t_mapping(t_bytes32,t_bytes32)": { + "label": "mapping(bytes32 => bytes32)", + "numberOfBytes": "32" + }, + "t_mapping(t_bytes32,t_struct(Validator)1812_storage)": { + "label": "mapping(bytes32 => struct ISSVNetworkCore.Validator)", + "numberOfBytes": "32" + }, + "t_mapping(t_uint64,t_struct(Operator)1833_storage)": { + "label": "mapping(uint64 => struct ISSVNetworkCore.Operator)", + "numberOfBytes": "32" + }, + "t_mapping(t_uint64,t_struct(OperatorFeeChangeRequest)1840_storage)": { + "label": "mapping(uint64 => struct ISSVNetworkCore.OperatorFeeChangeRequest)", + "numberOfBytes": "32" + }, + "t_struct(Counter)1401_storage": { + "label": "struct Counters.Counter", + "members": [ + { + "label": "_value", + "type": "t_uint256", + "offset": 0, + "slot": "0" + } + ], + "numberOfBytes": "32" + }, + "t_struct(DAO)1858_storage": { + "label": "struct ISSVNetworkCore.DAO", + "members": [ + { + "label": "validatorCount", + "type": "t_uint32", + "offset": 0, + "slot": "0" + }, + { + "label": "balance", + "type": "t_uint64", + "offset": 4, + "slot": "0" + }, + { + "label": "block", + "type": "t_uint64", + "offset": 12, + "slot": "0" + } + ], + "numberOfBytes": "32" + }, + "t_struct(Network)1865_storage": { + "label": "struct ISSVNetworkCore.Network", + "members": [ + { + "label": "networkFee", + "type": "t_uint64", + "offset": 0, + "slot": "0" + }, + { + "label": "networkFeeIndex", + "type": "t_uint64", + "offset": 8, + "slot": "0" + }, + { + "label": "networkFeeIndexBlockNumber", + "type": "t_uint64", + "offset": 16, + "slot": "0" + } + ], + "numberOfBytes": "32" + }, + "t_struct(Operator)1833_storage": { + "label": "struct ISSVNetworkCore.Operator", + "members": [ + { + "label": "owner", + "type": "t_address", + "offset": 0, + "slot": "0" + }, + { + "label": "fee", + "type": "t_uint64", + "offset": 20, + "slot": "0" + }, + { + "label": "validatorCount", + "type": "t_uint32", + "offset": 28, + "slot": "0" + }, + { + "label": "snapshot", + "type": "t_struct(Snapshot)1822_storage", + "offset": 0, + "slot": "1" + } + ], + "numberOfBytes": "64" + }, + "t_struct(OperatorFeeChangeRequest)1840_storage": { + "label": "struct ISSVNetworkCore.OperatorFeeChangeRequest", + "members": [ + { + "label": "fee", + "type": "t_uint64", + "offset": 0, + "slot": "0" + }, + { + "label": "approvalBeginTime", + "type": "t_uint64", + "offset": 8, + "slot": "0" + }, + { + "label": "approvalEndTime", + "type": "t_uint64", + "offset": 16, + "slot": "0" + } + ], + "numberOfBytes": "32" + }, + "t_struct(Snapshot)1822_storage": { + "label": "struct ISSVNetworkCore.Snapshot", + "members": [ + { + "label": "block", + "type": "t_uint64", + "offset": 0, + "slot": "0" + }, + { + "label": "index", + "type": "t_uint64", + "offset": 8, + "slot": "0" + }, + { + "label": "balance", + "type": "t_uint64", + "offset": 16, + "slot": "0" + } + ], + "numberOfBytes": "32" + }, + "t_struct(Validator)1812_storage": { + "label": "struct ISSVNetworkCore.Validator", + "members": [ + { + "label": "owner", + "type": "t_address", + "offset": 0, + "slot": "0" + }, + { + "label": "active", + "type": "t_bool", + "offset": 20, + "slot": "0" + } + ], + "numberOfBytes": "32" + }, + "t_uint256": { + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint32": { + "label": "uint32", + "numberOfBytes": "4" + }, + "t_uint64": { + "label": "uint64", + "numberOfBytes": "8" + }, + "t_uint8": { + "label": "uint8", + "numberOfBytes": "1" + } + } + } + } + } +} From 36842a75234606aed150b4d592c13d624481ba16 Mon Sep 17 00:00:00 2001 From: Marco Date: Sat, 11 Mar 2023 01:20:06 +0100 Subject: [PATCH 138/149] setup deploy_manager --- .gitignore | 4 + hardhat.config.ts | 5 +- scripts/bash/deploy_manager | 137 ++++++++++++++ scripts/bash/tag-version | 256 +++++++++++++++++++++++++++ scripts/deploy-all.ts | 51 ------ scripts/upgrade-ssv-network-views.ts | 19 -- scripts/upgrade-ssv-network.ts | 17 -- tasks/deploy-all.ts | 53 ++++++ tasks/upgrade-ssvnetwork.ts | 27 +++ tasks/upgrade-ssvnetworkviews.ts | 27 +++ tasks/utils.ts | 19 ++ 11 files changed, 527 insertions(+), 88 deletions(-) create mode 100644 scripts/bash/deploy_manager create mode 100644 scripts/bash/tag-version delete mode 100644 scripts/deploy-all.ts delete mode 100644 scripts/upgrade-ssv-network-views.ts delete mode 100644 scripts/upgrade-ssv-network.ts create mode 100644 tasks/deploy-all.ts create mode 100644 tasks/upgrade-ssvnetwork.ts create mode 100644 tasks/upgrade-ssvnetworkviews.ts create mode 100644 tasks/utils.ts diff --git a/.gitignore b/.gitignore index 083546ce..8edb8904 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,9 @@ node_modules .env .env.prod .env.stage + +.DS_Store + #Hardhat files cache coverage @@ -9,6 +12,7 @@ coverage.json artifacts .openzeppelin/dev-*.json subgraph/build +typechain-types/ .idea /incentivized_testnet/operators* /incentivized_testnet/validators* diff --git a/hardhat.config.ts b/hardhat.config.ts index cf68cacc..f5bb7ef9 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -1,12 +1,15 @@ import 'dotenv/config'; -import { HardhatUserConfig, task } from 'hardhat/config'; +import { HardhatUserConfig } from 'hardhat/config'; import '@nomicfoundation/hardhat-toolbox'; import '@openzeppelin/hardhat-upgrades'; import 'hardhat-tracer'; import '@nomiclabs/hardhat-solhint'; import 'hardhat-contract-sizer'; import 'hardhat-storage-layout-changes'; +import './tasks/deploy-all' +import './tasks/upgrade-ssvnetwork' +import './tasks/upgrade-ssvnetworkviews' const config: HardhatUserConfig = { // Your type-safe config goes here diff --git a/scripts/bash/deploy_manager b/scripts/bash/deploy_manager new file mode 100644 index 00000000..b1879437 --- /dev/null +++ b/scripts/bash/deploy_manager @@ -0,0 +1,137 @@ +#!/bin/bash + +ABIDIR="" +ACTION="" +NETWORK="localhost" +CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD) +VERSIONTYPE="" + +# Function to return help text when requested with -h option. +help() { + # Display help. + echo + echo "SSV Deployment manager." + echo "Run deployment / upgrade of the branch selected." + echo "When the target network is testnet (goerli) or mainnet, an annotated semantic version tag for current branch is created" + echo "and the ABI is published to this location in gh-pages: " + echo "'docs//abi/' when using stage or main" + echo "'docs//abi/dev' when using develop" + echo + echo "Usage:" + echo " sh deploy_manger [-n|--network] [-a|--action] [-t|--version-type]" + echo + echo "Options:" + echo "-n,--network " + echo " Target network to run the deployment / upgrade." + echo " Possible values: [goerli | mainnet | localhost]" + echo " If ommited, defaults to localhost." + echo + echo "-a,--action " + echo " Action to perform." + echo " Possible values: [deploy | upgrade]" + echo + echo "-t,--version-type [major|minor|patch]" + echo " Type of semantic version to create. Valid options are 'major', 'minor' or 'patch'" + echo " major: Will bump up to next major release (i.e v1.0.0 -> v2.0.0)" + echo " minor: Will bump up to next minor release (i.e v1.0.1 -> v1.1.0)" + echo " patch: Will bump up to next patch release (i.e v1.0.2 -> v1.0.3)" + echo " Rules:" + echo " Tags created using 'stage' branch are treated as RCs (i.e v0.1.0-rc.0 -> v0.1.0-rc.1 ...)" + echo " Tags created using 'main' branch are treated as releases (i.e v0.1.0-rc.1 becomes v0.1.0)" + echo " In both cases, if a version-type parameter is passed, the rule is override (i.e v0.1.0-rc.2 -> -t minor -> v0.2.0-rc.0)" + echo " Tags created using 'develop' branch are not tagged" + echo " If ommited, will default to current version" + echo + echo "-h,--help, help" + echo " Prints this help." + echo +} + +while [[ "$#" -gt 0 ]]; do + case $1 in + -h | --help | help) + help + exit + ;; + -n | --network) + NETWORK=$2 + ;; + -t | --version-type) + VERSIONTYPE=$2 + ;; + -a | --action) + ACTION=$2 + ;; + esac + shift +done + +if [ "$ACTION" == "" ]; then + echo "-- ERROR: ACTION option is mandatory. Possible values: [deploy | upgrade]" + exit 1 +fi + +# Get the list of branches from the repository +BRANCHES=$(git branch --format='%(refname:short)' | grep -E '^(develop|stage|main)$') +select BRANCH in $BRANCHES; do + if [ ! -z "$BRANCH" ]; then + break + fi +done + +run_command() { + if ! "$@"; then + echo "$1 command failed" + exit 1 + fi +} + +# Checkout the selected branch and install npm dependencies +run_command git checkout $BRANCH +run_command npm ci -q --no-progress + +# Compile project +run_command npx hardhat compile --force + +# Only deployments for stage and main branches are tagged +if [[ $BRANCH == "stage" || $BRANCH == "main" ]]; then + run_command source ./tag-version -b "$BRANCH" -n -t "$VERSIONTYPE" +else + TAGVERSION="dev" +fi + +if [ "$ACTION" == "deploy" ]; then + # Run script to deploy the contracts + run_command npx hardhat --network "$NETWORK" deploy:contracts --tag "$TAGVERSION" +elif [ "$ACTION" == "upgrade" ]; then + # Run script to upgrade the contracts + run_command npx hardhat --network "$NETWORK" upgrade:Lock --tag "$TAGVERSION" +else + echo "-- ERROR: Wrong ACTION value. Possible values: [deploy | upgrade]" + exit 1 +fi + +if [[ $NETWORK == "mainnet" || $NETWORK == "goerli" ]]; then + + # Update .openzeppelin metadata + run_command git add .openzeppelin/"$NETWORK".json + run_command git commit -m "Update .openzeppelin folder" + run_command git push -u origin $branch + + if [[ $BRANCH == "stage" || $BRANCH == "main" ]]; then + run_command source ./tag-version -b "$BRANCH" -t "$VERSIONTYPE" + fi + ABIDIR="docs/$NETWORK/abi/$TAGVERSION" + + run_command git checkout gh-pages + + # Publish the ABI to a specific GitHub Pages location + mkdir -p $ABIDIR + cp abi/*.json $ABIDIR + + run_command git add $ABIDIR + run_command git commit -m "Publish ABI for deployment to $NETWORK" + run_command git push -u -f origin gh-pages +fi + +run_command git checkout $CURRENT_BRANCH diff --git a/scripts/bash/tag-version b/scripts/bash/tag-version new file mode 100644 index 00000000..c381dfa9 --- /dev/null +++ b/scripts/bash/tag-version @@ -0,0 +1,256 @@ +ARGUMENTS="$@" +BRANCH="" +DRYRUN="0" +GITPARAMS=() +RELEASEDATE=$(date '+%Y%m%d') +RELEASENOTES="" +REMOTE="origin" +PREVIOUS_COMMIT="" +RUNSILENT="0" +VERBOSE="0" +VERSIONTYPE="" + +# Function to return help text when requested with -h option. +help() { + # Display help. + echo + echo "Generates, increments and pushes an annotated semantic version tag for current git repository." + echo + echo "Usage:" + echo " sh tag-release [-b|--branch] [-d|--date] [-h|--help] [-m|--message] [-p|--previous] [-r|--remote] [-v|--version-type]" + echo + echo "Options:" + echo "-b,--branch " + echo " Branch to generate release tag on." + echo " Possible values: [stage | main]" + echo + echo "-d,--date " + echo " Date string to specify when release was created." + echo " If ommited, defaults to %Y%m%d of current date." + echo + echo "-h,--help, help" + echo " Prints this help." + echo + echo "-m,--message " + echo " Message to use to annotate release." + echo " If ommited a list of non-merge commit messages will be compiled as release annotation." + echo " If ommited and -p is given, will compile a list of non-merge commit messages between and HEAD." + echo " If ommited and -p is not given, will compile a list of non-merge commit messages between last found release and HEAD." + echo + echo "-n,--dry-run" + echo " Do everything except actually send the updates." + echo " If -q is also given then only error messages will be output." + echo + echo "-p,--previous " + echo " Previous commit to use to generate release notes." + echo " If ommited, will attempt to get commit hash of last release tag." + echo + echo "-q,--quiet" + echo " Supress all output, unless an error occurs." + echo + echo "-r,--remote " + echo " Name of remote to use for pushing." + echo " If ommited, defaults to '$REMOTE'" + echo + echo "-t,--version-type [major|minor|patch]" + echo " Type of semantic version to create. Valid options are 'major', 'minor' or 'patch'" + echo " major: Will bump up to next major release (i.e v1.0.0 -> v2.0.0)" + echo " minor: Will bump up to next minor release (i.e v1.0.1 -> v1.1.0)" + echo " patch: Will bump up to next patch release (i.e v1.0.2 -> v1.0.3)" + echo " Rules:" + echo " Tags created using 'stage' branch are treated as RCs (i.e v0.1.0-rc.0 -> v0.1.0-rc.1 ...)" + echo " Tags created using 'main' branch are treated as releases (i.e v0.1.0-rc.1 becomes v0.1.0)" + echo " In both cases, if a version-type parameter is passed, the rule is override (i.e v0.1.0-rc.2 -> -t minor -> v0.2.0-rc.0)" + echo " Tags created using 'develop' branch are not tagged" + echo " If ommited, will default to current version" + echo + echo "-v,--verbose" + echo " Run verbosley." + echo +} + +conditional_echo() { + if [[ "$RUNQUIET" -eq 0 ]]; then + echo "$1" + fi +} + +while [[ "$#" -gt 0 ]]; do + case $1 in + -b | --branch) + BRANCH=$2 + ;; + -d | --date) + RELEASEDATE=$2 + ;; + -h | --help | help) + help + exit + ;; + -m | --message) + RELEASENOTES=$2 + ;; + -n | --dry-run) + DRYRUN="1" + ;; + -p | --previous) + PREVIOUS_COMMIT=$2 + ;; + -r | --remote) + REMOTE=$2 + ;; + -t | --type) + VERSIONTYPE=$2 + ;; + -q | --quiet) + RUNQUIET="1" + GITPARAMS+=(--dry-run) + ;; + -v | --verbose) + # See if a second argument is passed, due to argument reassignment to -v. + if [[ "$1" == "-v" ]] && [[ -n "$2" ]]; then + echo "ERROR: Unsupported value \"$2\" passed to -v argument. If trying to set semantic version tag, use the -t or --type argument". + exit + fi + VERBOSE="1" + GITPARAMS+=(--verbose) + ;; + esac + shift +done + +# Get top-level of git repo. +REPO_DIR=$(echo $(git rev-parse --show-toplevel)) +# CD into the top level +cd "${REPO_DIR}" + +if [ "$BRANCH" == "" ]; then + conditional_echo "-- ERROR: BRANCH option is mandatory." + exit 1 +elif [[ "$BRANCH" != "stage" && "$BRANCH" != "main" ]]; then + conditional_echo "-- ERROR: Wrong branch. Possible values: [stage | main] " + exit 1 +fi + +# Get current active branch +CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD) +# Switch to production branch +if [ $CURRENT_BRANCH != "$BRANCH" ]; then + conditional_echo "- Switching from $CURRENT_BRANCH to $BRANCH branch. (stashing any local change)" + # stash any current work + git stash "${GITPARAMS[@]}" + # go to the production branch + git checkout $BRANCH "${GITPARAMS[@]}" +fi + +conditional_echo "- Updating local $BRANCH branch." +# pull latest version of production branch +git pull $REMOTE $BRANCH "${GITPARAMS[@]}" +# fetch remote, to get latest tags +git fetch $REMOTE "${GITPARAMS[@]}" + +# Get previous release tags +conditional_echo "- Getting previous tag." +PREVIOUS_TAG=$(echo $(git ls-remote --tags --ref --sort="v:refname" $REMOTE | tail -n1)) + +# If specific commit not set, get the from the previous release. +if [ -z "$PREVIOUS_COMMIT" ]; then + # Split on the first space + PREVIOUS_COMMIT=$(echo $PREVIOUS_TAG | cut -d' ' -f 1) +fi + +conditional_echo "-- PREVIOUS TAG: $PREVIOUS_TAG" + +# Get previous release number +PREVIOUS_RELEASE=$(echo $PREVIOUS_TAG | awk -F"/" '{print $3}') + +conditional_echo "-- PREVIOUS_RELEASE: $PREVIOUS_RELEASE" + +# Get raw version +RAW_VERSION=$(echo $PREVIOUS_RELEASE | sed 's/^v//' | cut -d'-' -f1) +conditional_echo "-- RAW_VERSION: $RAW_VERSION" + +conditional_echo "- Creating release tag" +# Get last commit +LASTCOMMIT=$(echo $(git rev-parse $REMOTE/$BRANCH)) +# Check if commit already has a tag +NEEDSTAG=$(echo $(git describe --contains $LASTCOMMIT 2>/dev/null)) + +if [ -z "$NEEDSTAG" ]; then + conditional_echo "-- Generating release number ($VERSIONTYPE)" + # Replace . with spaces so that can split into an array. + VERSION_BITS=(${RAW_VERSION//./ }) + # Get number parts, only the digits. + VNUM1=${VERSION_BITS[0]//[^0-9]/} + VNUM2=${VERSION_BITS[1]//[^[0-9]/} + VNUM3=${VERSION_BITS[2]//[^0-9]/} + # Update tagging number based on option that was passed. + if [ "$VERSIONTYPE" == "major" ]; then + VNUM1=$((VNUM1 + 1)) + VNUM2=0 + VNUM3=0 + elif [ "$VERSIONTYPE" == "minor" ]; then + VNUM2=$((VNUM2 + 1)) + VNUM3=0 + elif [ "$VERSIONTYPE" == "patch" ]; then + VNUM3=$((VNUM3 + 1)) + fi + + # Update tagging number based on option that was passed. + if [ "$BRANCH" == "stage" ]; then + if [[ $PREVIOUS_RELEASE == "v${VNUM1}.${VNUM2}.${VNUM3}-rc"* ]]; then + # Extract the current rc suffix and increment it by one + RC_SUFFIX=$(echo $PREVIOUS_TAG | sed -n 's/.*-rc\.\([[:digit:]]\{1,\}\)$/\1/p') + NEW_RC_SUFFIX=$((RC_SUFFIX + 1)) + NEWTAG="v${VNUM1}.${VNUM2}.${VNUM3}-rc.${NEW_RC_SUFFIX}" + else + NEWTAG="v${VNUM1}.${VNUM2}.${VNUM3}-rc.0" + fi + elif [ "$BRANCH" == "main" ]; then + if [[ $PREVIOUS_RELEASE == "v${VNUM1}.${VNUM2}.${VNUM3}-rc"* ]]; then + NEWTAG="v${VNUM1}.${VNUM2}.${VNUM3}" + else + NEWTAG="v${VNUM1}.${VNUM2}.${VNUM3}" + fi + fi + conditional_echo "-- Release number: $NEWTAG" + + # Check to see if new tag already exists + TAGEXISTS=$(echo $(git ls-remote --tags --ref $REMOTE | grep -w "$NEWTAG$")) + + if [ -z "$TAGEXISTS" ]; then + # Check if release notes were not provided. + if [ -z "$RELEASENOTES" ]; then + conditional_echo "- Generating basic release notes of commits since last release." + # Generate a list of commit messages since the last release. + RELEASENOTES=$(git log --pretty=format:"- %s" $PREVIOUS_COMMIT...$LASTCOMMIT --no-merges) + fi + # Tag the commit. + if [[ "$DRYRUN" -eq 0 ]]; then + conditional_echo "-- Tagging commit. ($LASTCOMMIT)" + git tag -a $NEWTAG -m"$RELEASEDATE: Release $VNUM1.$VNUM2.$VNUM3" -m"$RELEASENOTES" $LASTCOMMIT + conditional_echo "- Pushing release to $REMOTE" + # Push up the tag + git push $REMOTE $NEWTAG "${GITPARAMS[@]}" + else + conditional_echo "Release Notes:" + conditional_echo "$RELEASENOTES" + fi + else + conditional_echo "-- ERROR: TAG $NEWTAG already exists." + exit 1 + fi +else + conditional_echo "-- ERROR: Commit already tagged as a release. ($LASTCOMMIT)" + exit 1 +fi + +# Switch to back to original branch +if [ $CURRENT_BRANCH != "$BRANCH" ]; then + conditional_echo "- Switching back to $CURRENT_BRANCH branch. (restoring local changes)" + git checkout "$CURRENT_BRANCH" "${GITPARAMS[@]}" + # remove the stash + git stash pop "${GITPARAMS[@]}" +fi + +export TAGVERSION=$NEWTAG diff --git a/scripts/deploy-all.ts b/scripts/deploy-all.ts deleted file mode 100644 index fdebe8b3..00000000 --- a/scripts/deploy-all.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { ethers, upgrades } from 'hardhat'; -import { getEnvVar } from './utils'; - -async function deploy() { - const ssvTokenAddress = getEnvVar('SSVTOKEN_ADDRESS'); - - const [deployer] = await ethers.getSigners(); - console.log(`Deploying contracts with the account:${deployer.address}`); - - // deploy SSVNetwork - const ssvNetworkFactory = await ethers.getContractFactory('SSVNetwork'); - console.log(`Deploying SSVNetwork with ssvToken ${ssvTokenAddress}`); - const ssvNetwork = await upgrades.deployProxy(ssvNetworkFactory, [ - process.env.INITIAL_VERSION, - ssvTokenAddress, - getEnvVar('OPERATOR_MAX_FEE_INCREASE'), - getEnvVar('DECLARE_OPERATOR_FEE_PERIOD'), - getEnvVar('EXECUTE_OPERATOR_FEE_PERIOD'), - getEnvVar('MINIMUM_BLOCKS_BEFORE_LIQUIDATION') - ], - { - kind: "uups" - }); - await ssvNetwork.deployed(); - console.log(`SSVNetwork proxy deployed to: ${ssvNetwork.address}`); - - let implAddress = await upgrades.erc1967.getImplementationAddress(ssvNetwork.address); - console.log(`SSVNetwork implementation deployed to: ${implAddress}`); - - // deploy SSVNetworkViews - const ssvViewsFactory = await ethers.getContractFactory('SSVNetworkViews'); - console.log(`Deploying SSVNetworkViews with SSVNetwork ${ssvNetwork.address}...`); - const viewsContract = await upgrades.deployProxy(ssvViewsFactory, [ - ssvNetwork.address - ], - { - kind: "uups" - }); - await viewsContract.deployed(); - console.log(`SSVNetworkViews proxy deployed to: ${viewsContract.address}`); - - implAddress = await upgrades.erc1967.getImplementationAddress(viewsContract.address); - console.log(`SSVNetworkViews implementation deployed to: ${implAddress}`); -} - -deploy() - .then(() => process.exit(0)) - .catch(error => { - console.error(error); - process.exit(1); - }); diff --git a/scripts/upgrade-ssv-network-views.ts b/scripts/upgrade-ssv-network-views.ts deleted file mode 100644 index 77487839..00000000 --- a/scripts/upgrade-ssv-network-views.ts +++ /dev/null @@ -1,19 +0,0 @@ -const { ethers, upgrades } = require("hardhat"); - -async function upgradeSSVNetworkViews() { - const proxyAddress = process.env.SSVNETWORKVIEWS_PROXY_ADDRESS; - const [deployer] = await ethers.getSigners(); - console.log("Upgading contract with the account:", deployer.address); - - const SSVNetworkViews = await ethers.getContractFactory("SSVNetworkViews_V2"); - - await upgrades.upgradeProxy(proxyAddress, SSVNetworkViews, { kind: 'uups' }); - console.log("SSVNetworkViews upgraded successfully"); -} - -upgradeSSVNetworkViews() - .then(() => process.exit(0)) - .catch(error => { - console.error(error); - process.exit(1); - }); \ No newline at end of file diff --git a/scripts/upgrade-ssv-network.ts b/scripts/upgrade-ssv-network.ts deleted file mode 100644 index 1dd8e31a..00000000 --- a/scripts/upgrade-ssv-network.ts +++ /dev/null @@ -1,17 +0,0 @@ -async function upgradeSSVNetwork() { - const proxyAddress = process.env.SSVNETWORK_PROXY_ADDRESS; - const [deployer] = await ethers.getSigners(); - console.log("Upgading contract with the account:", deployer.address); - - const SSVNetwork = await ethers.getContractFactory("SSVNetwork_V2"); - - await upgrades.upgradeProxy(proxyAddress, SSVNetwork, { kind: 'uups' }); - console.log("SSVNetwork upgraded successfully"); -} - -upgradeSSVNetwork() - .then(() => process.exit(0)) - .catch(error => { - console.error(error); - process.exit(1); - }); \ No newline at end of file diff --git a/tasks/deploy-all.ts b/tasks/deploy-all.ts new file mode 100644 index 00000000..2b05dc22 --- /dev/null +++ b/tasks/deploy-all.ts @@ -0,0 +1,53 @@ +import { task } from "hardhat/config"; +import { generateABI } from "./utils"; + +task("deploy:all", "Deploy SSVNetwork and SSVNetworkViews contracts") + .addParam("tag", "Version of the contract") + .setAction(async ({ tag: version }, hre) => { + try { + const ssvTokenAddress = process.env.SSVTOKEN_ADDRESS; + + const [deployer] = await ethers.getSigners(); + console.log(`Deploying contracts with the account:${deployer.address}`); + + // deploy SSVNetwork + const ssvNetworkFactory = await ethers.getContractFactory('SSVNetwork'); + console.log(`Deploying SSVNetwork with ssvToken ${ssvTokenAddress}`); + const ssvNetwork = await upgrades.deployProxy(ssvNetworkFactory, [ + version, + ssvTokenAddress, + process.env.OPERATOR_MAX_FEE_INCREASE, + process.env.DECLARE_OPERATOR_FEE_PERIOD, + process.env.EXECUTE_OPERATOR_FEE_PERIOD, + process.env.MINIMUM_BLOCKS_BEFORE_LIQUIDATION + ], + { + kind: "uups" + }); + await ssvNetwork.deployed(); + console.log(`SSVNetwork proxy deployed to: ${ssvNetwork.address}`); + + let implAddress = await upgrades.erc1967.getImplementationAddress(ssvNetwork.address); + console.log(`SSVNetwork implementation deployed to: ${implAddress}`); + + // deploy SSVNetworkViews + const ssvViewsFactory = await ethers.getContractFactory('SSVNetworkViews'); + console.log(`Deploying SSVNetworkViews with SSVNetwork ${ssvNetwork.address}...`); + const viewsContract = await upgrades.deployProxy(ssvViewsFactory, [ + ssvNetwork.address + ], + { + kind: "uups" + }); + await viewsContract.deployed(); + console.log(`SSVNetworkViews proxy deployed to: ${viewsContract.address}`); + + implAddress = await upgrades.erc1967.getImplementationAddress(viewsContract.address); + console.log(`SSVNetworkViews implementation deployed to: ${implAddress}`); + + await generateABI(hre, ["SSVNetwork", "SSVNetworkViews"], [ssvNetwork.address, viewsContract.address]); + } catch (error) { + console.error(error); + process.exitCode = 1; + } + }); \ No newline at end of file diff --git a/tasks/upgrade-ssvnetwork.ts b/tasks/upgrade-ssvnetwork.ts new file mode 100644 index 00000000..56b49085 --- /dev/null +++ b/tasks/upgrade-ssvnetwork.ts @@ -0,0 +1,27 @@ +import { task } from "hardhat/config"; +import { generateABI } from "./utils"; + +task("upgrade:ssvnetwork", "Upgrade SSVNetwork contract") + .addParam("tag", "Version of the contract") + .setAction(async ({ tag: version }, hre) => { + try { + const proxyAddress = process.env.SSVNETWORK_PROXY_ADDRESS; + const [deployer] = await ethers.getSigners(); + console.log("Upgading contract with the account:", deployer.address); + + const SSVNetwork = await ethers.getContractFactory("SSVNetwork_V2"); + + await upgrades.upgradeProxy(proxyAddress, SSVNetwork, { + kind: 'uups', + call: { + fn: 'initializev2', + args: [version] + } + }); + console.log("SSVNetwork upgraded successfully"); + await generateABI(hre, ["SSVNetwork"], [proxyAddress as string]); + } catch (error) { + console.error(error); + process.exitCode = 1; + } + }); \ No newline at end of file diff --git a/tasks/upgrade-ssvnetworkviews.ts b/tasks/upgrade-ssvnetworkviews.ts new file mode 100644 index 00000000..160ce334 --- /dev/null +++ b/tasks/upgrade-ssvnetworkviews.ts @@ -0,0 +1,27 @@ +import { task } from "hardhat/config"; +import { generateABI } from "./utils"; + +task("upgrade:ssvnetworkviews", "Upgrade SSVNetworkViews contract") + .addParam("tag", "Version of the contract") + .setAction(async ({ tag: version }, hre) => { + try { + const proxyAddress = process.env.SSVNETWORKVIEWS_PROXY_ADDRESS; + const [deployer] = await ethers.getSigners(); + console.log("Upgading contract with the account:", deployer.address); + + const SSVNetworkViews = await ethers.getContractFactory("SSVNetworkViews_V2"); + + await upgrades.upgradeProxy(proxyAddress, SSVNetworkViews, { + kind: 'uups', + call: { + fn: 'initializev2', + args: [version] + } + }); + console.log("SSVNetworkViews upgraded successfully"); + await generateABI(hre, ["SSVNetworkViews"], [proxyAddress as string]); + } catch (error) { + console.error(error); + process.exitCode = 1; + } + }); \ No newline at end of file diff --git a/tasks/utils.ts b/tasks/utils.ts new file mode 100644 index 00000000..ad174d41 --- /dev/null +++ b/tasks/utils.ts @@ -0,0 +1,19 @@ +const fs = require('fs').promises; + +export const generateABI = async (hre: any, contractNames: string[], contractAddresses: string[]) => { + // Only extract ABIs for mainnet or goerli deployments + if (hre.network.name == 'goerli' || hre.network.name == 'mainnet') { + await fs.mkdir('abi/', { recursive: true }); + + for (let i = 0; i < contractNames.length; i++) { + const { abi, contractName } = await hre.artifacts.readArtifact(contractNames[i]); + + const metadata = { + address: contractAddresses[i], + abi + }; + + await fs.writeFile(`abi/${contractName}.json`, `${JSON.stringify(metadata, null, 2)}\n`, { flag: 'w' }); + } + } +} \ No newline at end of file From 5f7cbfb72e0046de30093cacece66e94b3be06dd Mon Sep 17 00:00:00 2001 From: Marco Tabasco Date: Mon, 13 Mar 2023 14:15:09 +0100 Subject: [PATCH 139/149] Liquidate cluster negative balance - IO1-2756 (#198) * cluster.disabled -> cluster.active * liquidate cluster with negative balance --- .github/workflows/code-coverage.yaml | 2 +- .github/workflows/linter.yaml | 2 +- .github/workflows/tests.yaml | 2 +- .prettierrc | 14 + .solhint.json | 4 + contracts/ISSVNetwork.sol | 141 +-- contracts/ISSVNetworkCore.sol | 5 +- contracts/ISSVNetworkViews.sol | 16 +- contracts/SSVNetwork.sol | 292 ++---- contracts/SSVNetworkViews.sol | 158 +-- contracts/libraries/ClusterLib.sol | 38 +- contracts/libraries/NetworkLib.sol | 28 +- contracts/libraries/OperatorLib.sol | 10 +- contracts/libraries/Types.sol | 2 +- contracts/mocks/SSVNetworkBasicUpgrade.sol | 2 +- contracts/mocks/SSVNetworkLibUpgrade.sol | 8 +- contracts/mocks/SSVNetworkReinitializable.sol | 4 +- .../mocks/SSVNetworkValidatorsPerOperator.sol | 5 +- contracts/mocks/SSVNetworkVersionUpgrade.sol | 4 +- .../mocks/SSVNetworkViewsBasicUpgrade.sol | 6 +- contracts/mocks/SSVNetworkViewsLibUpgrade.sol | 2 +- .../mocks/SSVNetworkViewsReinitializable.sol | 2 +- contracts/mocks/SSVTokenMock.sol | 2 +- .../mocks/libraries/NetworkLibUpgrade.sol | 38 +- hardhat.config.ts | 2 +- package-lock.json | 944 ++++++++---------- package.json | 2 +- scripts/deploy-all.ts | 11 +- test/account/deposit.ts | 37 +- test/account/withdraw.ts | 5 + test/helpers/contract-helpers.ts | 15 +- test/helpers/gas-usage.ts | 18 +- test/liquidate/liquidate.ts | 35 + test/liquidate/reactivate.ts | 19 +- test/sanity/balances.ts | 4 +- test/validators/register.ts | 52 + test/validators/remove.ts | 10 + 37 files changed, 833 insertions(+), 1108 deletions(-) create mode 100644 .prettierrc diff --git a/.github/workflows/code-coverage.yaml b/.github/workflows/code-coverage.yaml index 0b550135..4a387ef9 100644 --- a/.github/workflows/code-coverage.yaml +++ b/.github/workflows/code-coverage.yaml @@ -12,7 +12,7 @@ jobs: - uses: actions/setup-node@v1 with: node-version: '16.x' - - run: npm install + - run: npm ci env: GH_TOKEN: ${{ secrets.github_token }} - run: NO_GAS_ENFORCE=1 npx hardhat coverage diff --git a/.github/workflows/linter.yaml b/.github/workflows/linter.yaml index 9be7e729..bb5df843 100644 --- a/.github/workflows/linter.yaml +++ b/.github/workflows/linter.yaml @@ -11,7 +11,7 @@ jobs: - uses: actions/setup-node@v1 with: node-version: '16.x' - - run: npm install + - run: npm ci env: GH_TOKEN: ${{ secrets.github_token }} - run: npx hardhat check diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 41b426dc..c67d420e 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -12,7 +12,7 @@ jobs: - uses: actions/setup-node@v1 with: node-version: '16.x' - - run: npm install + - run: npm ci env: GH_TOKEN: ${{ secrets.github_token }} - run: npx hardhat test diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 00000000..3bc5d52a --- /dev/null +++ b/.prettierrc @@ -0,0 +1,14 @@ +{ + "printWidth": 120, + "singleQuote": true, + "trailingComma": "all", + "arrowParens": "avoid", + "overrides": [ + { + "files": "*.sol", + "options": { + "singleQuote": false + } + } + ] +} \ No newline at end of file diff --git a/.solhint.json b/.solhint.json index 5234ef46..0b9ee47c 100644 --- a/.solhint.json +++ b/.solhint.json @@ -13,6 +13,10 @@ ], "ordering": "warn", "mark-callable-contracts": "off", + "max-line-length": [ + "error", + 120 + ], "compiler-version": "off", "not-rely-on-time": "off" } diff --git a/contracts/ISSVNetwork.sol b/contracts/ISSVNetwork.sol index 710d842a..c8b056a0 100644 --- a/contracts/ISSVNetwork.sol +++ b/contracts/ISSVNetwork.sol @@ -1,7 +1,8 @@ // SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity 0.8.16; -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +pragma solidity 0.8.18; + import "./ISSVNetworkCore.sol"; +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; interface ISSVNetwork is ISSVNetworkCore { /**********/ @@ -15,12 +16,7 @@ interface ISSVNetwork is ISSVNetworkCore { * @param publicKey Operator's public key. Will be used to encrypt secret shares of validators keys. * @param fee Operator's fee. */ - event OperatorAdded( - uint64 indexed id, - address indexed owner, - bytes publicKey, - uint256 fee - ); + event OperatorAdded(uint64 indexed id, address indexed owner, bytes publicKey, uint256 fee); /** * @dev Emitted when operator has been removed. @@ -35,13 +31,7 @@ interface ISSVNetwork is ISSVNetworkCore { * @param shares snappy compressed shares(a set of encrypted and public shares). * @param cluster All the cluster data. */ - event ValidatorAdded( - address indexed owner, - uint64[] operatorIds, - bytes publicKey, - bytes shares, - Cluster cluster - ); + event ValidatorAdded(address indexed owner, uint64[] operatorIds, bytes publicKey, bytes shares, Cluster cluster); /** * @dev Emitted when the validator is removed. @@ -49,24 +39,11 @@ interface ISSVNetwork is ISSVNetworkCore { * @param operatorIds The operator ids list. * @param cluster All the cluster data. */ - event ValidatorRemoved( - address indexed owner, - uint64[] operatorIds, - bytes publicKey, - Cluster cluster - ); - - event OperatorFeeDeclared( - address indexed owner, - uint64 indexed operatorId, - uint256 blockNumber, - uint256 fee - ); - - event OperatorFeeCancelationDeclared( - address indexed owner, - uint64 indexed operatorId - ); + event ValidatorRemoved(address indexed owner, uint64[] operatorIds, bytes publicKey, Cluster cluster); + + event OperatorFeeDeclared(address indexed owner, uint64 indexed operatorId, uint256 blockNumber, uint256 fee); + + event OperatorFeeCancelationDeclared(address indexed owner, uint64 indexed operatorId); /** * @dev Emitted when an operator's fee is updated. @@ -74,24 +51,11 @@ interface ISSVNetwork is ISSVNetworkCore { * @param blockNumber from which block number. * @param fee updated fee value. */ - event OperatorFeeExecuted( - address indexed owner, - uint64 indexed operatorId, - uint256 blockNumber, - uint256 fee - ); - - event ClusterLiquidated( - address indexed owner, - uint64[] operatorIds, - Cluster cluster - ); - - event ClusterReactivated( - address indexed owner, - uint64[] operatorIds, - Cluster cluster - ); + event OperatorFeeExecuted(address indexed owner, uint64 indexed operatorId, uint256 blockNumber, uint256 fee); + + event ClusterLiquidated(address indexed owner, uint64[] operatorIds, Cluster cluster); + + event ClusterReactivated(address indexed owner, uint64[] operatorIds, Cluster cluster); event OperatorFeeIncreaseLimitUpdated(uint64 value); @@ -115,24 +79,10 @@ interface ISSVNetwork is ISSVNetworkCore { */ event NetworkEarningsWithdrawn(uint256 value, address recipient); - event ClusterWithdrawn( - address indexed owner, - uint64[] operatorIds, - uint256 value, - Cluster cluster - ); - event OperatorWithdrawn( - address indexed owner, - uint64 indexed operatorId, - uint256 value - ); - - event ClusterDeposited( - address indexed owner, - uint64[] operatorIds, - uint256 value, - Cluster cluster - ); + event ClusterWithdrawn(address indexed owner, uint64[] operatorIds, uint256 value, Cluster cluster); + event OperatorWithdrawn(address indexed owner, uint64 indexed operatorId, uint256 value); + + event ClusterDeposited(address indexed owner, uint64[] operatorIds, uint256 value, Cluster cluster); event FeeRecipientAddressUpdated(address indexed owner, address recipientAddress); @@ -165,10 +115,7 @@ interface ISSVNetwork is ISSVNetworkCore { * @param publicKey Operator's public key. Used to encrypt secret shares of validators keys. * @param fee operator's fee. When fee is set to zero (mostly for private operators), it can not be increased. */ - function registerOperator( - bytes calldata publicKey, - uint256 fee - ) external returns (uint64); + function registerOperator(bytes calldata publicKey, uint256 fee) external returns (uint64); /** * @dev Removes an operator. @@ -196,51 +143,27 @@ interface ISSVNetwork is ISSVNetworkCore { Cluster memory cluster ) external; - function removeValidator( - bytes calldata publicKey, - uint64[] memory operatorIds, - Cluster memory cluster - ) external; + function removeValidator(bytes calldata publicKey, uint64[] memory operatorIds, Cluster memory cluster) external; /**************************/ /* Cluster External Functions */ /**************************/ - function liquidate( - address owner, - uint64[] memory operatorIds, - Cluster memory cluster - ) external; + function liquidate(address owner, uint64[] memory operatorIds, Cluster memory cluster) external; - function reactivate( - uint64[] memory operatorIds, - uint256 amount, - Cluster memory cluster - ) external; + function reactivate(uint64[] memory operatorIds, uint256 amount, Cluster memory cluster) external; /******************************/ /* Balance External Functions */ /******************************/ - function deposit( - address owner, - uint64[] memory operatorIds, - uint256 amount, - Cluster memory cluster - ) external; + function deposit(address owner, uint64[] memory operatorIds, uint256 amount, Cluster memory cluster) external; - function withdrawOperatorEarnings( - uint64 operatorId, - uint256 tokenAmount - ) external; + function withdrawOperatorEarnings(uint64 operatorId, uint256 tokenAmount) external; function withdrawOperatorEarnings(uint64 operatorId) external; - function withdraw( - uint64[] memory operatorIds, - uint256 tokenAmount, - Cluster memory cluster - ) external; + function withdraw(uint64[] memory operatorIds, uint256 tokenAmount, Cluster memory cluster) external; /**************************/ /* DAO External Functions */ @@ -250,17 +173,11 @@ interface ISSVNetwork is ISSVNetworkCore { function withdrawNetworkEarnings(uint256 amount) external; - function updateOperatorFeeIncreaseLimit( - uint64 newOperatorMaxFeeIncrease - ) external; + function updateOperatorFeeIncreaseLimit(uint64 newOperatorMaxFeeIncrease) external; - function updateDeclareOperatorFeePeriod( - uint64 newDeclareOperatorFeePeriod - ) external; + function updateDeclareOperatorFeePeriod(uint64 newDeclareOperatorFeePeriod) external; - function updateExecuteOperatorFeePeriod( - uint64 newExecuteOperatorFeePeriod - ) external; + function updateExecuteOperatorFeePeriod(uint64 newExecuteOperatorFeePeriod) external; function updateLiquidationThresholdPeriod(uint64 blocks) external; } diff --git a/contracts/ISSVNetworkCore.sol b/contracts/ISSVNetworkCore.sol index 466f0dc2..75563cb1 100644 --- a/contracts/ISSVNetworkCore.sol +++ b/contracts/ISSVNetworkCore.sol @@ -1,6 +1,6 @@ -// File: contracts/ISSVNetwork.sol // SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity 0.8.16; +pragma solidity 0.8.18; + import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; interface ISSVNetworkCore { @@ -72,7 +72,6 @@ interface ISSVNetworkCore { error InvalidPublicKeyLength(); error InvalidOperatorIdsLength(); error ValidatorOwnedByOtherAddress(); - error InsufficientFunds(); error ClusterAlreadyEnabled(); error ClusterIsLiquidated(); error ClusterDoesNotExists(); diff --git a/contracts/ISSVNetworkViews.sol b/contracts/ISSVNetworkViews.sol index 7ce98def..ad1214ab 100644 --- a/contracts/ISSVNetworkViews.sol +++ b/contracts/ISSVNetworkViews.sol @@ -1,10 +1,12 @@ -// File: contracts/ISSVNetwork.sol // SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity 0.8.16; -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +pragma solidity 0.8.18; + import "./ISSVNetworkCore.sol"; import "./SSVNetwork.sol"; +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; + + interface ISSVNetworkViews is ISSVNetworkCore { /****************/ /* Initializers */ @@ -22,9 +24,7 @@ interface ISSVNetworkViews is ISSVNetworkCore { function getOperatorFee(uint64 operatorId) external view returns (uint256); - function getOperatorDeclaredFee( - uint64 operatorId - ) external view returns (uint256, uint256, uint256); + function getOperatorDeclaredFee(uint64 operatorId) external view returns (uint256, uint256, uint256); function getOperatorById( uint64 operatorId @@ -56,9 +56,7 @@ interface ISSVNetworkViews is ISSVNetworkCore { /* Balance External View Functions */ /***********************************/ - function getOperatorEarnings( - uint64 id - ) external view returns (uint256); + function getOperatorEarnings(uint64 id) external view returns (uint256); function getBalance( address owner, diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index 82985ab2..832c7489 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -1,17 +1,16 @@ -// File: contracts/SSVRegistry.sol // SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity 0.8.16; +pragma solidity 0.8.18; import "./ISSVNetwork.sol"; +import "./libraries/Types.sol"; +import "./libraries/ClusterLib.sol"; +import "./libraries/OperatorLib.sol"; +import "./libraries/NetworkLib.sol"; import "@openzeppelin/contracts/utils/Counters.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol"; -import "./libraries/Types.sol"; -import "./libraries/ClusterLib.sol"; -import "./libraries/OperatorLib.sol"; -import "./libraries/NetworkLib.sol"; contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { /*************/ @@ -30,8 +29,8 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { /* Constants */ /*************/ - uint64 constant MINIMAL_LIQUIDATION_THRESHOLD = 6_570; - uint64 constant MINIMAL_OPERATOR_FEE = 100_000_000; + uint64 private constant MINIMAL_LIQUIDATION_THRESHOLD = 6_570; + uint64 private constant MINIMAL_OPERATOR_FEE = 100_000_000; /********************/ /* Global Variables */ @@ -44,8 +43,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { /*************/ mapping(uint64 => Operator) public operators; - mapping(uint64 => OperatorFeeChangeRequest) - public operatorFeeChangeRequests; + mapping(uint64 => OperatorFeeChangeRequest) public operatorFeeChangeRequests; mapping(bytes32 => bytes32) public clusters; mapping(bytes32 => Validator) private _validatorPKs; @@ -125,10 +123,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { /* Operator External Functions */ /*******************************/ - function registerOperator( - bytes calldata publicKey, - uint256 fee - ) external override returns (uint64 id) { + function registerOperator(bytes calldata publicKey, uint256 fee) external override returns (uint64 id) { if (fee != 0 && fee < MINIMAL_OPERATOR_FEE) { revert FeeTooLow(); } @@ -137,11 +132,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { id = uint64(lastOperatorId.current()); operators[id] = Operator({ owner: msg.sender, - snapshot: Snapshot({ - block: uint64(block.number), - index: 0, - balance: 0 - }), + snapshot: Snapshot({block: uint64(block.number), index: 0, balance: 0}), validatorCount: 0, fee: fee.shrink() }); @@ -152,10 +143,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { _removeOperator(operatorId, operators[operatorId]); } - function declareOperatorFee( - uint64 operatorId, - uint256 fee - ) external override { + function declareOperatorFee(uint64 operatorId, uint256 fee) external override { _declareOperatorFee(operatorId, operators[operatorId], fee); } @@ -167,9 +155,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { _cancelDeclaredOperatorFee(operatorId, operators[operatorId]); } - function setFeeRecipientAddress( - address recipientAddress - ) external override { + function setFeeRecipientAddress(address recipientAddress) external override { emit FeeRecipientAddressUpdated(msg.sender, recipientAddress); } @@ -194,17 +180,24 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { if (_validatorPKs[keccak256(publicKey)].owner != address(0)) { revert ValidatorAlreadyExists(); } - _validatorPKs[keccak256(publicKey)] = Validator({ - owner: msg.sender, - active: true - }); + _validatorPKs[keccak256(publicKey)] = Validator({owner: msg.sender, active: true}); } - bytes32 hashedCluster = keccak256( - abi.encodePacked(msg.sender, operatorIds) - ); - { - bytes32 hashedClusterData = keccak256( + bytes32 hashedCluster = keccak256(abi.encodePacked(msg.sender, operatorIds)); + + if (clusters[hashedCluster] == bytes32(0)) { + if ( + cluster.validatorCount != 0 || + cluster.networkFeeIndex != 0 || + cluster.index != 0 || + cluster.balance != 0 || + !cluster.active + ) { + revert IncorrectClusterState(); + } + } else if ( + clusters[hashedCluster] != + keccak256( abi.encodePacked( cluster.validatorCount, cluster.networkFeeIndex, @@ -212,13 +205,10 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { cluster.balance, cluster.active ) - ); - if ( - clusters[hashedCluster] != bytes32(0) && - clusters[hashedCluster] != hashedClusterData - ) { - revert IncorrectClusterState(); - } + ) + ) { + revert IncorrectClusterState(); + } else { cluster.validateClusterIsNotLiquidated(); } @@ -226,9 +216,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { uint64 burnRate; Network memory network_ = network; - uint64 currentNetworkFeeIndex = NetworkLib.currentNetworkFeeIndex( - network_ - ); + uint64 currentNetworkFeeIndex = NetworkLib.currentNetworkFeeIndex(network_); { cluster.balance += amount; @@ -244,7 +232,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { if (operator.snapshot.block == 0) { revert OperatorDoesNotExist(); } - operator.getSnapshot(); + operator.updateSnapshot(); if (++operator.validatorCount > validatorsPerOperatorLimit) { revert ExceedValidatorLimit(); } @@ -266,13 +254,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { ++cluster.validatorCount; - if ( - cluster.liquidatable( - burnRate, - network_.networkFee, - minimumBlocksBeforeLiquidation - ) - ) { + if (cluster.isLiquidatable(burnRate, network_.networkFee, minimumBlocksBeforeLiquidation)) { revert InsufficientBalance(); } @@ -290,13 +272,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { _deposit(amount); } - emit ValidatorAdded( - msg.sender, - operatorIds, - publicKey, - shares, - cluster - ); + emit ValidatorAdded(msg.sender, operatorIds, publicKey, shares, cluster); } function removeValidator( @@ -304,8 +280,6 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { uint64[] memory operatorIds, Cluster memory cluster ) external override { - uint operatorsLength = operatorIds.length; - bytes32 hashedValidator = keccak256(publicKey); address validatorOwner = _validatorPKs[hashedValidator].owner; if (validatorOwner == address(0)) { @@ -315,24 +289,21 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { revert ValidatorOwnedByOtherAddress(); } + bytes32 hashedCluster = cluster.validateHashedCluster(msg.sender, operatorIds, this); + uint operatorsLength = operatorIds.length; + { _validateOperatorIds(operatorsLength); _validatePublicKey(publicKey); } - bytes32 hashedCluster = cluster.validateHashedCluster( - msg.sender, - operatorIds, - this - ); - uint64 clusterIndex; { if (cluster.active) { for (uint i; i < operatorsLength; ) { Operator memory operator = operators[operatorIds[i]]; if (operator.snapshot.block != 0) { - operator.getSnapshot(); + operator.updateSnapshot(); --operator.validatorCount; operators[operatorIds[i]] = operator; } @@ -342,10 +313,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { ++i; } } - cluster.updateClusterData( - clusterIndex, - NetworkLib.currentNetworkFeeIndex(network) - ); + cluster.updateClusterData(clusterIndex, NetworkLib.currentNetworkFeeIndex(network)); DAO memory dao_ = dao; dao_.updateDAOEarnings(network.networkFee); @@ -371,19 +339,10 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { emit ValidatorRemoved(msg.sender, operatorIds, publicKey, cluster); } - function liquidate( - address owner, - uint64[] memory operatorIds, - Cluster memory cluster - ) external override { + function liquidate(address owner, uint64[] memory operatorIds, Cluster memory cluster) external override { + bytes32 hashedCluster = cluster.validateHashedCluster(owner, operatorIds, this); cluster.validateClusterIsNotLiquidated(); - bytes32 hashedCluster = cluster.validateHashedCluster( - owner, - operatorIds, - this - ); - uint64 clusterIndex; uint64 burnRate; { @@ -392,7 +351,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { Operator memory operator = operators[operatorIds[i]]; if (operator.snapshot.block != 0) { - operator.getSnapshot(); + operator.updateSnapshot(); operator.validatorCount -= cluster.validatorCount; burnRate += operator.fee; operators[operatorIds[i]] = operator; @@ -405,22 +364,12 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { } } - cluster.balance = cluster.clusterBalance( - clusterIndex, - NetworkLib.currentNetworkFeeIndex(network) - ); - + cluster.updateBalance(clusterIndex, NetworkLib.currentNetworkFeeIndex(network)); + uint64 networkFee = network.networkFee; - uint256 balanceLiquidatable = cluster.balance; + uint256 balanceLiquidatable; - if ( - owner != msg.sender && - !cluster.liquidatable( - burnRate, - networkFee, - minimumBlocksBeforeLiquidation - ) - ) { + if (owner != msg.sender && !cluster.isLiquidatable(burnRate, networkFee, minimumBlocksBeforeLiquidation)) { revert ClusterNotLiquidatable(); } @@ -428,10 +377,13 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { dao_.updateDAOEarnings(networkFee); dao_.validatorCount -= cluster.validatorCount; dao = dao_; - - cluster.active = false; - cluster.balance = 0; + + if (cluster.balance != 0) { + balanceLiquidatable = cluster.balance; + cluster.balance = 0; + } cluster.index = 0; + cluster.active = false; clusters[hashedCluster] = keccak256( abi.encodePacked( @@ -443,19 +395,16 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { ) ); - _transfer(msg.sender, balanceLiquidatable); + if (balanceLiquidatable != 0) { + _transfer(msg.sender, balanceLiquidatable); + } emit ClusterLiquidated(owner, operatorIds, cluster); } - function reactivate( - uint64[] memory operatorIds, - uint256 amount, - Cluster memory cluster - ) external override { - if (cluster.active) { - revert ClusterAlreadyEnabled(); - } + function reactivate(uint64[] memory operatorIds, uint256 amount, Cluster memory cluster) external override { + bytes32 hashedCluster = cluster.validateHashedCluster(msg.sender, operatorIds, this); + if (cluster.active) revert ClusterAlreadyEnabled(); uint64 clusterIndex; uint64 burnRate; @@ -464,7 +413,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { for (uint i; i < operatorsLength; ) { Operator memory operator = operators[operatorIds[i]]; if (operator.snapshot.block != 0) { - operator.getSnapshot(); + operator.updateSnapshot(); operator.validatorCount += cluster.validatorCount; burnRate += operator.fee; operators[operatorIds[i]] = operator; @@ -477,15 +426,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { } } - bytes32 hashedCluster = cluster.validateHashedCluster( - msg.sender, - operatorIds, - this - ); - - uint64 currentNetworkFeeIndex = NetworkLib.currentNetworkFeeIndex( - network - ); + uint64 currentNetworkFeeIndex = NetworkLib.currentNetworkFeeIndex(network); cluster.balance += amount; cluster.active = true; @@ -502,13 +443,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { dao = dao_; } - if ( - cluster.liquidatable( - burnRate, - networkFee, - minimumBlocksBeforeLiquidation - ) - ) { + if (cluster.isLiquidatable(burnRate, networkFee, minimumBlocksBeforeLiquidation)) { revert InsufficientBalance(); } @@ -539,14 +474,9 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { uint256 amount, Cluster memory cluster ) external override { + bytes32 hashedCluster = cluster.validateHashedCluster(owner, operatorIds, this); cluster.validateClusterIsNotLiquidated(); - bytes32 hashedCluster = cluster.validateHashedCluster( - owner, - operatorIds, - this - ); - cluster.balance += amount; clusters[hashedCluster] = keccak256( @@ -564,10 +494,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { emit ClusterDeposited(owner, operatorIds, amount, cluster); } - function withdrawOperatorEarnings( - uint64 operatorId, - uint256 amount - ) external override { + function withdrawOperatorEarnings(uint64 operatorId, uint256 amount) external override { _withdrawOperatorEarnings(operatorId, operators[operatorId], amount); } @@ -575,11 +502,8 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { _withdrawOperatorEarnings(operatorId, operators[operatorId], 0); } - function withdraw( - uint64[] memory operatorIds, - uint256 amount, - Cluster memory cluster - ) external override { + function withdraw(uint64[] memory operatorIds, uint256 amount, Cluster memory cluster) external override { + bytes32 hashedCluster = cluster.validateHashedCluster(msg.sender, operatorIds, this); cluster.validateClusterIsNotLiquidated(); uint64 clusterIndex; @@ -599,21 +523,11 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { } } - bytes32 hashedCluster = cluster.validateHashedCluster( - msg.sender, - operatorIds, - this - ); - cluster.updateClusterData(clusterIndex, NetworkLib.currentNetworkFeeIndex(network)); if ( cluster.balance < amount || - cluster.liquidatable( - burnRate, - network.networkFee, - minimumBlocksBeforeLiquidation - ) + cluster.isLiquidatable(burnRate, network.networkFee, minimumBlocksBeforeLiquidation) ) { revert InsufficientBalance(); } @@ -655,9 +569,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { network = network_; } - function withdrawNetworkEarnings( - uint256 amount - ) external override onlyOwner { + function withdrawNetworkEarnings(uint256 amount) external override onlyOwner { DAO memory dao_ = dao; uint64 shrunkAmount = amount.shrink(); @@ -676,30 +588,22 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { emit NetworkEarningsWithdrawn(amount, msg.sender); } - function updateOperatorFeeIncreaseLimit( - uint64 newOperatorMaxFeeIncrease - ) external override onlyOwner { + function updateOperatorFeeIncreaseLimit(uint64 newOperatorMaxFeeIncrease) external override onlyOwner { operatorMaxFeeIncrease = newOperatorMaxFeeIncrease; emit OperatorFeeIncreaseLimitUpdated(operatorMaxFeeIncrease); } - function updateDeclareOperatorFeePeriod( - uint64 newDeclareOperatorFeePeriod - ) external override onlyOwner { + function updateDeclareOperatorFeePeriod(uint64 newDeclareOperatorFeePeriod) external override onlyOwner { declareOperatorFeePeriod = newDeclareOperatorFeePeriod; emit DeclareOperatorFeePeriodUpdated(newDeclareOperatorFeePeriod); } - function updateExecuteOperatorFeePeriod( - uint64 newExecuteOperatorFeePeriod - ) external override onlyOwner { + function updateExecuteOperatorFeePeriod(uint64 newExecuteOperatorFeePeriod) external override onlyOwner { executeOperatorFeePeriod = newExecuteOperatorFeePeriod; emit ExecuteOperatorFeePeriodUpdated(newExecuteOperatorFeePeriod); } - function updateLiquidationThresholdPeriod( - uint64 blocks - ) external override onlyOwner { + function updateLiquidationThresholdPeriod(uint64 blocks) external override onlyOwner { if (blocks < MINIMAL_LIQUIDATION_THRESHOLD) { revert NewBlockPeriodIsBelowMinimum(); } @@ -724,11 +628,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { } function _validateOperatorIds(uint operatorsLength) private pure { - if ( - operatorsLength < 4 || - operatorsLength > 13 || - operatorsLength % 3 != 1 - ) { + if (operatorsLength < 4 || operatorsLength > 13 || operatorsLength % 3 != 1) { revert InvalidOperatorIdsLength(); } } @@ -737,10 +637,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { /* Operator Private Functions */ /******************************/ - function _transferOperatorBalanceUnsafe( - uint64 operatorId, - uint256 amount - ) private { + function _transferOperatorBalanceUnsafe(uint64 operatorId, uint256 amount) private { _transfer(msg.sender, amount); emit OperatorWithdrawn(msg.sender, operatorId, amount); } @@ -750,7 +647,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { Operator memory operator, uint256 amount ) private onlyOperatorOwner(operator) { - operator.getSnapshot(); + operator.updateSnapshot(); uint64 shrunkAmount; @@ -769,11 +666,8 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { _transferOperatorBalanceUnsafe(operatorId, shrunkAmount.expand()); } - function _removeOperator( - uint64 operatorId, - Operator memory operator - ) private onlyOperatorOwner(operator) { - operator.getSnapshot(); + function _removeOperator(uint64 operatorId, Operator memory operator) private onlyOperatorOwner(operator) { + operator.updateSnapshot(); uint64 currentBalance = operator.snapshot.balance; operator.snapshot.block = 0; @@ -805,58 +699,44 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { } // @dev 100% = 10000, 10% = 1000 - using 10000 to represent 2 digit precision - uint64 maxAllowedFee = (operatorFee * - (10000 + operatorMaxFeeIncrease)) / 10000; + uint64 maxAllowedFee = (operatorFee * (10000 + operatorMaxFeeIncrease)) / 10000; if (shrunkFee > maxAllowedFee) revert FeeExceedsIncreaseLimit(); operatorFeeChangeRequests[operatorId] = OperatorFeeChangeRequest( shrunkFee, uint64(block.timestamp) + declareOperatorFeePeriod, - uint64(block.timestamp) + - declareOperatorFeePeriod + - executeOperatorFeePeriod + uint64(block.timestamp) + declareOperatorFeePeriod + executeOperatorFeePeriod ); emit OperatorFeeDeclared(msg.sender, operatorId, block.number, fee); } - function _executeOperatorFee( - uint64 operatorId, - Operator memory operator - ) private onlyOperatorOwner(operator) { - OperatorFeeChangeRequest - memory feeChangeRequest = operatorFeeChangeRequests[operatorId]; + function _executeOperatorFee(uint64 operatorId, Operator memory operator) private onlyOperatorOwner(operator) { + OperatorFeeChangeRequest memory feeChangeRequest = operatorFeeChangeRequests[operatorId]; if (feeChangeRequest.approvalBeginTime == 0) revert NoFeeDelcared(); if ( - block.timestamp < feeChangeRequest.approvalBeginTime || - block.timestamp > feeChangeRequest.approvalEndTime + block.timestamp < feeChangeRequest.approvalBeginTime || block.timestamp > feeChangeRequest.approvalEndTime ) { revert ApprovalNotWithinTimeframe(); } - operator.getSnapshot(); + operator.updateSnapshot(); operator.fee = feeChangeRequest.fee; operators[operatorId] = operator; delete operatorFeeChangeRequests[operatorId]; - emit OperatorFeeExecuted( - msg.sender, - operatorId, - block.number, - feeChangeRequest.fee.expand() - ); + emit OperatorFeeExecuted(msg.sender, operatorId, block.number, feeChangeRequest.fee.expand()); } function _cancelDeclaredOperatorFee( uint64 operatorId, Operator memory operator ) private onlyOperatorOwner(operator) { - if (operatorFeeChangeRequests[operatorId].approvalBeginTime == 0) - revert NoFeeDelcared(); + if (operatorFeeChangeRequests[operatorId].approvalBeginTime == 0) revert NoFeeDelcared(); delete operatorFeeChangeRequests[operatorId]; diff --git a/contracts/SSVNetworkViews.sol b/contracts/SSVNetworkViews.sol index b584668a..6cfe6a83 100644 --- a/contracts/SSVNetworkViews.sol +++ b/contracts/SSVNetworkViews.sol @@ -1,9 +1,8 @@ -// File: contracts/SSVRegistry.sol // SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity 0.8.16; +pragma solidity 0.8.18; -import "./SSVNetwork.sol"; import "./ISSVNetworkViews.sol"; +import "./SSVNetwork.sol"; import "./libraries/Types.sol"; import "./libraries/ClusterLib.sol"; import "./libraries/OperatorLib.sol"; @@ -12,11 +11,7 @@ import "./libraries/NetworkLib.sol"; import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol"; -contract SSVNetworkViews is - UUPSUpgradeable, - Ownable2StepUpgradeable, - ISSVNetworkViews -{ +contract SSVNetworkViews is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetworkViews { using Types256 for uint256; using Types64 for uint64; using ClusterLib for Cluster; @@ -41,25 +36,17 @@ contract SSVNetworkViews is /* Operator External View Functions */ /************************************/ - function getOperatorFee( - uint64 operatorId - ) external view override returns (uint256) { - (, uint64 fee, , Snapshot memory snapshot) = _ssvNetwork.operators( - operatorId - ); + function getOperatorFee(uint64 operatorId) external view override returns (uint256) { + (, uint64 fee, , Snapshot memory snapshot) = _ssvNetwork.operators(operatorId); if (snapshot.block == 0) revert OperatorDoesNotExist(); return fee.expand(); } - function getOperatorDeclaredFee( - uint64 operatorId - ) external view override returns (uint256, uint256, uint256) { - ( - uint64 fee, - uint64 approvalBeginTime, - uint64 approvalEndTime - ) = _ssvNetwork.operatorFeeChangeRequests(operatorId); + function getOperatorDeclaredFee(uint64 operatorId) external view override returns (uint256, uint256, uint256) { + (uint64 fee, uint64 approvalBeginTime, uint64 approvalEndTime) = _ssvNetwork.operatorFeeChangeRequests( + operatorId + ); if (fee == 0) { revert NoFeeDelcared(); @@ -68,15 +55,10 @@ contract SSVNetworkViews is return (fee.expand(), approvalBeginTime, approvalEndTime); } - function getOperatorById( - uint64 operatorId - ) external view override returns (address, uint256, uint32, bool) { - ( - address operatorOwner, - uint64 fee, - uint32 validatorCount, - Snapshot memory snapshot - ) = _ssvNetwork.operators(operatorId); + function getOperatorById(uint64 operatorId) external view override returns (address, uint256, uint32, bool) { + (address operatorOwner, uint64 fee, uint32 validatorCount, Snapshot memory snapshot) = _ssvNetwork.operators( + operatorId + ); bool active; if (snapshot.block != 0) active = true; @@ -92,40 +74,24 @@ contract SSVNetworkViews is uint64[] calldata operatorIds, Cluster memory cluster ) external view override returns (bool) { + cluster.validateHashedCluster(owner, operatorIds, _ssvNetwork); + uint64 clusterIndex; uint64 burnRate; uint operatorsLength = operatorIds.length; for (uint i; i < operatorsLength; ++i) { - (, uint64 fee, , Snapshot memory snapshot) = _ssvNetwork.operators( - operatorIds[i] - ); - clusterIndex += - snapshot.index + - (uint64(block.number) - snapshot.block) * - fee; + (, uint64 fee, , Snapshot memory snapshot) = _ssvNetwork.operators(operatorIds[i]); + clusterIndex += snapshot.index + (uint64(block.number) - snapshot.block) * fee; burnRate += fee; } - cluster.validateHashedCluster(owner, operatorIds, _ssvNetwork); - - ( - uint64 networkFee, - uint64 networkFeeIndex, - uint64 networkFeeIndexBlockNumber - ) = _ssvNetwork.network(); + (uint64 networkFee, uint64 networkFeeIndex, uint64 networkFeeIndexBlockNumber) = _ssvNetwork.network(); - cluster.balance = cluster.clusterBalance( + cluster.updateBalance( clusterIndex, - NetworkLib.currentNetworkFeeIndex( - Network(networkFee, networkFeeIndex, networkFeeIndexBlockNumber) - ) + NetworkLib.currentNetworkFeeIndex(Network(networkFee, networkFeeIndex, networkFeeIndexBlockNumber)) ); - return - cluster.liquidatable( - burnRate, - networkFee, - _ssvNetwork.minimumBlocksBeforeLiquidation() - ); + return cluster.isLiquidatable(burnRate, networkFee, _ssvNetwork.minimumBlocksBeforeLiquidation()); } function isLiquidated( @@ -148,9 +114,7 @@ contract SSVNetworkViews is uint64 aggregateFee; uint operatorsLength = operatorIds.length; for (uint i; i < operatorsLength; ++i) { - (address operatorOwner, uint64 fee, , ) = _ssvNetwork.operators( - operatorIds[i] - ); + (address operatorOwner, uint64 fee, , ) = _ssvNetwork.operators(operatorIds[i]); if (operatorOwner != address(0)) { aggregateFee += fee; } @@ -166,28 +130,19 @@ contract SSVNetworkViews is /* Balance External View Functions */ /***********************************/ - function getOperatorEarnings( - uint64 id - ) external view override returns (uint256) { - ( - address operatorOwner, - uint64 fee, - uint32 validatorCount, - Snapshot memory snapshot - ) = _ssvNetwork.operators(id); + function getOperatorEarnings(uint64 id) external view override returns (uint256) { + (address operatorOwner, uint64 fee, uint32 validatorCount, Snapshot memory snapshot) = _ssvNetwork.operators( + id + ); Operator memory operator = Operator({ owner: operatorOwner, fee: fee, - snapshot: Snapshot({ - block: snapshot.block, - index: snapshot.index, - balance: snapshot.balance - }), + snapshot: Snapshot({block: snapshot.block, index: snapshot.index, balance: snapshot.balance}), validatorCount: validatorCount }); - operator.getSnapshot(); + operator.updateSnapshot(); return operator.snapshot.balance.expand(); } @@ -196,34 +151,27 @@ contract SSVNetworkViews is uint64[] calldata operatorIds, Cluster memory cluster ) external view override returns (uint256) { + cluster.validateHashedCluster(owner, operatorIds, _ssvNetwork); cluster.validateClusterIsNotLiquidated(); uint64 clusterIndex; { uint operatorsLength = operatorIds.length; for (uint i; i < operatorsLength; ++i) { - (, uint64 fee, , Snapshot memory snapshot) = _ssvNetwork - .operators(operatorIds[i]); - clusterIndex += - snapshot.index + - (uint64(block.number) - snapshot.block) * - fee; + (, uint64 fee, , Snapshot memory snapshot) = _ssvNetwork.operators(operatorIds[i]); + clusterIndex += snapshot.index + (uint64(block.number) - snapshot.block) * fee; } } - cluster.validateHashedCluster(owner, operatorIds, _ssvNetwork); - - ( - uint64 networkFee, - uint64 networkFeeIndex, - uint64 networkFeeIndexBlockNumber - ) = _ssvNetwork.network(); + (uint64 networkFee, uint64 networkFeeIndex, uint64 networkFeeIndexBlockNumber) = _ssvNetwork.network(); uint64 currrentNetworkFeeIndex = NetworkLib.currentNetworkFeeIndex( Network(networkFee, networkFeeIndex, networkFeeIndexBlockNumber) ); - return cluster.clusterBalance(clusterIndex, currrentNetworkFeeIndex); + cluster.updateBalance(clusterIndex, currrentNetworkFeeIndex); + + return cluster.balance; } /*******************************/ @@ -236,51 +184,27 @@ contract SSVNetworkViews is } function getNetworkEarnings() external view override returns (uint256) { - (uint32 validatorCount, uint64 balance, uint64 block) = _ssvNetwork.dao(); + (uint32 validatorCount_, uint64 balance_, uint64 block_) = _ssvNetwork.dao(); - DAO memory dao = DAO({ - validatorCount: validatorCount, - balance: balance, - block: block - }); + DAO memory dao = DAO({validatorCount: validatorCount_, balance: balance_, block: block_}); (uint64 networkFee, , ) = _ssvNetwork.network(); return dao.networkTotalEarnings(networkFee).expand(); } - function getOperatorFeeIncreaseLimit() - external - view - override - returns (uint64) - { + function getOperatorFeeIncreaseLimit() external view override returns (uint64) { return _ssvNetwork.operatorMaxFeeIncrease(); } - function getExecuteOperatorFeePeriod() - external - view - override - returns (uint64) - { + function getExecuteOperatorFeePeriod() external view override returns (uint64) { return _ssvNetwork.executeOperatorFeePeriod(); } - function getDeclaredOperatorFeePeriod() - external - view - override - returns (uint64) - { + function getDeclaredOperatorFeePeriod() external view override returns (uint64) { return _ssvNetwork.declareOperatorFeePeriod(); } - function getLiquidationThresholdPeriod() - external - view - override - returns (uint64) - { + function getLiquidationThresholdPeriod() external view override returns (uint64) { return _ssvNetwork.minimumBlocksBeforeLiquidation(); } diff --git a/contracts/libraries/ClusterLib.sol b/contracts/libraries/ClusterLib.sol index ee169097..dc35a41c 100644 --- a/contracts/libraries/ClusterLib.sol +++ b/contracts/libraries/ClusterLib.sol @@ -1,6 +1,5 @@ -// File: contracts/SSVNetwork.sol // SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity 0.8.16; +pragma solidity 0.8.18; import "../ISSVNetworkCore.sol"; import "../SSVNetwork.sol"; @@ -9,40 +8,27 @@ import "./Types.sol"; library ClusterLib { using Types64 for uint64; - function clusterBalance( + function updateBalance( ISSVNetworkCore.Cluster memory cluster, uint64 newIndex, uint64 currentNetworkFeeIndex - ) internal pure returns (uint256 balance) { - uint64 networkFee = uint64( - currentNetworkFeeIndex - cluster.networkFeeIndex - ) * cluster.validatorCount; - uint64 usage = (newIndex - cluster.index) * - cluster.validatorCount + - networkFee; - - if (usage.expand() > cluster.balance) { - revert ISSVNetworkCore.InsufficientFunds(); - } - - balance = cluster.balance - usage.expand(); + ) internal pure { + uint64 networkFee = uint64(currentNetworkFeeIndex - cluster.networkFeeIndex) * cluster.validatorCount; + uint64 usage = (newIndex - cluster.index) * cluster.validatorCount + networkFee; + cluster.balance = usage.expand() > cluster.balance ? 0 : cluster.balance - usage.expand(); } - function liquidatable( + function isLiquidatable( ISSVNetworkCore.Cluster memory cluster, uint64 burnRate, uint64 networkFee, uint64 minimumBlocksBeforeLiquidation ) internal pure returns (bool) { - uint64 liquidationThreshold = minimumBlocksBeforeLiquidation * - (burnRate + networkFee) * - cluster.validatorCount; + uint64 liquidationThreshold = minimumBlocksBeforeLiquidation * (burnRate + networkFee) * cluster.validatorCount; return cluster.balance < liquidationThreshold.expand(); } - function validateClusterIsNotLiquidated( - ISSVNetworkCore.Cluster memory cluster - ) internal pure { + function validateClusterIsNotLiquidated(ISSVNetworkCore.Cluster memory cluster) internal pure { if (!cluster.active) revert ISSVNetworkCore.ClusterIsLiquidated(); } @@ -77,11 +63,7 @@ library ClusterLib { uint64 clusterIndex, uint64 currentNetworkFeeIndex ) internal pure { - cluster.balance = clusterBalance( - cluster, - clusterIndex, - currentNetworkFeeIndex - ); + updateBalance(cluster, clusterIndex, currentNetworkFeeIndex); cluster.index = clusterIndex; cluster.networkFeeIndex = currentNetworkFeeIndex; } diff --git a/contracts/libraries/NetworkLib.sol b/contracts/libraries/NetworkLib.sol index e96203ec..fa2af523 100644 --- a/contracts/libraries/NetworkLib.sol +++ b/contracts/libraries/NetworkLib.sol @@ -1,36 +1,20 @@ -// File: contracts/SSVNetwork.sol // SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity 0.8.16; +pragma solidity 0.8.18; import "../ISSVNetworkCore.sol"; import "../SSVNetwork.sol"; library NetworkLib { - function updateDAOEarnings( - ISSVNetworkCore.DAO memory dao, - uint64 networkFee - ) internal view { + function updateDAOEarnings(ISSVNetworkCore.DAO memory dao, uint64 networkFee) internal view { dao.balance = networkTotalEarnings(dao, networkFee); dao.block = uint64(block.number); } - function networkTotalEarnings( - ISSVNetworkCore.DAO memory dao, - uint64 networkFee - ) internal view returns (uint64) { - return - dao.balance + - (uint64(block.number) - dao.block) * - networkFee * - dao.validatorCount; + function networkTotalEarnings(ISSVNetworkCore.DAO memory dao, uint64 networkFee) internal view returns (uint64) { + return dao.balance + (uint64(block.number) - dao.block) * networkFee * dao.validatorCount; } - function currentNetworkFeeIndex( - ISSVNetworkCore.Network memory network - ) internal view returns (uint64) { - return - network.networkFeeIndex + - uint64(block.number - network.networkFeeIndexBlockNumber) * - network.networkFee; + function currentNetworkFeeIndex(ISSVNetworkCore.Network memory network) internal view returns (uint64) { + return network.networkFeeIndex + uint64(block.number - network.networkFeeIndexBlockNumber) * network.networkFee; } } diff --git a/contracts/libraries/OperatorLib.sol b/contracts/libraries/OperatorLib.sol index 771e3607..aba540d0 100644 --- a/contracts/libraries/OperatorLib.sol +++ b/contracts/libraries/OperatorLib.sol @@ -1,15 +1,11 @@ -// File: contracts/SSVNetwork.sol // SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity 0.8.16; +pragma solidity 0.8.18; import "../ISSVNetworkCore.sol"; library OperatorLib { - function getSnapshot( - ISSVNetworkCore.Operator memory operator - ) internal view { - uint64 blockDiffFee = (uint64(block.number) - operator.snapshot.block) * - operator.fee; + function updateSnapshot(ISSVNetworkCore.Operator memory operator) internal view { + uint64 blockDiffFee = (uint64(block.number) - operator.snapshot.block) * operator.fee; operator.snapshot.index += blockDiffFee; operator.snapshot.balance += blockDiffFee * operator.validatorCount; diff --git a/contracts/libraries/Types.sol b/contracts/libraries/Types.sol index 20c1628f..a99e5737 100644 --- a/contracts/libraries/Types.sol +++ b/contracts/libraries/Types.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity 0.8.16; +pragma solidity 0.8.18; uint256 constant DEDUCTED_DIGITS = 10_000_000; diff --git a/contracts/mocks/SSVNetworkBasicUpgrade.sol b/contracts/mocks/SSVNetworkBasicUpgrade.sol index 8efbf0c1..37642570 100644 --- a/contracts/mocks/SSVNetworkBasicUpgrade.sol +++ b/contracts/mocks/SSVNetworkBasicUpgrade.sol @@ -1,6 +1,6 @@ // File: contracts/SSVRegistry.sol // SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity 0.8.16; +pragma solidity 0.8.18; import "../SSVNetwork.sol"; diff --git a/contracts/mocks/SSVNetworkLibUpgrade.sol b/contracts/mocks/SSVNetworkLibUpgrade.sol index e9e7ae22..588a6767 100644 --- a/contracts/mocks/SSVNetworkLibUpgrade.sol +++ b/contracts/mocks/SSVNetworkLibUpgrade.sol @@ -1,6 +1,6 @@ // File: contracts/SSVRegistry.sol // SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity 0.8.16; +pragma solidity 0.8.18; import "../SSVNetwork.sol"; import "./libraries/NetworkLibUpgrade.sol"; @@ -9,11 +9,7 @@ contract SSVNetworkLibUpgrade is SSVNetwork { using NetworkLibUpgrade for DAO; function getFixedNetworkRawBalance() external view returns (uint64) { - DAO memory dao = ISSVNetworkCore.DAO({ - validatorCount: 0, - balance: 100, - block: uint64(block.number) - }); + DAO memory dao = ISSVNetworkCore.DAO({validatorCount: 0, balance: 100, block: uint64(block.number)}); return dao.networkRawBalance(); } diff --git a/contracts/mocks/SSVNetworkReinitializable.sol b/contracts/mocks/SSVNetworkReinitializable.sol index b14ff526..fad61b47 100644 --- a/contracts/mocks/SSVNetworkReinitializable.sol +++ b/contracts/mocks/SSVNetworkReinitializable.sol @@ -1,13 +1,13 @@ // File: contracts/SSVRegistry.sol // SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity 0.8.16; +pragma solidity 0.8.18; import "../SSVNetwork.sol"; contract SSVNetworkReinitializable is SSVNetwork { uint256 public count; - function initializeV2() reinitializer(2) public { + function initializeV2() public reinitializer(2) { count = 100; } } diff --git a/contracts/mocks/SSVNetworkValidatorsPerOperator.sol b/contracts/mocks/SSVNetworkValidatorsPerOperator.sol index 693b0a95..bd43a5c1 100644 --- a/contracts/mocks/SSVNetworkValidatorsPerOperator.sol +++ b/contracts/mocks/SSVNetworkValidatorsPerOperator.sol @@ -1,11 +1,10 @@ // SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity 0.8.16; +pragma solidity 0.8.18; import "../SSVNetwork.sol"; contract SSVNetworkValidatorsPerOperator is SSVNetwork { - - function initializev2(uint32 validatorsPerOperatorLimit_) reinitializer(2) external { + function initializev2(uint32 validatorsPerOperatorLimit_) external reinitializer(2) { validatorsPerOperatorLimit = validatorsPerOperatorLimit_; } } diff --git a/contracts/mocks/SSVNetworkVersionUpgrade.sol b/contracts/mocks/SSVNetworkVersionUpgrade.sol index 94ad0224..1d1ca129 100644 --- a/contracts/mocks/SSVNetworkVersionUpgrade.sol +++ b/contracts/mocks/SSVNetworkVersionUpgrade.sol @@ -1,10 +1,10 @@ // SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity 0.8.16; +pragma solidity 0.8.18; import "../SSVNetwork.sol"; contract SSVNetworkVersionUpgrade is SSVNetwork { function initializev2(string calldata _version) external reinitializer(_getInitializedVersion() + 1) { - version = bytes32(abi.encodePacked((_version))); + version = bytes32(abi.encodePacked((_version))); } } diff --git a/contracts/mocks/SSVNetworkViewsBasicUpgrade.sol b/contracts/mocks/SSVNetworkViewsBasicUpgrade.sol index 24b0f928..d76cea9c 100644 --- a/contracts/mocks/SSVNetworkViewsBasicUpgrade.sol +++ b/contracts/mocks/SSVNetworkViewsBasicUpgrade.sol @@ -1,13 +1,11 @@ // File: contracts/SSVRegistry.sol // SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity 0.8.16; +pragma solidity 0.8.18; import "../SSVNetworkViews.sol"; contract SSVNetworkViewsBasicUpgrade is SSVNetworkViews { - function getOperatorOwnerdById( - uint64 operatorId - ) external view returns (address) { + function getOperatorOwnerdById(uint64 operatorId) external view returns (address) { (address operatorOwner, , , ) = _ssvNetwork.operators(operatorId); if (operatorOwner == address(0)) revert ISSVNetworkCore.OperatorDoesNotExist(); diff --git a/contracts/mocks/SSVNetworkViewsLibUpgrade.sol b/contracts/mocks/SSVNetworkViewsLibUpgrade.sol index b3ecaae3..8c065e0c 100644 --- a/contracts/mocks/SSVNetworkViewsLibUpgrade.sol +++ b/contracts/mocks/SSVNetworkViewsLibUpgrade.sol @@ -1,6 +1,6 @@ // File: contracts/SSVRegistry.sol // SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity 0.8.16; +pragma solidity 0.8.18; import "../SSVNetworkViews.sol"; import "../ISSVNetworkCore.sol"; diff --git a/contracts/mocks/SSVNetworkViewsReinitializable.sol b/contracts/mocks/SSVNetworkViewsReinitializable.sol index d2a68120..a85f50e2 100644 --- a/contracts/mocks/SSVNetworkViewsReinitializable.sol +++ b/contracts/mocks/SSVNetworkViewsReinitializable.sol @@ -1,6 +1,6 @@ // File: contracts/SSVRegistry.sol // SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity 0.8.16; +pragma solidity 0.8.18; import "../SSVNetworkViews.sol"; diff --git a/contracts/mocks/SSVTokenMock.sol b/contracts/mocks/SSVTokenMock.sol index adea872a..d37ad827 100644 --- a/contracts/mocks/SSVTokenMock.sol +++ b/contracts/mocks/SSVTokenMock.sol @@ -1,5 +1,5 @@ //SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity 0.8.16; +pragma solidity 0.8.18; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; diff --git a/contracts/mocks/libraries/NetworkLibUpgrade.sol b/contracts/mocks/libraries/NetworkLibUpgrade.sol index 2aacf181..e30809cc 100644 --- a/contracts/mocks/libraries/NetworkLibUpgrade.sol +++ b/contracts/mocks/libraries/NetworkLibUpgrade.sol @@ -1,49 +1,29 @@ // File: contracts/SSVNetwork.sol // SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity 0.8.16; +pragma solidity 0.8.18; import "../../ISSVNetwork.sol"; import "../../SSVNetwork.sol"; library NetworkLibUpgrade { - - function networkRawBalance( - ISSVNetwork.DAO memory dao - ) internal pure returns (uint64) { + function networkRawBalance(ISSVNetwork.DAO memory dao) internal pure returns (uint64) { return dao.balance; } - function networkBalance( - ISSVNetworkCore.DAO memory dao, - uint64 networkFee - ) internal view returns (uint64) { + + function networkBalance(ISSVNetworkCore.DAO memory dao, uint64 networkFee) internal view returns (uint64) { return networkTotalEarnings(dao, networkFee); } - function updateDAOEarnings( - ISSVNetworkCore.DAO memory dao, - uint64 networkFee - ) internal view { + function updateDAOEarnings(ISSVNetworkCore.DAO memory dao, uint64 networkFee) internal view { dao.balance = networkTotalEarnings(dao, networkFee); //dao.earnings.block = uint64(block.number); } - function networkTotalEarnings( - ISSVNetworkCore.DAO memory dao, - uint64 networkFee - ) internal view returns (uint64) { - return - dao.balance + - (uint64(block.number) - dao.block) * - networkFee * - dao.validatorCount; + function networkTotalEarnings(ISSVNetworkCore.DAO memory dao, uint64 networkFee) internal view returns (uint64) { + return dao.balance + (uint64(block.number) - dao.block) * networkFee * dao.validatorCount; } - function currentNetworkFeeIndex( - ISSVNetworkCore.Network memory network - ) internal view returns (uint64) { - return - network.networkFeeIndex + - uint64(block.number - network.networkFeeIndexBlockNumber) * - network.networkFee; + function currentNetworkFeeIndex(ISSVNetworkCore.Network memory network) internal view returns (uint64) { + return network.networkFeeIndex + uint64(block.number - network.networkFeeIndexBlockNumber) * network.networkFee; } } diff --git a/hardhat.config.ts b/hardhat.config.ts index cf68cacc..8b2174a6 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -16,7 +16,7 @@ const config: HardhatUserConfig = { solidity: { compilers: [ { - version: '0.8.16', + version: '0.8.18', settings: { optimizer: { enabled: true, diff --git a/package-lock.json b/package-lock.json index e7e2430f..f6f3e17b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,7 +22,7 @@ "dotenv": "^16.0.0", "eslint": "^8.23.0", "gh-pages": "^3.2.3", - "hardhat": "^2.12.5", + "hardhat": "^2.13.0", "hardhat-contract-sizer": "^2.6.1", "hardhat-storage-layout-changes": "^0.1.2", "hardhat-tracer": "^1.2.1", @@ -161,9 +161,9 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz", - "integrity": "sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.0.tgz", + "integrity": "sha512-fluIaaV+GyV24CCu/ggiHdV+j4RNh85yQnAYS/G2mZODZgGmmlrgCydjUcV3YvxCm9x8nMAfThsqTni4KiXT4A==", "dev": true, "dependencies": { "ajv": "^6.12.4", @@ -183,6 +183,15 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/@eslint/js": { + "version": "8.35.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.35.0.tgz", + "integrity": "sha512-JXdzbRiWclLVoD8sNUjR443VVlYqiYmDVT6rGUEIEHU5YJW0gaVZwV2xgM7D4arkvASqD0IlLUVjHiFuxaftRw==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, "node_modules/@ethersproject/abi": { "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz", @@ -1003,10 +1012,44 @@ "rlp": "^2.2.3" } }, + "node_modules/@morgan-stanley/ts-mocking-bird": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@morgan-stanley/ts-mocking-bird/-/ts-mocking-bird-0.6.4.tgz", + "integrity": "sha512-57VJIflP8eR2xXa9cD1LUawh+Gh+BVQfVu0n6GALyg/AqV/Nz25kDRvws3i9kIe1PTrbsZZOYpsYp6bXPd6nVA==", + "dev": true, + "peer": true, + "dependencies": { + "lodash": "^4.17.16", + "uuid": "^7.0.3" + }, + "peerDependencies": { + "jasmine": "2.x || 3.x || 4.x", + "jest": "26.x || 27.x || 28.x", + "typescript": ">=4.2" + }, + "peerDependenciesMeta": { + "jasmine": { + "optional": true + }, + "jest": { + "optional": true + } + } + }, + "node_modules/@morgan-stanley/ts-mocking-bird/node_modules/uuid": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz", + "integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==", + "dev": true, + "peer": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/@noble/hashes": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.1.2.tgz", - "integrity": "sha512-KYRCASVTv6aeUi1tsF8/vpyR7zpfs3FUzy2Jqm+MU+LmUKhQ0y2FpfwqkCcxSg2ua4GALJd8k2R76WxwZGbQpA==", + "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": [ { @@ -1016,9 +1059,9 @@ ] }, "node_modules/@noble/secp256k1": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-1.6.3.tgz", - "integrity": "sha512-T04e4iTurVy7I8Sw4+c5OSN9/RkPlo1uKxAomtxQNLq8j1uPAqnsqG1bqvY3Jv7c13gyr6dui0zmh/I3+f/JaQ==", + "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, "funding": [ { @@ -1246,16 +1289,15 @@ } }, "node_modules/@nomicfoundation/hardhat-chai-matchers": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-chai-matchers/-/hardhat-chai-matchers-1.0.5.tgz", - "integrity": "sha512-+W5C/+5FHI2xBajUN9THSNc1UP6FUsA7LeLmfnaC9VMi/50/DEjjxd8OmizEXgV1Bjck7my4NVQLL1Ti39FkpA==", + "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, "dependencies": { "@ethersproject/abi": "^5.1.2", "@types/chai-as-promised": "^7.1.3", "chai-as-promised": "^7.1.1", - "chalk": "^2.4.2", "deep-eql": "^4.0.1", "ordinal": "^1.0.3" }, @@ -1266,88 +1308,10 @@ "hardhat": "^2.9.4" } }, - "node_modules/@nomicfoundation/hardhat-chai-matchers/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/@nomicfoundation/hardhat-chai-matchers/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, - "peer": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@nomicfoundation/hardhat-chai-matchers/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" - } - }, - "node_modules/@nomicfoundation/hardhat-chai-matchers/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/@nomicfoundation/hardhat-chai-matchers/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/@nomicfoundation/hardhat-chai-matchers/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, - "peer": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@nomicfoundation/hardhat-chai-matchers/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/@nomicfoundation/hardhat-network-helpers": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-network-helpers/-/hardhat-network-helpers-1.0.7.tgz", - "integrity": "sha512-X+3mNvn8B7BY5hpIaLO+TrfzWq12bpux+ajGGdmdcfC78NXmYmOZkAtiz1QZx1YIZGMS1LaXzPXyBExxKFpCaw==", + "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==", "dev": true, "peer": true, "dependencies": { @@ -1358,9 +1322,9 @@ } }, "node_modules/@nomicfoundation/hardhat-toolbox": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-toolbox/-/hardhat-toolbox-2.0.1.tgz", - "integrity": "sha512-/pr8m9xlqiNlq6fXv4hEPNwdNwUhysoB2qbDCKqERfPpq34EydUQTC3Vis4aIea8RLwSrU8sDXFdv4TQxYstKw==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-toolbox/-/hardhat-toolbox-2.0.2.tgz", + "integrity": "sha512-vnN1AzxbvpSx9pfdRHbUzTRIXpMLPXnUlkW855VaDk6N1pwRaQ2gNzEmFAABk4lWf11E00PKwFd/q27HuwYrYg==", "dev": true, "peerDependencies": { "@ethersproject/abi": "^5.4.7", @@ -1577,9 +1541,9 @@ } }, "node_modules/@nomiclabs/hardhat-etherscan": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-3.1.5.tgz", - "integrity": "sha512-PxPX28AGBAlxgXLU27NB3oiMsklxbNhM75SDC4v1QPCyPeAxGm4xV0WpYbR10W7sxY2WF3Ek7u7GhjbQWa2Fcg==", + "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, "dependencies": { @@ -1689,21 +1653,21 @@ } }, "node_modules/@openzeppelin/contracts": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.8.0.tgz", - "integrity": "sha512-AGuwhRRL+NaKx73WKRNzeCxOCOCxpaqF+kp8TJ89QzAipSwZy/NoflkWaL9bywXFRhIzXt8j38sfF7KBKCPWLw==", + "version": "4.8.2", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.8.2.tgz", + "integrity": "sha512-kEUOgPQszC0fSYWpbh2kT94ltOJwj1qfT2DWo+zVttmGmf97JZ99LspePNaeeaLhCImaHVeBbjaQFZQn7+Zc5g==", "dev": true }, "node_modules/@openzeppelin/contracts-upgradeable": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.8.0.tgz", - "integrity": "sha512-5GeFgqMiDlqGT8EdORadp1ntGF0qzWZLmEY7Wbp/yVhN7/B3NNzCxujuI77ktlyG81N3CUZP8cZe3ZAQ/cW10w==", + "version": "4.8.2", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.8.2.tgz", + "integrity": "sha512-zIggnBwemUmmt9IS73qxi+tumALxCY4QEs3zLCII78k0Gfse2hAOdAkuAeLUzvWUpneMUfFE5sGHzEUSTvn4Ag==", "dev": true }, "node_modules/@openzeppelin/hardhat-upgrades": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/@openzeppelin/hardhat-upgrades/-/hardhat-upgrades-1.22.0.tgz", - "integrity": "sha512-1qyZnDaxl0C8tne7ykNRa/fxw3FrNCY2M3fGuCiQW5DDkJoXhLgm3JVsXwl6X7q9mQSrik4vgBbI3ErmxmZTYg==", + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/@openzeppelin/hardhat-upgrades/-/hardhat-upgrades-1.22.1.tgz", + "integrity": "sha512-MdoitCTLl4zwMU8MeE/bCj+7JMWBEvd38XqJkw36PkJrXlbv6FedDVCPoumMAhpmtymm0nTwTYYklYG+L6WiiQ==", "dev": true, "dependencies": { "@openzeppelin/upgrades-core": "^1.20.0", @@ -1727,9 +1691,9 @@ } }, "node_modules/@openzeppelin/upgrades-core": { - "version": "1.20.6", - "resolved": "https://registry.npmjs.org/@openzeppelin/upgrades-core/-/upgrades-core-1.20.6.tgz", - "integrity": "sha512-KWdtlahm+iunlAlzLsdpBueanwEx0LLPfAkDL1p0C4SPjMiUqHHFlyGtmmWwdiqDpJ//605vfwkd5RqfnFrHSg==", + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/@openzeppelin/upgrades-core/-/upgrades-core-1.24.1.tgz", + "integrity": "sha512-QhdIQDUykJ3vQauB6CheV7vk4zgn0e1iY+IDg7r1KqpA1m2bqIGjQCpzidW33K4bZc9zdJSPx2/Z6Um5KxCB7A==", "dev": true, "dependencies": { "cbor": "^8.0.0", @@ -1754,9 +1718,9 @@ ] }, "node_modules/@scure/bip32": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.0.tgz", - "integrity": "sha512-ftTW3kKX54YXLCxH6BB7oEEoJfoE2pIgw7MINKAs5PsS6nqKPuKk1haTF/EuHmYqG330t5GSrdmtRuHaY1a62Q==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.5.tgz", + "integrity": "sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw==", "dev": true, "funding": [ { @@ -1765,15 +1729,15 @@ } ], "dependencies": { - "@noble/hashes": "~1.1.1", - "@noble/secp256k1": "~1.6.0", + "@noble/hashes": "~1.2.0", + "@noble/secp256k1": "~1.7.0", "@scure/base": "~1.1.0" } }, "node_modules/@scure/bip39": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.0.tgz", - "integrity": "sha512-pwrPOS16VeTKg98dYXQyIjJEcWfz7/1YJIwxUEPFfQPtc86Ym/1sVgQ2RLoD43AazMk2l/unK4ITySSpW2+82w==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.1.tgz", + "integrity": "sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg==", "dev": true, "funding": [ { @@ -1782,7 +1746,7 @@ } ], "dependencies": { - "@noble/hashes": "~1.1.1", + "@noble/hashes": "~1.2.0", "@scure/base": "~1.1.0" } }, @@ -2135,15 +2099,16 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.48.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.48.1.tgz", - "integrity": "sha512-9nY5K1Rp2ppmpb9s9S2aBiF3xo5uExCehMDmYmmFqqyxgenbHJ3qbarcLt4ITgaD6r/2ypdlcFRdcuVPnks+fQ==", + "version": "5.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.54.0.tgz", + "integrity": "sha512-+hSN9BdSr629RF02d7mMtXhAJvDTyCbprNYJKrXETlul/Aml6YZwd90XioVbjejQeHbb3R8Dg0CkRgoJDxo8aw==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.48.1", - "@typescript-eslint/type-utils": "5.48.1", - "@typescript-eslint/utils": "5.48.1", + "@typescript-eslint/scope-manager": "5.54.0", + "@typescript-eslint/type-utils": "5.54.0", + "@typescript-eslint/utils": "5.54.0", "debug": "^4.3.4", + "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", "natural-compare-lite": "^1.4.0", "regexpp": "^3.2.0", @@ -2201,15 +2166,15 @@ "dev": true }, "node_modules/@typescript-eslint/parser": { - "version": "5.48.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.48.1.tgz", - "integrity": "sha512-4yg+FJR/V1M9Xoq56SF9Iygqm+r5LMXvheo6DQ7/yUWynQ4YfCRnsKuRgqH4EQ5Ya76rVwlEpw4Xu+TgWQUcdA==", + "version": "5.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.54.0.tgz", + "integrity": "sha512-aAVL3Mu2qTi+h/r04WI/5PfNWvO6pdhpeMRWk9R7rEV4mwJNzoWf5CCU5vDKBsPIFQFjEq1xg7XBI2rjiMXQbQ==", "dev": true, "peer": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.48.1", - "@typescript-eslint/types": "5.48.1", - "@typescript-eslint/typescript-estree": "5.48.1", + "@typescript-eslint/scope-manager": "5.54.0", + "@typescript-eslint/types": "5.54.0", + "@typescript-eslint/typescript-estree": "5.54.0", "debug": "^4.3.4" }, "engines": { @@ -2229,13 +2194,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.48.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.48.1.tgz", - "integrity": "sha512-S035ueRrbxRMKvSTv9vJKIWgr86BD8s3RqoRZmsSh/s8HhIs90g6UlK8ZabUSjUZQkhVxt7nmZ63VJ9dcZhtDQ==", + "version": "5.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.54.0.tgz", + "integrity": "sha512-VTPYNZ7vaWtYna9M4oD42zENOBrb+ZYyCNdFs949GcN8Miwn37b8b7eMj+EZaq7VK9fx0Jd+JhmkhjFhvnovhg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.48.1", - "@typescript-eslint/visitor-keys": "5.48.1" + "@typescript-eslint/types": "5.54.0", + "@typescript-eslint/visitor-keys": "5.54.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -2246,13 +2211,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.48.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.48.1.tgz", - "integrity": "sha512-Hyr8HU8Alcuva1ppmqSYtM/Gp0q4JOp1F+/JH5D1IZm/bUBrV0edoewQZiEc1r6I8L4JL21broddxK8HAcZiqQ==", + "version": "5.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.54.0.tgz", + "integrity": "sha512-WI+WMJ8+oS+LyflqsD4nlXMsVdzTMYTxl16myXPaCXnSgc7LWwMsjxQFZCK/rVmTZ3FN71Ct78ehO9bRC7erYQ==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "5.48.1", - "@typescript-eslint/utils": "5.48.1", + "@typescript-eslint/typescript-estree": "5.54.0", + "@typescript-eslint/utils": "5.54.0", "debug": "^4.3.4", "tsutils": "^3.21.0" }, @@ -2273,9 +2238,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.48.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.48.1.tgz", - "integrity": "sha512-xHyDLU6MSuEEdIlzrrAerCGS3T7AA/L8Hggd0RCYBi0w3JMvGYxlLlXHeg50JI9Tfg5MrtsfuNxbS/3zF1/ATg==", + "version": "5.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.54.0.tgz", + "integrity": "sha512-nExy+fDCBEgqblasfeE3aQ3NuafBUxZxgxXcYfzYRZFHdVvk5q60KhCSkG0noHgHRo/xQ/BOzURLZAafFpTkmQ==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -2286,13 +2251,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.48.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.48.1.tgz", - "integrity": "sha512-Hut+Osk5FYr+sgFh8J/FHjqX6HFcDzTlWLrFqGoK5kVUN3VBHF/QzZmAsIXCQ8T/W9nQNBTqalxi1P3LSqWnRA==", + "version": "5.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.54.0.tgz", + "integrity": "sha512-X2rJG97Wj/VRo5YxJ8Qx26Zqf0RRKsVHd4sav8NElhbZzhpBI8jU54i6hfo9eheumj4oO4dcRN1B/zIVEqR/MQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.48.1", - "@typescript-eslint/visitor-keys": "5.48.1", + "@typescript-eslint/types": "5.54.0", + "@typescript-eslint/visitor-keys": "5.54.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -2346,16 +2311,16 @@ "dev": true }, "node_modules/@typescript-eslint/utils": { - "version": "5.48.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.48.1.tgz", - "integrity": "sha512-SmQuSrCGUOdmGMwivW14Z0Lj8dxG1mOFZ7soeJ0TQZEJcs3n5Ndgkg0A4bcMFzBELqLJ6GTHnEU+iIoaD6hFGA==", + "version": "5.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.54.0.tgz", + "integrity": "sha512-cuwm8D/Z/7AuyAeJ+T0r4WZmlnlxQ8wt7C7fLpFlKMR+dY6QO79Cq1WpJhvZbMA4ZeZGHiRWnht7ZJ8qkdAunw==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.48.1", - "@typescript-eslint/types": "5.48.1", - "@typescript-eslint/typescript-estree": "5.48.1", + "@typescript-eslint/scope-manager": "5.54.0", + "@typescript-eslint/types": "5.54.0", + "@typescript-eslint/typescript-estree": "5.54.0", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0", "semver": "^7.3.7" @@ -2405,12 +2370,12 @@ "dev": true }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.48.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.48.1.tgz", - "integrity": "sha512-Ns0XBwmfuX7ZknznfXozgnydyR8F6ev/KEGePP4i74uL3ArsKbEhJ7raeKr1JSa997DBDwol/4a0Y+At82c9dA==", + "version": "5.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.54.0.tgz", + "integrity": "sha512-xu4wT7aRCakGINTLGeyGqDn+78BwFlggwBjnHa1ar/KaGagnmwLYmlrXIrgAaQ3AE1Vd6nLfKASm7LrFHNbKGA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.48.1", + "@typescript-eslint/types": "5.54.0", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -2459,9 +2424,9 @@ } }, "node_modules/acorn": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", - "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -3581,9 +3546,9 @@ } }, "node_modules/concat-stream/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, "peer": true, "dependencies": { @@ -3849,9 +3814,9 @@ "dev": true }, "node_modules/define-properties": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", - "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", + "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==", "dev": true, "peer": true, "dependencies": { @@ -4245,12 +4210,13 @@ } }, "node_modules/eslint": { - "version": "8.31.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.31.0.tgz", - "integrity": "sha512-0tQQEVdmPZ1UtUKXjX7EMm9BlgJ08G90IhWh0PKDCb3ZLsgAOHI8fYSIzYVZej92zsgq+ft0FGsxhJ3xo2tbuA==", + "version": "8.35.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.35.0.tgz", + "integrity": "sha512-BxAf1fVL7w+JLRQhWl2pzGeSiGqbWumV4WNvc9Rhp6tiCtm4oHnyPBSEtMGZwrQgudFQ+otqzWoPB7x+hxoWsw==", "dev": true, "dependencies": { - "@eslint/eslintrc": "^1.4.1", + "@eslint/eslintrc": "^2.0.0", + "@eslint/js": "8.35.0", "@humanwhocodes/config-array": "^0.11.8", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -4264,7 +4230,7 @@ "eslint-utils": "^3.0.0", "eslint-visitor-keys": "^3.3.0", "espree": "^9.4.0", - "esquery": "^1.4.0", + "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", @@ -4403,9 +4369,9 @@ } }, "node_modules/esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dev": true, "dependencies": { "estraverse": "^5.1.0" @@ -4761,16 +4727,16 @@ } }, "node_modules/eth-gas-reporter/node_modules/ethereum-cryptography": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.1.2.tgz", - "integrity": "sha512-XDSJlg4BD+hq9N2FjvotwUET9Tfxpxc3kWGE2AqUG5vcbeunnbImVk3cj6e/xT3phdW21mE8R5IugU4fspQDcQ==", + "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": { - "@noble/hashes": "1.1.2", - "@noble/secp256k1": "1.6.3", - "@scure/bip32": "1.1.0", - "@scure/bip39": "1.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/ethers": { @@ -5892,9 +5858,9 @@ } }, "node_modules/get-intrinsic": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", - "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", + "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", "dev": true, "dependencies": { "function-bind": "^1.1.1", @@ -6181,9 +6147,9 @@ } }, "node_modules/globals": { - "version": "13.19.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", - "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -6324,9 +6290,9 @@ } }, "node_modules/hardhat": { - "version": "2.12.6", - "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.12.6.tgz", - "integrity": "sha512-0Ent1O5DsPgvaVb5sxEgsQ3bJRt/Ex92tsoO+xjoNH2Qc4bFmhI5/CHVlFikulalxOPjNmw5XQ2vJFuVQFESAA==", + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.13.0.tgz", + "integrity": "sha512-ZlzBOLML1QGlm6JWyVAG8lVTEAoOaVm1in/RU2zoGAnYEoD1Rp4T+ZMvrLNhHaaeS9hfjJ1gJUBfiDr4cx+htQ==", "dev": true, "dependencies": { "@ethersproject/abi": "^5.1.2", @@ -6381,10 +6347,10 @@ "ws": "^7.4.6" }, "bin": { - "hardhat": "internal/cli/cli.js" + "hardhat": "internal/cli/bootstrap.js" }, "engines": { - "node": "^14.0.0 || ^16.0.0 || ^18.0.0" + "node": ">=14.0.0" }, "peerDependencies": { "ts-node": "*", @@ -6400,13 +6366,14 @@ } }, "node_modules/hardhat-contract-sizer": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/hardhat-contract-sizer/-/hardhat-contract-sizer-2.6.1.tgz", - "integrity": "sha512-b8wS7DBvyo22kmVwpzstAQTdDCThpl/ySBqZh5ga9Yxjf61/uTL12TEg5nl7lDeWy73ntEUzxMwY6XxbQEc2wA==", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/hardhat-contract-sizer/-/hardhat-contract-sizer-2.8.0.tgz", + "integrity": "sha512-jXt2Si3uIDx5z99J+gvKa0yvIw156pE4dpH9X/PvTQv652BUd+qGj7WT93PXnHXGh5qhQLkjDYeZMYNOThfjFg==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "cli-table3": "^0.6.0" + "cli-table3": "^0.6.0", + "strip-ansi": "^6.0.0" }, "peerDependencies": { "hardhat": "^2.0.0" @@ -6437,9 +6404,9 @@ } }, "node_modules/hardhat-tracer": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/hardhat-tracer/-/hardhat-tracer-1.2.1.tgz", - "integrity": "sha512-ZZVXZfWfRzPkjGdkLoxC4v3Dqja7cpG1mOOr+3+m9xGmqfw9P6cKMDo+wYtGPNM6KttwsJ226Gqt5AwBjMxgTg==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/hardhat-tracer/-/hardhat-tracer-1.3.0.tgz", + "integrity": "sha512-mUYuRJWlxCwY4R2urCpNM4ecVSq/iMLiVP9YZKlfXyv4R8T+4HAcTfumilUOXHGe6wHI+8Ki2EaTon3KgzATDA==", "dev": true, "dependencies": { "ethers": "^5.6.1" @@ -6501,15 +6468,15 @@ } }, "node_modules/hardhat/node_modules/ethereum-cryptography": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.1.2.tgz", - "integrity": "sha512-XDSJlg4BD+hq9N2FjvotwUET9Tfxpxc3kWGE2AqUG5vcbeunnbImVk3cj6e/xT3phdW21mE8R5IugU4fspQDcQ==", + "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, "dependencies": { - "@noble/hashes": "1.1.2", - "@noble/secp256k1": "1.6.3", - "@scure/bip32": "1.1.0", - "@scure/bip39": "1.1.0" + "@noble/hashes": "1.2.0", + "@noble/secp256k1": "1.7.1", + "@scure/bip32": "1.1.5", + "@scure/bip39": "1.1.1" } }, "node_modules/hardhat/node_modules/find-up": { @@ -6856,9 +6823,9 @@ } }, "node_modules/immutable": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.2.2.tgz", - "integrity": "sha512-fTMKDwtbvO5tldky9QZ2fMX7slR0mYpY5nbnFWYp0fOzDhHqhgIw9KoYgxLWsoNTS9ZHGauHj18DTyEw6BK3Og==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.2.4.tgz", + "integrity": "sha512-WDxL3Hheb1JkRN3sQkyujNlL/xRjAo3rJtaU5xeufUauG66JdMr32bLj4gF+vWl84DIA3Zxw7tiAjneYzRRw+w==", "dev": true }, "node_modules/import-fresh": { @@ -7087,13 +7054,13 @@ } }, "node_modules/internal-slot": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.4.tgz", - "integrity": "sha512-tA8URYccNzMo94s5MQZgH8NB/XTa6HsOo0MLfXTKKEnHVVdegzaQoFZ7Jp44bdvLvY2waT5dc+j5ICEswhi7UQ==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", + "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", "dev": true, "peer": true, "dependencies": { - "get-intrinsic": "^1.1.3", + "get-intrinsic": "^1.2.0", "has": "^1.0.3", "side-channel": "^1.0.4" }, @@ -7121,14 +7088,14 @@ } }, "node_modules/is-array-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.1.tgz", - "integrity": "sha512-ASfLknmY8Xa2XtB4wmbz13Wu202baeA18cJBCeCy0wXUHZF0IPyVEXqKEcd+t2fNSLLL1vC6k7lxZEojNbISXQ==", + "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.1.3", + "get-intrinsic": "^1.2.0", "is-typed-array": "^1.1.10" }, "funding": { @@ -7475,9 +7442,9 @@ "peer": true }, "node_modules/js-sdsl": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.2.0.tgz", - "integrity": "sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz", + "integrity": "sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==", "dev": true, "funding": { "type": "opencollective", @@ -7909,9 +7876,9 @@ } }, "node_modules/minimist": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", - "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -8214,9 +8181,9 @@ } }, "node_modules/object-inspect": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", - "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -8681,9 +8648,9 @@ "peer": true }, "node_modules/punycode": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.2.0.tgz", - "integrity": "sha512-LN6QV1IJ9ZhxWTNdktaPClrNfp8xdSAYS0Zk2ddX7XsXZAxckMHPCBcHRo0cTcEIgYPRiGEkmji3Idkh2yFtYw==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", "dev": true, "engines": { "node": ">=6" @@ -8734,9 +8701,9 @@ } }, "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==", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", "dev": true, "dependencies": { "bytes": "3.1.2", @@ -8749,9 +8716,9 @@ } }, "node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.1.tgz", + "integrity": "sha512-+rQmrWMYGA90yenhTYsLWAsLsqVC8osOw6PKE1HDYiO0gdPeKe/xDHNzIAIn4C91YQ6oenEhfYqqc1883qHbjQ==", "dev": true, "dependencies": { "inherits": "^2.0.3", @@ -9470,9 +9437,9 @@ "dev": true }, "node_modules/simple-git": { - "version": "3.15.1", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.15.1.tgz", - "integrity": "sha512-73MVa5984t/JP4JcQt0oZlKGr42ROYWC3BcUZfuHtT3IHKPspIvL0cZBnvPXF7LL3S/qVeVHVdYYmJ3LOTw4Rg==", + "version": "3.16.1", + "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.16.1.tgz", + "integrity": "sha512-xzRxMKiy1zEYeHGXgAzvuXffDS0xgsq07Oi4LWEEcVH29vLpcZ2tyQRWyK0NLLlCVaKysZeem5tC1qHEOxsKwA==", "dev": true, "dependencies": { "@kwsites/file-exists": "^1.1.1", @@ -10154,9 +10121,9 @@ } }, "node_modules/solidity-ast": { - "version": "0.4.40", - "resolved": "https://registry.npmjs.org/solidity-ast/-/solidity-ast-0.4.40.tgz", - "integrity": "sha512-M8uLBT2jgFB7B0iVAC5a2l71J8vim7aEm03AZkaHbDqyrl1pE+i5PriMEw6WlwGfHp3/Ym7cn9BqvVLQgRk+Yw==", + "version": "0.4.46", + "resolved": "https://registry.npmjs.org/solidity-ast/-/solidity-ast-0.4.46.tgz", + "integrity": "sha512-MlPZQfPhjWXqh7YxWcBGDXaPZIfMYCOHYoLEhGDWulNwEPIQQZuB7mA9eP17CU0jY/bGR4avCEUVVpvHtT2gbA==", "dev": true }, "node_modules/solidity-coverage": { @@ -11317,12 +11284,13 @@ } }, "node_modules/ts-command-line-args": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/ts-command-line-args/-/ts-command-line-args-2.3.1.tgz", - "integrity": "sha512-FR3y7pLl/fuUNSmnPhfLArGqRrpojQgIEEOVzYx9DhTmfIN7C9RWSfpkJEF4J+Gk7aVx5pak8I7vWZsaN4N84g==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/ts-command-line-args/-/ts-command-line-args-2.4.2.tgz", + "integrity": "sha512-mJLQQBOdyD4XI/ZWQY44PIdYde47JhV2xl380O7twPkTQ+Y5vFDHsk8LOeXKuz7dVY5aDCfAzRarNfSqtKOkQQ==", "dev": true, "peer": true, "dependencies": { + "@morgan-stanley/ts-mocking-bird": "^0.6.2", "chalk": "^4.1.0", "command-line-args": "^5.1.1", "command-line-usage": "^6.1.0", @@ -11540,9 +11508,9 @@ } }, "node_modules/typechain/node_modules/prettier": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.2.tgz", - "integrity": "sha512-BtRV9BcncDyI2tsuS19zzhzoxD8Dh8LiCx7j7tHzrkz8GFXAexeWFdi22mjE1d16dftH2qNaytVxqiRTGlMfpw==", + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.4.tgz", + "integrity": "sha512-vIS4Rlc2FNh0BySk3Wkd6xmwxB0FpOndW5fisM5H8hsZSxU2VWVB5CWIkIjWvrHjIhxk2g3bfMKM87zNTrZddw==", "dev": true, "peer": true, "bin": { @@ -11578,9 +11546,9 @@ "peer": true }, "node_modules/typescript": { - "version": "4.9.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", - "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -11631,9 +11599,9 @@ } }, "node_modules/undici": { - "version": "5.15.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.15.0.tgz", - "integrity": "sha512-wCAZJDyjw9Myv+Ay62LAoB+hZLPW9SmKbQkbHIhMw/acKSlpn7WohdMUc/Vd4j1iSMBO0hWwU8mjB7a5p5bl8g==", + "version": "5.20.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.20.0.tgz", + "integrity": "sha512-J3j60dYzuo6Eevbawwp1sdg16k5Tf768bxYK4TUJRH7cBM4kFCbf3mOnM/0E3vQYXvpxITbbWmBafaDbxLDz3g==", "dev": true, "dependencies": { "busboy": "^1.6.0" @@ -11713,9 +11681,9 @@ } }, "node_modules/web3-utils": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.8.1.tgz", - "integrity": "sha512-LgnM9p6V7rHHUGfpMZod+NST8cRfGzJ1BTXAyNo7A9cJX9LczBfSRxJp+U/GInYe9mby40t3v22AJdlELibnsQ==", + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.8.2.tgz", + "integrity": "sha512-v7j6xhfLQfY7xQDrUP0BKbaNrmZ2/+egbqP9q3KYmOiPpnvAfol+32slgL0WX/5n8VPvKCK5EZ1HGrAVICSToA==", "dev": true, "peer": true, "dependencies": { @@ -12141,9 +12109,9 @@ } }, "@eslint/eslintrc": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz", - "integrity": "sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.0.tgz", + "integrity": "sha512-fluIaaV+GyV24CCu/ggiHdV+j4RNh85yQnAYS/G2mZODZgGmmlrgCydjUcV3YvxCm9x8nMAfThsqTni4KiXT4A==", "dev": true, "requires": { "ajv": "^6.12.4", @@ -12157,6 +12125,12 @@ "strip-json-comments": "^3.1.1" } }, + "@eslint/js": { + "version": "8.35.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.35.0.tgz", + "integrity": "sha512-JXdzbRiWclLVoD8sNUjR443VVlYqiYmDVT6rGUEIEHU5YJW0gaVZwV2xgM7D4arkvASqD0IlLUVjHiFuxaftRw==", + "dev": true + }, "@ethersproject/abi": { "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz", @@ -12663,16 +12637,36 @@ } } }, + "@morgan-stanley/ts-mocking-bird": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@morgan-stanley/ts-mocking-bird/-/ts-mocking-bird-0.6.4.tgz", + "integrity": "sha512-57VJIflP8eR2xXa9cD1LUawh+Gh+BVQfVu0n6GALyg/AqV/Nz25kDRvws3i9kIe1PTrbsZZOYpsYp6bXPd6nVA==", + "dev": true, + "peer": true, + "requires": { + "lodash": "^4.17.16", + "uuid": "^7.0.3" + }, + "dependencies": { + "uuid": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz", + "integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==", + "dev": true, + "peer": true + } + } + }, "@noble/hashes": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.1.2.tgz", - "integrity": "sha512-KYRCASVTv6aeUi1tsF8/vpyR7zpfs3FUzy2Jqm+MU+LmUKhQ0y2FpfwqkCcxSg2ua4GALJd8k2R76WxwZGbQpA==", + "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.6.3", - "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-1.6.3.tgz", - "integrity": "sha512-T04e4iTurVy7I8Sw4+c5OSN9/RkPlo1uKxAomtxQNLq8j1uPAqnsqG1bqvY3Jv7c13gyr6dui0zmh/I3+f/JaQ==", + "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 }, "@nodelib/fs.scandir": { @@ -12855,89 +12849,23 @@ } }, "@nomicfoundation/hardhat-chai-matchers": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-chai-matchers/-/hardhat-chai-matchers-1.0.5.tgz", - "integrity": "sha512-+W5C/+5FHI2xBajUN9THSNc1UP6FUsA7LeLmfnaC9VMi/50/DEjjxd8OmizEXgV1Bjck7my4NVQLL1Ti39FkpA==", + "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": { "@ethersproject/abi": "^5.1.2", "@types/chai-as-promised": "^7.1.3", "chai-as-promised": "^7.1.1", - "chalk": "^2.4.2", "deep-eql": "^4.0.1", "ordinal": "^1.0.3" - }, - "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" - } - } } }, "@nomicfoundation/hardhat-network-helpers": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-network-helpers/-/hardhat-network-helpers-1.0.7.tgz", - "integrity": "sha512-X+3mNvn8B7BY5hpIaLO+TrfzWq12bpux+ajGGdmdcfC78NXmYmOZkAtiz1QZx1YIZGMS1LaXzPXyBExxKFpCaw==", + "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==", "dev": true, "peer": true, "requires": { @@ -12945,9 +12873,9 @@ } }, "@nomicfoundation/hardhat-toolbox": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-toolbox/-/hardhat-toolbox-2.0.1.tgz", - "integrity": "sha512-/pr8m9xlqiNlq6fXv4hEPNwdNwUhysoB2qbDCKqERfPpq34EydUQTC3Vis4aIea8RLwSrU8sDXFdv4TQxYstKw==", + "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": {} }, @@ -13048,9 +12976,9 @@ "requires": {} }, "@nomiclabs/hardhat-etherscan": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-3.1.5.tgz", - "integrity": "sha512-PxPX28AGBAlxgXLU27NB3oiMsklxbNhM75SDC4v1QPCyPeAxGm4xV0WpYbR10W7sxY2WF3Ek7u7GhjbQWa2Fcg==", + "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": { @@ -13141,21 +13069,21 @@ } }, "@openzeppelin/contracts": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.8.0.tgz", - "integrity": "sha512-AGuwhRRL+NaKx73WKRNzeCxOCOCxpaqF+kp8TJ89QzAipSwZy/NoflkWaL9bywXFRhIzXt8j38sfF7KBKCPWLw==", + "version": "4.8.2", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.8.2.tgz", + "integrity": "sha512-kEUOgPQszC0fSYWpbh2kT94ltOJwj1qfT2DWo+zVttmGmf97JZ99LspePNaeeaLhCImaHVeBbjaQFZQn7+Zc5g==", "dev": true }, "@openzeppelin/contracts-upgradeable": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.8.0.tgz", - "integrity": "sha512-5GeFgqMiDlqGT8EdORadp1ntGF0qzWZLmEY7Wbp/yVhN7/B3NNzCxujuI77ktlyG81N3CUZP8cZe3ZAQ/cW10w==", + "version": "4.8.2", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.8.2.tgz", + "integrity": "sha512-zIggnBwemUmmt9IS73qxi+tumALxCY4QEs3zLCII78k0Gfse2hAOdAkuAeLUzvWUpneMUfFE5sGHzEUSTvn4Ag==", "dev": true }, "@openzeppelin/hardhat-upgrades": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/@openzeppelin/hardhat-upgrades/-/hardhat-upgrades-1.22.0.tgz", - "integrity": "sha512-1qyZnDaxl0C8tne7ykNRa/fxw3FrNCY2M3fGuCiQW5DDkJoXhLgm3JVsXwl6X7q9mQSrik4vgBbI3ErmxmZTYg==", + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/@openzeppelin/hardhat-upgrades/-/hardhat-upgrades-1.22.1.tgz", + "integrity": "sha512-MdoitCTLl4zwMU8MeE/bCj+7JMWBEvd38XqJkw36PkJrXlbv6FedDVCPoumMAhpmtymm0nTwTYYklYG+L6WiiQ==", "dev": true, "requires": { "@openzeppelin/upgrades-core": "^1.20.0", @@ -13165,9 +13093,9 @@ } }, "@openzeppelin/upgrades-core": { - "version": "1.20.6", - "resolved": "https://registry.npmjs.org/@openzeppelin/upgrades-core/-/upgrades-core-1.20.6.tgz", - "integrity": "sha512-KWdtlahm+iunlAlzLsdpBueanwEx0LLPfAkDL1p0C4SPjMiUqHHFlyGtmmWwdiqDpJ//605vfwkd5RqfnFrHSg==", + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/@openzeppelin/upgrades-core/-/upgrades-core-1.24.1.tgz", + "integrity": "sha512-QhdIQDUykJ3vQauB6CheV7vk4zgn0e1iY+IDg7r1KqpA1m2bqIGjQCpzidW33K4bZc9zdJSPx2/Z6Um5KxCB7A==", "dev": true, "requires": { "cbor": "^8.0.0", @@ -13186,23 +13114,23 @@ "dev": true }, "@scure/bip32": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.0.tgz", - "integrity": "sha512-ftTW3kKX54YXLCxH6BB7oEEoJfoE2pIgw7MINKAs5PsS6nqKPuKk1haTF/EuHmYqG330t5GSrdmtRuHaY1a62Q==", + "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.1.1", - "@noble/secp256k1": "~1.6.0", + "@noble/hashes": "~1.2.0", + "@noble/secp256k1": "~1.7.0", "@scure/base": "~1.1.0" } }, "@scure/bip39": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.0.tgz", - "integrity": "sha512-pwrPOS16VeTKg98dYXQyIjJEcWfz7/1YJIwxUEPFfQPtc86Ym/1sVgQ2RLoD43AazMk2l/unK4ITySSpW2+82w==", + "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.1.1", + "@noble/hashes": "~1.2.0", "@scure/base": "~1.1.0" } }, @@ -13512,15 +13440,16 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "5.48.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.48.1.tgz", - "integrity": "sha512-9nY5K1Rp2ppmpb9s9S2aBiF3xo5uExCehMDmYmmFqqyxgenbHJ3qbarcLt4ITgaD6r/2ypdlcFRdcuVPnks+fQ==", + "version": "5.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.54.0.tgz", + "integrity": "sha512-+hSN9BdSr629RF02d7mMtXhAJvDTyCbprNYJKrXETlul/Aml6YZwd90XioVbjejQeHbb3R8Dg0CkRgoJDxo8aw==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.48.1", - "@typescript-eslint/type-utils": "5.48.1", - "@typescript-eslint/utils": "5.48.1", + "@typescript-eslint/scope-manager": "5.54.0", + "@typescript-eslint/type-utils": "5.54.0", + "@typescript-eslint/utils": "5.54.0", "debug": "^4.3.4", + "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", "natural-compare-lite": "^1.4.0", "regexpp": "^3.2.0", @@ -13555,54 +13484,54 @@ } }, "@typescript-eslint/parser": { - "version": "5.48.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.48.1.tgz", - "integrity": "sha512-4yg+FJR/V1M9Xoq56SF9Iygqm+r5LMXvheo6DQ7/yUWynQ4YfCRnsKuRgqH4EQ5Ya76rVwlEpw4Xu+TgWQUcdA==", + "version": "5.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.54.0.tgz", + "integrity": "sha512-aAVL3Mu2qTi+h/r04WI/5PfNWvO6pdhpeMRWk9R7rEV4mwJNzoWf5CCU5vDKBsPIFQFjEq1xg7XBI2rjiMXQbQ==", "dev": true, "peer": true, "requires": { - "@typescript-eslint/scope-manager": "5.48.1", - "@typescript-eslint/types": "5.48.1", - "@typescript-eslint/typescript-estree": "5.48.1", + "@typescript-eslint/scope-manager": "5.54.0", + "@typescript-eslint/types": "5.54.0", + "@typescript-eslint/typescript-estree": "5.54.0", "debug": "^4.3.4" } }, "@typescript-eslint/scope-manager": { - "version": "5.48.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.48.1.tgz", - "integrity": "sha512-S035ueRrbxRMKvSTv9vJKIWgr86BD8s3RqoRZmsSh/s8HhIs90g6UlK8ZabUSjUZQkhVxt7nmZ63VJ9dcZhtDQ==", + "version": "5.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.54.0.tgz", + "integrity": "sha512-VTPYNZ7vaWtYna9M4oD42zENOBrb+ZYyCNdFs949GcN8Miwn37b8b7eMj+EZaq7VK9fx0Jd+JhmkhjFhvnovhg==", "dev": true, "requires": { - "@typescript-eslint/types": "5.48.1", - "@typescript-eslint/visitor-keys": "5.48.1" + "@typescript-eslint/types": "5.54.0", + "@typescript-eslint/visitor-keys": "5.54.0" } }, "@typescript-eslint/type-utils": { - "version": "5.48.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.48.1.tgz", - "integrity": "sha512-Hyr8HU8Alcuva1ppmqSYtM/Gp0q4JOp1F+/JH5D1IZm/bUBrV0edoewQZiEc1r6I8L4JL21broddxK8HAcZiqQ==", + "version": "5.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.54.0.tgz", + "integrity": "sha512-WI+WMJ8+oS+LyflqsD4nlXMsVdzTMYTxl16myXPaCXnSgc7LWwMsjxQFZCK/rVmTZ3FN71Ct78ehO9bRC7erYQ==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "5.48.1", - "@typescript-eslint/utils": "5.48.1", + "@typescript-eslint/typescript-estree": "5.54.0", + "@typescript-eslint/utils": "5.54.0", "debug": "^4.3.4", "tsutils": "^3.21.0" } }, "@typescript-eslint/types": { - "version": "5.48.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.48.1.tgz", - "integrity": "sha512-xHyDLU6MSuEEdIlzrrAerCGS3T7AA/L8Hggd0RCYBi0w3JMvGYxlLlXHeg50JI9Tfg5MrtsfuNxbS/3zF1/ATg==", + "version": "5.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.54.0.tgz", + "integrity": "sha512-nExy+fDCBEgqblasfeE3aQ3NuafBUxZxgxXcYfzYRZFHdVvk5q60KhCSkG0noHgHRo/xQ/BOzURLZAafFpTkmQ==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.48.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.48.1.tgz", - "integrity": "sha512-Hut+Osk5FYr+sgFh8J/FHjqX6HFcDzTlWLrFqGoK5kVUN3VBHF/QzZmAsIXCQ8T/W9nQNBTqalxi1P3LSqWnRA==", + "version": "5.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.54.0.tgz", + "integrity": "sha512-X2rJG97Wj/VRo5YxJ8Qx26Zqf0RRKsVHd4sav8NElhbZzhpBI8jU54i6hfo9eheumj4oO4dcRN1B/zIVEqR/MQ==", "dev": true, "requires": { - "@typescript-eslint/types": "5.48.1", - "@typescript-eslint/visitor-keys": "5.48.1", + "@typescript-eslint/types": "5.54.0", + "@typescript-eslint/visitor-keys": "5.54.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -13637,16 +13566,16 @@ } }, "@typescript-eslint/utils": { - "version": "5.48.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.48.1.tgz", - "integrity": "sha512-SmQuSrCGUOdmGMwivW14Z0Lj8dxG1mOFZ7soeJ0TQZEJcs3n5Ndgkg0A4bcMFzBELqLJ6GTHnEU+iIoaD6hFGA==", + "version": "5.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.54.0.tgz", + "integrity": "sha512-cuwm8D/Z/7AuyAeJ+T0r4WZmlnlxQ8wt7C7fLpFlKMR+dY6QO79Cq1WpJhvZbMA4ZeZGHiRWnht7ZJ8qkdAunw==", "dev": true, "requires": { "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.48.1", - "@typescript-eslint/types": "5.48.1", - "@typescript-eslint/typescript-estree": "5.48.1", + "@typescript-eslint/scope-manager": "5.54.0", + "@typescript-eslint/types": "5.54.0", + "@typescript-eslint/typescript-estree": "5.54.0", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0", "semver": "^7.3.7" @@ -13679,12 +13608,12 @@ } }, "@typescript-eslint/visitor-keys": { - "version": "5.48.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.48.1.tgz", - "integrity": "sha512-Ns0XBwmfuX7ZknznfXozgnydyR8F6ev/KEGePP4i74uL3ArsKbEhJ7raeKr1JSa997DBDwol/4a0Y+At82c9dA==", + "version": "5.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.54.0.tgz", + "integrity": "sha512-xu4wT7aRCakGINTLGeyGqDn+78BwFlggwBjnHa1ar/KaGagnmwLYmlrXIrgAaQ3AE1Vd6nLfKASm7LrFHNbKGA==", "dev": true, "requires": { - "@typescript-eslint/types": "5.48.1", + "@typescript-eslint/types": "5.54.0", "eslint-visitor-keys": "^3.3.0" } }, @@ -13720,9 +13649,9 @@ } }, "acorn": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", - "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", "dev": true }, "acorn-jsx": { @@ -14597,9 +14526,9 @@ }, "dependencies": { "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, "peer": true, "requires": { @@ -14812,9 +14741,9 @@ "dev": true }, "define-properties": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", - "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", + "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==", "dev": true, "peer": true, "requires": { @@ -15123,12 +15052,13 @@ } }, "eslint": { - "version": "8.31.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.31.0.tgz", - "integrity": "sha512-0tQQEVdmPZ1UtUKXjX7EMm9BlgJ08G90IhWh0PKDCb3ZLsgAOHI8fYSIzYVZej92zsgq+ft0FGsxhJ3xo2tbuA==", + "version": "8.35.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.35.0.tgz", + "integrity": "sha512-BxAf1fVL7w+JLRQhWl2pzGeSiGqbWumV4WNvc9Rhp6tiCtm4oHnyPBSEtMGZwrQgudFQ+otqzWoPB7x+hxoWsw==", "dev": true, "requires": { - "@eslint/eslintrc": "^1.4.1", + "@eslint/eslintrc": "^2.0.0", + "@eslint/js": "8.35.0", "@humanwhocodes/config-array": "^0.11.8", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -15142,7 +15072,7 @@ "eslint-utils": "^3.0.0", "eslint-visitor-keys": "^3.3.0", "espree": "^9.4.0", - "esquery": "^1.4.0", + "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", @@ -15239,9 +15169,9 @@ "peer": true }, "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "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" @@ -15522,16 +15452,16 @@ "peer": true }, "ethereum-cryptography": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.1.2.tgz", - "integrity": "sha512-XDSJlg4BD+hq9N2FjvotwUET9Tfxpxc3kWGE2AqUG5vcbeunnbImVk3cj6e/xT3phdW21mE8R5IugU4fspQDcQ==", + "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.1.2", - "@noble/secp256k1": "1.6.3", - "@scure/bip32": "1.1.0", - "@scure/bip39": "1.1.0" + "@noble/hashes": "1.2.0", + "@noble/secp256k1": "1.7.1", + "@scure/bip32": "1.1.5", + "@scure/bip39": "1.1.1" } }, "ethers": { @@ -16437,9 +16367,9 @@ "peer": true }, "get-intrinsic": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", - "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", + "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", "dev": true, "requires": { "function-bind": "^1.1.1", @@ -16665,9 +16595,9 @@ } }, "globals": { - "version": "13.19.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", - "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -16768,9 +16698,9 @@ } }, "hardhat": { - "version": "2.12.6", - "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.12.6.tgz", - "integrity": "sha512-0Ent1O5DsPgvaVb5sxEgsQ3bJRt/Ex92tsoO+xjoNH2Qc4bFmhI5/CHVlFikulalxOPjNmw5XQ2vJFuVQFESAA==", + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.13.0.tgz", + "integrity": "sha512-ZlzBOLML1QGlm6JWyVAG8lVTEAoOaVm1in/RU2zoGAnYEoD1Rp4T+ZMvrLNhHaaeS9hfjJ1gJUBfiDr4cx+htQ==", "dev": true, "requires": { "@ethersproject/abi": "^5.1.2", @@ -16867,15 +16797,15 @@ "dev": true }, "ethereum-cryptography": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.1.2.tgz", - "integrity": "sha512-XDSJlg4BD+hq9N2FjvotwUET9Tfxpxc3kWGE2AqUG5vcbeunnbImVk3cj6e/xT3phdW21mE8R5IugU4fspQDcQ==", + "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, "requires": { - "@noble/hashes": "1.1.2", - "@noble/secp256k1": "1.6.3", - "@scure/bip32": "1.1.0", - "@scure/bip39": "1.1.0" + "@noble/hashes": "1.2.0", + "@noble/secp256k1": "1.7.1", + "@scure/bip32": "1.1.5", + "@scure/bip39": "1.1.1" } }, "find-up": { @@ -16945,13 +16875,14 @@ } }, "hardhat-contract-sizer": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/hardhat-contract-sizer/-/hardhat-contract-sizer-2.6.1.tgz", - "integrity": "sha512-b8wS7DBvyo22kmVwpzstAQTdDCThpl/ySBqZh5ga9Yxjf61/uTL12TEg5nl7lDeWy73ntEUzxMwY6XxbQEc2wA==", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/hardhat-contract-sizer/-/hardhat-contract-sizer-2.8.0.tgz", + "integrity": "sha512-jXt2Si3uIDx5z99J+gvKa0yvIw156pE4dpH9X/PvTQv652BUd+qGj7WT93PXnHXGh5qhQLkjDYeZMYNOThfjFg==", "dev": true, "requires": { "chalk": "^4.0.0", - "cli-table3": "^0.6.0" + "cli-table3": "^0.6.0", + "strip-ansi": "^6.0.0" } }, "hardhat-gas-reporter": { @@ -16974,9 +16905,9 @@ "requires": {} }, "hardhat-tracer": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/hardhat-tracer/-/hardhat-tracer-1.2.1.tgz", - "integrity": "sha512-ZZVXZfWfRzPkjGdkLoxC4v3Dqja7cpG1mOOr+3+m9xGmqfw9P6cKMDo+wYtGPNM6KttwsJ226Gqt5AwBjMxgTg==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/hardhat-tracer/-/hardhat-tracer-1.3.0.tgz", + "integrity": "sha512-mUYuRJWlxCwY4R2urCpNM4ecVSq/iMLiVP9YZKlfXyv4R8T+4HAcTfumilUOXHGe6wHI+8Ki2EaTon3KgzATDA==", "dev": true, "requires": { "ethers": "^5.6.1" @@ -17171,9 +17102,9 @@ "dev": true }, "immutable": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.2.2.tgz", - "integrity": "sha512-fTMKDwtbvO5tldky9QZ2fMX7slR0mYpY5nbnFWYp0fOzDhHqhgIw9KoYgxLWsoNTS9ZHGauHj18DTyEw6BK3Og==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.2.4.tgz", + "integrity": "sha512-WDxL3Hheb1JkRN3sQkyujNlL/xRjAo3rJtaU5xeufUauG66JdMr32bLj4gF+vWl84DIA3Zxw7tiAjneYzRRw+w==", "dev": true }, "import-fresh": { @@ -17355,13 +17286,13 @@ } }, "internal-slot": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.4.tgz", - "integrity": "sha512-tA8URYccNzMo94s5MQZgH8NB/XTa6HsOo0MLfXTKKEnHVVdegzaQoFZ7Jp44bdvLvY2waT5dc+j5ICEswhi7UQ==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", + "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", "dev": true, "peer": true, "requires": { - "get-intrinsic": "^1.1.3", + "get-intrinsic": "^1.2.0", "has": "^1.0.3", "side-channel": "^1.0.4" } @@ -17383,14 +17314,14 @@ } }, "is-array-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.1.tgz", - "integrity": "sha512-ASfLknmY8Xa2XtB4wmbz13Wu202baeA18cJBCeCy0wXUHZF0IPyVEXqKEcd+t2fNSLLL1vC6k7lxZEojNbISXQ==", + "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.1.3", + "get-intrinsic": "^1.2.0", "is-typed-array": "^1.1.10" } }, @@ -17620,9 +17551,9 @@ "peer": true }, "js-sdsl": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.2.0.tgz", - "integrity": "sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz", + "integrity": "sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==", "dev": true }, "js-sha3": { @@ -17970,9 +17901,9 @@ } }, "minimist": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", - "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "dev": true }, "mkdirp": { @@ -18216,9 +18147,9 @@ "dev": true }, "object-inspect": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", - "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", "dev": true }, "object-keys": { @@ -18568,9 +18499,9 @@ "peer": true }, "punycode": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.2.0.tgz", - "integrity": "sha512-LN6QV1IJ9ZhxWTNdktaPClrNfp8xdSAYS0Zk2ddX7XsXZAxckMHPCBcHRo0cTcEIgYPRiGEkmji3Idkh2yFtYw==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", "dev": true }, "qs": { @@ -18598,9 +18529,9 @@ } }, "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==", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", "dev": true, "requires": { "bytes": "3.1.2", @@ -18610,9 +18541,9 @@ } }, "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.1.tgz", + "integrity": "sha512-+rQmrWMYGA90yenhTYsLWAsLsqVC8osOw6PKE1HDYiO0gdPeKe/xDHNzIAIn4C91YQ6oenEhfYqqc1883qHbjQ==", "dev": true, "requires": { "inherits": "^2.0.3", @@ -19144,9 +19075,9 @@ "dev": true }, "simple-git": { - "version": "3.15.1", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.15.1.tgz", - "integrity": "sha512-73MVa5984t/JP4JcQt0oZlKGr42ROYWC3BcUZfuHtT3IHKPspIvL0cZBnvPXF7LL3S/qVeVHVdYYmJ3LOTw4Rg==", + "version": "3.16.1", + "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.16.1.tgz", + "integrity": "sha512-xzRxMKiy1zEYeHGXgAzvuXffDS0xgsq07Oi4LWEEcVH29vLpcZ2tyQRWyK0NLLlCVaKysZeem5tC1qHEOxsKwA==", "dev": true, "requires": { "@kwsites/file-exists": "^1.1.1", @@ -19678,9 +19609,9 @@ } }, "solidity-ast": { - "version": "0.4.40", - "resolved": "https://registry.npmjs.org/solidity-ast/-/solidity-ast-0.4.40.tgz", - "integrity": "sha512-M8uLBT2jgFB7B0iVAC5a2l71J8vim7aEm03AZkaHbDqyrl1pE+i5PriMEw6WlwGfHp3/Ym7cn9BqvVLQgRk+Yw==", + "version": "0.4.46", + "resolved": "https://registry.npmjs.org/solidity-ast/-/solidity-ast-0.4.46.tgz", + "integrity": "sha512-MlPZQfPhjWXqh7YxWcBGDXaPZIfMYCOHYoLEhGDWulNwEPIQQZuB7mA9eP17CU0jY/bGR4avCEUVVpvHtT2gbA==", "dev": true }, "solidity-coverage": { @@ -20612,12 +20543,13 @@ } }, "ts-command-line-args": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/ts-command-line-args/-/ts-command-line-args-2.3.1.tgz", - "integrity": "sha512-FR3y7pLl/fuUNSmnPhfLArGqRrpojQgIEEOVzYx9DhTmfIN7C9RWSfpkJEF4J+Gk7aVx5pak8I7vWZsaN4N84g==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/ts-command-line-args/-/ts-command-line-args-2.4.2.tgz", + "integrity": "sha512-mJLQQBOdyD4XI/ZWQY44PIdYde47JhV2xl380O7twPkTQ+Y5vFDHsk8LOeXKuz7dVY5aDCfAzRarNfSqtKOkQQ==", "dev": true, "peer": true, "requires": { + "@morgan-stanley/ts-mocking-bird": "^0.6.2", "chalk": "^4.1.0", "command-line-args": "^5.1.1", "command-line-usage": "^6.1.0", @@ -20768,9 +20700,9 @@ "peer": true }, "prettier": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.2.tgz", - "integrity": "sha512-BtRV9BcncDyI2tsuS19zzhzoxD8Dh8LiCx7j7tHzrkz8GFXAexeWFdi22mjE1d16dftH2qNaytVxqiRTGlMfpw==", + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.4.tgz", + "integrity": "sha512-vIS4Rlc2FNh0BySk3Wkd6xmwxB0FpOndW5fisM5H8hsZSxU2VWVB5CWIkIjWvrHjIhxk2g3bfMKM87zNTrZddw==", "dev": true, "peer": true } @@ -20796,9 +20728,9 @@ "peer": true }, "typescript": { - "version": "4.9.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", - "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "dev": true }, "typical": { @@ -20830,9 +20762,9 @@ } }, "undici": { - "version": "5.15.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.15.0.tgz", - "integrity": "sha512-wCAZJDyjw9Myv+Ay62LAoB+hZLPW9SmKbQkbHIhMw/acKSlpn7WohdMUc/Vd4j1iSMBO0hWwU8mjB7a5p5bl8g==", + "version": "5.20.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.20.0.tgz", + "integrity": "sha512-J3j60dYzuo6Eevbawwp1sdg16k5Tf768bxYK4TUJRH7cBM4kFCbf3mOnM/0E3vQYXvpxITbbWmBafaDbxLDz3g==", "dev": true, "requires": { "busboy": "^1.6.0" @@ -20897,9 +20829,9 @@ } }, "web3-utils": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.8.1.tgz", - "integrity": "sha512-LgnM9p6V7rHHUGfpMZod+NST8cRfGzJ1BTXAyNo7A9cJX9LczBfSRxJp+U/GInYe9mby40t3v22AJdlELibnsQ==", + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.8.2.tgz", + "integrity": "sha512-v7j6xhfLQfY7xQDrUP0BKbaNrmZ2/+egbqP9q3KYmOiPpnvAfol+32slgL0WX/5n8VPvKCK5EZ1HGrAVICSToA==", "dev": true, "peer": true, "requires": { diff --git a/package.json b/package.json index c1a8cf84..3e1d1e37 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "dotenv": "^16.0.0", "eslint": "^8.23.0", "gh-pages": "^3.2.3", - "hardhat": "^2.12.5", + "hardhat": "^2.13.0", "hardhat-contract-sizer": "^2.6.1", "hardhat-storage-layout-changes": "^0.1.2", "hardhat-tracer": "^1.2.1", diff --git a/scripts/deploy-all.ts b/scripts/deploy-all.ts index fdebe8b3..348c965d 100644 --- a/scripts/deploy-all.ts +++ b/scripts/deploy-all.ts @@ -1,8 +1,7 @@ import { ethers, upgrades } from 'hardhat'; -import { getEnvVar } from './utils'; async function deploy() { - const ssvTokenAddress = getEnvVar('SSVTOKEN_ADDRESS'); + const ssvTokenAddress = process.env.SSVTOKEN_ADDRESS; const [deployer] = await ethers.getSigners(); console.log(`Deploying contracts with the account:${deployer.address}`); @@ -13,10 +12,10 @@ async function deploy() { const ssvNetwork = await upgrades.deployProxy(ssvNetworkFactory, [ process.env.INITIAL_VERSION, ssvTokenAddress, - getEnvVar('OPERATOR_MAX_FEE_INCREASE'), - getEnvVar('DECLARE_OPERATOR_FEE_PERIOD'), - getEnvVar('EXECUTE_OPERATOR_FEE_PERIOD'), - getEnvVar('MINIMUM_BLOCKS_BEFORE_LIQUIDATION') + process.env.OPERATOR_MAX_FEE_INCREASE, + process.env.DECLARE_OPERATOR_FEE_PERIOD, + process.env.EXECUTE_OPERATOR_FEE_PERIOD, + process.env.MINIMUM_BLOCKS_BEFORE_LIQUIDATION ], { kind: "uups" diff --git a/test/account/deposit.ts b/test/account/deposit.ts index 7dde8925..4105d9ef 100644 --- a/test/account/deposit.ts +++ b/test/account/deposit.ts @@ -20,7 +20,7 @@ describe('Deposit Tests', () => { await helpers.DB.ssvToken.connect(helpers.DB.owners[6]).approve(helpers.DB.ssvNetwork.contract.address, '1000000000000000'); await ssvNetworkContract.connect(helpers.DB.owners[6]).registerValidator( '0x221111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111119', - [1,2,3,4], + [1, 2, 3, 4], helpers.DataGenerator.shares(4), '1000000000000000', { @@ -37,31 +37,52 @@ describe('Deposit Tests', () => { cluster1 = await helpers.registerValidators(4, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); }); - it('Deposit to a cluster I own emits "ClusterDeposited', async () => { + it('Deposit to a cluster I own emits "ClusterDeposited"', async () => { await helpers.DB.ssvToken.connect(helpers.DB.owners[4]).approve(ssvNetworkContract.address, minDepositAmount); - await expect(ssvNetworkContract.connect(helpers.DB.owners[4])['deposit(address,uint64[],uint256,(uint32,uint64,uint64,uint256,bool))'](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(address,uint64[],uint256,(uint32,uint64,uint64,uint256,bool))'](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(address,uint64[],uint256,(uint32,uint64,uint64,uint256,bool))'](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(address,uint64[],uint256,(uint32,uint64,uint64,uint256,bool))'](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(address,uint64[],uint256,(uint32,uint64,uint64,uint256,bool))'](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(address,uint64[],uint256,(uint32,uint64,uint64,uint256,bool))'](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'); }); }); \ No newline at end of file diff --git a/test/account/withdraw.ts b/test/account/withdraw.ts index a3593676..78928776 100644 --- a/test/account/withdraw.ts +++ b/test/account/withdraw.ts @@ -76,6 +76,11 @@ describe('Withdraw Tests', () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).withdraw(cluster1.args.operatorIds, helpers.CONFIG.minimalOperatorFee, cluster1.args.cluster)).to.be.revertedWithCustomError(ssvNetworkContract,'InsufficientBalance'); }); + it('Withdraw from a liquidatable cluster after liquidatrion period reverts "InsufficientBalance"', async () => { + await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation + 10); + await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).withdraw(cluster1.args.operatorIds, helpers.CONFIG.minimalOperatorFee, cluster1.args.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(uint64,uint256)'](1, minDepositAmount)).to.be.revertedWithCustomError(ssvNetworkContract,'CallerNotOwner'); }); diff --git a/test/helpers/contract-helpers.ts b/test/helpers/contract-helpers.ts index 8901cece..2f6475fa 100644 --- a/test/helpers/contract-helpers.ts +++ b/test/helpers/contract-helpers.ts @@ -176,7 +176,7 @@ export const registerValidators = async (ownerId: number, numberOfValidators: nu return { validators, args }; }; -export const registerValidatorsRaw = async (ownerId: number, numberOfValidators: number, amount: string, operatorIds: number[]) => { +export const registerValidatorsRaw = async (ownerId: number, numberOfValidators: number, amount: string, operatorIds: number[], gasGroups?: GasGroup[]) => { let cluster: any = { validatorCount: 0, @@ -198,18 +198,9 @@ export const registerValidatorsRaw = async (ownerId: number, numberOfValidators: shares, amount, cluster - )); - - const clusterData = result.eventsByName.ValidatorAdded[0].args.cluster; - cluster = { - validatorCount: clusterData.validatorCount, - networkFee: clusterData.networkFee, - networkFeeIndex: clusterData.networkFeeIndex, - index: clusterData.index, - balance: clusterData.balance, - active: true - }; + ), gasGroups); + cluster = result.eventsByName.ValidatorAdded[0].args.cluster; } } diff --git a/test/helpers/gas-usage.ts b/test/helpers/gas-usage.ts index 3f6977d6..6573db02 100644 --- a/test/helpers/gas-usage.ts +++ b/test/helpers/gas-usage.ts @@ -36,17 +36,17 @@ const MAX_GAS_PER_GROUP: any = { [GasGroup.REMOVE_OPERATOR]: 62000, [GasGroup.REMOVE_OPERATOR_WITH_WITHDRAW]: 62000, - [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]: 185300, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE]: 202200, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT]: 164800, + [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]: 185200, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE]: 201750, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT]: 164700, - [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_7]: 248500, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]: 265400, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_7]: 228000, + [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_7]: 248300, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]: 264900, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_7]: 227800, - [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_13]: 375500, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]: 392300, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_13]: 355000, + [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_13]: 375200, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]: 391750, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_13]: 354700, [GasGroup.REMOVE_VALIDATOR]: 106300, [GasGroup.TRANSFER_VALIDATOR_NEW_CLUSTER]: 400000, diff --git a/test/liquidate/liquidate.ts b/test/liquidate/liquidate.ts index dd928125..fe993dba 100644 --- a/test/liquidate/liquidate.ts +++ b/test/liquidate/liquidate.ts @@ -70,12 +70,29 @@ describe('Liquidate Tests', () => { ); }); + 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') + .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); }); + 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); + }); + it('Liquidate validator with removed operator in a cluster', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); await ssvNetworkContract.removeOperator(1); @@ -95,6 +112,7 @@ describe('Liquidate Tests', () => { ), [GasGroup.LIQUIDATE_POD]); 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), @@ -140,11 +158,28 @@ describe('Liquidate Tests', () => { 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_POD]); + const updatedCluster = liquidatedCluster.eventsByName.ClusterLiquidated[0].args; + + 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); }); + 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); + }); + it('Get if the cluster is not liquidatable', async () => { expect(await ssvViews.isLiquidatable(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster)).to.equal(false); }); diff --git a/test/liquidate/reactivate.ts b/test/liquidate/reactivate.ts index daed3ed7..5a7bbbf3 100644 --- a/test/liquidate/reactivate.ts +++ b/test/liquidate/reactivate.ts @@ -1,6 +1,6 @@ // Declare imports import * as helpers from '../helpers/contract-helpers'; -import * as utils from '../helpers/utils'; +import { progressBlocks } from '../helpers/utils'; import { expect } from 'chai'; import { trackGas, GasGroup } from '../helpers/gas-usage'; @@ -55,7 +55,7 @@ describe('Reactivate Tests', () => { }); it('Reactivate a disabled cluster emits "ClusterReactivated"', async () => { - await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); + await progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); const liquidatedCluster = await trackGas(ssvNetworkContract.liquidate(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster), [GasGroup.LIQUIDATE_POD]); const updatedCluster = liquidatedCluster.eventsByName.ClusterLiquidated[0].args; await helpers.DB.ssvToken.connect(helpers.DB.owners[1]).approve(ssvNetworkContract.address, minDepositAmount); @@ -64,7 +64,7 @@ describe('Reactivate Tests', () => { }); it('Reactivate with 0 deposit and no validators emits ClusterReactivated', async () => { - await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); + await progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); const liquidatedCluster = await trackGas(ssvNetworkContract.liquidate(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster), [GasGroup.LIQUIDATE_POD]); const updatedCluster = liquidatedCluster.eventsByName.ClusterLiquidated[0].args; @@ -79,7 +79,7 @@ describe('Reactivate Tests', () => { }); it('Reactivate a cluster with a removed operator in the cluster', async () => { - await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); + await progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); const liquidatedCluster = await trackGas(ssvNetworkContract.liquidate(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster), [GasGroup.LIQUIDATE_POD]); const updatedCluster = liquidatedCluster.eventsByName.ClusterLiquidated[0].args; await ssvNetworkContract.removeOperator(1); @@ -93,11 +93,20 @@ describe('Reactivate Tests', () => { }); it('Reactivate a cluster when the amount is not enough reverts "InsufficientFunds"', async () => { - await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); + await progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); const liquidatedCluster = await trackGas(ssvNetworkContract.liquidate(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster), [GasGroup.LIQUIDATE_POD]); 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'); + }); + it('Reactivate a cluster after liquidation period when the amount is not enough reverts "InsufficientFunds"', async () => { + await progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); + const liquidatedCluster = await trackGas(ssvNetworkContract.liquidate(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster), [GasGroup.LIQUIDATE_POD]); + 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'); }); }); \ No newline at end of file diff --git a/test/sanity/balances.ts b/test/sanity/balances.ts index 52e9f649..9f8003d6 100644 --- a/test/sanity/balances.ts +++ b/test/sanity/balances.ts @@ -116,9 +116,9 @@ describe('Balance Tests', () => { 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 reverts "InsufficientFunds"', async () => { + it('Check cluster balance with not enough balance', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation + 10); - await expect(ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster)).to.be.revertedWithCustomError(ssvNetworkContract, 'InsufficientFunds'); + expect(await ssvViews.getBalance(helpers.DB.owners[4].address, cluster1.args.operatorIds, cluster1.args.cluster)).to.be.equals(0); }); it('Check operator earnings, cluster balances and network earnings"', async () => { diff --git a/test/validators/register.ts b/test/validators/register.ts index 4425bc3a..24dca82c 100644 --- a/test/validators/register.ts +++ b/test/validators/register.ts @@ -1,5 +1,6 @@ // Declare imports import * as helpers from '../helpers/contract-helpers'; +import * as utils from '../helpers/utils'; import { expect } from 'chai'; import { trackGas, GasGroup } from '../helpers/gas-usage'; @@ -471,6 +472,24 @@ describe('Register Validator Tests', () => { )).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'); + }); + it('Register validator when an operator does not exsit in the cluster reverts "OperatorDoesNotExist"', async () => { await expect(ssvNetworkContract.registerValidator( helpers.DataGenerator.publicKey(2), @@ -557,6 +576,39 @@ describe('Register Validator Tests', () => { )).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 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'); + }); + + it('Register an existing validator reverts "ValidatorAlreadyExists"', async () => { await helpers.DB.ssvToken.approve(ssvNetworkContract.address, helpers.CONFIG.minimalOperatorFee); await expect(ssvNetworkContract.connect(helpers.DB.owners[6]).registerValidator( diff --git a/test/validators/remove.ts b/test/validators/remove.ts index 9294957b..f0ba63ec 100644 --- a/test/validators/remove.ts +++ b/test/validators/remove.ts @@ -62,6 +62,16 @@ describe('Remove Validator Tests', () => { )).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'); + }); + it('Remove validator gas limit', async () => { await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).removeValidator( helpers.DataGenerator.publicKey(1), From a4bbabd7683f27a4101c9381d04564c48bcbbd5d Mon Sep 17 00:00:00 2001 From: Marco Tabasco Date: Mon, 13 Mar 2023 17:44:48 +0100 Subject: [PATCH 140/149] Deposit in liquidated pod - IO1-2170 (#186) * Remove check for liquidation in deposit * Fix cluster balance on reactivation --- .gitignore | 9 +- contracts/ISSVNetwork.sol | 2 +- contracts/SSVNetwork.sol | 73 ++++++++-------- contracts/SSVNetworkViews.sol | 4 + package-lock.json | 2 +- package.json | 2 +- test-e2e/register-validator-gas.ts | 5 -- test-e2e/stress.ts | 3 - test/account/deposit.ts | 42 +++++++-- test/account/withdraw.ts | 1 - test/dao/network-fee-withdraw.ts | 1 - test/helpers/contract-helpers.ts | 55 ++++++++++-- test/liquidate/liquidate.ts | 9 +- test/liquidate/liquidated-cluster.ts | 125 +++++++++++++++++++++++++++ test/liquidate/reactivate.ts | 35 +++++--- test/operators/remove.ts | 1 - test/operators/update-fee.ts | 4 +- test/sanity/balances.ts | 21 ++++- test/validators/register.ts | 29 +------ test/validators/remove.ts | 2 - 20 files changed, 301 insertions(+), 124 deletions(-) create mode 100644 test/liquidate/liquidated-cluster.ts diff --git a/.gitignore b/.gitignore index 083546ce..e63b2629 100644 --- a/.gitignore +++ b/.gitignore @@ -7,11 +7,6 @@ cache coverage coverage.json artifacts +typechain-types/ .openzeppelin/dev-*.json -subgraph/build -.idea -/incentivized_testnet/operators* -/incentivized_testnet/validators* -/incentivized_testnet/prod -/incentivized_testnet/stage -/incentivized_testnet/latest_metrics.json +.DS_Store diff --git a/contracts/ISSVNetwork.sol b/contracts/ISSVNetwork.sol index c8b056a0..b715298e 100644 --- a/contracts/ISSVNetwork.sol +++ b/contracts/ISSVNetwork.sol @@ -43,7 +43,7 @@ interface ISSVNetwork is ISSVNetworkCore { event OperatorFeeDeclared(address indexed owner, uint64 indexed operatorId, uint256 blockNumber, uint256 fee); - event OperatorFeeCancelationDeclared(address indexed owner, uint64 indexed operatorId); + event OperatorFeeCancellationDeclared(address indexed owner, uint64 indexed operatorId); /** * @dev Emitted when an operator's fee is updated. diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index 832c7489..5f799f23 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -171,17 +171,13 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { ) external override { uint operatorsLength = operatorIds.length; - { - _validateOperatorIds(operatorsLength); - _validatePublicKey(publicKey); - } + _validateOperatorIds(operatorsLength); + _validatePublicKey(publicKey); - { - if (_validatorPKs[keccak256(publicKey)].owner != address(0)) { - revert ValidatorAlreadyExists(); - } - _validatorPKs[keccak256(publicKey)] = Validator({owner: msg.sender, active: true}); + if (_validatorPKs[keccak256(publicKey)].owner != address(0)) { + revert ValidatorAlreadyExists(); } + _validatorPKs[keccak256(publicKey)] = Validator({owner: msg.sender, active: true}); bytes32 hashedCluster = keccak256(abi.encodePacked(msg.sender, operatorIds)); @@ -218,38 +214,36 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { Network memory network_ = network; uint64 currentNetworkFeeIndex = NetworkLib.currentNetworkFeeIndex(network_); - { - cluster.balance += amount; + cluster.balance += amount; - if (cluster.active) { - for (uint i; i < operatorsLength; ) { - if (i + 1 < operatorsLength) { - if (operatorIds[i] > operatorIds[i + 1]) { - revert UnsortedOperatorsList(); - } - } - Operator memory operator = operators[operatorIds[i]]; - if (operator.snapshot.block == 0) { - revert OperatorDoesNotExist(); - } - operator.updateSnapshot(); - if (++operator.validatorCount > validatorsPerOperatorLimit) { - revert ExceedValidatorLimit(); - } - clusterIndex += operator.snapshot.index; - burnRate += operator.fee; - operators[operatorIds[i]] = operator; - unchecked { - ++i; + if (cluster.active) { + for (uint i; i < operatorsLength; ) { + if (i + 1 < operatorsLength) { + if (operatorIds[i] > operatorIds[i + 1]) { + revert UnsortedOperatorsList(); } } - cluster.updateClusterData(clusterIndex, currentNetworkFeeIndex); - - DAO memory dao_ = dao; - dao_.updateDAOEarnings(network_.networkFee); - ++dao_.validatorCount; - dao = dao_; + Operator memory operator = operators[operatorIds[i]]; + if (operator.snapshot.block == 0) { + revert OperatorDoesNotExist(); + } + operator.updateSnapshot(); + if (++operator.validatorCount > validatorsPerOperatorLimit) { + revert ExceedValidatorLimit(); + } + clusterIndex += operator.snapshot.index; + burnRate += operator.fee; + operators[operatorIds[i]] = operator; + unchecked { + ++i; + } } + cluster.updateClusterData(clusterIndex, currentNetworkFeeIndex); + + DAO memory dao_ = dao; + dao_.updateDAOEarnings(network_.networkFee); + ++dao_.validatorCount; + dao = dao_; } ++cluster.validatorCount; @@ -383,6 +377,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { cluster.balance = 0; } cluster.index = 0; + cluster.networkFeeIndex = 0; cluster.active = false; clusters[hashedCluster] = keccak256( @@ -431,6 +426,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { cluster.balance += amount; cluster.active = true; cluster.index = clusterIndex; + cluster.networkFeeIndex = currentNetworkFeeIndex; cluster.updateClusterData(clusterIndex, currentNetworkFeeIndex); @@ -475,7 +471,6 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { Cluster memory cluster ) external override { bytes32 hashedCluster = cluster.validateHashedCluster(owner, operatorIds, this); - cluster.validateClusterIsNotLiquidated(); cluster.balance += amount; @@ -740,7 +735,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { delete operatorFeeChangeRequests[operatorId]; - emit OperatorFeeCancelationDeclared(msg.sender, operatorId); + emit OperatorFeeCancellationDeclared(msg.sender, operatorId); } /*****************************/ diff --git a/contracts/SSVNetworkViews.sol b/contracts/SSVNetworkViews.sol index 6cfe6a83..79fbece9 100644 --- a/contracts/SSVNetworkViews.sol +++ b/contracts/SSVNetworkViews.sol @@ -76,6 +76,10 @@ contract SSVNetworkViews is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwor ) external view override returns (bool) { cluster.validateHashedCluster(owner, operatorIds, _ssvNetwork); + if (!cluster.active) { + return false; + } + uint64 clusterIndex; uint64 burnRate; uint operatorsLength = operatorIds.length; diff --git a/package-lock.json b/package-lock.json index f6f3e17b..17113c10 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,7 +27,7 @@ "hardhat-storage-layout-changes": "^0.1.2", "hardhat-tracer": "^1.2.1", "prompts": "^2.4.2", - "simple-git": "^3.10.0", + "simple-git": "^3.16.1", "ts-node": "^10.7.0", "typescript": "^4.6.3" } diff --git a/package.json b/package.json index 3e1d1e37..6f9fdbf2 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "hardhat-storage-layout-changes": "^0.1.2", "hardhat-tracer": "^1.2.1", "prompts": "^2.4.2", - "simple-git": "^3.10.0", + "simple-git": "^3.16.1", "ts-node": "^10.7.0", "typescript": "^4.6.3" } diff --git a/test-e2e/register-validator-gas.ts b/test-e2e/register-validator-gas.ts index 603f16e9..78b9b9db 100644 --- a/test-e2e/register-validator-gas.ts +++ b/test-e2e/register-validator-gas.ts @@ -32,7 +32,6 @@ describe('Register Validator Gas Tests', () => { minDepositAmount, { validatorCount: 0, - networkFee: 0, networkFeeIndex: 0, index: 0, balance: 0, @@ -57,7 +56,6 @@ describe('Register Validator Gas Tests', () => { minDepositAmount, { validatorCount: 0, - networkFee: 0, networkFeeIndex: 0, index: 0, balance: 0, @@ -101,7 +99,6 @@ describe('Register Validator Gas Tests', () => { minDepositAmount * 2, { validatorCount: 0, - networkFee: 0, networkFeeIndex: 0, index: 0, balance: 0, @@ -145,7 +142,6 @@ describe('Register Validator Gas Tests', () => { minDepositAmount * 3, { validatorCount: 0, - networkFee: 0, networkFeeIndex: 0, index: 0, balance: 0, @@ -189,7 +185,6 @@ describe('Register Validator Gas Tests', () => { minDepositAmount * 4, { validatorCount: 0, - networkFee: 0, networkFeeIndex: 0, index: 0, balance: 0, diff --git a/test-e2e/stress.ts b/test-e2e/stress.ts index 82ee3900..385bd6b3 100644 --- a/test-e2e/stress.ts +++ b/test-e2e/stress.ts @@ -35,7 +35,6 @@ describe('Stress Tests', () => { // Define empty pod data to send let podData = { validatorCount: 0, - networkFee: 0, networkFeeIndex: 0, index: 0, balance: 0, @@ -67,7 +66,6 @@ describe('Stress Tests', () => { // Break the pod event to a struct const pod = { validatorCount: args.validatorCount, - networkFee: args.networkFee, networkFeeIndex: args.networkFeeIndex, index: args.index, balance: args.balance, @@ -134,7 +132,6 @@ describe('Stress Tests', () => { // Form a pod struct const pod = { validatorCount: args.validatorCount, - networkFee: args.networkFee, networkFeeIndex: args.networkFeeIndex, index: args.index, balance: args.balance, diff --git a/test/account/deposit.ts b/test/account/deposit.ts index 4105d9ef..f4df0e2c 100644 --- a/test/account/deposit.ts +++ b/test/account/deposit.ts @@ -1,15 +1,19 @@ // Declare imports import * as helpers from '../helpers/contract-helpers'; +import { progressBlocks } from '../helpers/utils'; import { expect } from 'chai'; import { trackGas, GasGroup } from '../helpers/gas-usage'; // Declare globals -let ssvNetworkContract: any, cluster1: any, minDepositAmount: any; +let ssvNetworkContract: any, ssvViews: any, cluster1: any, minDepositAmount: any; describe('Deposit Tests', () => { beforeEach(async () => { // Initialize contract - ssvNetworkContract = (await helpers.initializeContract()).contract; + const metadata = (await helpers.initializeContract()); + ssvNetworkContract = metadata.contract; + ssvViews = metadata.ssvViews; + // Register operators await helpers.registerOperators(0, 12, helpers.CONFIG.minimalOperatorFee); @@ -25,7 +29,6 @@ describe('Deposit Tests', () => { '1000000000000000', { validatorCount: 0, - networkFee: 0, networkFeeIndex: 0, index: 0, balance: 0, @@ -37,7 +40,8 @@ describe('Deposit Tests', () => { cluster1 = await helpers.registerValidators(4, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); }); - it('Deposit to a cluster I own emits "ClusterDeposited"', async () => { + 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); 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, @@ -66,23 +70,47 @@ describe('Deposit Tests', () => { 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, + 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, + 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, + 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 updatedCluster = liquidatedCluster.eventsByName.ClusterLiquidated[0].args; + + 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'); + }); }); \ No newline at end of file diff --git a/test/account/withdraw.ts b/test/account/withdraw.ts index 78928776..35d275a8 100644 --- a/test/account/withdraw.ts +++ b/test/account/withdraw.ts @@ -27,7 +27,6 @@ describe('Withdraw Tests', () => { '1000000000000000', { validatorCount: 0, - networkFee: 0, networkFeeIndex: 0, index: 0, balance: 0, diff --git a/test/dao/network-fee-withdraw.ts b/test/dao/network-fee-withdraw.ts index ecf6dbf1..99fbc2ff 100644 --- a/test/dao/network-fee-withdraw.ts +++ b/test/dao/network-fee-withdraw.ts @@ -39,7 +39,6 @@ describe('DAO Network Fee Withdraw Tests', () => { '1000000000000000', { validatorCount: 0, - networkFee: 0, networkFeeIndex: 0, index: 0, balance: 0, diff --git a/test/helpers/contract-helpers.ts b/test/helpers/contract-helpers.ts index 2f6475fa..d6c4cac3 100644 --- a/test/helpers/contract-helpers.ts +++ b/test/helpers/contract-helpers.ts @@ -109,9 +109,9 @@ export const initializeContract = async () => { DB.ssvViews.contract = await upgrades.deployProxy(ssvViews, [ DB.ssvNetwork.contract.address ], - { - kind: 'uups' - }); + { + kind: 'uups' + }); await DB.ssvViews.contract.deployed(); @@ -140,9 +140,50 @@ export const registerOperators = async (ownerId: number, numberOfOperators: numb } }; -export const deposit = async (ownerId: number, clusterId: string, amount: string) => { +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)); + 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 + )); + 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)); + + 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); - await DB.ssvNetwork.contract.connect(DB.owners[ownerId])['deposit(bytes32,uint256)'](clusterId, amount); + 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[]) => { @@ -161,7 +202,6 @@ export const registerValidators = async (ownerId: number, numberOfValidators: nu amount, { validatorCount: 0, - networkFee: 0, networkFeeIndex: 0, index: 0, balance: 0, @@ -180,7 +220,6 @@ export const registerValidatorsRaw = async (ownerId: number, numberOfValidators: let cluster: any = { validatorCount: 0, - networkFee: 0, networkFeeIndex: 0, index: 0, balance: 0, @@ -190,7 +229,7 @@ export const registerValidatorsRaw = async (ownerId: number, numberOfValidators: for (let i = 0; i < numberOfValidators; i++) { const shares = DataGenerator.shares(4); const publicKey = DataGenerator.publicKey(i); - + 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, diff --git a/test/liquidate/liquidate.ts b/test/liquidate/liquidate.ts index fe993dba..8164c153 100644 --- a/test/liquidate/liquidate.ts +++ b/test/liquidate/liquidate.ts @@ -28,7 +28,6 @@ describe('Liquidate Tests', () => { '1000000000000000', { validatorCount: 0, - networkFee: 0, networkFeeIndex: 0, index: 0, balance: 0, @@ -45,7 +44,6 @@ describe('Liquidate Tests', () => { minDepositAmount, { validatorCount: 0, - networkFee: 0, networkFeeIndex: 0, index: 0, balance: 0, @@ -96,11 +94,13 @@ describe('Liquidate Tests', () => { it('Liquidate validator with removed operator in a cluster', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); await ssvNetworkContract.removeOperator(1); - await trackGas(ssvNetworkContract.liquidate( + const liquidatedCluster = await trackGas(ssvNetworkContract.liquidate( firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster ), [GasGroup.LIQUIDATE_POD]); + const updatedCluster = liquidatedCluster.eventsByName.ClusterLiquidated[0].args; + 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 () => { @@ -112,7 +112,6 @@ describe('Liquidate Tests', () => { ), [GasGroup.LIQUIDATE_POD]); 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), @@ -190,6 +189,7 @@ describe('Liquidate Tests', () => { 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 () => { @@ -198,7 +198,6 @@ describe('Liquidate Tests', () => { firstCluster.operatorIds, { validatorCount: 0, - networkFee: 0, networkFeeIndex: 0, index: 0, balance: 0, diff --git a/test/liquidate/liquidated-cluster.ts b/test/liquidate/liquidated-cluster.ts new file mode 100644 index 00000000..479fc5d5 --- /dev/null +++ b/test/liquidate/liquidated-cluster.ts @@ -0,0 +1,125 @@ +// Decalre imports +import * as helpers from '../helpers/contract-helpers'; +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; + +// Declare globals +describe('Liquidate Tests', () => { + beforeEach(async () => { + // Initialize contract + const metadata = (await helpers.initializeContract()); + ssvNetworkContract = metadata.contract; + ssvViews = metadata.ssvViews; + + // Register operators + await helpers.registerOperators(0, 12, helpers.CONFIG.minimalOperatorFee); + + networkFee = helpers.CONFIG.minimalOperatorFee; + burnPerBlock = helpers.CONFIG.minimalOperatorFee * 4 + networkFee; + minDepositAmount = helpers.CONFIG.minimalBlocksBeforeLiquidation * burnPerBlock; + + 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), + [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; + }); + + it('Liquidate -> deposit -> reactivate', async () => { + await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); + + let clusterEventData = await helpers.liquidate(firstCluster.owner, + firstCluster.operatorIds, + firstCluster.cluster); + + expect(await ssvViews.isLiquidated(firstCluster.owner, + firstCluster.operatorIds, + clusterEventData.cluster)).to.equal(true); + + clusterEventData = await helpers.deposit(1, + firstCluster.owner, + firstCluster.operatorIds, + minDepositAmount, + 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'); + }); + + 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), + minDepositAmount, + firstCluster.cluster + )); + let clusterEventData = register.eventsByName.ValidatorAdded[0].args; + + 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 + + await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).withdraw( + clusterEventData.operatorIds, + minDepositAmount, + clusterEventData.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, + 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)); + + await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation - 2); + + 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.owner, + clusterEventData.operatorIds, + minDepositAmount, + clusterEventData.cluster) + + 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); + + await utils.progressBlocks(2); + expect(await ssvViews.getBalance(helpers.DB.owners[1].address, clusterEventData.operatorIds, clusterEventData.cluster)).to.be.equals(minDepositAmount * 2 - burnPerBlock * 2); + }); +}); \ No newline at end of file diff --git a/test/liquidate/reactivate.ts b/test/liquidate/reactivate.ts index 5a7bbbf3..61a4ce88 100644 --- a/test/liquidate/reactivate.ts +++ b/test/liquidate/reactivate.ts @@ -22,12 +22,11 @@ describe('Reactivate Tests', () => { await helpers.DB.ssvToken.connect(helpers.DB.owners[6]).approve(helpers.DB.ssvNetwork.contract.address, '1000000000000000'); await ssvNetworkContract.connect(helpers.DB.owners[6]).registerValidator( '0x221111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111119', - [1,2,3,4], + [1, 2, 3, 4], helpers.DataGenerator.shares(4), '1000000000000000', { validatorCount: 0, - networkFee: 0, networkFeeIndex: 0, index: 0, balance: 0, @@ -39,12 +38,11 @@ describe('Reactivate Tests', () => { 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], + [1, 2, 3, 4], helpers.DataGenerator.shares(4), minDepositAmount, { validatorCount: 0, - networkFee: 0, networkFeeIndex: 0, index: 0, balance: 0, @@ -89,24 +87,39 @@ describe('Reactivate Tests', () => { }); 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 "InsufficientFunds"', async () => { + 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_POD]); 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 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)); + 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)); + clusterData = depositedCluster.eventsByName.ClusterDeposited[0].args; + + 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 "InsufficientFunds"', async () => { + 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_POD]); 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 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 f2eaa51e..387af474 100644 --- a/test/operators/remove.ts +++ b/test/operators/remove.ts @@ -22,7 +22,6 @@ describe('Remove Operator Tests', () => { '1000000000000000', { validatorCount: 0, - networkFee: 0, networkFeeIndex: 0, index: 0, balance: 0, diff --git a/test/operators/update-fee.ts b/test/operators/update-fee.ts index a3c40721..fcf1d85e 100644 --- a/test/operators/update-fee.ts +++ b/test/operators/update-fee.ts @@ -35,10 +35,10 @@ describe('Operator Fee Tests', () => { await trackGas(ssvNetworkContract.connect(helpers.DB.owners[2]).declareOperatorFee(1, initialFee + initialFee / 10), [GasGroup.REGISTER_OPERATOR]); }); - it('Cancel declared fee emits "OperatorFeeCancelationDeclared"', async () => { + it('Cancel declared fee emits "OperatorFeeCancellationDeclared"', async () => { await ssvNetworkContract.connect(helpers.DB.owners[2]).declareOperatorFee(1, initialFee + initialFee / 10); await expect(ssvNetworkContract.connect(helpers.DB.owners[2]).cancelDeclaredOperatorFee(1 - )).to.emit(ssvNetworkContract, 'OperatorFeeCancelationDeclared'); + )).to.emit(ssvNetworkContract, 'OperatorFeeCancellationDeclared'); }); it('Cancel declared fee gas limits', async () => { diff --git a/test/sanity/balances.ts b/test/sanity/balances.ts index 9f8003d6..53d3d2e1 100644 --- a/test/sanity/balances.ts +++ b/test/sanity/balances.ts @@ -2,7 +2,7 @@ import * as helpers from '../helpers/contract-helpers'; import * as utils from '../helpers/utils'; import { expect } from 'chai'; -import { GasGroup, trackGas } from '../helpers/gas-usage'; +import { trackGas, GasGroup } from '../helpers/gas-usage'; let ssvNetworkContract: any, ssvViews: any, cluster1: any, minDepositAmount: any, burnPerBlock: any, networkFee: any, initNetworkFeeBalance: any; @@ -37,7 +37,6 @@ describe('Balance Tests', () => { '1000000000000000', { validatorCount: 0, - networkFee: 0, networkFeeIndex: 0, index: 0, balance: 0, @@ -121,6 +120,24 @@ describe('Balance Tests', () => { 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); + }); + + 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 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'); + }); + it('Check operator earnings, cluster balances and network earnings"', async () => { // 2 exisiting clusters // update network fee diff --git a/test/validators/register.ts b/test/validators/register.ts index 24dca82c..f373fdbc 100644 --- a/test/validators/register.ts +++ b/test/validators/register.ts @@ -27,7 +27,6 @@ describe('Register Validator Tests', () => { '1000000000000000', { validatorCount: 0, - networkFee: 0, networkFeeIndex: 0, index: 0, balance: 0, @@ -45,7 +44,6 @@ describe('Register Validator Tests', () => { minDepositAmount, { validatorCount: 0, - networkFee: 0, networkFeeIndex: 0, index: 0, balance: 0, @@ -63,7 +61,6 @@ describe('Register Validator Tests', () => { minDepositAmount, { validatorCount: 0, - networkFee: 0, networkFeeIndex: 0, index: 0, balance: 0, @@ -81,7 +78,6 @@ describe('Register Validator Tests', () => { minDepositAmount, { validatorCount: 0, - networkFee: 0, networkFeeIndex: 0, index: 0, balance: 0, @@ -110,7 +106,6 @@ describe('Register Validator Tests', () => { minDepositAmount, { validatorCount: 0, - networkFee: 0, networkFeeIndex: 0, index: 0, balance: 0, @@ -137,7 +132,6 @@ describe('Register Validator Tests', () => { minDepositAmount, { validatorCount: 0, - networkFee: 0, networkFeeIndex: 0, index: 0, balance: 0, @@ -155,7 +149,6 @@ describe('Register Validator Tests', () => { `${minDepositAmount * 2}`, { validatorCount: 0, - networkFee: 0, networkFeeIndex: 0, index: 0, balance: 0, @@ -184,7 +177,6 @@ describe('Register Validator Tests', () => { minDepositAmount, { validatorCount: 0, - networkFee: 0, networkFeeIndex: 0, index: 0, balance: 0, @@ -202,7 +194,6 @@ describe('Register Validator Tests', () => { minDepositAmount, { validatorCount: 0, - networkFee: 0, networkFeeIndex: 0, index: 0, balance: 0, @@ -231,7 +222,6 @@ describe('Register Validator Tests', () => { minDepositAmount, { validatorCount: 0, - networkFee: 0, networkFeeIndex: 0, index: 0, balance: 0, @@ -258,7 +248,6 @@ describe('Register Validator Tests', () => { minDepositAmount, { validatorCount: 0, - networkFee: 0, networkFeeIndex: 0, index: 0, balance: 0, @@ -276,7 +265,6 @@ describe('Register Validator Tests', () => { `${minDepositAmount * 2}`, { validatorCount: 0, - networkFee: 0, networkFeeIndex: 0, index: 0, balance: 0, @@ -305,7 +293,6 @@ describe('Register Validator Tests', () => { minDepositAmount, { validatorCount: 0, - networkFee: 0, networkFeeIndex: 0, index: 0, balance: 0, @@ -323,7 +310,6 @@ describe('Register Validator Tests', () => { minDepositAmount, { validatorCount: 0, - networkFee: 0, networkFeeIndex: 0, index: 0, balance: 0, @@ -352,7 +338,6 @@ describe('Register Validator Tests', () => { minDepositAmount, { validatorCount: 0, - networkFee: 0, networkFeeIndex: 0, index: 0, balance: 0, @@ -379,7 +364,6 @@ describe('Register Validator Tests', () => { minDepositAmount, { validatorCount: 0, - networkFee: 0, networkFeeIndex: 0, index: 0, balance: 0, @@ -397,7 +381,6 @@ describe('Register Validator Tests', () => { `${minDepositAmount * 2}`, { validatorCount: 0, - networkFee: 0, networkFeeIndex: 0, index: 0, balance: 0, @@ -448,7 +431,6 @@ describe('Register Validator Tests', () => { minDepositAmount, { validatorCount: 0, - networkFee: 0, networkFeeIndex: 0, index: 0, balance: 0, @@ -463,8 +445,7 @@ describe('Register Validator Tests', () => { minDepositAmount, { validatorCount: 2, - networkFee: 10, - networkFeeIndex: 0, + networkFeeIndex: 10, index: 0, balance: 0, active: true @@ -498,7 +479,6 @@ describe('Register Validator Tests', () => { minDepositAmount, { validatorCount: 0, - networkFee: 0, networkFeeIndex: 0, index: 0, balance: 0, @@ -516,7 +496,6 @@ describe('Register Validator Tests', () => { minDepositAmount, { validatorCount: 0, - networkFee: 0, networkFeeIndex: 0, index: 0, balance: 0, @@ -549,7 +528,6 @@ describe('Register Validator Tests', () => { minDepositAmount, { validatorCount: 0, - networkFee: 0, networkFeeIndex: 0, index: 0, balance: 0, @@ -567,7 +545,6 @@ describe('Register Validator Tests', () => { helpers.CONFIG.minimalOperatorFee, { validatorCount: 0, - networkFee: 0, networkFeeIndex: 0, index: 0, balance: 0, @@ -610,7 +587,7 @@ describe('Register Validator Tests', () => { it('Register an existing validator reverts "ValidatorAlreadyExists"', async () => { - await helpers.DB.ssvToken.approve(ssvNetworkContract.address, helpers.CONFIG.minimalOperatorFee); + 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], @@ -618,7 +595,6 @@ describe('Register Validator Tests', () => { minDepositAmount, { validatorCount: 0, - networkFee: 0, networkFeeIndex: 0, index: 0, balance: 0, @@ -648,7 +624,6 @@ describe('Register Validator Tests', () => { minDepositAmount, { validatorCount: 0, - networkFee: 0, networkFeeIndex: 0, index: 0, balance: 0, diff --git a/test/validators/remove.ts b/test/validators/remove.ts index f0ba63ec..05236b1b 100644 --- a/test/validators/remove.ts +++ b/test/validators/remove.ts @@ -27,7 +27,6 @@ describe('Remove Validator Tests', () => { '1000000000000000', { validatorCount: 0, - networkFee: 0, networkFeeIndex: 0, index: 0, balance: 0, @@ -44,7 +43,6 @@ describe('Remove Validator Tests', () => { minDepositAmount, { validatorCount: 0, - networkFee: 0, networkFeeIndex: 0, index: 0, balance: 0, From ec1f73d50c1d988c1715c89bb8c43dfbb2f827b2 Mon Sep 17 00:00:00 2001 From: Marco Tabasco Date: Tue, 14 Mar 2023 16:41:18 +0100 Subject: [PATCH 141/149] No timelocks when reducing operator fee - IO1-2834 (#200) * reduceOperatorFee function --- contracts/ISSVNetwork.sol | 2 ++ contracts/ISSVNetworkCore.sol | 1 + contracts/SSVNetwork.sol | 20 +++++++++++++++++++- test/helpers/gas-usage.ts | 4 ++-- test/operators/update-fee.ts | 12 ++++++++++++ test/sanity/balances.ts | 13 +++++++++++-- 6 files changed, 47 insertions(+), 5 deletions(-) diff --git a/contracts/ISSVNetwork.sol b/contracts/ISSVNetwork.sol index b715298e..4e84b1dc 100644 --- a/contracts/ISSVNetwork.sol +++ b/contracts/ISSVNetwork.sol @@ -129,6 +129,8 @@ interface ISSVNetwork is ISSVNetworkCore { function cancelDeclaredOperatorFee(uint64 operatorId) external; + function reduceOperatorFee(uint64 operatorId, uint256 fee) external; + function setFeeRecipientAddress(address feeRecipientAddress) external; /********************************/ diff --git a/contracts/ISSVNetworkCore.sol b/contracts/ISSVNetworkCore.sol index 75563cb1..3bb0dca4 100644 --- a/contracts/ISSVNetworkCore.sol +++ b/contracts/ISSVNetworkCore.sol @@ -82,4 +82,5 @@ interface ISSVNetworkCore { error TokenTransferFailed(); error SameFeeChangeNotAllowed(); error ZeroFeeIncreaseNotAllowed(); + error FeeIncreaseNotAllowed(); } diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index 5f799f23..4ae6a557 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -155,6 +155,10 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { _cancelDeclaredOperatorFee(operatorId, operators[operatorId]); } + function reduceOperatorFee(uint64 operatorId, uint256 fee) external override { + _reduceOperatorFee(operatorId, operators[operatorId], fee); + } + function setFeeRecipientAddress(address recipientAddress) external override { emit FeeRecipientAddressUpdated(msg.sender, recipientAddress); } @@ -719,7 +723,6 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { operator.updateSnapshot(); operator.fee = feeChangeRequest.fee; - operators[operatorId] = operator; delete operatorFeeChangeRequests[operatorId]; @@ -738,6 +741,21 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { emit OperatorFeeCancellationDeclared(msg.sender, operatorId); } + function _reduceOperatorFee( + uint64 operatorId, + Operator memory operator, + uint256 fee + ) private onlyOperatorOwner(operator) { + uint64 shrunkAmount = fee.shrink(); + if (shrunkAmount >= operator.fee) revert FeeIncreaseNotAllowed(); + + operator.updateSnapshot(); + operator.fee = shrunkAmount; + operators[operatorId] = operator; + + emit OperatorFeeExecuted(msg.sender, operatorId, block.number, fee); + } + /*****************************/ /* Balance Private Functions */ /*****************************/ diff --git a/test/helpers/gas-usage.ts b/test/helpers/gas-usage.ts index 6573db02..66ef7c6e 100644 --- a/test/helpers/gas-usage.ts +++ b/test/helpers/gas-usage.ts @@ -37,11 +37,11 @@ const MAX_GAS_PER_GROUP: any = { [GasGroup.REMOVE_OPERATOR_WITH_WITHDRAW]: 62000, [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]: 185200, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE]: 201750, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE]: 201800, [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT]: 164700, [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_7]: 248300, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]: 264900, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]: 264950, [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_7]: 227800, [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_13]: 375200, diff --git a/test/operators/update-fee.ts b/test/operators/update-fee.ts index fcf1d85e..a019561c 100644 --- a/test/operators/update-fee.ts +++ b/test/operators/update-fee.ts @@ -144,6 +144,18 @@ describe('Operator Fee Tests', () => { )).to.be.revertedWithCustomError(ssvNetworkContract, 'ApprovalNotWithinTimeframe'); }); + it('Reduce fee emits "OperatorFeeExecuted"', async () => { + expect(await ssvNetworkContract.connect(helpers.DB.owners[2]).reduceOperatorFee(1, initialFee / 2)).to.emit(ssvNetworkContract, 'OperatorFeeExecuted'); + expect(await ssvViews.getOperatorFee(1)).to.equal(initialFee / 2); + + expect(await ssvNetworkContract.connect(helpers.DB.owners[2]).reduceOperatorFee(1, 0)).to.emit(ssvNetworkContract, 'OperatorFeeExecuted'); + expect(await ssvViews.getOperatorFee(1)).to.equal(0); + }); + + it('Reduce fee with an increased value reverts "FeeIncreaseNotAllowed"', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[2]).reduceOperatorFee(1, initialFee * 2)).to.be.revertedWithCustomError(ssvNetworkContract, 'FeeIncreaseNotAllowed');; + }); + //Dao it('DAO increase the fee emits "OperatorFeeIncreaseLimitUpdated"', async () => { await expect(ssvNetworkContract.updateOperatorFeeIncreaseLimit(1000 diff --git a/test/sanity/balances.ts b/test/sanity/balances.ts index 53d3d2e1..4a37448b 100644 --- a/test/sanity/balances.ts +++ b/test/sanity/balances.ts @@ -161,7 +161,7 @@ describe('Balance Tests', () => { 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 * 9 + helpers.CONFIG.minimalOperatorFee * 7); expect(await ssvViews.getOperatorEarnings(3)).to.equal(helpers.CONFIG.minimalOperatorFee * 9 + helpers.CONFIG.minimalOperatorFee * 7 + helpers.CONFIG.minimalOperatorFee * 2); @@ -169,7 +169,7 @@ describe('Balance Tests', () => { expect(await ssvViews.getOperatorEarnings(5)).to.equal(helpers.CONFIG.minimalOperatorFee * 2); 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 * 5 + newNetworkFee * 2); @@ -185,7 +185,16 @@ describe('Balance Tests', () => { // 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); + }); + + it('Check operator earnings and cluster balance when reducing operator fee"', async () => { + const newFee = helpers.CONFIG.minimalOperatorFee / 2; + await ssvNetworkContract.connect(helpers.DB.owners[0]).reduceOperatorFee(1, newFee); + + await utils.progressBlocks(2); + expect(await ssvViews.getOperatorEarnings(1)).to.equal(helpers.CONFIG.minimalOperatorFee * 3 + helpers.CONFIG.minimalOperatorFee + newFee * 4); + 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 () => { From f1b90f4a828edef5b176ff41da08d9af4c048213 Mon Sep 17 00:00:00 2001 From: Marco Tabasco Date: Wed, 15 Mar 2023 13:41:27 +0100 Subject: [PATCH 142/149] SSVNetworkViews.getValidator function (#201) * add getValidator function * change getClusterBurnRate to getBurnRate * todo to change var to public --------- Co-authored-by: Lior Rutenberg --- contracts/ISSVNetworkViews.sol | 9 +++++++-- contracts/SSVNetwork.sol | 3 ++- contracts/SSVNetworkViews.sol | 11 ++++++++++- test/validators/register.ts | 18 +++++++++++++++--- 4 files changed, 34 insertions(+), 7 deletions(-) diff --git a/contracts/ISSVNetworkViews.sol b/contracts/ISSVNetworkViews.sol index ad1214ab..ab9ae463 100644 --- a/contracts/ISSVNetworkViews.sol +++ b/contracts/ISSVNetworkViews.sol @@ -6,7 +6,6 @@ import "./SSVNetwork.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; - interface ISSVNetworkViews is ISSVNetworkCore { /****************/ /* Initializers */ @@ -18,6 +17,12 @@ interface ISSVNetworkViews is ISSVNetworkCore { */ function initialize(SSVNetwork ssvNetwork_) external; + /*************************************/ + /* Validator External View Functions */ + /*************************************/ + + function getValidator(bytes calldata publicKey) external view returns (address, bool); + /************************************/ /* Operator External View Functions */ /************************************/ @@ -46,7 +51,7 @@ interface ISSVNetworkViews is ISSVNetworkCore { ISSVNetwork.Cluster memory cluster ) external view returns (bool); - function getClusterBurnRate( + function getBurnRate( address owner, uint64[] memory operatorIds, ISSVNetwork.Cluster memory cluster diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index 4ae6a557..2fcd5f97 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -45,7 +45,8 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { mapping(uint64 => Operator) public operators; mapping(uint64 => OperatorFeeChangeRequest) public operatorFeeChangeRequests; mapping(bytes32 => bytes32) public clusters; - mapping(bytes32 => Validator) private _validatorPKs; + //TODO Change the name to be public + mapping(bytes32 => Validator) public _validatorPKs; bytes32 public version; diff --git a/contracts/SSVNetworkViews.sol b/contracts/SSVNetworkViews.sol index 79fbece9..51b56b6b 100644 --- a/contracts/SSVNetworkViews.sol +++ b/contracts/SSVNetworkViews.sol @@ -32,6 +32,15 @@ contract SSVNetworkViews is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwor _ssvNetwork = ssvNetwork_; } + /*************************************/ + /* Validator External View Functions */ + /*************************************/ + + function getValidator(bytes calldata publicKey) external view override returns (address, bool) { + (address owner, bool active) = _ssvNetwork._validatorPKs(keccak256(publicKey)); + return (owner, active); + } + /************************************/ /* Operator External View Functions */ /************************************/ @@ -108,7 +117,7 @@ contract SSVNetworkViews is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwor return !cluster.active; } - function getClusterBurnRate( + function getBurnRate( address owner, uint64[] calldata operatorIds, Cluster memory cluster diff --git a/test/validators/register.ts b/test/validators/register.ts index f373fdbc..d536f3a2 100644 --- a/test/validators/register.ts +++ b/test/validators/register.ts @@ -403,7 +403,7 @@ describe('Register Validator Tests', () => { await ssvNetworkContract.updateNetworkFee(networkFee); let clusterData = cluster1.eventsByName.ValidatorAdded[0].args.cluster; - expect(await ssvViews.getClusterBurnRate(helpers.DB.owners[6].address, [1, 2, 3, 4], clusterData)).to.equal((helpers.CONFIG.minimalOperatorFee * 4) + networkFee); + 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( @@ -414,12 +414,12 @@ describe('Register Validator Tests', () => { clusterData )); clusterData = validator2.eventsByName.ValidatorAdded[0].args.cluster; - expect(await ssvViews.getClusterBurnRate(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 exsit', async () => { const clusterData = cluster1.eventsByName.ValidatorAdded[0].args.cluster; - await expect(ssvViews.getClusterBurnRate(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 () => { @@ -632,4 +632,16 @@ describe('Register Validator Tests', () => { )).to.be.revertedWithCustomError(ssvNetwork, 'ExceedValidatorLimit'); }); + + it('Retrieve an existing validator', async () => { + const validator = await ssvViews.getValidator(helpers.DataGenerator.publicKey(90)); + expect(validator[0]).to.be.equals(helpers.DB.owners[6].address); + expect(validator[1]).to.be.equals(true); + }); + + it('Retrieve a non-existing validator', async () => { + const validator = await ssvViews.getValidator(helpers.DataGenerator.publicKey(1)); + expect(validator[0]).to.be.equals(ethers.constants.AddressZero); + expect(validator[1]).to.be.equals(false); + }); }); From b35c676bb2725168f36220dbb1c9bd46263b5890 Mon Sep 17 00:00:00 2001 From: Marco Tabasco Date: Wed, 15 Mar 2023 14:46:59 +0100 Subject: [PATCH 143/149] Private operators - IO1-2147 (#190) * add Operator.whitelisted * update Views contract, gas usage update * test passed * operatorsWhitelist mapping * emit whitelisted address on registration * remove unused flag * add registerPrivateOperator * registerOperator -> setOperatorWhitelist for private operators * use only setOperatorWhitelist for setting / removing whithelist address --- contracts/ISSVNetwork.sol | 31 ++++++++++++++----- contracts/ISSVNetworkCore.sol | 1 + contracts/ISSVNetworkViews.sol | 4 +-- contracts/SSVNetwork.sol | 25 +++++++++++++++- contracts/SSVNetworkViews.sol | 21 ++++++++----- test/account/deposit.ts | 3 +- test/deployment/deploy.ts | 8 ++--- test/helpers/contract-helpers.ts | 10 +++---- test/helpers/gas-usage.ts | 30 +++++++++---------- test/operators/others.ts | 51 ++++++++++++++++++++++++++++++++ test/operators/register.ts | 41 ++++++++++++++++++------- test/operators/remove.ts | 15 ++++++++++ test/operators/update-fee.ts | 3 +- test/validators/register.ts | 50 +++++++++++++++++++++++++++++++ 14 files changed, 235 insertions(+), 58 deletions(-) diff --git a/contracts/ISSVNetwork.sol b/contracts/ISSVNetwork.sol index 4e84b1dc..a49161bf 100644 --- a/contracts/ISSVNetwork.sol +++ b/contracts/ISSVNetwork.sol @@ -11,18 +11,30 @@ interface ISSVNetwork is ISSVNetworkCore { /** * @dev Emitted when a new operator has been added. - * @param id operator's ID. + * @param operatorId operator's ID. * @param owner Operator's ethereum address that can collect fees. * @param publicKey Operator's public key. Will be used to encrypt secret shares of validators keys. * @param fee Operator's fee. */ - event OperatorAdded(uint64 indexed id, address indexed owner, bytes publicKey, uint256 fee); + event OperatorAdded( + uint64 indexed operatorId, + address indexed owner, + bytes publicKey, + uint256 fee + ); /** * @dev Emitted when operator has been removed. - * @param id operator's ID. + * @param operatorId operator's ID. */ - event OperatorRemoved(uint64 indexed id); + event OperatorRemoved(uint64 indexed operatorId); + + /** + * @dev Emitted when the whitelist of an operator is updated. + * @param operatorId operator's ID. + * @param whitelisted operator's new whitelisted address. + */ + event OperatorWhitelistUpdated(uint64 indexed operatorId, address whitelisted); /** * @dev Emitted when the validator has been added. @@ -84,7 +96,10 @@ interface ISSVNetwork is ISSVNetworkCore { event ClusterDeposited(address indexed owner, uint64[] operatorIds, uint256 value, Cluster cluster); - event FeeRecipientAddressUpdated(address indexed owner, address recipientAddress); + event FeeRecipientAddressUpdated( + address indexed owner, + address recipientAddress + ); /****************/ /* Initializers */ @@ -119,9 +134,11 @@ interface ISSVNetwork is ISSVNetworkCore { /** * @dev Removes an operator. - * @param id Operator's id. + * @param operatorId Operator's id. */ - function removeOperator(uint64 id) external; + function removeOperator(uint64 operatorId) external; + + function setOperatorWhitelist(uint64 operatorId, address whitelisted) external; function declareOperatorFee(uint64 operatorId, uint256 fee) external; diff --git a/contracts/ISSVNetworkCore.sol b/contracts/ISSVNetworkCore.sol index 3bb0dca4..cc3c2f5c 100644 --- a/contracts/ISSVNetworkCore.sol +++ b/contracts/ISSVNetworkCore.sol @@ -60,6 +60,7 @@ interface ISSVNetworkCore { /**********/ error CallerNotOwner(); + error CallerNotWhitelisted(); error FeeTooLow(); error FeeExceedsIncreaseLimit(); error NoFeeDelcared(); diff --git a/contracts/ISSVNetworkViews.sol b/contracts/ISSVNetworkViews.sol index ab9ae463..30dbfd2d 100644 --- a/contracts/ISSVNetworkViews.sol +++ b/contracts/ISSVNetworkViews.sol @@ -33,7 +33,7 @@ interface ISSVNetworkViews is ISSVNetworkCore { function getOperatorById( uint64 operatorId - ) external view returns (address owner, uint256 fee, uint32 validatorCount, bool active); + ) external view returns (address owner, uint256 fee, uint32 validatorCount, bool isPrivate, bool active); /*******************************/ /* Cluster External View Functions */ @@ -61,7 +61,7 @@ interface ISSVNetworkViews is ISSVNetworkCore { /* Balance External View Functions */ /***********************************/ - function getOperatorEarnings(uint64 id) external view returns (uint256); + function getOperatorEarnings(uint64 operatorId) external view returns (uint256); function getBalance( address owner, diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index 2fcd5f97..9770793f 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -43,6 +43,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { /*************/ mapping(uint64 => Operator) public operators; + mapping(uint64 => address) public operatorsWhitelist; mapping(uint64 => OperatorFeeChangeRequest) public operatorFeeChangeRequests; mapping(bytes32 => bytes32) public clusters; //TODO Change the name to be public @@ -144,6 +145,10 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { _removeOperator(operatorId, operators[operatorId]); } + function setOperatorWhitelist(uint64 operatorId, address whitelisted) external override { + _setOperatorWhitelist(operatorId, whitelisted, operators[operatorId]); + } + function declareOperatorFee(uint64 operatorId, uint256 fee) external override { _declareOperatorFee(operatorId, operators[operatorId], fee); } @@ -232,6 +237,11 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { if (operator.snapshot.block == 0) { revert OperatorDoesNotExist(); } + if ( + operatorsWhitelist[operatorIds[i]] != address(0) && operatorsWhitelist[operatorIds[i]] != msg.sender + ) { + revert CallerNotWhitelisted(); + } operator.updateSnapshot(); if (++operator.validatorCount > validatorsPerOperatorLimit) { revert ExceedValidatorLimit(); @@ -511,7 +521,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { { uint operatorsLength = operatorIds.length; for (uint i; i < operatorsLength; ) { - Operator memory operator = operators[operatorIds[i]]; + Operator storage operator = operators[operatorIds[i]]; clusterIndex += operator.snapshot.index + (uint64(block.number) - operator.snapshot.block) * @@ -677,12 +687,25 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { operators[operatorId] = operator; + if (operatorsWhitelist[operatorId] != address(0)) { + delete operatorsWhitelist[operatorId]; + } + if (currentBalance > 0) { _transferOperatorBalanceUnsafe(operatorId, currentBalance.expand()); } emit OperatorRemoved(operatorId); } + function _setOperatorWhitelist( + uint64 operatorId, + address whitelisted, + Operator storage operator + ) private onlyOperatorOwner(operator) { + operatorsWhitelist[operatorId] = whitelisted; + emit OperatorWhitelistUpdated(operatorId, whitelisted); + } + function _declareOperatorFee( uint64 operatorId, Operator memory operator, diff --git a/contracts/SSVNetworkViews.sol b/contracts/SSVNetworkViews.sol index 51b56b6b..6d695e77 100644 --- a/contracts/SSVNetworkViews.sol +++ b/contracts/SSVNetworkViews.sol @@ -64,14 +64,19 @@ contract SSVNetworkViews is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwor return (fee.expand(), approvalBeginTime, approvalEndTime); } - function getOperatorById(uint64 operatorId) external view override returns (address, uint256, uint32, bool) { - (address operatorOwner, uint64 fee, uint32 validatorCount, Snapshot memory snapshot) = _ssvNetwork.operators( - operatorId - ); - bool active; - if (snapshot.block != 0) active = true; - - return (operatorOwner, fee.expand(), validatorCount, active); + function getOperatorById( + uint64 operatorId + ) external view override returns (address, uint256, uint32, bool, bool) { + ( + address operatorOwner, + uint64 fee, + uint32 validatorCount, + Snapshot memory snapshot + ) = _ssvNetwork.operators(operatorId); + bool isPrivate = _ssvNetwork.operatorsWhitelist(operatorId) == address(0) ? false : true; + bool isActive = snapshot.block == 0 ? false : true; + + return (operatorOwner, fee.expand(), validatorCount, isPrivate, isActive); } /***********************************/ diff --git a/test/account/deposit.ts b/test/account/deposit.ts index f4df0e2c..670205b4 100644 --- a/test/account/deposit.ts +++ b/test/account/deposit.ts @@ -35,12 +35,11 @@ describe('Deposit Tests', () => { active: true } ); - // Register validators cluster1 = await helpers.registerValidators(4, 1, minDepositAmount, helpers.DataGenerator.cluster.new(), [GasGroup.REGISTER_VALIDATOR_NEW_STATE]); }); - it('Deposit to a non liquidated cluster I own emits "ClusterDeposited', async () => { + 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); await helpers.DB.ssvToken.connect(helpers.DB.owners[4]).approve(ssvNetworkContract.address, minDepositAmount); await expect(ssvNetworkContract.connect(helpers.DB.owners[4]).deposit( diff --git a/test/deployment/deploy.ts b/test/deployment/deploy.ts index cb4beb1a..b8ec3475 100644 --- a/test/deployment/deploy.ts +++ b/test/deployment/deploy.ts @@ -15,7 +15,7 @@ describe('Deployment tests', () => { it('Test initial deployment of SSVNetwork and SSVNetworkViews', async () => { await ssvNetworkContract.connect(DB.owners[1]).registerOperator( DataGenerator.publicKey(0), - CONFIG.minimalOperatorFee, + CONFIG.minimalOperatorFee ); expect((await ssvNetworkViews.getOperatorById(1))[0]).to.equal(DB.owners[1].address); // owner @@ -31,8 +31,7 @@ describe('Deployment tests', () => { it('Upgrade SSVNetwork contract. Check new function execution', async () => { await ssvNetworkContract.connect(DB.owners[1]).registerOperator( DataGenerator.publicKey(0), - CONFIG.minimalOperatorFee, - ); + CONFIG.minimalOperatorFee); const BasicUpgrade = await ethers.getContractFactory("SSVNetworkBasicUpgrade"); const ssvNetworkUpgrade = await upgrades.upgradeProxy(ssvNetworkContract.address, BasicUpgrade, { kind: 'uups' }); @@ -94,8 +93,7 @@ describe('Deployment tests', () => { it('Upgrade SSVNetworkViews contract. Check new function execution', async () => { await ssvNetworkContract.connect(DB.owners[1]).registerOperator( DataGenerator.publicKey(0), - CONFIG.minimalOperatorFee, - ); + CONFIG.minimalOperatorFee); const SSVNetworkViewsBasicUpgrade = await ethers.getContractFactory("SSVNetworkViewsBasicUpgrade"); const ssvNetworkUpgrade = await upgrades.upgradeProxy(ssvNetworkViews.address, SSVNetworkViewsBasicUpgrade, { kind: 'uups' }); diff --git a/test/helpers/contract-helpers.ts b/test/helpers/contract-helpers.ts index d6c4cac3..903f0662 100644 --- a/test/helpers/contract-helpers.ts +++ b/test/helpers/contract-helpers.ts @@ -43,9 +43,9 @@ export const DataGenerator = { const result = []; for (const operator of DB.operators) { - if (operator && !usedOperatorIds[operator.id]) { - result.push(operator.id); - usedOperatorIds[operator.id] = true; + if (operator && !usedOperatorIds[operator.operatorId]) { + result.push(operator.operatorId); + usedOperatorIds[operator.operatorId] = true; if (result.length == size) { break; @@ -134,8 +134,8 @@ export const registerOperators = async (ownerId: number, numberOfOperators: numb gasGroups ); const event = eventsByName.OperatorAdded[0]; - DB.operators[event.args.id] = { - id: event.args.id, ownerId: ownerId, publicKey: DataGenerator.publicKey(i) + DB.operators[event.args.operatorId] = { + operatorId: event.args.operatorId, ownerId: ownerId, publicKey: DataGenerator.publicKey(i) }; } }; diff --git a/test/helpers/gas-usage.ts b/test/helpers/gas-usage.ts index 66ef7c6e..c9324c00 100644 --- a/test/helpers/gas-usage.ts +++ b/test/helpers/gas-usage.ts @@ -32,21 +32,21 @@ export enum GasGroup { const MAX_GAS_PER_GROUP: any = { /* REAL GAS LIMITS */ - [GasGroup.REGISTER_OPERATOR]: 105000, - [GasGroup.REMOVE_OPERATOR]: 62000, + [GasGroup.REGISTER_OPERATOR]: 120900, + [GasGroup.REMOVE_OPERATOR]: 62600, [GasGroup.REMOVE_OPERATOR_WITH_WITHDRAW]: 62000, - [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]: 185200, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE]: 201800, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT]: 164700, + [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]: 194600, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE]: 211200, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT]: 174100, - [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_7]: 248300, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]: 264950, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_7]: 227800, + [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_7]: 264800, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]: 281400, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_7]: 244300, - [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_13]: 375200, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]: 391750, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_13]: 354700, + [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_13]: 405700, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]: 422300, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_13]: 385200, [GasGroup.REMOVE_VALIDATOR]: 106300, [GasGroup.TRANSFER_VALIDATOR_NEW_CLUSTER]: 400000, @@ -55,11 +55,11 @@ const MAX_GAS_PER_GROUP: any = { [GasGroup.BULK_TRANSFER_VALIDATOR]: 366000, [GasGroup.BULK_TRANSFER_VALIDATOR_NON_EXISTING_POD]: 383000, [GasGroup.DEPOSIT]: 77500, - [GasGroup.WITHDRAW_POD_BALANCE]: 95500, - [GasGroup.WITHDRAW_OPERATOR_BALANCE]: 59000, + [GasGroup.WITHDRAW_POD_BALANCE]: 90700, + [GasGroup.WITHDRAW_OPERATOR_BALANCE]: 56600, [GasGroup.REGISTER_POD]: 137000, - [GasGroup.LIQUIDATE_POD]: 137000, - [GasGroup.REACTIVATE_POD]: 137000, + [GasGroup.LIQUIDATE_POD]: 125700, + [GasGroup.REACTIVATE_POD]: 126600, }; class GasStats { diff --git a/test/operators/others.ts b/test/operators/others.ts index 958002bd..9566376d 100644 --- a/test/operators/others.ts +++ b/test/operators/others.ts @@ -1,6 +1,7 @@ // Declare imports import * as helpers from '../helpers/contract-helpers'; import { expect } from 'chai'; +import { trackGas } from '../helpers/gas-usage'; // Declare globals let ssvNetworkContract: any; @@ -34,4 +35,54 @@ describe('Others Operator Tests', () => { expect((await ssvNetwork.validatorsPerOperatorLimit())).to.equal(50); }); + it('Remove operator whitelisted address', async () => { + const result = await trackGas(ssvNetworkContract.registerOperator( + helpers.DataGenerator.publicKey(1), + helpers.CONFIG.minimalOperatorFee + )); + const { operatorId } = result.eventsByName.OperatorAdded[0].args; + + await ssvNetworkContract.setOperatorWhitelist(operatorId, helpers.DB.owners[2].address); + + await expect(ssvNetworkContract.setOperatorWhitelist(operatorId, ethers.constants.AddressZero)) + .to.emit(ssvNetworkContract, 'OperatorWhitelistUpdated') + .withArgs(operatorId, ethers.constants.AddressZero); + }); + + it('Non-owner remove operator whitelisted address reverts "CallerNotOwner"', async () => { + const result = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerOperator( + helpers.DataGenerator.publicKey(1), + helpers.CONFIG.minimalOperatorFee + )); + const { operatorId } = result.eventsByName.OperatorAdded[0].args; + + await ssvNetworkContract.connect(helpers.DB.owners[1]).setOperatorWhitelist(operatorId, helpers.DB.owners[2].address); + + await expect(ssvNetworkContract.setOperatorWhitelist(operatorId, ethers.constants.AddressZero)) + .to.be.revertedWithCustomError(ssvNetworkContract, 'CallerNotOwner'); + }); + + it('Update operator whitelisted address', async () => { + const result = await trackGas(ssvNetworkContract.registerOperator( + helpers.DataGenerator.publicKey(1), + helpers.CONFIG.minimalOperatorFee + )); + const { operatorId } = result.eventsByName.OperatorAdded[0].args; + + await expect(ssvNetworkContract.setOperatorWhitelist(operatorId, helpers.DB.owners[2].address)) + .to.emit(ssvNetworkContract, 'OperatorWhitelistUpdated') + .withArgs(operatorId, helpers.DB.owners[2].address); + }); + + it('Non-owner update operator whitelisted address reverts "CallerNotOwner"', async () => { + const result = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerOperator( + helpers.DataGenerator.publicKey(1), + helpers.CONFIG.minimalOperatorFee + )); + const { operatorId } = result.eventsByName.OperatorAdded[0].args; + + await expect(ssvNetworkContract.setOperatorWhitelist(operatorId, helpers.DB.owners[2].address)) + .to.be.revertedWithCustomError(ssvNetworkContract, 'CallerNotOwner'); + }); + }); \ No newline at end of file diff --git a/test/operators/register.ts b/test/operators/register.ts index defe1dea..5ad86d4f 100644 --- a/test/operators/register.ts +++ b/test/operators/register.ts @@ -17,57 +17,76 @@ describe('Register Operator Tests', () => { const publicKey = helpers.DataGenerator.publicKey(0); await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).registerOperator( publicKey, - helpers.CONFIG.minimalOperatorFee, + helpers.CONFIG.minimalOperatorFee )).to.emit(ssvNetworkContract, 'OperatorAdded').withArgs(1, helpers.DB.owners[1].address, publicKey, helpers.CONFIG.minimalOperatorFee); }); it('Register operator gas limits', async () => { await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerOperator( helpers.DataGenerator.publicKey(0), - helpers.CONFIG.minimalOperatorFee, + helpers.CONFIG.minimalOperatorFee ), [GasGroup.REGISTER_OPERATOR]); }); it('Get operator by id', async () => { await ssvNetworkContract.connect(helpers.DB.owners[1]).registerOperator( helpers.DataGenerator.publicKey(0), - helpers.CONFIG.minimalOperatorFee); + helpers.CONFIG.minimalOperatorFee, + ); + + expect((await ssvViews.getOperatorById(1))[0]).to.equal(helpers.DB.owners[1].address); // owner + expect((await ssvViews.getOperatorById(1))[1]).to.equal(helpers.CONFIG.minimalOperatorFee); // fee + expect((await ssvViews.getOperatorById(1))[2]).to.equal(0); // validatorCount + expect((await ssvViews.getOperatorById(1))[3]).to.equal(false); // isPrivate + expect((await ssvViews.getOperatorById(1))[4]).to.equal(true); // active + }); + + it('Get private operator by id', async () => { + await ssvNetworkContract.connect(helpers.DB.owners[1]).registerOperator( + helpers.DataGenerator.publicKey(0), + helpers.CONFIG.minimalOperatorFee + ); + + await ssvNetworkContract.connect(helpers.DB.owners[1]).setOperatorWhitelist(1, helpers.DB.owners[2].address); expect((await ssvViews.getOperatorById(1))[0]).to.equal(helpers.DB.owners[1].address); // owner expect((await ssvViews.getOperatorById(1))[1]).to.equal(helpers.CONFIG.minimalOperatorFee); // fee expect((await ssvViews.getOperatorById(1))[2]).to.equal(0); // validatorCount - expect((await ssvViews.getOperatorById(1))[3]).to.equal(true); // active + expect((await ssvViews.getOperatorById(1))[3]).to.equal(true); // isPrivate + expect((await ssvViews.getOperatorById(1))[4]).to.equal(true); // active }); it('Get non-existent operator by id', async () => { - await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerOperator( + await ssvNetworkContract.connect(helpers.DB.owners[1]).registerOperator( helpers.DataGenerator.publicKey(0), - helpers.CONFIG.minimalOperatorFee, - ), [GasGroup.REGISTER_OPERATOR]); + helpers.CONFIG.minimalOperatorFee + ); expect((await ssvViews.getOperatorById(3))[0]).to.equal(ethers.constants.AddressZero); // owner expect((await ssvViews.getOperatorById(3))[1]).to.equal(0); // fee expect((await ssvViews.getOperatorById(3))[2]).to.equal(0); // validatorCount - expect((await ssvViews.getOperatorById(3))[3]).to.equal(false); // active + expect((await ssvViews.getOperatorById(1))[3]).to.equal(false); // isPrivate + expect((await ssvViews.getOperatorById(3))[4]).to.equal(false); // active }); it('Get operator removed by id', async () => { await ssvNetworkContract.connect(helpers.DB.owners[1]).registerOperator( helpers.DataGenerator.publicKey(0), - helpers.CONFIG.minimalOperatorFee, + helpers.CONFIG.minimalOperatorFee ); await ssvNetworkContract.connect(helpers.DB.owners[1]).removeOperator(1); expect((await ssvViews.getOperatorById(1))[0]).to.equal(helpers.DB.owners[1].address); // owner expect((await ssvViews.getOperatorById(1))[1]).to.equal(0); // fee expect((await ssvViews.getOperatorById(1))[2]).to.equal(0); // validatorCount - expect((await ssvViews.getOperatorById(1))[3]).to.equal(false); // active + expect((await ssvViews.getOperatorById(1))[3]).to.equal(false); // isPrivate + expect((await ssvViews.getOperatorById(1))[4]).to.equal(false); // active }); it('Register an operator with a fee thats too low reverts "FeeTooLow"', async () => { await expect(ssvNetworkContract.registerOperator( helpers.DataGenerator.publicKey(0), - '10' + '10', )).to.be.revertedWithCustomError(ssvNetworkContract, 'FeeTooLow'); }); }); \ No newline at end of file diff --git a/test/operators/remove.ts b/test/operators/remove.ts index 387af474..8fc44295 100644 --- a/test/operators/remove.ts +++ b/test/operators/remove.ts @@ -35,6 +35,21 @@ describe('Remove Operator Tests', () => { .to.emit(ssvNetworkContract, 'OperatorRemoved').withArgs(1); }); + it('Remove private operator emits "OperatorRemoved"', async () => { + const result = await trackGas(ssvNetworkContract.registerOperator( + helpers.DataGenerator.publicKey(0), + 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); + + expect(await ssvNetworkContract.operatorsWhitelist(operatorId)).to.be.equals(ethers.constants.AddressZero); + }); + it('Remove operator gas limits', async () => { await trackGas(ssvNetworkContract.removeOperator(1), [GasGroup.REMOVE_OPERATOR]); }); diff --git a/test/operators/update-fee.ts b/test/operators/update-fee.ts index a019561c..b1f10a60 100644 --- a/test/operators/update-fee.ts +++ b/test/operators/update-fee.ts @@ -97,8 +97,7 @@ describe('Operator Fee Tests', () => { it('Declare fee after registering an operator with zero fee reverts "ZeroFeeIncreaseNotAllowed"', async () => { await ssvNetworkContract.connect(helpers.DB.owners[2]).registerOperator( helpers.DataGenerator.publicKey(0), - 0, - ); + 0); await expect(ssvNetworkContract.connect(helpers.DB.owners[2]).declareOperatorFee(2, initialFee + initialFee / 10 )).to.be.revertedWithCustomError(ssvNetworkContract, 'ZeroFeeIncreaseNotAllowed'); }); diff --git a/test/validators/register.ts b/test/validators/register.ts index d536f3a2..078f1f5d 100644 --- a/test/validators/register.ts +++ b/test/validators/register.ts @@ -633,6 +633,56 @@ describe('Register Validator Tests', () => { }); + 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(2), + 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 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'); + }); + + it('Register a non whitelisted validator reverts "CallerNotWhitelisted"', async () => { + const result = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).registerOperator( + helpers.DataGenerator.publicKey(2), + 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 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'); + }); + it('Retrieve an existing validator', async () => { const validator = await ssvViews.getValidator(helpers.DataGenerator.publicKey(90)); expect(validator[0]).to.be.equals(helpers.DB.owners[6].address); From 16046e8873e71089f06853b1bb919a783c69d811 Mon Sep 17 00:00:00 2001 From: Marco Tabasco Date: Wed, 15 Mar 2023 15:11:06 +0100 Subject: [PATCH 144/149] Implement Minimum Liquidation Collateral - IO1-2838 (#202) * use minimumLiquidationCollateral * add MINIMAL_LIQUIDATION_COLLATERAL * update min liquidation defualt value to 2 * allow owner to set any min collateral * update gas usage * remove MINIMAL_COLLATERAL constant --------- Co-authored-by: Lior Rutenberg --- contracts/ISSVNetwork.sol | 7 ++++- contracts/ISSVNetworkViews.sol | 2 ++ contracts/SSVNetwork.sol | 41 +++++++++++++++++++++++++----- contracts/SSVNetworkViews.sol | 12 ++++++++- contracts/libraries/ClusterLib.sol | 5 +++- test/dao/liquidation-collateral.ts | 34 +++++++++++++++++++++++++ test/deployment/deploy.ts | 1 + test/helpers/contract-helpers.ts | 4 ++- test/helpers/gas-usage.ts | 18 ++++++------- test/liquidate/liquidate.ts | 19 ++++++++++++-- test/liquidate/reactivate.ts | 15 ----------- 11 files changed, 121 insertions(+), 37 deletions(-) create mode 100644 test/dao/liquidation-collateral.ts diff --git a/contracts/ISSVNetwork.sol b/contracts/ISSVNetwork.sol index a49161bf..8291380d 100644 --- a/contracts/ISSVNetwork.sol +++ b/contracts/ISSVNetwork.sol @@ -77,6 +77,8 @@ interface ISSVNetwork is ISSVNetworkCore { event LiquidationThresholdPeriodUpdated(uint64 value); + event MinimumLiquidationCollateralUpdated(uint256 value); + /** * @dev Emitted when the network fee is updated. * @param oldFee The old fee @@ -118,7 +120,8 @@ interface ISSVNetwork is ISSVNetworkCore { uint64 operatorMaxFeeIncrease_, uint64 declareOperatorFeePeriod_, uint64 executeOperatorFeePeriod_, - uint64 minimumBlocksBeforeLiquidation_ + uint64 minimumBlocksBeforeLiquidation_, + uint256 minimumLiquidationCollateral_ ) external; /*******************************/ @@ -199,4 +202,6 @@ interface ISSVNetwork is ISSVNetworkCore { function updateExecuteOperatorFeePeriod(uint64 newExecuteOperatorFeePeriod) external; function updateLiquidationThresholdPeriod(uint64 blocks) external; + + function updateMinimumLiquidationCollateral(uint256 amount) external; } diff --git a/contracts/ISSVNetworkViews.sol b/contracts/ISSVNetworkViews.sol index 30dbfd2d..cbf7215f 100644 --- a/contracts/ISSVNetworkViews.sol +++ b/contracts/ISSVNetworkViews.sol @@ -84,4 +84,6 @@ interface ISSVNetworkViews is ISSVNetworkCore { function getDeclaredOperatorFeePeriod() external view returns (uint64); function getLiquidationThresholdPeriod() external view returns (uint64); + + function getMinimumLiquidationCollateral() external view returns (uint256); } diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index 9770793f..60f99851 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -56,6 +56,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { uint64 public executeOperatorFeePeriod; uint64 public operatorMaxFeeIncrease; uint64 public minimumBlocksBeforeLiquidation; + uint64 public minimumLiquidationCollateral; DAO public dao; IERC20 private _token; @@ -84,7 +85,8 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { uint64 operatorMaxFeeIncrease_, uint64 declareOperatorFeePeriod_, uint64 executeOperatorFeePeriod_, - uint64 minimumBlocksBeforeLiquidation_ + uint64 minimumBlocksBeforeLiquidation_, + uint256 minimumLiquidationCollateral_ ) external override initializer onlyProxy { __UUPSUpgradeable_init(); __Ownable_init_unchained(); @@ -94,7 +96,8 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { operatorMaxFeeIncrease_, declareOperatorFeePeriod_, executeOperatorFeePeriod_, - minimumBlocksBeforeLiquidation_ + minimumBlocksBeforeLiquidation_, + minimumLiquidationCollateral_ ); } @@ -104,7 +107,8 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { uint64 operatorMaxFeeIncrease_, uint64 declareOperatorFeePeriod_, uint64 executeOperatorFeePeriod_, - uint64 minimumBlocksBeforeLiquidation_ + uint64 minimumBlocksBeforeLiquidation_, + uint256 minimumLiquidationCollateral_ ) internal onlyInitializing { version = bytes32(abi.encodePacked(initialVersion_)); _token = token_; @@ -112,6 +116,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { declareOperatorFeePeriod = declareOperatorFeePeriod_; executeOperatorFeePeriod = executeOperatorFeePeriod_; minimumBlocksBeforeLiquidation = minimumBlocksBeforeLiquidation_; + minimumLiquidationCollateral = minimumLiquidationCollateral_.shrink(); validatorsPerOperatorLimit = 2_000; } @@ -263,7 +268,14 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { ++cluster.validatorCount; - if (cluster.isLiquidatable(burnRate, network_.networkFee, minimumBlocksBeforeLiquidation)) { + if ( + cluster.isLiquidatable( + burnRate, + network_.networkFee, + minimumBlocksBeforeLiquidation, + minimumLiquidationCollateral + ) + ) { revert InsufficientBalance(); } @@ -378,7 +390,10 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { uint64 networkFee = network.networkFee; uint256 balanceLiquidatable; - if (owner != msg.sender && !cluster.isLiquidatable(burnRate, networkFee, minimumBlocksBeforeLiquidation)) { + if ( + owner != msg.sender && + !cluster.isLiquidatable(burnRate, networkFee, minimumBlocksBeforeLiquidation, minimumLiquidationCollateral) + ) { revert ClusterNotLiquidatable(); } @@ -454,7 +469,9 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { dao = dao_; } - if (cluster.isLiquidatable(burnRate, networkFee, minimumBlocksBeforeLiquidation)) { + if ( + cluster.isLiquidatable(burnRate, networkFee, minimumBlocksBeforeLiquidation, minimumLiquidationCollateral) + ) { revert InsufficientBalance(); } @@ -537,7 +554,12 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { if ( cluster.balance < amount || - cluster.isLiquidatable(burnRate, network.networkFee, minimumBlocksBeforeLiquidation) + cluster.isLiquidatable( + burnRate, + network.networkFee, + minimumBlocksBeforeLiquidation, + minimumLiquidationCollateral + ) ) { revert InsufficientBalance(); } @@ -622,6 +644,11 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { emit LiquidationThresholdPeriodUpdated(blocks); } + function updateMinimumLiquidationCollateral(uint256 amount) external override onlyOwner { + minimumLiquidationCollateral = amount.shrink(); + emit MinimumLiquidationCollateralUpdated(amount); + } + /********************************/ /* Validation Private Functions */ /********************************/ diff --git a/contracts/SSVNetworkViews.sol b/contracts/SSVNetworkViews.sol index 6d695e77..48c2bd47 100644 --- a/contracts/SSVNetworkViews.sol +++ b/contracts/SSVNetworkViews.sol @@ -109,7 +109,13 @@ contract SSVNetworkViews is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwor clusterIndex, NetworkLib.currentNetworkFeeIndex(Network(networkFee, networkFeeIndex, networkFeeIndexBlockNumber)) ); - return cluster.isLiquidatable(burnRate, networkFee, _ssvNetwork.minimumBlocksBeforeLiquidation()); + return + cluster.isLiquidatable( + burnRate, + networkFee, + _ssvNetwork.minimumBlocksBeforeLiquidation(), + _ssvNetwork.minimumLiquidationCollateral() + ); } function isLiquidated( @@ -226,6 +232,10 @@ contract SSVNetworkViews is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwor return _ssvNetwork.minimumBlocksBeforeLiquidation(); } + function getMinimumLiquidationCollateral() external view override returns (uint256) { + return _ssvNetwork.minimumLiquidationCollateral().expand(); + } + function getVersion() external view returns (string memory version) { bytes memory currentVersion = abi.encodePacked(_ssvNetwork.version()); diff --git a/contracts/libraries/ClusterLib.sol b/contracts/libraries/ClusterLib.sol index dc35a41c..47f2947a 100644 --- a/contracts/libraries/ClusterLib.sol +++ b/contracts/libraries/ClusterLib.sol @@ -22,8 +22,11 @@ library ClusterLib { ISSVNetworkCore.Cluster memory cluster, uint64 burnRate, uint64 networkFee, - uint64 minimumBlocksBeforeLiquidation + uint64 minimumBlocksBeforeLiquidation, + uint64 minimumLiquidationCollateral ) internal pure returns (bool) { + if (cluster.balance < minimumLiquidationCollateral.expand()) return true; + uint64 liquidationThreshold = minimumBlocksBeforeLiquidation * (burnRate + networkFee) * cluster.validatorCount; return cluster.balance < liquidationThreshold.expand(); } diff --git a/test/dao/liquidation-collateral.ts b/test/dao/liquidation-collateral.ts new file mode 100644 index 00000000..17c9b005 --- /dev/null +++ b/test/dao/liquidation-collateral.ts @@ -0,0 +1,34 @@ +// Declare imports +import * as helpers from '../helpers/contract-helpers'; +import { expect } from 'chai'; + +// Declare globals +let ssvNetworkContract: any, ssvViews: any, networkFee: any; + +describe('Liquidation Collateral Tests', () => { + beforeEach(async () => { + // Initialize contract + const metadata = (await helpers.initializeContract()); + ssvNetworkContract = metadata.contract; + ssvViews = metadata.ssvViews; + + // Define minumum allowed network fee to pass shrinkable validation + networkFee = helpers.CONFIG.minimalOperatorFee / 10; + }); + + it('Change minimum collateral emits "MinimumLiquidationCollateralUpdated"', async () => { + await expect(ssvNetworkContract.updateMinimumLiquidationCollateral(helpers.CONFIG.minimumLiquidationCollateral * 2)) + .to.emit(ssvNetworkContract, 'MinimumLiquidationCollateralUpdated') + .withArgs(helpers.CONFIG.minimumLiquidationCollateral * 2); + }); + + it('Get minimum collateral', async () => { + expect(await ssvViews.getMinimumLiquidationCollateral()).to.equal(helpers.CONFIG.minimumLiquidationCollateral); + }); + + + it('Change minimum collateral reverts "caller is not the owner"', async () => { + await expect(ssvNetworkContract.connect(helpers.DB.owners[3]).updateMinimumLiquidationCollateral(helpers.CONFIG.minimumLiquidationCollateral * 2)) + .to.be.revertedWith('Ownable: caller is not the owner'); + }); +}); diff --git a/test/deployment/deploy.ts b/test/deployment/deploy.ts index b8ec3475..2838f2d2 100644 --- a/test/deployment/deploy.ts +++ b/test/deployment/deploy.ts @@ -56,6 +56,7 @@ describe('Deployment tests', () => { 2000000, 2000000, 2000000, + 2000000, 2000000)).to.be.revertedWith('Function must be called through delegatecall'); }); diff --git a/test/helpers/contract-helpers.ts b/test/helpers/contract-helpers.ts index 903f0662..1dde634a 100644 --- a/test/helpers/contract-helpers.ts +++ b/test/helpers/contract-helpers.ts @@ -69,6 +69,7 @@ export const initializeContract = async () => { executeOperatorFeePeriod: 86400, // DAY minimalOperatorFee: 100000000, minimalBlocksBeforeLiquidation: 6570, + minimumLiquidationCollateral: 60000000 }; DB = { @@ -98,7 +99,8 @@ export const initializeContract = async () => { CONFIG.operatorMaxFeeIncrease, CONFIG.declareOperatorFeePeriod, CONFIG.executeOperatorFeePeriod, - CONFIG.minimalBlocksBeforeLiquidation + CONFIG.minimalBlocksBeforeLiquidation, + CONFIG.minimumLiquidationCollateral ], { kind: 'uups' diff --git a/test/helpers/gas-usage.ts b/test/helpers/gas-usage.ts index c9324c00..7fdf8fa7 100644 --- a/test/helpers/gas-usage.ts +++ b/test/helpers/gas-usage.ts @@ -36,17 +36,17 @@ const MAX_GAS_PER_GROUP: any = { [GasGroup.REMOVE_OPERATOR]: 62600, [GasGroup.REMOVE_OPERATOR_WITH_WITHDRAW]: 62000, - [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]: 194600, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE]: 211200, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT]: 174100, + [GasGroup.REGISTER_VALIDATOR_EXISTING_POD]: 194800, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE]: 211400, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT]: 174300, - [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_7]: 264800, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]: 281400, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_7]: 244300, + [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_7]: 265000, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_7]: 281600, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_7]: 244500, - [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_13]: 405700, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]: 422300, - [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_13]: 385200, + [GasGroup.REGISTER_VALIDATOR_EXISTING_POD_13]: 405900, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_13]: 422500, + [GasGroup.REGISTER_VALIDATOR_NEW_STATE_WITHOUT_DEPOSIT_13]: 385400, [GasGroup.REMOVE_VALIDATOR]: 106300, [GasGroup.TRANSFER_VALIDATOR_NEW_CLUSTER]: 400000, diff --git a/test/liquidate/liquidate.ts b/test/liquidate/liquidate.ts index 8164c153..c6e01a1d 100644 --- a/test/liquidate/liquidate.ts +++ b/test/liquidate/liquidate.ts @@ -53,7 +53,7 @@ describe('Liquidate Tests', () => { firstCluster = register.eventsByName.ValidatorAdded[0].args; }); - it('Liquidate a cluster emits "ClusterLiquidated"', async () => { + it('Liquidate a cluster via liquidation threshold emits "ClusterLiquidated"', async () => { await utils.progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); await expect(ssvNetworkContract.liquidate( @@ -64,7 +64,22 @@ describe('Liquidate Tests', () => { .to.emit(helpers.DB.ssvToken, 'Transfer').withArgs( ssvNetworkContract.address, helpers.DB.owners[0].address, - minDepositAmount - (helpers.CONFIG.minimalOperatorFee * 4 * 6571) + 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( + ssvNetworkContract.address, + helpers.DB.owners[0].address, + minDepositAmount - (helpers.CONFIG.minimalOperatorFee * 4 * (helpers.CONFIG.minimalBlocksBeforeLiquidation + 1 - 2)) ); }); diff --git a/test/liquidate/reactivate.ts b/test/liquidate/reactivate.ts index 61a4ce88..2a0e0528 100644 --- a/test/liquidate/reactivate.ts +++ b/test/liquidate/reactivate.ts @@ -61,21 +61,6 @@ describe('Reactivate Tests', () => { await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).reactivate(updatedCluster.operatorIds, minDepositAmount, updatedCluster.cluster)).to.emit(ssvNetworkContract, 'ClusterReactivated'); }); - it('Reactivate with 0 deposit and no validators emits ClusterReactivated', async () => { - await progressBlocks(helpers.CONFIG.minimalBlocksBeforeLiquidation); - const liquidatedCluster = await trackGas(ssvNetworkContract.liquidate(firstCluster.owner, firstCluster.operatorIds, firstCluster.cluster), [GasGroup.LIQUIDATE_POD]); - const updatedCluster = liquidatedCluster.eventsByName.ClusterLiquidated[0].args; - - const remove = await trackGas(ssvNetworkContract.connect(helpers.DB.owners[1]).removeValidator( - helpers.DataGenerator.publicKey(1), - firstCluster.operatorIds, - updatedCluster.cluster - ), [GasGroup.REMOVE_VALIDATOR]); - const updatedClusterAfrerRemove = remove.eventsByName.ValidatorRemoved[0].args; - - await expect(ssvNetworkContract.connect(helpers.DB.owners[1]).reactivate(updatedClusterAfrerRemove.operatorIds, 0, updatedClusterAfrerRemove.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_POD]); From 7dbd797812e8831872ccd8f6f42fa70e4297d327 Mon Sep 17 00:00:00 2001 From: Marco Date: Thu, 16 Mar 2023 01:02:45 +0100 Subject: [PATCH 145/149] validatorPKs public name --- .env.example | 15 +- .gitignore | 1 + .openzeppelin/goerli.json | 574 ++++++++++++++++++++++++++++++++++ contracts/ISSVNetwork.sol | 12 +- contracts/SSVNetwork.sol | 11 +- contracts/SSVNetworkViews.sol | 2 +- scripts/deploy-all.ts | 5 +- 7 files changed, 593 insertions(+), 27 deletions(-) diff --git a/.env.example b/.env.example index 5852e35a..11e886bb 100644 --- a/.env.example +++ b/.env.example @@ -1,17 +1,16 @@ GOERLI_ETH_NODE_URL= GOERLI_OWNER_PRIVATE_KEY= -GANACHE_ETH_NODE_URL= -GANACHE_OWNER_PRIVATE_KEY= +MAINNET_ETH_NODE_URL= +MAINNET_OWNER_PRIVATE_KEY= GAS_PRICE= +GAS= ETHERSCAN_KEY= SSV_TOKEN_ADDRESS= -CDT_TOKEN_ADDRESS= MINIMUM_BLOCKS_BEFORE_LIQUIDATION=100 +MINIMUM_LIQUIDATION_COLLATERAL=200000000 OPERATOR_MAX_FEE_INCREASE=3 -SET_OPERATOR_FEE_PERIOD=259200 # 3 days -APPROVE_OPERATOR_FEE_PERIOD=345600 # 4 days -VALIDATORS_PER_OPERATOR_LIMIT=2000 -REGISTERED_OPERATORS_PER_ACCOUNT_LIMIT=10 +DECLARE_OPERATOR_FEE_PERIOD=259200 # 3 days +EXECUTE_OPERATOR_FEE_PERIOD=345600 # 4 days SSVNETWORK_PROXY_ADDRESS= SSVNETWORKVIEWS_PROXY_ADDRESS= -INITIAL_VERSION="0.0.1" +INITIAL_VERSION="0.3.0" diff --git a/.gitignore b/.gitignore index e63b2629..bd5fa1d9 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ artifacts typechain-types/ .openzeppelin/dev-*.json .DS_Store +.history diff --git a/.openzeppelin/goerli.json b/.openzeppelin/goerli.json index 777629d5..8530f23d 100644 --- a/.openzeppelin/goerli.json +++ b/.openzeppelin/goerli.json @@ -10,6 +10,16 @@ "address": "0x4ddfE2966f7Cdfe1F7d4f7d48949b3AB16BCc6B5", "txHash": "0x7f46d97d62a3f25fe62473d9839871949408b23a07bd4541b52eb4a03090523f", "kind": "uups" + }, + { + "address": "0xAfdb141Dd99b5a101065f40e3D7636262dce65b3", + "txHash": "0xc7a324e98962c685088d1ad056d33c9a57f64770e9ee8d755dd1133552419c38", + "kind": "uups" + }, + { + "address": "0x8dB45282d7C4559fd093C26f677B3837a5598914", + "txHash": "0xb8a3be822bd5dda92d8a03a0ced6dbac1f60aedacf4970ef912a81e25cbc5bec", + "kind": "uups" } ], "impls": { @@ -1388,6 +1398,570 @@ } } } + }, + "c4480254e15501bebfa4ff3227ffafce858a7084193ac664b9626254f8e6b23a": { + "address": "0x6b2CA261957B4b2f795aEeF5A806EdCc6bE04eB9", + "txHash": "0xcd619ab625bebdd3436c5b1158d1aeb76fb5b834c137a336b35c51050d454a93", + "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:62", + "retypedFrom": "bool" + }, + { + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:67" + }, + { + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)50_storage", + "contract": "ERC1967UpgradeUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol:211" + }, + { + "label": "__gap", + "offset": 0, + "slot": "51", + "type": "t_array(t_uint256)50_storage", + "contract": "UUPSUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol:107" + }, + { + "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": "lastOperatorId", + "offset": 0, + "slot": "251", + "type": "t_struct(Counter)2148_storage", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:39" + }, + { + "label": "operators", + "offset": 0, + "slot": "252", + "type": "t_mapping(t_uint64,t_struct(Operator)2612_storage)", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:45" + }, + { + "label": "operatorsWhitelist", + "offset": 0, + "slot": "253", + "type": "t_mapping(t_uint64,t_address)", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:46" + }, + { + "label": "operatorFeeChangeRequests", + "offset": 0, + "slot": "254", + "type": "t_mapping(t_uint64,t_struct(OperatorFeeChangeRequest)2619_storage)", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:47" + }, + { + "label": "clusters", + "offset": 0, + "slot": "255", + "type": "t_mapping(t_bytes32,t_bytes32)", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:48" + }, + { + "label": "validatorPKs", + "offset": 0, + "slot": "256", + "type": "t_mapping(t_bytes32,t_struct(Validator)2591_storage)", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:49" + }, + { + "label": "version", + "offset": 0, + "slot": "257", + "type": "t_bytes32", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:51" + }, + { + "label": "validatorsPerOperatorLimit", + "offset": 0, + "slot": "258", + "type": "t_uint32", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:53" + }, + { + "label": "declareOperatorFeePeriod", + "offset": 4, + "slot": "258", + "type": "t_uint64", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:54" + }, + { + "label": "executeOperatorFeePeriod", + "offset": 12, + "slot": "258", + "type": "t_uint64", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:55" + }, + { + "label": "operatorMaxFeeIncrease", + "offset": 20, + "slot": "258", + "type": "t_uint64", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:56" + }, + { + "label": "minimumBlocksBeforeLiquidation", + "offset": 0, + "slot": "259", + "type": "t_uint64", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:57" + }, + { + "label": "minimumLiquidationCollateral", + "offset": 8, + "slot": "259", + "type": "t_uint64", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:58" + }, + { + "label": "dao", + "offset": 0, + "slot": "260", + "type": "t_struct(DAO)2637_storage", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:60" + }, + { + "label": "_token", + "offset": 0, + "slot": "261", + "type": "t_contract(IERC20)2095", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:61" + }, + { + "label": "network", + "offset": 0, + "slot": "262", + "type": "t_struct(Network)2644_storage", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:62" + }, + { + "label": "__gap", + "offset": 0, + "slot": "263", + "type": "t_array(t_uint256)50_storage", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:66" + } + ], + "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_bytes32": { + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_contract(IERC20)2095": { + "label": "contract IERC20", + "numberOfBytes": "20" + }, + "t_mapping(t_bytes32,t_bytes32)": { + "label": "mapping(bytes32 => bytes32)", + "numberOfBytes": "32" + }, + "t_mapping(t_bytes32,t_struct(Validator)2591_storage)": { + "label": "mapping(bytes32 => struct ISSVNetworkCore.Validator)", + "numberOfBytes": "32" + }, + "t_mapping(t_uint64,t_address)": { + "label": "mapping(uint64 => address)", + "numberOfBytes": "32" + }, + "t_mapping(t_uint64,t_struct(Operator)2612_storage)": { + "label": "mapping(uint64 => struct ISSVNetworkCore.Operator)", + "numberOfBytes": "32" + }, + "t_mapping(t_uint64,t_struct(OperatorFeeChangeRequest)2619_storage)": { + "label": "mapping(uint64 => struct ISSVNetworkCore.OperatorFeeChangeRequest)", + "numberOfBytes": "32" + }, + "t_struct(Counter)2148_storage": { + "label": "struct Counters.Counter", + "members": [ + { + "label": "_value", + "type": "t_uint256", + "offset": 0, + "slot": "0" + } + ], + "numberOfBytes": "32" + }, + "t_struct(DAO)2637_storage": { + "label": "struct ISSVNetworkCore.DAO", + "members": [ + { + "label": "validatorCount", + "type": "t_uint32", + "offset": 0, + "slot": "0" + }, + { + "label": "balance", + "type": "t_uint64", + "offset": 4, + "slot": "0" + }, + { + "label": "block", + "type": "t_uint64", + "offset": 12, + "slot": "0" + } + ], + "numberOfBytes": "32" + }, + "t_struct(Network)2644_storage": { + "label": "struct ISSVNetworkCore.Network", + "members": [ + { + "label": "networkFee", + "type": "t_uint64", + "offset": 0, + "slot": "0" + }, + { + "label": "networkFeeIndex", + "type": "t_uint64", + "offset": 8, + "slot": "0" + }, + { + "label": "networkFeeIndexBlockNumber", + "type": "t_uint64", + "offset": 16, + "slot": "0" + } + ], + "numberOfBytes": "32" + }, + "t_struct(Operator)2612_storage": { + "label": "struct ISSVNetworkCore.Operator", + "members": [ + { + "label": "owner", + "type": "t_address", + "offset": 0, + "slot": "0" + }, + { + "label": "fee", + "type": "t_uint64", + "offset": 20, + "slot": "0" + }, + { + "label": "validatorCount", + "type": "t_uint32", + "offset": 28, + "slot": "0" + }, + { + "label": "snapshot", + "type": "t_struct(Snapshot)2601_storage", + "offset": 0, + "slot": "1" + } + ], + "numberOfBytes": "64" + }, + "t_struct(OperatorFeeChangeRequest)2619_storage": { + "label": "struct ISSVNetworkCore.OperatorFeeChangeRequest", + "members": [ + { + "label": "fee", + "type": "t_uint64", + "offset": 0, + "slot": "0" + }, + { + "label": "approvalBeginTime", + "type": "t_uint64", + "offset": 8, + "slot": "0" + }, + { + "label": "approvalEndTime", + "type": "t_uint64", + "offset": 16, + "slot": "0" + } + ], + "numberOfBytes": "32" + }, + "t_struct(Snapshot)2601_storage": { + "label": "struct ISSVNetworkCore.Snapshot", + "members": [ + { + "label": "block", + "type": "t_uint64", + "offset": 0, + "slot": "0" + }, + { + "label": "index", + "type": "t_uint64", + "offset": 8, + "slot": "0" + }, + { + "label": "balance", + "type": "t_uint64", + "offset": 16, + "slot": "0" + } + ], + "numberOfBytes": "32" + }, + "t_struct(Validator)2591_storage": { + "label": "struct ISSVNetworkCore.Validator", + "members": [ + { + "label": "owner", + "type": "t_address", + "offset": 0, + "slot": "0" + }, + { + "label": "active", + "type": "t_bool", + "offset": 20, + "slot": "0" + } + ], + "numberOfBytes": "32" + }, + "t_uint256": { + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint32": { + "label": "uint32", + "numberOfBytes": "4" + }, + "t_uint64": { + "label": "uint64", + "numberOfBytes": "8" + }, + "t_uint8": { + "label": "uint8", + "numberOfBytes": "1" + } + } + } + }, + "106a1e0908460b53147eafb4015f9beae2025df135b0a046f54cfb62b99ab5c4": { + "address": "0x8383d719377047b1B8824CbB7f8ba7f24F12c715", + "txHash": "0x923fe64b46b47b4a91612bb457980cca97017d569c91ed2343ec7ad04cac8693", + "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:62", + "retypedFrom": "bool" + }, + { + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:67" + }, + { + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)50_storage", + "contract": "ERC1967UpgradeUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol:211" + }, + { + "label": "__gap", + "offset": 0, + "slot": "51", + "type": "t_array(t_uint256)50_storage", + "contract": "UUPSUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol:107" + }, + { + "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(SSVNetwork)5302", + "contract": "SSVNetworkViews", + "src": "contracts/SSVNetworkViews.sol:21" + }, + { + "label": "__gap", + "offset": 0, + "slot": "252", + "type": "t_array(t_uint256)50_storage", + "contract": "SSVNetworkViews", + "src": "contracts/SSVNetworkViews.sol:25" + } + ], + "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(SSVNetwork)5302": { + "label": "contract SSVNetwork", + "numberOfBytes": "20" + }, + "t_uint256": { + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint8": { + "label": "uint8", + "numberOfBytes": "1" + } + } + } } } } diff --git a/contracts/ISSVNetwork.sol b/contracts/ISSVNetwork.sol index 8291380d..2e3cdc4b 100644 --- a/contracts/ISSVNetwork.sol +++ b/contracts/ISSVNetwork.sol @@ -16,12 +16,7 @@ interface ISSVNetwork is ISSVNetworkCore { * @param publicKey Operator's public key. Will be used to encrypt secret shares of validators keys. * @param fee Operator's fee. */ - event OperatorAdded( - uint64 indexed operatorId, - address indexed owner, - bytes publicKey, - uint256 fee - ); + event OperatorAdded(uint64 indexed operatorId, address indexed owner, bytes publicKey, uint256 fee); /** * @dev Emitted when operator has been removed. @@ -98,10 +93,7 @@ interface ISSVNetwork is ISSVNetworkCore { event ClusterDeposited(address indexed owner, uint64[] operatorIds, uint256 value, Cluster cluster); - event FeeRecipientAddressUpdated( - address indexed owner, - address recipientAddress - ); + event FeeRecipientAddressUpdated(address indexed owner, address recipientAddress); /****************/ /* Initializers */ diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index 60f99851..f692926b 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -46,8 +46,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { mapping(uint64 => address) public operatorsWhitelist; mapping(uint64 => OperatorFeeChangeRequest) public operatorFeeChangeRequests; mapping(bytes32 => bytes32) public clusters; - //TODO Change the name to be public - mapping(bytes32 => Validator) public _validatorPKs; + mapping(bytes32 => Validator) public validatorPKs; bytes32 public version; @@ -189,10 +188,10 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { _validateOperatorIds(operatorsLength); _validatePublicKey(publicKey); - if (_validatorPKs[keccak256(publicKey)].owner != address(0)) { + if (validatorPKs[keccak256(publicKey)].owner != address(0)) { revert ValidatorAlreadyExists(); } - _validatorPKs[keccak256(publicKey)] = Validator({owner: msg.sender, active: true}); + validatorPKs[keccak256(publicKey)] = Validator({owner: msg.sender, active: true}); bytes32 hashedCluster = keccak256(abi.encodePacked(msg.sender, operatorIds)); @@ -302,7 +301,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { Cluster memory cluster ) external override { bytes32 hashedValidator = keccak256(publicKey); - address validatorOwner = _validatorPKs[hashedValidator].owner; + address validatorOwner = validatorPKs[hashedValidator].owner; if (validatorOwner == address(0)) { revert ValidatorDoesNotExist(); } @@ -345,7 +344,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { --cluster.validatorCount; - delete _validatorPKs[hashedValidator]; + delete validatorPKs[hashedValidator]; clusters[hashedCluster] = keccak256( abi.encodePacked( diff --git a/contracts/SSVNetworkViews.sol b/contracts/SSVNetworkViews.sol index 48c2bd47..66885cc4 100644 --- a/contracts/SSVNetworkViews.sol +++ b/contracts/SSVNetworkViews.sol @@ -37,7 +37,7 @@ contract SSVNetworkViews is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwor /*************************************/ function getValidator(bytes calldata publicKey) external view override returns (address, bool) { - (address owner, bool active) = _ssvNetwork._validatorPKs(keccak256(publicKey)); + (address owner, bool active) = _ssvNetwork.validatorPKs(keccak256(publicKey)); return (owner, active); } diff --git a/scripts/deploy-all.ts b/scripts/deploy-all.ts index 348c965d..adaf91b6 100644 --- a/scripts/deploy-all.ts +++ b/scripts/deploy-all.ts @@ -1,7 +1,7 @@ import { ethers, upgrades } from 'hardhat'; async function deploy() { - const ssvTokenAddress = process.env.SSVTOKEN_ADDRESS; + const ssvTokenAddress = process.env.SSV_TOKEN_ADDRESS; const [deployer] = await ethers.getSigners(); console.log(`Deploying contracts with the account:${deployer.address}`); @@ -15,7 +15,8 @@ async function deploy() { process.env.OPERATOR_MAX_FEE_INCREASE, process.env.DECLARE_OPERATOR_FEE_PERIOD, process.env.EXECUTE_OPERATOR_FEE_PERIOD, - process.env.MINIMUM_BLOCKS_BEFORE_LIQUIDATION + process.env.MINIMUM_BLOCKS_BEFORE_LIQUIDATION, + process.env.MINIMUM_LIQUIDATION_COLLATERAL ], { kind: "uups" From 79f2086f8253b43a04f35c4d2351ffa942e53996 Mon Sep 17 00:00:00 2001 From: Marco Date: Thu, 16 Mar 2023 15:10:24 +0100 Subject: [PATCH 146/149] v0.3.0-rc.0 --- .env.example | 2 +- .openzeppelin/goerli.json | 446 +++++++++++++++++++++++++++++++ contracts/ISSVNetworkCore.sol | 1 - contracts/SSVNetwork.sol | 4 +- contracts/SSVNetworkViews.sol | 13 +- test/helpers/contract-helpers.ts | 2 +- test/operators/update-fee.ts | 8 +- 7 files changed, 458 insertions(+), 18 deletions(-) diff --git a/.env.example b/.env.example index 11e886bb..1e1982fe 100644 --- a/.env.example +++ b/.env.example @@ -6,7 +6,7 @@ GAS_PRICE= GAS= ETHERSCAN_KEY= SSV_TOKEN_ADDRESS= -MINIMUM_BLOCKS_BEFORE_LIQUIDATION=100 +MINIMUM_BLOCKS_BEFORE_LIQUIDATION=100800 MINIMUM_LIQUIDATION_COLLATERAL=200000000 OPERATOR_MAX_FEE_INCREASE=3 DECLARE_OPERATOR_FEE_PERIOD=259200 # 3 days diff --git a/.openzeppelin/goerli.json b/.openzeppelin/goerli.json index 8530f23d..67a92f8a 100644 --- a/.openzeppelin/goerli.json +++ b/.openzeppelin/goerli.json @@ -20,6 +20,16 @@ "address": "0x8dB45282d7C4559fd093C26f677B3837a5598914", "txHash": "0xb8a3be822bd5dda92d8a03a0ced6dbac1f60aedacf4970ef912a81e25cbc5bec", "kind": "uups" + }, + { + "address": "0x78ccf8eD5A7324866B1F663938dc0923bd2Fa8Df", + "txHash": "0x4fda09cc41369a54f3b750f8f757f01721427f4f81c9f3a9924ef94d7f971e63", + "kind": "uups" + }, + { + "address": "0x4935780f792bBc06BBbA6933d900698F7E74a51a", + "txHash": "0x54836afb5d593fce4c5aa4ee36c1d6c34d1b6f379984301632e0c96d1ecb3d7e", + "kind": "uups" } ], "impls": { @@ -1962,6 +1972,442 @@ } } } + }, + "2eb98242bc5110431e468ef0b6b4893fc5af474b8bfada3b85b4ffdbf6fbaf5c": { + "address": "0xDea29CF8d8769c0b015360636E07e5f9953F2dDd", + "txHash": "0xb03f69580afbd2d728030fc53fc391f071b75176e05876113a044ab9d74bf99f", + "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:62", + "retypedFrom": "bool" + }, + { + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:67" + }, + { + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)50_storage", + "contract": "ERC1967UpgradeUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol:211" + }, + { + "label": "__gap", + "offset": 0, + "slot": "51", + "type": "t_array(t_uint256)50_storage", + "contract": "UUPSUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol:107" + }, + { + "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": "lastOperatorId", + "offset": 0, + "slot": "251", + "type": "t_struct(Counter)2148_storage", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:39" + }, + { + "label": "operators", + "offset": 0, + "slot": "252", + "type": "t_mapping(t_uint64,t_struct(Operator)2612_storage)", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:45" + }, + { + "label": "operatorsWhitelist", + "offset": 0, + "slot": "253", + "type": "t_mapping(t_uint64,t_address)", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:46" + }, + { + "label": "operatorFeeChangeRequests", + "offset": 0, + "slot": "254", + "type": "t_mapping(t_uint64,t_struct(OperatorFeeChangeRequest)2619_storage)", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:47" + }, + { + "label": "clusters", + "offset": 0, + "slot": "255", + "type": "t_mapping(t_bytes32,t_bytes32)", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:48" + }, + { + "label": "validatorPKs", + "offset": 0, + "slot": "256", + "type": "t_mapping(t_bytes32,t_struct(Validator)2591_storage)", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:49" + }, + { + "label": "version", + "offset": 0, + "slot": "257", + "type": "t_bytes32", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:51" + }, + { + "label": "validatorsPerOperatorLimit", + "offset": 0, + "slot": "258", + "type": "t_uint32", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:53" + }, + { + "label": "declareOperatorFeePeriod", + "offset": 4, + "slot": "258", + "type": "t_uint64", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:54" + }, + { + "label": "executeOperatorFeePeriod", + "offset": 12, + "slot": "258", + "type": "t_uint64", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:55" + }, + { + "label": "operatorMaxFeeIncrease", + "offset": 20, + "slot": "258", + "type": "t_uint64", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:56" + }, + { + "label": "minimumBlocksBeforeLiquidation", + "offset": 0, + "slot": "259", + "type": "t_uint64", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:57" + }, + { + "label": "minimumLiquidationCollateral", + "offset": 8, + "slot": "259", + "type": "t_uint64", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:58" + }, + { + "label": "dao", + "offset": 0, + "slot": "260", + "type": "t_struct(DAO)2637_storage", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:60" + }, + { + "label": "_token", + "offset": 0, + "slot": "261", + "type": "t_contract(IERC20)2095", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:61" + }, + { + "label": "network", + "offset": 0, + "slot": "262", + "type": "t_struct(Network)2644_storage", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:62" + }, + { + "label": "__gap", + "offset": 0, + "slot": "263", + "type": "t_array(t_uint256)50_storage", + "contract": "SSVNetwork", + "src": "contracts/SSVNetwork.sol:66" + } + ], + "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_bytes32": { + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_contract(IERC20)2095": { + "label": "contract IERC20", + "numberOfBytes": "20" + }, + "t_mapping(t_bytes32,t_bytes32)": { + "label": "mapping(bytes32 => bytes32)", + "numberOfBytes": "32" + }, + "t_mapping(t_bytes32,t_struct(Validator)2591_storage)": { + "label": "mapping(bytes32 => struct ISSVNetworkCore.Validator)", + "numberOfBytes": "32" + }, + "t_mapping(t_uint64,t_address)": { + "label": "mapping(uint64 => address)", + "numberOfBytes": "32" + }, + "t_mapping(t_uint64,t_struct(Operator)2612_storage)": { + "label": "mapping(uint64 => struct ISSVNetworkCore.Operator)", + "numberOfBytes": "32" + }, + "t_mapping(t_uint64,t_struct(OperatorFeeChangeRequest)2619_storage)": { + "label": "mapping(uint64 => struct ISSVNetworkCore.OperatorFeeChangeRequest)", + "numberOfBytes": "32" + }, + "t_struct(Counter)2148_storage": { + "label": "struct Counters.Counter", + "members": [ + { + "label": "_value", + "type": "t_uint256", + "offset": 0, + "slot": "0" + } + ], + "numberOfBytes": "32" + }, + "t_struct(DAO)2637_storage": { + "label": "struct ISSVNetworkCore.DAO", + "members": [ + { + "label": "validatorCount", + "type": "t_uint32", + "offset": 0, + "slot": "0" + }, + { + "label": "balance", + "type": "t_uint64", + "offset": 4, + "slot": "0" + }, + { + "label": "block", + "type": "t_uint64", + "offset": 12, + "slot": "0" + } + ], + "numberOfBytes": "32" + }, + "t_struct(Network)2644_storage": { + "label": "struct ISSVNetworkCore.Network", + "members": [ + { + "label": "networkFee", + "type": "t_uint64", + "offset": 0, + "slot": "0" + }, + { + "label": "networkFeeIndex", + "type": "t_uint64", + "offset": 8, + "slot": "0" + }, + { + "label": "networkFeeIndexBlockNumber", + "type": "t_uint64", + "offset": 16, + "slot": "0" + } + ], + "numberOfBytes": "32" + }, + "t_struct(Operator)2612_storage": { + "label": "struct ISSVNetworkCore.Operator", + "members": [ + { + "label": "owner", + "type": "t_address", + "offset": 0, + "slot": "0" + }, + { + "label": "fee", + "type": "t_uint64", + "offset": 20, + "slot": "0" + }, + { + "label": "validatorCount", + "type": "t_uint32", + "offset": 28, + "slot": "0" + }, + { + "label": "snapshot", + "type": "t_struct(Snapshot)2601_storage", + "offset": 0, + "slot": "1" + } + ], + "numberOfBytes": "64" + }, + "t_struct(OperatorFeeChangeRequest)2619_storage": { + "label": "struct ISSVNetworkCore.OperatorFeeChangeRequest", + "members": [ + { + "label": "fee", + "type": "t_uint64", + "offset": 0, + "slot": "0" + }, + { + "label": "approvalBeginTime", + "type": "t_uint64", + "offset": 8, + "slot": "0" + }, + { + "label": "approvalEndTime", + "type": "t_uint64", + "offset": 16, + "slot": "0" + } + ], + "numberOfBytes": "32" + }, + "t_struct(Snapshot)2601_storage": { + "label": "struct ISSVNetworkCore.Snapshot", + "members": [ + { + "label": "block", + "type": "t_uint64", + "offset": 0, + "slot": "0" + }, + { + "label": "index", + "type": "t_uint64", + "offset": 8, + "slot": "0" + }, + { + "label": "balance", + "type": "t_uint64", + "offset": 16, + "slot": "0" + } + ], + "numberOfBytes": "32" + }, + "t_struct(Validator)2591_storage": { + "label": "struct ISSVNetworkCore.Validator", + "members": [ + { + "label": "owner", + "type": "t_address", + "offset": 0, + "slot": "0" + }, + { + "label": "active", + "type": "t_bool", + "offset": 20, + "slot": "0" + } + ], + "numberOfBytes": "32" + }, + "t_uint256": { + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint32": { + "label": "uint32", + "numberOfBytes": "4" + }, + "t_uint64": { + "label": "uint64", + "numberOfBytes": "8" + }, + "t_uint8": { + "label": "uint8", + "numberOfBytes": "1" + } + } + } } } } diff --git a/contracts/ISSVNetworkCore.sol b/contracts/ISSVNetworkCore.sol index cc3c2f5c..e7a5562c 100644 --- a/contracts/ISSVNetworkCore.sol +++ b/contracts/ISSVNetworkCore.sol @@ -82,6 +82,5 @@ interface ISSVNetworkCore { error ExceedValidatorLimit(); error TokenTransferFailed(); error SameFeeChangeNotAllowed(); - error ZeroFeeIncreaseNotAllowed(); error FeeIncreaseNotAllowed(); } diff --git a/contracts/SSVNetwork.sol b/contracts/SSVNetwork.sol index f692926b..d09412ae 100644 --- a/contracts/SSVNetwork.sol +++ b/contracts/SSVNetwork.sol @@ -29,7 +29,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { /* Constants */ /*************/ - uint64 private constant MINIMAL_LIQUIDATION_THRESHOLD = 6_570; + uint64 private constant MINIMAL_LIQUIDATION_THRESHOLD = 100_800; uint64 private constant MINIMAL_OPERATOR_FEE = 100_000_000; /********************/ @@ -744,7 +744,7 @@ contract SSVNetwork is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwork { if (operatorFee == shrunkFee) { revert SameFeeChangeNotAllowed(); } else if (shrunkFee != 0 && operatorFee == 0) { - revert ZeroFeeIncreaseNotAllowed(); + revert FeeIncreaseNotAllowed(); } // @dev 100% = 10000, 10% = 1000 - using 10000 to represent 2 digit precision diff --git a/contracts/SSVNetworkViews.sol b/contracts/SSVNetworkViews.sol index 66885cc4..fb174cac 100644 --- a/contracts/SSVNetworkViews.sol +++ b/contracts/SSVNetworkViews.sol @@ -64,15 +64,10 @@ contract SSVNetworkViews is UUPSUpgradeable, Ownable2StepUpgradeable, ISSVNetwor return (fee.expand(), approvalBeginTime, approvalEndTime); } - function getOperatorById( - uint64 operatorId - ) external view override returns (address, uint256, uint32, bool, bool) { - ( - address operatorOwner, - uint64 fee, - uint32 validatorCount, - Snapshot memory snapshot - ) = _ssvNetwork.operators(operatorId); + function getOperatorById(uint64 operatorId) external view override returns (address, uint256, uint32, bool, bool) { + (address operatorOwner, uint64 fee, uint32 validatorCount, Snapshot memory snapshot) = _ssvNetwork.operators( + operatorId + ); bool isPrivate = _ssvNetwork.operatorsWhitelist(operatorId) == address(0) ? false : true; bool isActive = snapshot.block == 0 ? false : true; diff --git a/test/helpers/contract-helpers.ts b/test/helpers/contract-helpers.ts index 1dde634a..bad585b2 100644 --- a/test/helpers/contract-helpers.ts +++ b/test/helpers/contract-helpers.ts @@ -68,7 +68,7 @@ export const initializeContract = async () => { declareOperatorFeePeriod: 3600, // HOUR executeOperatorFeePeriod: 86400, // DAY minimalOperatorFee: 100000000, - minimalBlocksBeforeLiquidation: 6570, + minimalBlocksBeforeLiquidation: 100800, minimumLiquidationCollateral: 60000000 }; diff --git a/test/operators/update-fee.ts b/test/operators/update-fee.ts index b1f10a60..3ade38eb 100644 --- a/test/operators/update-fee.ts +++ b/test/operators/update-fee.ts @@ -78,12 +78,12 @@ describe('Operator Fee Tests', () => { )).to.be.revertedWithCustomError(ssvNetworkContract, 'OperatorDoesNotExist'); }); - it('Declare fee when previously set to zero reverts "ZeroFeeIncreaseNotAllowed"', async () => { + it('Declare fee when previously set to zero reverts "FeeIncreaseNotAllowed"', async () => { await ssvNetworkContract.connect(helpers.DB.owners[2]).declareOperatorFee(1, 0); await progressTime(helpers.CONFIG.declareOperatorFeePeriod); await ssvNetworkContract.connect(helpers.DB.owners[2]).executeOperatorFee(1); await expect(ssvNetworkContract.connect(helpers.DB.owners[2]).declareOperatorFee(1, initialFee + initialFee / 10 - )).to.be.revertedWithCustomError(ssvNetworkContract, 'ZeroFeeIncreaseNotAllowed'); + )).to.be.revertedWithCustomError(ssvNetworkContract, 'FeeIncreaseNotAllowed'); }); it('Declare same fee value as actual reverts "SameFeeChangeNotAllowed"', async () => { @@ -94,12 +94,12 @@ describe('Operator Fee Tests', () => { )).to.be.revertedWithCustomError(ssvNetworkContract, 'SameFeeChangeNotAllowed'); }); - it('Declare fee after registering an operator with zero fee reverts "ZeroFeeIncreaseNotAllowed"', async () => { + it('Declare fee after registering an operator with zero fee reverts "FeeIncreaseNotAllowed"', async () => { await ssvNetworkContract.connect(helpers.DB.owners[2]).registerOperator( helpers.DataGenerator.publicKey(0), 0); await expect(ssvNetworkContract.connect(helpers.DB.owners[2]).declareOperatorFee(2, initialFee + initialFee / 10 - )).to.be.revertedWithCustomError(ssvNetworkContract, 'ZeroFeeIncreaseNotAllowed'); + )).to.be.revertedWithCustomError(ssvNetworkContract, 'FeeIncreaseNotAllowed'); }); it('Declare fee above the operators max fee increase limit reverts "FeeExceedsIncreaseLimit"', async () => { From 514884702fbc2606688330d2913f46cd718b6c18 Mon Sep 17 00:00:00 2001 From: Marco Date: Fri, 17 Mar 2023 14:24:47 +0100 Subject: [PATCH 147/149] update test helper --- test/helpers/utils.ts | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/test/helpers/utils.ts b/test/helpers/utils.ts index f1bf131d..9c4c4703 100644 --- a/test/helpers/utils.ts +++ b/test/helpers/utils.ts @@ -3,20 +3,20 @@ declare let ethers: any; export const strToHex = (str: any) => `0x${Buffer.from(str, 'utf8').toString('hex')}`; -export const asciiToHex = (str: any) => { +export const asciiToHex = (str: any) => { const arr1 = []; - for (let n = 0, l = str.length; n < l; n ++) { + for (let n = 0, l = str.length; n < l; n++) { const hex = Number(str.charCodeAt(n)).toString(16); arr1.push(hex); } return arr1.join(''); }; -export const blockNumber = async function() { +export const blockNumber = async function () { return await ethers.provider.getBlockNumber(); }; -export const progress = async function(time: any, blocks: any, func: any = null) { +export const progress = async function (time: any, blocks: any, func: any = null) { let snapshot; if (func) { @@ -25,14 +25,8 @@ export const progress = async function(time: any, blocks: any, func: any = null) if (time) { await network.provider.send('evm_increaseTime', [time]); - if (!blocks) { - await network.provider.send('evm_mine', []); - } - } - - for (let index = 0; index < blocks; ++index) { - await network.provider.send('evm_mine', []); } + await network.provider.send('hardhat_mine', ['0x' + blocks.toString(16)]); if (func) { await func(); @@ -40,15 +34,15 @@ export const progress = async function(time: any, blocks: any, func: any = null) } }; -export const progressTime = async function(time: any, func: any = null) { +export const progressTime = async function (time: any, func: any = null) { return progress(time, 1, func); }; -export const progressBlocks = async function(blocks: any, func = null) { +export const progressBlocks = async function (blocks: any, func = null) { return progress(0, blocks, func); }; -export const snapshot = async function(func: any) { +export const snapshot = async function (func: any) { return progress(0, 0, func); }; From 07fc333f01a7453b7bdc5fe23e416408baaf7ea7 Mon Sep 17 00:00:00 2001 From: Marco Date: Fri, 17 Mar 2023 14:51:09 +0100 Subject: [PATCH 148/149] stage/testnet/main deployments/upgrades hardhat tasks support quash 74bdd53 test --- hardhat.config.ts | 3 +- scripts/deploy-all.ts | 51 ------------- scripts/{bash => }/deploy_manager | 76 ++++++++++++------- scripts/{bash => }/tag-version | 28 +++---- scripts/validate-upgrade-ssv-network-views.ts | 14 ---- scripts/validate-upgrade-ssv-network.ts | 14 ---- tasks/{deploy-all.ts => deploy.ts} | 9 ++- tasks/utils.ts | 7 +- tasks/validate.ts | 25 ++++++ 9 files changed, 91 insertions(+), 136 deletions(-) delete mode 100644 scripts/deploy-all.ts rename scripts/{bash => }/deploy_manager (62%) rename scripts/{bash => }/tag-version (92%) delete mode 100644 scripts/validate-upgrade-ssv-network-views.ts delete mode 100644 scripts/validate-upgrade-ssv-network.ts rename tasks/{deploy-all.ts => deploy.ts} (89%) create mode 100644 tasks/validate.ts diff --git a/hardhat.config.ts b/hardhat.config.ts index 3e6489cb..23768f70 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -7,7 +7,8 @@ import 'hardhat-tracer'; import '@nomiclabs/hardhat-solhint'; import 'hardhat-contract-sizer'; import 'hardhat-storage-layout-changes'; -import './tasks/deploy-all' +import './tasks/deploy' +import './tasks/validate' import './tasks/upgrade-ssvnetwork' import './tasks/upgrade-ssvnetworkviews' diff --git a/scripts/deploy-all.ts b/scripts/deploy-all.ts deleted file mode 100644 index adaf91b6..00000000 --- a/scripts/deploy-all.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { ethers, upgrades } from 'hardhat'; - -async function deploy() { - const ssvTokenAddress = process.env.SSV_TOKEN_ADDRESS; - - const [deployer] = await ethers.getSigners(); - console.log(`Deploying contracts with the account:${deployer.address}`); - - // deploy SSVNetwork - const ssvNetworkFactory = await ethers.getContractFactory('SSVNetwork'); - console.log(`Deploying SSVNetwork with ssvToken ${ssvTokenAddress}`); - const ssvNetwork = await upgrades.deployProxy(ssvNetworkFactory, [ - process.env.INITIAL_VERSION, - ssvTokenAddress, - process.env.OPERATOR_MAX_FEE_INCREASE, - process.env.DECLARE_OPERATOR_FEE_PERIOD, - process.env.EXECUTE_OPERATOR_FEE_PERIOD, - process.env.MINIMUM_BLOCKS_BEFORE_LIQUIDATION, - process.env.MINIMUM_LIQUIDATION_COLLATERAL - ], - { - kind: "uups" - }); - await ssvNetwork.deployed(); - console.log(`SSVNetwork proxy deployed to: ${ssvNetwork.address}`); - - let implAddress = await upgrades.erc1967.getImplementationAddress(ssvNetwork.address); - console.log(`SSVNetwork implementation deployed to: ${implAddress}`); - - // deploy SSVNetworkViews - const ssvViewsFactory = await ethers.getContractFactory('SSVNetworkViews'); - console.log(`Deploying SSVNetworkViews with SSVNetwork ${ssvNetwork.address}...`); - const viewsContract = await upgrades.deployProxy(ssvViewsFactory, [ - ssvNetwork.address - ], - { - kind: "uups" - }); - await viewsContract.deployed(); - console.log(`SSVNetworkViews proxy deployed to: ${viewsContract.address}`); - - implAddress = await upgrades.erc1967.getImplementationAddress(viewsContract.address); - console.log(`SSVNetworkViews implementation deployed to: ${implAddress}`); -} - -deploy() - .then(() => process.exit(0)) - .catch(error => { - console.error(error); - process.exit(1); - }); diff --git a/scripts/bash/deploy_manager b/scripts/deploy_manager similarity index 62% rename from scripts/bash/deploy_manager rename to scripts/deploy_manager index b1879437..757183c5 100644 --- a/scripts/bash/deploy_manager +++ b/scripts/deploy_manager @@ -2,7 +2,9 @@ ABIDIR="" ACTION="" -NETWORK="localhost" +NETWORK="" +CONTRACT="" +ENVIRONMENT="develop" CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD) VERSIONTYPE="" @@ -21,15 +23,19 @@ help() { echo " sh deploy_manger [-n|--network] [-a|--action] [-t|--version-type]" echo echo "Options:" - echo "-n,--network " - echo " Target network to run the deployment / upgrade." - echo " Possible values: [goerli | mainnet | localhost]" - echo " If ommited, defaults to localhost." + echo "-e,--environment " + echo " Target environment to run the deployment / upgrade." + echo " Possible values: [develop | stage | testnet | main]" + echo " If ommited, defaults to develop." echo - echo "-a,--action " + echo "-a,--action " echo " Action to perform." echo " Possible values: [deploy | upgrade]" echo + echo "-c,--contract " + echo " Contract to be used with the upgrade action." + echo " Possible values: [ssvnetwork | ssvnetworkviews]" + echo echo "-t,--version-type [major|minor|patch]" echo " Type of semantic version to create. Valid options are 'major', 'minor' or 'patch'" echo " major: Will bump up to next major release (i.e v1.0.0 -> v2.0.0)" @@ -37,7 +43,7 @@ help() { echo " patch: Will bump up to next patch release (i.e v1.0.2 -> v1.0.3)" echo " Rules:" echo " Tags created using 'stage' branch are treated as RCs (i.e v0.1.0-rc.0 -> v0.1.0-rc.1 ...)" - echo " Tags created using 'main' branch are treated as releases (i.e v0.1.0-rc.1 becomes v0.1.0)" + echo " Tags created using 'testnet' or 'main' branches are treated as releases (i.e v0.1.0-rc.1 becomes v0.1.0)" echo " In both cases, if a version-type parameter is passed, the rule is override (i.e v0.1.0-rc.2 -> -t minor -> v0.2.0-rc.0)" echo " Tags created using 'develop' branch are not tagged" echo " If ommited, will default to current version" @@ -53,8 +59,8 @@ while [[ "$#" -gt 0 ]]; do help exit ;; - -n | --network) - NETWORK=$2 + -e | --environment) + ENVIRONMENT=$2 ;; -t | --version-type) VERSIONTYPE=$2 @@ -62,6 +68,9 @@ while [[ "$#" -gt 0 ]]; do -a | --action) ACTION=$2 ;; + -c | --contract) + CONTRACT=$2 + ;; esac shift done @@ -71,13 +80,21 @@ if [ "$ACTION" == "" ]; then exit 1 fi -# Get the list of branches from the repository -BRANCHES=$(git branch --format='%(refname:short)' | grep -E '^(develop|stage|main)$') -select BRANCH in $BRANCHES; do - if [ ! -z "$BRANCH" ]; then - break - fi -done +if [ "$ENVIRONMENT" == "stage" ]; then + BRANCH="stage" + NETWORK="goerli" +elif [ "$ENVIRONMENT" == "testnet" ]; then + BRANCH="testnet" + NETWORK="goerli" +elif [ "$ENVIRONMENT" == "main" ]; then + BRANCH="main" + NETWORK="mainnet" +else + BRANCH="develop" + NETWORK="goerli" +fi + +echo "Using branch $BRANCH for environment $ENVIRONMENT" run_command() { if ! "$@"; then @@ -93,8 +110,8 @@ run_command npm ci -q --no-progress # Compile project run_command npx hardhat compile --force -# Only deployments for stage and main branches are tagged -if [[ $BRANCH == "stage" || $BRANCH == "main" ]]; then +# Only deployments for stage, testnet and main branches are tagged +if [[ $BRANCH == "stage" ||  $BRANCH == "testnet" || $BRANCH == "main" ]]; then run_command source ./tag-version -b "$BRANCH" -n -t "$VERSIONTYPE" else TAGVERSION="dev" @@ -102,28 +119,31 @@ fi if [ "$ACTION" == "deploy" ]; then # Run script to deploy the contracts - run_command npx hardhat --network "$NETWORK" deploy:contracts --tag "$TAGVERSION" + run_command npx hardhat --network "$NETWORK" deploy:all --tag "$TAGVERSION" elif [ "$ACTION" == "upgrade" ]; then - # Run script to upgrade the contracts - run_command npx hardhat --network "$NETWORK" upgrade:Lock --tag "$TAGVERSION" + if [[ "$CONTRACT" == "ssvnetwork" || "$CONTRACT" == "ssvnetworkviews" ]]; then + # Run script to upgrade the contracts + run_command npx hardhat --network "$NETWORK" upgrade:"$CONTRACT" --tag "$TAGVERSION" + else + echo "-- ERROR: Wrong CONTRACT value for upgrade action" + exit 1 + fi else echo "-- ERROR: Wrong ACTION value. Possible values: [deploy | upgrade]" exit 1 fi -if [[ $NETWORK == "mainnet" || $NETWORK == "goerli" ]]; then +if [[ "$ENVIRONMENT" == "stage" || "$ENVIRONMENT" == "testnet" || "$ENVIRONMENT" == "main" ]]; then # Update .openzeppelin metadata run_command git add .openzeppelin/"$NETWORK".json run_command git commit -m "Update .openzeppelin folder" run_command git push -u origin $branch - if [[ $BRANCH == "stage" || $BRANCH == "main" ]]; then - run_command source ./tag-version -b "$BRANCH" -t "$VERSIONTYPE" - fi - ABIDIR="docs/$NETWORK/abi/$TAGVERSION" + run_command source ./tag-version -b "$BRANCH" -t "$VERSIONTYPE" + ABIDIR="docs/$ENVIRONMENT/abi/$TAGVERSION" - run_command git checkout gh-pages + run_command git checkout contract-abi # Publish the ABI to a specific GitHub Pages location mkdir -p $ABIDIR @@ -131,7 +151,7 @@ if [[ $NETWORK == "mainnet" || $NETWORK == "goerli" ]]; then run_command git add $ABIDIR run_command git commit -m "Publish ABI for deployment to $NETWORK" - run_command git push -u -f origin gh-pages + run_command git push -u -f origin contract-abi fi run_command git checkout $CURRENT_BRANCH diff --git a/scripts/bash/tag-version b/scripts/tag-version similarity index 92% rename from scripts/bash/tag-version rename to scripts/tag-version index c381dfa9..dad6903a 100644 --- a/scripts/bash/tag-version +++ b/scripts/tag-version @@ -127,21 +127,15 @@ cd "${REPO_DIR}" if [ "$BRANCH" == "" ]; then conditional_echo "-- ERROR: BRANCH option is mandatory." exit 1 -elif [[ "$BRANCH" != "stage" && "$BRANCH" != "main" ]]; then - conditional_echo "-- ERROR: Wrong branch. Possible values: [stage | main] " +elif [[ "$BRANCH" != "stage" && "$BRANCH" != "testnet" && "$BRANCH" != "main" ]]; then + conditional_echo "-- ERROR: Wrong branch. Possible values: [stage | testnet | main] " exit 1 fi # Get current active branch CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD) -# Switch to production branch -if [ $CURRENT_BRANCH != "$BRANCH" ]; then - conditional_echo "- Switching from $CURRENT_BRANCH to $BRANCH branch. (stashing any local change)" - # stash any current work - git stash "${GITPARAMS[@]}" - # go to the production branch - git checkout $BRANCH "${GITPARAMS[@]}" -fi + +git checkout $BRANCH "${GITPARAMS[@]}" conditional_echo "- Updating local $BRANCH branch." # pull latest version of production branch @@ -203,12 +197,16 @@ if [ -z "$NEEDSTAG" ]; then RC_SUFFIX=$(echo $PREVIOUS_TAG | sed -n 's/.*-rc\.\([[:digit:]]\{1,\}\)$/\1/p') NEW_RC_SUFFIX=$((RC_SUFFIX + 1)) NEWTAG="v${VNUM1}.${VNUM2}.${VNUM3}-rc.${NEW_RC_SUFFIX}" + elif [[ $PREVIOUS_RELEASE == "v${VNUM1}.${VNUM2}.${VNUM3}" ]]; then + NEWTAG="v${VNUM1}.${VNUM2}.$((VNUM3 + 1))-rc.0" else NEWTAG="v${VNUM1}.${VNUM2}.${VNUM3}-rc.0" fi - elif [ "$BRANCH" == "main" ]; then + elif [[ "$BRANCH" == "main" || "$BRANCH" == "testnet" ]]; then if [[ $PREVIOUS_RELEASE == "v${VNUM1}.${VNUM2}.${VNUM3}-rc"* ]]; then NEWTAG="v${VNUM1}.${VNUM2}.${VNUM3}" + elif [[ $PREVIOUS_RELEASE == "v${VNUM1}.${VNUM2}.${VNUM3}" ]]; then + NEWTAG="v${VNUM1}.${VNUM2}.$((VNUM3 + 1))" else NEWTAG="v${VNUM1}.${VNUM2}.${VNUM3}" fi @@ -245,12 +243,6 @@ else exit 1 fi -# Switch to back to original branch -if [ $CURRENT_BRANCH != "$BRANCH" ]; then - conditional_echo "- Switching back to $CURRENT_BRANCH branch. (restoring local changes)" - git checkout "$CURRENT_BRANCH" "${GITPARAMS[@]}" - # remove the stash - git stash pop "${GITPARAMS[@]}" -fi +git checkout "$CURRENT_BRANCH" "${GITPARAMS[@]}" export TAGVERSION=$NEWTAG diff --git a/scripts/validate-upgrade-ssv-network-views.ts b/scripts/validate-upgrade-ssv-network-views.ts deleted file mode 100644 index 6c488c04..00000000 --- a/scripts/validate-upgrade-ssv-network-views.ts +++ /dev/null @@ -1,14 +0,0 @@ -async function validateUpgradeSSVNetworkViews() { - const proxyAddress = process.env.SSVNETWORKVIEWS_PROXY_ADDRESS; - const SSVNetworkViews = await ethers.getContractFactory("SSVNetworkViews_V2"); - - await upgrades.validateUpgrade(proxyAddress, SSVNetworkViews, { kind: 'uups' }); - console.log("Contract validation finished"); -} - -validateUpgradeSSVNetworkViews() - .then(() => process.exit(0)) - .catch(error => { - console.error(error); - process.exit(1); - }); \ No newline at end of file diff --git a/scripts/validate-upgrade-ssv-network.ts b/scripts/validate-upgrade-ssv-network.ts deleted file mode 100644 index da3b8bfd..00000000 --- a/scripts/validate-upgrade-ssv-network.ts +++ /dev/null @@ -1,14 +0,0 @@ -async function validateUpgradeSSVNetwork() { - const proxyAddress = process.env.SSVNETWORK_PROXY_ADDRESS; - const SSVNetwork = await ethers.getContractFactory("SSVNetwork_V2"); - - await upgrades.validateUpgrade(proxyAddress, SSVNetwork, { kind: 'uups' }); - console.log("Contract validation finished"); -} - -validateUpgradeSSVNetwork() - .then(() => process.exit(0)) - .catch(error => { - console.error(error); - process.exit(1); - }); \ No newline at end of file diff --git a/tasks/deploy-all.ts b/tasks/deploy.ts similarity index 89% rename from tasks/deploy-all.ts rename to tasks/deploy.ts index 2b05dc22..b1d34f92 100644 --- a/tasks/deploy-all.ts +++ b/tasks/deploy.ts @@ -3,9 +3,9 @@ import { generateABI } from "./utils"; task("deploy:all", "Deploy SSVNetwork and SSVNetworkViews contracts") .addParam("tag", "Version of the contract") - .setAction(async ({ tag: version }, hre) => { + .setAction(async ({ tag }, hre) => { try { - const ssvTokenAddress = process.env.SSVTOKEN_ADDRESS; + const ssvTokenAddress = process.env.SSV_TOKEN_ADDRESS; const [deployer] = await ethers.getSigners(); console.log(`Deploying contracts with the account:${deployer.address}`); @@ -14,12 +14,13 @@ task("deploy:all", "Deploy SSVNetwork and SSVNetworkViews contracts") const ssvNetworkFactory = await ethers.getContractFactory('SSVNetwork'); console.log(`Deploying SSVNetwork with ssvToken ${ssvTokenAddress}`); const ssvNetwork = await upgrades.deployProxy(ssvNetworkFactory, [ - version, + tag, ssvTokenAddress, process.env.OPERATOR_MAX_FEE_INCREASE, process.env.DECLARE_OPERATOR_FEE_PERIOD, process.env.EXECUTE_OPERATOR_FEE_PERIOD, - process.env.MINIMUM_BLOCKS_BEFORE_LIQUIDATION + process.env.MINIMUM_BLOCKS_BEFORE_LIQUIDATION, + process.env.MINIMUM_LIQUIDATION_COLLATERAL ], { kind: "uups" diff --git a/tasks/utils.ts b/tasks/utils.ts index ad174d41..d2de3836 100644 --- a/tasks/utils.ts +++ b/tasks/utils.ts @@ -8,12 +8,7 @@ export const generateABI = async (hre: any, contractNames: string[], contractAdd for (let i = 0; i < contractNames.length; i++) { const { abi, contractName } = await hre.artifacts.readArtifact(contractNames[i]); - const metadata = { - address: contractAddresses[i], - abi - }; - - await fs.writeFile(`abi/${contractName}.json`, `${JSON.stringify(metadata, null, 2)}\n`, { flag: 'w' }); + await fs.writeFile(`abi/${contractName}.json`, `${JSON.stringify(abi, null, 2)}\n`, { flag: 'w' }); } } } \ No newline at end of file diff --git a/tasks/validate.ts b/tasks/validate.ts new file mode 100644 index 00000000..c9dcfdde --- /dev/null +++ b/tasks/validate.ts @@ -0,0 +1,25 @@ +import { task } from "hardhat/config"; + +task("validate:upgrade", "Validate SSVNetwork or SSVNetworkViews contract upgrade") + .addParam("type", "Contract type [ssvnetwork | ssvnetworkviews]") + .addParam("name", "Contract name to validate") + .setAction(async ({ type, name }) => { + try { + let proxyAddress; + if(type === 'ssvnetwork') { + proxyAddress = process.env.SSVNETWORK_PROXY_ADDRESS; + } else if(type === 'ssvnetworkviews') { + proxyAddress = process.env.SSVNETWORKVIEWS_PROXY_ADDRESS; + } else { + throw new Error(`Wrong contract type ${type}`); + } + + const contract = await ethers.getContractFactory(name); + + await upgrades.validateUpgrade(proxyAddress, contract, { kind: 'uups' }); + console.log("Contract validation finished"); + } catch (error) { + console.error(error); + process.exitCode = 1; + } + }); \ No newline at end of file From dc6fa9c942224992bace604edc6d1567d4045eac Mon Sep 17 00:00:00 2001 From: Marco Date: Wed, 22 Mar 2023 14:06:17 +0100 Subject: [PATCH 149/149] create DEPLOYMENT.md doc, minor changes --- .env.example | 1 - DEPLOYMENT.md | 121 +++++++++++++++++++++++++++++++++ README.md | 147 +---------------------------------------- scripts/deploy_manager | 10 +-- 4 files changed, 130 insertions(+), 149 deletions(-) create mode 100644 DEPLOYMENT.md diff --git a/.env.example b/.env.example index 1e1982fe..5193e61e 100644 --- a/.env.example +++ b/.env.example @@ -13,4 +13,3 @@ DECLARE_OPERATOR_FEE_PERIOD=259200 # 3 days EXECUTE_OPERATOR_FEE_PERIOD=345600 # 4 days SSVNETWORK_PROXY_ADDRESS= SSVNETWORKVIEWS_PROXY_ADDRESS= -INITIAL_VERSION="0.3.0" diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md new file mode 100644 index 00000000..ee60189f --- /dev/null +++ b/DEPLOYMENT.md @@ -0,0 +1,121 @@ +# SSV Contracts deployment guide + +## Overview + +The current structure of the repository branches conforms to the configuration of the target environments as follows: + +- `develop`: is the day-to-day working branch, where features are added. +- `stage`: the code here represents a Release Candidate of the next version. Target environment: stage. +- `testnet`: after the stage version is approved, the code is pushed to this branch with the goal of deploying it to the testnet environment +- `main`: once the testnet release is approved, then the contracts are deployed to mainnet. + +To generate version numbers, [Sematic Versioning](https://semver.org/) is used, following these rules: + +- Tags created using `stage` environment are treated as RCs (i.e `v0.1.0-rc.0` -> `v0.1.0-rc.1` ...) +- Tags created using `testnet` or `main` envs are treated as releases (i.e `v0.1.0-rc.1` becomes `v0.1.0`) +- In both cases, if the user forces an update in the version number (major | minor | patch) via parameter, the rule is overriden (i.e `v0.1.0-rc.2` -> `-t minor` -> `v0.2.0-rc.0`) +- Tags created using develop environment are not tagged + +When the target environment is `stage`, `testnet` or `main`, an annotated semantic version tag for current branch is created and the ABI of the contracrs is published to this location in [`contract-abi`](https://github.com/bloxapp/ssv-network/tree/contract-abi) branch: + +- `docs//abi/` when using `stage`, `testnet` or `main` +- `docs/dev/abi` when using develop + +## Deployment guide + +First of all, commit all changes in your current and target branch. + +To deploy / upgrade contracts, the script `deploy_manger` is used. You can see all options with: +``` +sh deploy_manger -h +``` + +Example of deploying contracts to `stage` environment (Goerli). Previous version: `v0.3.0` + +Set all the paramenters in `.env` file: +```bash +[NETWORK]_ETH_NODE_URL=# RPC URL of the node +[NETWORK]_OWNER_PRIVATE_KEY=# Private key of the deployer account, without 0x prefix +GAS_PRICE=# example 30000000000 +GAS=# example 500000 +ETHERSCAN_KEY=# etherescan API key +SSV_TOKEN_ADDRESS=# etherescan API key +MINIMUM_BLOCKS_BEFORE_LIQUIDATION=# custom param +MINIMUM_LIQUIDATION_COLLATERAL=# custom param +OPERATOR_MAX_FEE_INCREASE=# custom param +DECLARE_OPERATOR_FEE_PERIOD=# custom param +EXECUTE_OPERATOR_FEE_PERIOD=# custom param +SSVNETWORK_PROXY_ADDRESS=# SSVNetwork proxy address, set it when upgrading +SSVNETWORKVIEWS_PROXY_ADDRESS=# SSVNetworkViews proxy address, set it when upgrading +``` + +```bash +sh deploy_manager -e stage -a deploy +``` + +The output of this command is composed by some information logs and this ones about the deployment to Goerli network: + +```bash +Deploying contracts with the account: 0xf39Fd6... +Deploying SSVNetwork with ssvToken 0x6471F7... +SSVNetwork proxy deployed to: 0x8A7916... +SSVNetwork implementation deployed to: 0x2279B7... +Deploying SSVNetworkViews with SSVNetwork 0x8A7916... +SSVNetworkViews proxy deployed to: 0xB7f8BC... +SSVNetworkViews implementation deployed to: 0x610178... +``` + +Now, the tag `v0.3.1-rc.0` is created and the ABIs are published to `https://github.com/bloxapp/ssv-network/tree/contract-abi/docs/stage/abi/v0.3.1-rc.0` + +**Verify implementation contract on etherscan** + +To verify an implementation contract, run this: +```bash +npx hardhat verify --network +``` +where in this case `network`must be goerli and `implementation-address` is the one showed on the deployment script. + +Output of this action will be: +```bash +Nothing to compile +No need to generate any newer typings. +Successfully submitted source code for contract +contracts/SSVNetwork.sol:SSVNetwork at 0x2279B7... +for verification on the block explorer. Waiting for verification result... + +Successfully verified contract SSVNetwork on Etherscan. +https://goerli.etherscan.io/address/0x2279b7dea8ba1bb59a0056f6a5eabd443d47ec78#code +``` +After this action, you can go to the proxy contract in Etherscan and start interacting with it. + +## Upgrade guide + +`deploy_manager` script is used to upgrade `SSVNetwork` and `SSVNetworkViews`. + +Pre-requisites: +- Commit all changes in current and target branch. +- Fill `.env` file properly, specially the values for `SSVNETWORK_PROXY_ADDRESS` / `SSVNETWORKVIEWS_PROXY_ADDRESS` +- Update `upgrade-ssvnetwork` / `upgrade-ssvnetworkviews` tasks as needed. + +Example of upgrading `SSVNetwork` contract to `stage` environment (Goerli). Previous version: `v0.3.1-rc0` + +```bash +sh deploy_manager -e stage -a upgrade -c ssvnetwork +``` + +This will generate a new tag version `v0.3.1-rc1` and publish the ABI to `https://github.com/bloxapp/ssv-network/tree/contract-abi/docs/stage/abi/v0.3.1-rc.1` + +## Overriding semantic versioning + +If a specific upgrade is wanted for the next version, like going from `v0.2.1` to `v1.0.0`, the `-t,--version-type [major|minor|patch]` parameter of `deploy_manager` script can be used. Examples: + +- `v0.2.1`: `deploy_manager -t major` -> `v1.0.0` +- `v0.3.0-rc0`: `deploy_manager -t minor` -> `v0.4.0-rc0` +- `v2.0.0`: `deploy_manager -t patch` -> `v2.0.1` + + +**Important note on upgrades** + +Pay special attention when changing storage layout, for example adding new storage variables in `SSVNetwork` and `SSVNetworkViews` (base) contracts. + +There is a state variable `uint256[50] __gap;` that you should reduce the size according to the size of the new variables added. More info: [Storage Gaps](https://docs.openzeppelin.com/upgrades-plugins/1.x/writing-upgradeable#storage-gaps) \ No newline at end of file diff --git a/README.md b/README.md index aa8cb349..82448b38 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ npx hardhat compile ## CI/CD Workflow -### Step 1: Test contracts +### Test contracts Take a look at `test/` folder, you should be able to find tests related to specific actions. @@ -54,150 +54,9 @@ npx hardhat test ``` -### Step 2: Deploy new contracts - -We use [UUPS Proxy Upgrade pattern](https://docs.openzeppelin.com/contracts/4.x/api/proxy) for smart contracts to have an ability to upgrade them later. - -To deploy the contract we will use a Hardhat script. Inside `scripts/` you will find: -- `deploy-all.ts`: Deploys both `SSVNetwork.sol` and `SSVNetworkViews.sol`. -- `validate-upgrade-ssv-network`: Validates if `SSVNetwork` is upgrade safe. -- `validate-upgrade-ssv-network-views`: Validates if `SSVNetworkViews` is upgrade safe. -- `upgrade-ssv-network`: Upgrades `SSVNetwork` contract. -- `upgrade-ssv-network-views`: Upgrades `SSVNetworkViews` contract. - -As general rule, you can target any network configured in the `hardhat.config.ts`, specifying the right [network]_ETH_NODE_URL and [network]_OWNER_PRIVATE_KEY in `.env` file. - -#### Deploy SSV Network - -Before run the cli command, in `.env` need to add the following seetings: - - -```sh -[NETWORK]_ETH_NODE_URL=# RPC URL of the node -[NETWORK]_OWNER_PRIVATE_KEY=# Private key of the deployer account, without 0x prefix -GAS_PRICE=# example 30000000000 -GAS=# example 8000000 -ETHERSCAN_KEY=# etherescan API key -SSVTOKEN_ADDRESS=#SSV Token contract address -MINIMUM_BLOCKS_BEFORE_LIQUIDATION=# custom param -OPERATOR_MAX_FEE_INCREASE=# custom param -DECLARE_OPERATOR_FEE_PERIOD=# custom param -EXECUTE_OPERATOR_FEE_PERIOD=# custom param -VALIDATORS_PER_OPERATOR_LIMIT=# custom param -REGISTERED_OPERATORS_PER_ACCOUNT_LIMIT=# custom param -SSVNETWORK_PROXY_ADDRESS=# SSVNetwork proxy address, set it when runnning upgrade-ssv-network.ts script -SSVNETWORKVIEWS_PROXY_ADDRESS=# SSVNetworkViews proxy address, set it when runnning upgrade-ssv-network-views.ts script -INITIAL_VERSION=# SSVNetwork initial version, example: "1.0.0" -``` - - Then run: -```sh -npx hardhat run --network scripts/deploy-all.ts -``` - -Output of this action will be: - -```sh -Deploying contracts with the account:0xf39Fd6... -Deploying SSVNetwork with ssvToken 0x6471F7... -SSVNetwork proxy deployed to: 0x8A7916... -SSVNetwork implementation deployed to: 0x2279B7... -Deploying SSVNetworkViews with SSVNetwork 0x8A7916... -SSVNetworkViews proxy deployed to: 0xB7f8BC... -SSVNetworkViews implementation deployed to: 0x610178... -``` - -You can now go to Etherscan and see: -- `SSVNetwork` proxy contract is deployed to the address shown previously in `SSVNetwork proxy deployed to` -- `SSVNetwork` implementation contract is deployed to the address shown previously in `SSVNetwork implementation deployed to` -- `SSVNetworkViews` proxy contract is deployed to the address shown previously in `SSVNetworkViews proxy deployed to` -- `SSVNetworkViews` implementation contract is deployed to the address shown previously in `SSVNetworkViews implementation deployed to` - -Example: [https://goerli.etherscan.io/address/0xe2e28fdea8ba1bb59a0056f6a5eabd443d47ec78](https://goerli.etherscan.io/address/0xe2e28fdea8ba1bb59a0056f6a5eabd443d47ec78) - -### Step 3: Verify implementation contract on etherscan (each time after upgrade) - -Open `.openzeppelin/.json` file and find `[impls..address]` value which is implementation smart contract address. -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. - - -To verify an implementation contract, run this: - -```sh -npx hardhat verify --network -``` - -Output of this action will be: -```sh -Nothing to compile -No need to generate any newer typings. -Successfully submitted source code for contract -contracts/SSVNetwork.sol:SSVNetwork at 0x2279B7... -for verification on the block explorer. Waiting for verification result... - -Successfully verified contract SSVNetwork on Etherscan. -https://goerli.etherscan.io/address/0x2279b7dea8ba1bb59a0056f6a5eabd443d47ec78#code -``` - -After this action, you can go to the proxy contract in Etherscan and start interacting with it. - -## Upgrade process -### Upgrade SSVNetwork contract - -Once we have tested our new implementation, for example `contracts/SSVNetwork_V2.sol` we can prepare the upgrade. - - -In `.env` file, remember to set `SSVNETWORK_PROXY_ADDRESS` with the address of the `SSVNetwork` proxy contract. - -To validate the upgrade before running it: - -```sh -npx hardhat run --network scripts/validate-upgrade-ssv-network.ts -``` - -To fire the upgrade process: - -```sh -npx hardhat run --network scripts/upgrade-ssv-network.ts -``` - -If you get the error: - -` -Error: invalid hex string ... -reason: 'invalid hex string', -code: 'INVALID_ARGUMENT', -` - -Set or change the parameters `GAS_PRICE` and `GAS` in `.env` file. - -### Upgrade SSVNetworkViews contract - -Once we have tested our new implementation, for example `contracts/SSVNetworkViews_V2.sol` we can prepare the upgrade. - -In `.env` file, remember to set `SSVNETWORKVIEWS_PROXY_ADDRESS` with the address of the `SSVNetworkViews` proxy . - -To validate the upgrade before running it: - -```sh -npx hardhat run --network scripts/validate-upgrade-ssv-network-views.ts -``` - -To fire the upgrade process: - -```sh -npx hardhat run --network scripts/upgrade-ssv-network-views.ts -``` - -**Important note on upgrades** - -Pay special attention when changing storage layout, for example adding new storage variables in `SSVNetwork` and `SSVNetworkViews` (base) contracts. - -There is a state variable `uint256[50] __gap;` that you should reduce the size according to the size of the new variables added. More info: [Storage Gaps](https://docs.openzeppelin.com/upgrades-plugins/1.x/writing-upgradeable#storage-gaps) +### Deployment / upgrade process +Please check the [deployment document](./DEPLOYMENT.md) for a detailed step by step guide. ## Modify the limit of validators that an operator can manage In `SSVNetwork` contract, the state variable `validatorsPerOperatorLimit` is used to represent the máximum number of validators that can be registered per operator. Its default value is `2000`. diff --git a/scripts/deploy_manager b/scripts/deploy_manager index 757183c5..c02b2458 100644 --- a/scripts/deploy_manager +++ b/scripts/deploy_manager @@ -14,13 +14,13 @@ help() { echo echo "SSV Deployment manager." echo "Run deployment / upgrade of the branch selected." - echo "When the target network is testnet (goerli) or mainnet, an annotated semantic version tag for current branch is created" + echo "When the target environment is testnet (goerli) or mainnet, an annotated semantic version tag for current branch is created" echo "and the ABI is published to this location in gh-pages: " - echo "'docs//abi/' when using stage or main" - echo "'docs//abi/dev' when using develop" + echo "'docs//abi/' when using stage or main" + echo "'docs//abi/dev' when using develop" echo echo "Usage:" - echo " sh deploy_manger [-n|--network] [-a|--action] [-t|--version-type]" + echo " sh deploy_manager [-e|--environment] [-a|--action] [-t|--version-type]" echo echo "Options:" echo "-e,--environment " @@ -152,6 +152,8 @@ if [[ "$ENVIRONMENT" == "stage" || "$ENVIRONMENT" == "testnet" || "$ENVIRONMENT" run_command git add $ABIDIR run_command git commit -m "Publish ABI for deployment to $NETWORK" run_command git push -u -f origin contract-abi + + rm -fr $ABIDIR fi run_command git checkout $CURRENT_BRANCH