diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index c564b167..fae81542 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,4 +1,4 @@ -* @payvint @kladkogex @DimaStebaev @yavrsky +* @payvint @DmytroNazarenko @DimaStebaev @yavrsky /docs/ @skalenetwork/docowners *.md @skalenetwork/docowners /dictionaries/ @skalenetwork/docowners diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index e2600a75..2b2f7d87 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -18,50 +18,93 @@ env: jobs: build: runs-on: ubuntu-latest - env: - DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} - DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} - steps: - - uses: actions/checkout@v2 - - name: Get yarn cache directory path - id: yarn-cache-dir-path - run: echo "::set-output name=dir::$(yarn cache dir)" + if: github.event_name != 'pull_request' || github.event.pull_request.merged == true - - uses: actions/cache@v2 - id: yarn-cache - with: - path: ${{ steps.yarn-cache-dir-path.outputs.dir }} - key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} - restore-keys: | - ${{ runner.os }}-yarn- + outputs: + version: ${{ steps.version.outputs.version }} + + steps: + - uses: actions/checkout@v4 - name: Install NODE JS - uses: actions/setup-node@v2 + uses: actions/setup-node@v3 with: node-version: ${{ env.NODE_VERSION }} + cache: 'yarn' - name: Install project run: yarn install - - name: Build and publish container + - name: Calculate version + id: version run: | export BRANCH=${GITHUB_REF##*/} echo "Branch $BRANCH" export VERSION=$(bash ./scripts/calculate_version.sh) echo "Version $VERSION" echo "VERSION=$VERSION" >> $GITHUB_ENV + echo "version=$VERSION" >> "$GITHUB_OUTPUT" ( test $BRANCH = "stable" || test $BRANCH = "master" && export PRERELEASE=false ) || export PRERELEASE=true echo "PRERELEASE=$PRERELEASE" >> $GITHUB_ENV - bash ./scripts/build_and_publish.sh + + - name: Generate ABI + run: npx hardhat run scripts/generateAbi.ts + + - name: Store artifacts + uses: actions/upload-artifact@v4 + with: + name: data + path: data - name: Create Release - id: create_release - uses: actions/create-release@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: ncipollo/release-action@v1 with: - tag_name: ${{ env.VERSION }} - release_name: ${{ env.VERSION }} - draft: false + tag: ${{ env.VERSION }} prerelease: ${{ env.PRERELEASE }} + artifacts: "data/skale-manager-*-abi.json" + + docker: + runs-on: ubuntu-latest + + if: github.event_name != 'pull_request' || github.event.pull_request.merged == true + + steps: + - uses: actions/checkout@v4 + + - name: Build and publish container + env: + DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} + DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} + run: | + export BRANCH=${GITHUB_REF##*/} + echo "Branch $BRANCH" + export VERSION=$(bash ./scripts/calculate_version.sh) + echo "Version $VERSION" + bash ./scripts/build_and_publish.sh + + abi: + runs-on: ubuntu-latest + + needs: + build + + env: + VERSION: ${{ needs.build.outputs.version }} + + steps: + - uses: actions/checkout@v4 + with: + ref: abi + + - name: Load artifacts + uses: actions/download-artifact@v4 + with: + name: data + + - name: Commit ABI + uses: EndBug/add-and-commit@v9 + with: + default_author: github_actions + message: "Add ABI for version ${{ env.VERSION }}" + add: "*-abi.json" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 86ddb738..cad355a1 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -23,36 +23,19 @@ jobs: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} steps: - - uses: actions/checkout@v2 - - - name: Get yarn cache directory path - id: yarn-cache-dir-path - run: echo "::set-output name=dir::$(yarn cache dir)" - - - uses: actions/cache@v2 - id: yarn-cache - with: - path: ${{ steps.yarn-cache-dir-path.outputs.dir }} - key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} - restore-keys: | - ${{ runner.os }}-yarn- - - - uses: actions/cache@v2 - with: - path: ~/.cache/pip - key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} - restore-keys: | - ${{ runner.os }}-pip- + - uses: actions/checkout@v4 - name: Install NODE JS - uses: actions/setup-node@v2 + uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} + cache: 'yarn' - name: Set up Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: ${{ env.PYTHON_VERSION }} + cache: 'pip' - name: Install project run: yarn install @@ -74,6 +57,9 @@ jobs: NODE_VERSION: ${{ matrix.node-version }} run: ./scripts/test_upgrade.sh + - name: Test ABI ageneration + run: npx hardhat run scripts/generateAbi.ts + - name: Run tests run: npx hardhat coverage --solcoverjs .solcover.js diff --git a/Dockerfile b/Dockerfile index 054488d8..a178b410 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM node:16 +FROM node:18 RUN mkdir /usr/src/manager WORKDIR /usr/src/manager diff --git a/README.md b/README.md index c08059e2..9099b45b 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # SKALE Manager -[![Discord](https://img.shields.io/discord/534485763354787851.svg)](https://discord.gg/vvUtWJB) [![Build Status](https://travis-ci.com/skalenetwork/skale-manager.svg?branch=develop)](https://travis-ci.com/skalenetwork/skale-manager) [![codecov](https://codecov.io/gh/skalenetwork/skale-manager/branch/develop/graph/badge.svg)](https://codecov.io/gh/skalenetwork/skale-manager) +[![Discord](https://img.shields.io/discord/534485763354787851.svg)](https://discord.gg/vvUtWJB) +[![Build Status](https://github.com/skalenetwork/skale-manager/actions/workflows/test.yml/badge.svg)](https://github.com/skalenetwork/skale-manager/actions) +[![codecov](https://codecov.io/gh/skalenetwork/skale-manager/branch/develop/graph/badge.svg)](https://codecov.io/gh/skalenetwork/skale-manager) A smart contract system that orchestrates and operates the SKALE Network. @@ -10,14 +12,10 @@ SKALE Manager controls Nodes, Validators, and SKALE chains. It also contains con ## Upgradeability -This system is upgradeable and uses the Separate Data and Functionality approach. - -1) ContractManager: main contract of Separate Data and Functionality approach. It stores all contract's addresses in the SKALE Manager system. -2) Permissions: connectable contract to every SKALE Manager contract except ContractManager. It stores address of ContractManager and a modifier that forbids calls only from the given contract +This system is upgradeable and uses the transparent proxy approach. ## Structure -All interaction with this system is possible only through SKALE Manager. For all statuses and data, see Data contracts. The main purpose of this system: 1) Control Nodes in the system: @@ -36,23 +34,28 @@ The main purpose of this system: ## Deployment -To create your network, see examples in `truffle-config.js` - Create a `.env` file with following data: - ENDPOINT="your endpoint" - PRIVATE_KEY="your private key" - NETWORK="your created network" +```.env +ENDPOINT="{your endpoint}" +PRIVATE_KEY="{your private key}" +GASPRICE={gas price in wei} # optional +ETHERSCAN={etherscan API key to verify contracts} # optional +``` -- deploy: +deploy: - truffle migrate --network +```bash +npx hardhat run migrations/deploy.ts --network custom +``` ## Test -_Need to deploy the system first_ +The is no need to deploy the system first - yarn test +```bash +yarn test +``` ## License diff --git a/VERSION b/VERSION index 81c871de..1cac385c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.10.0 +1.11.0 diff --git a/contracts/ConstantsHolder.sol b/contracts/ConstantsHolder.sol index f65f316f..b30d1315 100644 --- a/contracts/ConstantsHolder.sol +++ b/contracts/ConstantsHolder.sol @@ -81,9 +81,9 @@ contract ConstantsHolder is Permissions, IConstantsHolder { uint256 public constant ALRIGHT_DELTA = 134161; uint256 public constant BROADCAST_DELTA = 177490; uint256 public constant COMPLAINT_BAD_DATA_DELTA = 80995; - uint256 public constant PRE_RESPONSE_DELTA = 100061; - uint256 public constant COMPLAINT_DELTA = 106611; - uint256 public constant RESPONSE_DELTA = 48132; + uint256 public constant PRE_RESPONSE_DELTA = 114620; + uint256 public constant COMPLAINT_DELTA = 203463; + uint256 public constant RESPONSE_DELTA = 55111; // MSR - Minimum staking requirement uint256 public msr; diff --git a/contracts/NodeRotation.sol b/contracts/NodeRotation.sol index 517bbc55..acd21fbf 100644 --- a/contracts/NodeRotation.sol +++ b/contracts/NodeRotation.sol @@ -198,7 +198,7 @@ contract NodeRotation is Permissions, INodeRotation { ) public override - allowTwo("SkaleDKG", "SkaleManager") + allowThree("SkaleDKG", "SkaleManager", "Schains") returns (uint256 newNode) { ISchainsInternal schainsInternal = ISchainsInternal(contractManager.getContract("SchainsInternal")); @@ -297,6 +297,7 @@ contract NodeRotation is Permissions, INodeRotation { } leavingHistory[nodeIndex].push(LeavingHistory({schainHash: schainHash, finishedRotation: finishTimestamp})); require(_rotations[schainHash].newNodeIndexes.add(newNodeIndex), "New node was already added"); + _rotations[schainHash].nodeIndex = nodeIndex; _rotations[schainHash].newNodeIndex = newNodeIndex; _rotations[schainHash].rotationCounter++; _rotations[schainHash].previousNodes[newNodeIndex] = nodeIndex; diff --git a/contracts/Nodes.sol b/contracts/Nodes.sol index 65e7160b..7b899c7b 100644 --- a/contracts/Nodes.sol +++ b/contracts/Nodes.sol @@ -732,6 +732,26 @@ contract Nodes is Permissions, INodes { return nodeExtras[nodeIndex].lastChangeIpTime; } + function isNodeVisible(uint256 nodeIndex) + external + view + override + checkNodeExists(nodeIndex) + returns (bool visible) + { + return !_invisible[nodeIndex]; + } + + function getFreeSpace(uint256 nodeIndex) + external + view + override + checkNodeExists(nodeIndex) + returns (uint8 freeSpace) + { + return spaceOfNodes[nodeIndex].freeSpace; + } + /** * @dev Returns the Validator ID for a given node. */ diff --git a/contracts/Schains.sol b/contracts/Schains.sol index edc173c2..04f796b0 100644 --- a/contracts/Schains.sol +++ b/contracts/Schains.sol @@ -200,7 +200,13 @@ contract Schains is Permissions, ISchains { ISchainsInternal schainsInternal = ISchainsInternal( contractManager.getContract("SchainsInternal")); require(schainsInternal.isAnyFreeNode(schainHash), "No free Nodes for new group formation"); - uint256 newNodeIndex = nodeRotation.selectNodeToGroup(schainHash); + uint256 newNodeIndex = nodeRotation.rotateNode( + skaleDKG.pendingToBeReplaced(schainHash), + schainHash, + false, + true + ); + skaleDKG.resetPendingToBeReplaced(schainHash); skaleDKG.openChannel(schainHash); emit NodeAdded(schainHash, newNodeIndex); } diff --git a/contracts/SchainsInternal.sol b/contracts/SchainsInternal.sol index 32e5c1ac..1d3c1585 100644 --- a/contracts/SchainsInternal.sol +++ b/contracts/SchainsInternal.sol @@ -24,13 +24,13 @@ pragma solidity 0.8.17; import { EnumerableSetUpgradeable } from "@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol"; -import { ISkaleDKG } from "@skalenetwork/skale-manager-interfaces/ISkaleDKG.sol"; import { INodes } from "@skalenetwork/skale-manager-interfaces/INodes.sol"; +import { ISkaleDKG } from "@skalenetwork/skale-manager-interfaces/ISkaleDKG.sol"; -import { IPruningSchainsInternal } from "./interfaces/IPruningSchainInternal.sol"; -import { Permissions } from "./Permissions.sol"; import { ConstantsHolder } from "./ConstantsHolder.sol"; +import { IPruningSchainsInternal } from "./interfaces/IPruningSchainInternal.sol"; import { IRandom, Random } from "./utils/Random.sol"; +import { Permissions } from "./Permissions.sol"; /** @@ -755,9 +755,18 @@ contract SchainsInternal is Permissions, IPruningSchainsInternal { * - Schain must exist */ function isAnyFreeNode(bytes32 schainHash) external view override schainExists(schainHash) returns (bool free) { + // TODO: + // Move this function to Nodes? INodes nodes = INodes(contractManager.getContract("Nodes")); uint8 space = schains[schainHash].partOfNode; - return nodes.countNodesWithFreeSpace(space) > 0; + uint256 numberOfCandidates = nodes.countNodesWithFreeSpace(space); + for (uint256 i = 0; i < _schainToExceptionNodes[schainHash].length; i++) { + uint256 nodeIndex = _schainToExceptionNodes[schainHash][i]; + if (space <= nodes.getFreeSpace(nodeIndex) && nodes.isNodeVisible(nodeIndex)) { + --numberOfCandidates; + } + } + return numberOfCandidates > 0; } /** diff --git a/contracts/SkaleDKG.sol b/contracts/SkaleDKG.sol index 64487423..38f28b1d 100644 --- a/contracts/SkaleDKG.sol +++ b/contracts/SkaleDKG.sol @@ -71,6 +71,8 @@ contract SkaleDKG is Permissions, ISkaleDKG { mapping(bytes32 => uint256) private _badNodes; + mapping(bytes32 => uint256) public override pendingToBeReplaced; + modifier correctGroup(bytes32 schainHash) { require(channels[schainHash].active, "Group is not created"); _; @@ -320,6 +322,10 @@ contract SkaleDKG is Permissions, ISkaleDKG { _badNodes[schainHash] = nodeIndex; } + function resetPendingToBeReplaced(bytes32 schainHash) external override allow("Schains") { + delete pendingToBeReplaced[schainHash]; + } + function finalizeSlashing(bytes32 schainHash, uint256 badNode) external override allow("SkaleDKG") { INodeRotation nodeRotation = INodeRotation(contractManager.getContract("NodeRotation")); ISchainsInternal schainsInternal = ISchainsInternal( @@ -328,7 +334,6 @@ contract SkaleDKG is Permissions, ISkaleDKG { emit BadGuy(badNode); emit FailedDKG(schainHash); - schainsInternal.makeSchainNodesInvisible(schainHash); if (schainsInternal.isAnyFreeNode(schainHash)) { uint256 newNode = nodeRotation.rotateNode( badNode, @@ -338,14 +343,10 @@ contract SkaleDKG is Permissions, ISkaleDKG { ); emit NewGuy(newNode); } else { + pendingToBeReplaced[schainHash] = badNode; _openChannel(schainHash); - schainsInternal.removeNodeFromSchain( - badNode, - schainHash - ); channels[schainHash].active = false; } - schainsInternal.makeSchainNodesVisible(schainHash); IPunisher(contractManager.getPunisher()).slash( INodes(contractManager.getContract("Nodes")).getValidatorId(badNode), ISlashingTable(contractManager.getContract("SlashingTable")).getPenalty("FailedDKG") @@ -595,7 +596,7 @@ contract SkaleDKG is Permissions, ISkaleDKG { ); } else if (context.dkgFunction == DkgFunction.Response){ wallets.refundGasBySchain( - schainHash, payable(msg.sender), gasTotal - gasleft() - context.delta, context.isDebt + schainHash, payable(msg.sender), gasTotal - gasleft() + context.delta, context.isDebt ); } else { wallets.refundGasBySchain( diff --git a/dictionaries/libraries.txt b/dictionaries/libraries.txt index 840b6da0..f4d45d39 100644 --- a/dictionaries/libraries.txt +++ b/dictionaries/libraries.txt @@ -21,6 +21,7 @@ mulmod muln nbconvert nbformat +nomicfoundation nomiclabs pygments pyplot diff --git a/hardhat.config.ts b/hardhat.config.ts index 5a24e312..ff03ec59 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -1,6 +1,6 @@ import { task, HardhatUserConfig } from "hardhat/config"; +import "@nomicfoundation/hardhat-chai-matchers"; import "@nomiclabs/hardhat-etherscan"; -import "@nomiclabs/hardhat-waffle"; import "@openzeppelin/hardhat-upgrades"; import '@typechain/hardhat' import "solidity-coverage"; @@ -78,7 +78,7 @@ const config: HardhatUserConfig = { settings: { optimizer:{ enabled: true, - runs: 200 + runs: 100 } } } diff --git a/package.json b/package.json index 359d3eaf..30b8d06d 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "@openzeppelin/contracts": "^4.9.3", "@openzeppelin/contracts-upgradeable": "^4.9.3", "@openzeppelin/hardhat-upgrades": "^1.14.0", - "@skalenetwork/skale-manager-interfaces": "3.0.0", + "@skalenetwork/skale-manager-interfaces": "^3.0.0-develop.2", "@skalenetwork/upgrade-tools": "^2.0.1", "@typechain/hardhat": "^7.0.0", "dotenv": "^16.3.1", @@ -53,8 +53,8 @@ "hardhat": "2.11.0 - 2.16.1" }, "devDependencies": { + "@nomicfoundation/hardhat-chai-matchers": "<2.0.0", "@nomiclabs/hardhat-etherscan": "^3.1.0", - "@nomiclabs/hardhat-waffle": "^2.0.2", "@typechain/ethers-v5": "^11.1.1", "@types/chai": "^4.3.6", "@types/chai-almost": "^1.0.1", @@ -64,6 +64,7 @@ "@types/mocha": "^9.1.1", "@types/node": "^20.8.7", "@types/sinon-chai": "^3.2.9", + "@types/underscore": "^1.11.15", "@typescript-eslint/eslint-plugin": "^5.62.0", "@typescript-eslint/parser": "^5.62.0", "bignumber.js": "^9.1.2", diff --git a/scripts/generateAbi.ts b/scripts/generateAbi.ts new file mode 100644 index 00000000..016a95cd --- /dev/null +++ b/scripts/generateAbi.ts @@ -0,0 +1,50 @@ +import { promises as fs } from 'fs'; +import { contracts } from "../migrations/deploy"; +import { ethers } from "hardhat"; +import { getAbi, getVersion } from '@skalenetwork/upgrade-tools'; +import { ContractFactory } from 'ethers'; +import { Libraries } from '@nomiclabs/hardhat-ethers/types'; + +async function main() { + const allContracts = contracts.concat(["SkaleToken", "TimeHelpersWithDebug"]) + const abi: {[name: string]: []} = {}; + const librariesRequirements: {[name: string]: string[]} = { + "Nodes": [ + "SegmentTree" + ], + "SkaleDKG": [ + "SkaleDkgAlright", + "SkaleDkgBroadcast", + "SkaleDkgComplaint", + "SkaleDkgPreResponse", + "SkaleDkgResponse" + ] + } + for (const contractName of allContracts) { + console.log(`Load ABI of ${contractName}`); + let factory: ContractFactory; + if (Object.keys(librariesRequirements).includes(contractName)) { + const libraries: Libraries = {}; + for(const library of librariesRequirements[contractName]) { + libraries[library] = ethers.constants.AddressZero; + } + factory = await ethers.getContractFactory(contractName, {libraries}); + } else { + factory = await ethers.getContractFactory(contractName); + } + abi[contractName] = getAbi(factory.interface); + } + const version = await getVersion(); + const filename = `data/skale-manager-${version}-abi.json`; + console.log(`Save to ${filename}`) + await fs.writeFile(filename, JSON.stringify(abi, null, 4)); +} + +if (require.main === module) { + main() + .then(() => process.exit(0)) + .catch(error => { + console.error(error); + process.exit(1); + }); +} diff --git a/test/SkaleDKG.ts b/test/SkaleDKG.ts index 6924264c..d186d0e4 100644 --- a/test/SkaleDKG.ts +++ b/test/SkaleDKG.ts @@ -1409,7 +1409,7 @@ describe("SkaleDKG", () => { badEncryptedSecretKeyContributions[indexes[0]] ) ); - + const response = await skaleDKG.connect(validators[0].nodeAddress).response( stringKeccak256(schainName), 0, @@ -1498,7 +1498,7 @@ describe("SkaleDKG", () => { ), "Broadcast 1" ); - + await reimbursed( await skaleDKG.connect(validators[1].nodeAddress).broadcast( stringKeccak256(schainName), @@ -1509,7 +1509,7 @@ describe("SkaleDKG", () => { ), "Broadcast 2" ); - + const complaintBadData = await skaleDKG.connect(validators[1].nodeAddress).complaintBadData( stringKeccak256(schainName), 1, @@ -1533,7 +1533,7 @@ describe("SkaleDKG", () => { ), "Pre response" ); - + const responseTx = await skaleDKG.connect(validators[0].nodeAddress).response( stringKeccak256(schainName), 0, @@ -1928,7 +1928,7 @@ describe("SkaleDKG", () => { ), "Alright" ); - + alrightPoss = await skaleDKG.connect(validators[index].nodeAddress).isAlrightPossible( stringKeccak256("New16NodeSchain"), i @@ -2381,7 +2381,7 @@ describe("SkaleDKG", () => { accusedNode ) ); - + const complaint = await skaleDKG.connect(validators[0].nodeAddress).complaint( stringKeccak256("New16NodeSchain"), 8, @@ -2454,8 +2454,8 @@ describe("SkaleDKG", () => { rotation.rotationCounter ); } - const accusedNode = "15"; - const complaintNode = "7"; + const accusedNode = 15; + const complaintNode = 7; await skipTime(1800); await reimbursed( await skaleDKG.connect(validators[0].nodeAddress).complaint( @@ -2465,7 +2465,8 @@ describe("SkaleDKG", () => { ) ); const space = await nodes.spaceOfNodes(accusedNode); - space.freeSpace.should.be.equal(128); + // The node is still a part of schain because can't be replaced + space.freeSpace.should.be.equal(0); const complaint = await skaleDKG.connect(validators[0].nodeAddress).complaint( stringKeccak256("New16NodeSchain"), @@ -2486,11 +2487,18 @@ describe("SkaleDKG", () => { domainName: "some.domain.name" } ); + const createdNode = 16; await schains.restartSchainCreation("New16NodeSchain"); + rotation = await nodeRotation.getRotation(stringKeccak256("New16NodeSchain")); + + expect(rotation.rotationCounter).to.be.equal(1); + expect(rotation.nodeIndex).to.be.equal(accusedNode); + expect(rotation.newNodeIndex).to.be.equal(createdNode); + for (let i = 0; i < 17; i++) { - if (i.toString() === accusedNode) { + if (i === accusedNode) { continue; } let index = 0; @@ -2507,7 +2515,7 @@ describe("SkaleDKG", () => { } let comPubKey; for (let i = 0; i < 17; i++) { - if (i.toString() === accusedNode) { + if (i === accusedNode) { continue; } comPubKey = await keyStorage.getCommonPublicKey(stringKeccak256("New16NodeSchain")); @@ -2605,7 +2613,7 @@ describe("SkaleDKG", () => { accusedNode ) ); - + const complaint = await skaleDKG.connect(validators[0].nodeAddress).complaint( stringKeccak256("New16NodeSchain"), 8, diff --git a/yarn.lock b/yarn.lock index 33763ce6..6ab4caf8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1287,6 +1287,17 @@ mcl-wasm "^0.7.1" rustbn.js "~0.2.0" +"@nomicfoundation/hardhat-chai-matchers@<2.0.0": + version "1.0.6" + resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-chai-matchers/-/hardhat-chai-matchers-1.0.6.tgz#72a2e312e1504ee5dd73fe302932736432ba96bc" + integrity sha512-f5ZMNmabZeZegEfuxn/0kW+mm7+yV7VNDxLpMOMGXWFJ2l/Ct3QShujzDRF9cOkK9Ui/hbDeOWGZqyQALDXVCQ== + dependencies: + "@ethersproject/abi" "^5.1.2" + "@types/chai-as-promised" "^7.1.3" + chai-as-promised "^7.1.1" + deep-eql "^4.0.1" + ordinal "^1.0.3" + "@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.1": version "0.1.1" resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.1.tgz#4c858096b1c17fe58a474fe81b46815f93645c15" @@ -1374,14 +1385,6 @@ table "^6.8.0" undici "^5.14.0" -"@nomiclabs/hardhat-waffle@^2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-waffle/-/hardhat-waffle-2.0.2.tgz#6030aa6fd9ea05327bf79d1107356af906d8b1e4" - integrity sha512-dnhry6Bj15O8L3pBksTuXfr4RAUIf+BxRxWJXiu+ioSawcQaOcNF4gfMxn6ik0auk3zrsAJLA6m9vqe87d4xvg== - dependencies: - "@types/sinon-chai" "^3.2.3" - "@types/web3" "1.0.19" - "@oclif/command@^1.8.0": version "1.8.16" resolved "https://registry.yarnpkg.com/@oclif/command/-/command-1.8.16.tgz#bea46f81b2061b47e1cda318a0b923e62ca4cc0c" @@ -1752,10 +1755,10 @@ dependencies: "@sinonjs/commons" "^1.7.0" -"@skalenetwork/skale-manager-interfaces@3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@skalenetwork/skale-manager-interfaces/-/skale-manager-interfaces-3.0.0.tgz#6ea1a0eae4a1684f6985a96057151f89adb77bf4" - integrity sha512-SyVA23+Jec72GxdqgiFwwEfF/PZrD2bFfI4rlpld1U+MURMFKm99eALRaKAIyqU3X3uH4ujNALjnJvCBE3DC8A== +"@skalenetwork/skale-manager-interfaces@^3.0.0-develop.2": + version "3.0.0-develop.2" + resolved "https://registry.yarnpkg.com/@skalenetwork/skale-manager-interfaces/-/skale-manager-interfaces-3.0.0-develop.2.tgz#100508cda8a675b62a28a76c7e526617240ffd0c" + integrity sha512-ua92l+QAfPymtWn8lLpoFUyZ1t4I5ae1RCHEU96aSfkA6hVqxiXCRXJzbcDJR0HPtvOmbgF/iKc/LXtCEe9rvA== "@skalenetwork/upgrade-tools@^2.0.1": version "2.0.1" @@ -1854,6 +1857,13 @@ dependencies: "@types/chai" "*" +"@types/chai-as-promised@^7.1.3": + version "7.1.8" + resolved "https://registry.yarnpkg.com/@types/chai-as-promised/-/chai-as-promised-7.1.8.tgz#f2b3d82d53c59626b5d6bbc087667ccb4b677fe9" + integrity sha512-ThlRVIJhr69FLlh6IctTXFkmhtP3NpMZ2QGq69StYLyKZFp/HOp1VdKZj7RvfNWYYcJ1xlbLGLLWj1UvP5u/Gw== + dependencies: + "@types/chai" "*" + "@types/chai-as-promised@^7.1.6": version "7.1.6" resolved "https://registry.yarnpkg.com/@types/chai-as-promised/-/chai-as-promised-7.1.6.tgz#3b08cbe1e7206567a480dc6538bade374b19e4e1" @@ -1979,7 +1989,7 @@ resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.1.tgz#0480eeb7221eb9bc398ad7432c9d7e14b1a5a367" integrity sha512-cJRQXpObxfNKkFAZbJl2yjWtJCqELQIdShsogr1d2MilP8dKD9TE/nEKHkJgUNHdGKCQaf9HbIynuV2csLGVLg== -"@types/sinon-chai@^3.2.3", "@types/sinon-chai@^3.2.9": +"@types/sinon-chai@^3.2.9": version "3.2.9" resolved "https://registry.yarnpkg.com/@types/sinon-chai/-/sinon-chai-3.2.9.tgz#71feb938574bbadcb176c68e5ff1a6014c5e69d4" integrity sha512-/19t63pFYU0ikrdbXKBWj9PCdnKyTd0Qkz0X91Ta081cYsq90OxYdcWwK/dwEoDa6dtXgj2HJfmzgq+QZTHdmQ== @@ -1994,18 +2004,10 @@ dependencies: "@sinonjs/fake-timers" "^7.1.0" -"@types/underscore@*": - version "1.11.4" - resolved "https://registry.yarnpkg.com/@types/underscore/-/underscore-1.11.4.tgz#62e393f8bc4bd8a06154d110c7d042a93751def3" - integrity sha512-uO4CD2ELOjw8tasUrAhvnn2W4A0ZECOvMjCivJr4gA9pGgjv+qxKWY9GLTMVEK8ej85BxQOocUyE7hImmSQYcg== - -"@types/web3@1.0.19": - version "1.0.19" - resolved "https://registry.yarnpkg.com/@types/web3/-/web3-1.0.19.tgz#46b85d91d398ded9ab7c85a5dd57cb33ac558924" - integrity sha512-fhZ9DyvDYDwHZUp5/STa9XW2re0E8GxoioYJ4pEUZ13YHpApSagixj7IAdoYH5uAK+UalGq6Ml8LYzmgRA/q+A== - dependencies: - "@types/bn.js" "*" - "@types/underscore" "*" +"@types/underscore@^1.11.15": + version "1.11.15" + resolved "https://registry.yarnpkg.com/@types/underscore/-/underscore-1.11.15.tgz#29c776daecf6f1935da9adda17509686bf979947" + integrity sha512-HP38xE+GuWGlbSRq9WrZkousaQ7dragtZCruBVMi0oX1migFZavZ3OROKHSkNp/9ouq82zrWtZpg18jFnVN96g== "@typescript-eslint/eslint-plugin@^5.62.0": version "5.62.0" @@ -4325,7 +4327,7 @@ deep-eql@^2.0.2: dependencies: type-detect "^3.0.0" -deep-eql@^4.1.2: +deep-eql@^4.0.1, deep-eql@^4.1.2: version "4.1.3" resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-4.1.3.tgz#7c7775513092f7df98d8df9996dd085eb668cc6d" integrity sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw== @@ -8577,6 +8579,11 @@ optionator@^0.9.3: prelude-ls "^1.2.1" type-check "^0.4.0" +ordinal@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/ordinal/-/ordinal-1.0.3.tgz#1a3c7726a61728112f50944ad7c35c06ae3a0d4d" + integrity sha512-cMddMgb2QElm8G7vdaa02jhUNbTSrhsgAGUz1OokD83uJTwSUn+nKoNoKVVaRa08yF6sgfO7Maou1+bgLd9rdQ== + os-homedir@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3"