diff --git a/abis/0.8.25/MechActivityChecker.json b/abis/0.8.25/MechActivityChecker.json new file mode 100644 index 0000000..d5f67eb --- /dev/null +++ b/abis/0.8.25/MechActivityChecker.json @@ -0,0 +1,111 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "MechActivityChecker", + "sourceName": "contracts/mech_usage/MechActivityChecker.sol", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_agentMech", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_livenessRatio", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "ZeroMechAgentAddress", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroValue", + "type": "error" + }, + { + "inputs": [], + "name": "agentMech", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "multisig", + "type": "address" + } + ], + "name": "getMultisigNonces", + "outputs": [ + { + "internalType": "uint256[]", + "name": "nonces", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256[]", + "name": "curNonces", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "lastNonces", + "type": "uint256[]" + }, + { + "internalType": "uint256", + "name": "ts", + "type": "uint256" + } + ], + "name": "isRatioPass", + "outputs": [ + { + "internalType": "bool", + "name": "ratioPass", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "livenessRatio", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "0x60c060405234801561000f575f80fd5b506040516107b33803806107b383398101604081905261002e9161008a565b80805f0361004f57604051637c946ed760e01b815260040160405180910390fd5b6080526001600160a01b0382166100785760405162ca95f960e81b815260040160405180910390fd5b506001600160a01b031660a0526100c1565b5f806040838503121561009b575f80fd5b82516001600160a01b03811681146100b1575f80fd5b6020939093015192949293505050565b60805160a0516106c56100ee5f395f818160b0015261036501525f8181607b015261024701526106c55ff3fe608060405234801561000f575f80fd5b506004361061004a575f3560e01c8063184023a51461004e578063592cf3fb1461007657806375af4b6d146100ab578063d564c4bf146100f7575b5f80fd5b61006161005c3660046104d8565b610117565b60405190151581526020015b60405180910390f35b61009d7f000000000000000000000000000000000000000000000000000000000000000081565b60405190815260200161006d565b6100d27f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161006d565b61010a610105366004610540565b610276565b60405161006d9190610573565b5f80821180156101585750825f81518110610134576101346105b6565b6020026020010151845f8151811061014e5761014e6105b6565b6020026020010151115b8015610197575082600181518110610172576101726105b6565b60200260200101518460018151811061018d5761018d6105b6565b6020026020010151115b1561026f575f835f815181106101af576101af6105b6565b6020026020010151855f815181106101c9576101c96105b6565b60200260200101516101db9190610610565b90505f846001815181106101f1576101f16105b6565b60200260200101518660018151811061020c5761020c6105b6565b602002602001015161021e9190610610565b905081811161026c575f8461023b83670de0b6b3a7640000610629565b6102459190610640565b7f000000000000000000000000000000000000000000000000000000000000000011159350505b50505b9392505050565b60408051600280825260608083018452926020830190803683370190505090508173ffffffffffffffffffffffffffffffffffffffff1663affed0e06040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102df573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103039190610678565b815f81518110610315576103156105b6565b60209081029190910101526040517f7af7347300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301527f00000000000000000000000000000000000000000000000000000000000000001690637af7347390602401602060405180830381865afa1580156103aa573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103ce9190610678565b816001815181106103e1576103e16105b6565b602002602001018181525050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f82601f83011261042e575f80fd5b8135602067ffffffffffffffff8083111561044b5761044b6103f2565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f8301168101818110848211171561048e5761048e6103f2565b60405293845260208187018101949081019250878511156104ad575f80fd5b6020870191505b848210156104cd578135835291830191908301906104b4565b979650505050505050565b5f805f606084860312156104ea575f80fd5b833567ffffffffffffffff80821115610501575f80fd5b61050d8783880161041f565b94506020860135915080821115610522575f80fd5b5061052f8682870161041f565b925050604084013590509250925092565b5f60208284031215610550575f80fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461026f575f80fd5b602080825282518282018190525f9190848201906040850190845b818110156105aa5783518352928401929184019160010161058e565b50909695505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b81810381811115610623576106236105e3565b92915050565b8082028115828204841417610623576106236105e3565b5f82610673577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b500490565b5f60208284031215610688575f80fd5b505191905056fea2646970667358221220894d72b452919872cb67e1af83aac1b0e3f0f203c43fa9c3d08c937d8f2578b864736f6c63430008190033", + "deployedBytecode": "0x608060405234801561000f575f80fd5b506004361061004a575f3560e01c8063184023a51461004e578063592cf3fb1461007657806375af4b6d146100ab578063d564c4bf146100f7575b5f80fd5b61006161005c3660046104d8565b610117565b60405190151581526020015b60405180910390f35b61009d7f000000000000000000000000000000000000000000000000000000000000000081565b60405190815260200161006d565b6100d27f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161006d565b61010a610105366004610540565b610276565b60405161006d9190610573565b5f80821180156101585750825f81518110610134576101346105b6565b6020026020010151845f8151811061014e5761014e6105b6565b6020026020010151115b8015610197575082600181518110610172576101726105b6565b60200260200101518460018151811061018d5761018d6105b6565b6020026020010151115b1561026f575f835f815181106101af576101af6105b6565b6020026020010151855f815181106101c9576101c96105b6565b60200260200101516101db9190610610565b90505f846001815181106101f1576101f16105b6565b60200260200101518660018151811061020c5761020c6105b6565b602002602001015161021e9190610610565b905081811161026c575f8461023b83670de0b6b3a7640000610629565b6102459190610640565b7f000000000000000000000000000000000000000000000000000000000000000011159350505b50505b9392505050565b60408051600280825260608083018452926020830190803683370190505090508173ffffffffffffffffffffffffffffffffffffffff1663affed0e06040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102df573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103039190610678565b815f81518110610315576103156105b6565b60209081029190910101526040517f7af7347300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301527f00000000000000000000000000000000000000000000000000000000000000001690637af7347390602401602060405180830381865afa1580156103aa573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103ce9190610678565b816001815181106103e1576103e16105b6565b602002602001018181525050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f82601f83011261042e575f80fd5b8135602067ffffffffffffffff8083111561044b5761044b6103f2565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f8301168101818110848211171561048e5761048e6103f2565b60405293845260208187018101949081019250878511156104ad575f80fd5b6020870191505b848210156104cd578135835291830191908301906104b4565b979650505050505050565b5f805f606084860312156104ea575f80fd5b833567ffffffffffffffff80821115610501575f80fd5b61050d8783880161041f565b94506020860135915080821115610522575f80fd5b5061052f8682870161041f565b925050604084013590509250925092565b5f60208284031215610550575f80fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461026f575f80fd5b602080825282518282018190525f9190848201906040850190845b818110156105aa5783518352928401929184019160010161058e565b50909695505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b81810381811115610623576106236105e3565b92915050565b8082028115828204841417610623576106236105e3565b5f82610673577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b500490565b5f60208284031215610688575f80fd5b505191905056fea2646970667358221220894d72b452919872cb67e1af83aac1b0e3f0f203c43fa9c3d08c937d8f2578b864736f6c63430008190033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/contracts/mech_usage/MechAgentMod.sol b/contracts/mech_usage/MechActivityChecker.sol similarity index 82% rename from contracts/mech_usage/MechAgentMod.sol rename to contracts/mech_usage/MechActivityChecker.sol index b0bf4a1..ba9b388 100644 --- a/contracts/mech_usage/MechAgentMod.sol +++ b/contracts/mech_usage/MechActivityChecker.sol @@ -1,5 +1,7 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.23; +pragma solidity ^0.8.25; + +import {StakingActivityChecker} from "../../lib/autonolas-registries/contracts/staking/StakingActivityChecker.sol"; // Multisig interface interface IMultisig { @@ -19,17 +21,18 @@ interface IAgentMech { /// @dev Provided zero mech agent address. error ZeroMechAgentAddress(); -/// @title MechAgentMod - Abstract smart contract for AI agent mech staking modification +/// @title MechAgentMod - Smart contract for AI agent mech staking modification /// @author Aleksandr Kuperman - /// @author Andrey Lebedev - /// @author Mariapia Moscatiello - -abstract contract MechAgentMod { +contract MechActivityChecker is StakingActivityChecker{ // AI agent mech contract address. address public immutable agentMech; /// @dev MechAgentMod constructor. /// @param _agentMech AI agent mech contract address. - constructor(address _agentMech) { + /// @param _livenessRatio Liveness ratio in the format of 1e18. + constructor(address _agentMech, uint256 _livenessRatio) StakingActivityChecker(_livenessRatio) { if (_agentMech == address(0)) { revert ZeroMechAgentAddress(); } @@ -39,16 +42,12 @@ abstract contract MechAgentMod { /// @dev Gets service multisig nonces. /// @param multisig Service multisig address. /// @return nonces Set of a nonce and a requests count for the multisig. - function _getMultisigNonces(address multisig) internal view virtual returns (uint256[] memory nonces) { + function getMultisigNonces(address multisig) external view virtual override returns (uint256[] memory nonces) { nonces = new uint256[](2); nonces[0] = IMultisig(multisig).nonce(); nonces[1] = IAgentMech(agentMech).getRequestsCount(multisig); } - /// @dev Gets the liveness ratio. - /// @return Liveness ratio. - function _getLivenessRatio() internal view virtual returns (uint256); - /// @dev Checks if the service multisig liveness ratio passes the defined liveness threshold. /// @notice The formula for calculating the ratio is the following: /// currentNonces - [service multisig nonce at time now (block.timestamp), requests count at time now]; @@ -61,11 +60,11 @@ abstract contract MechAgentMod { /// @param lastNonces Last service multisig set of nonce and requests count. /// @param ts Time difference between current and last timestamps. /// @return ratioPass True, if the liveness ratio passes the check. - function _isRatioPass( + function isRatioPass( uint256[] memory curNonces, uint256[] memory lastNonces, uint256 ts - ) internal view virtual returns (bool ratioPass) + ) external view virtual override returns (bool ratioPass) { // If the checkpoint was called in the exact same block, the ratio is zero // If the current nonce is not greater than the last nonce, the ratio is zero @@ -76,7 +75,7 @@ abstract contract MechAgentMod { // Requests counts difference must be less or equal to the nonce difference if (diffRequestsCounts <= diffNonces) { uint256 ratio = (diffRequestsCounts * 1e18) / ts; - ratioPass = (ratio >= _getLivenessRatio()); + ratioPass = (ratio >= livenessRatio); } } } diff --git a/contracts/mech_usage/ServiceStakingMechUsage.sol b/contracts/mech_usage/ServiceStakingMechUsage.sol deleted file mode 100644 index c78f59c..0000000 --- a/contracts/mech_usage/ServiceStakingMechUsage.sol +++ /dev/null @@ -1,56 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.23; - -import {MechAgentMod} from "./MechAgentMod.sol"; -import {ServiceStakingNativeToken} from "../../lib/autonolas-registries/contracts/staking/ServiceStakingNativeToken.sol"; - -/// @title ServiceStakingMechUsage - Smart contract for staking a service with the service interacting with -/// AI agent mech and having a native network token as the deposit -/// @author Aleksandr Kuperman - -/// @author Andrey Lebedev - -/// @author Mariapia Moscatiello - -contract ServiceStakingMechUsage is ServiceStakingNativeToken, MechAgentMod { - /// @dev ServiceStakingNativeToken constructor. - /// @param _stakingParams Service staking parameters. - /// @param _serviceRegistry ServiceRegistry contract address. - /// @param _proxyHash Approved multisig proxy hash. - /// @param _agentMech AI agent mech contract address. - constructor(StakingParams memory _stakingParams, address _serviceRegistry, bytes32 _proxyHash, address _agentMech) - ServiceStakingNativeToken(_stakingParams, _serviceRegistry, _proxyHash) - MechAgentMod(_agentMech) - {} - - /// @dev Gets service multisig nonces. - /// @param multisig Service multisig address. - /// @return nonces Set of a nonce and a requests count for the multisig. - function _getMultisigNonces(address multisig) internal view override(ServiceStakingNativeToken, MechAgentMod) returns (uint256[] memory nonces) { - nonces = super._getMultisigNonces(multisig); - } - - /// @dev Gets the liveness ratio. - /// @return Liveness ratio. - function _getLivenessRatio() internal view override returns (uint256) { - return livenessRatio; - } - - /// @dev Checks if the service multisig liveness ratio passes the defined liveness threshold. - /// @notice The formula for calculating the ratio is the following: - /// currentNonces - [service multisig nonce at time now (block.timestamp), requests count at time now]; - /// lastNonces - [service multisig nonce at the previous checkpoint or staking time (tsStart), requests count at time tsStart]; - /// Requests count difference must be smaller or equal to the nonce difference: - /// (currentNonces[1] - lastNonces[1]) <= (currentNonces[0] - lastNonces[0]); - /// ratio = (currentNonces[1] - lastNonce[1]) / (block.timestamp - tsStart), - /// where ratio >= livenessRatio. - /// @param curNonces Current service multisig set of nonce and requests count. - /// @param lastNonces Last service multisig set of nonce and requests count. - /// @param ts Time difference between current and last timestamps. - /// @return ratioPass True, if the liveness ratio passes the check. - function _isRatioPass( - uint256[] memory curNonces, - uint256[] memory lastNonces, - uint256 ts - ) internal view override(ServiceStakingNativeToken, MechAgentMod) returns (bool ratioPass) - { - ratioPass = super._isRatioPass(curNonces, lastNonces, ts); - } -} \ No newline at end of file diff --git a/contracts/mech_usage/ServiceStakingTokenMechUsage.sol b/contracts/mech_usage/ServiceStakingTokenMechUsage.sol deleted file mode 100644 index 4cd10ba..0000000 --- a/contracts/mech_usage/ServiceStakingTokenMechUsage.sol +++ /dev/null @@ -1,65 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.23; - -import {MechAgentMod} from "./MechAgentMod.sol"; -import {ServiceStakingToken} from "../../lib/autonolas-registries/contracts/staking/ServiceStakingToken.sol"; - -/// @title ServiceStakingTokenMechUsage - Smart contract for staking a service with the service interacting with -/// AI agent mech and having a custom ERC20 token as the deposit -/// @author Aleksandr Kuperman - -/// @author Andrey Lebedev - -/// @author Mariapia Moscatiello - -contract ServiceStakingTokenMechUsage is ServiceStakingToken, MechAgentMod { - /// @dev ServiceStakingNativeToken constructor. - /// @param _stakingParams Service staking parameters. - /// @param _serviceRegistry ServiceRegistry contract address. - /// @param _serviceRegistryTokenUtility ServiceRegistryTokenUtility contract address. - /// @param _stakingToken Address of a service staking token. - /// @param _proxyHash Approved multisig proxy hash. - /// @param _agentMech AI agent mech contract address. - constructor( - StakingParams memory _stakingParams, - address _serviceRegistry, - address _serviceRegistryTokenUtility, - address _stakingToken, - bytes32 _proxyHash, - address _agentMech - ) - ServiceStakingToken(_stakingParams, _serviceRegistry, _serviceRegistryTokenUtility, _stakingToken, _proxyHash) - MechAgentMod(_agentMech) - {} - - /// @dev Gets service multisig nonces. - /// @param multisig Service multisig address. - /// @return nonces Set of a nonce and a requests count for the multisig. - function _getMultisigNonces(address multisig) internal view override(ServiceStakingToken, MechAgentMod) returns (uint256[] memory nonces) { - nonces = super._getMultisigNonces(multisig); - } - - /// @dev Gets the liveness ratio. - /// @return Liveness ratio. - function _getLivenessRatio() internal view override returns (uint256) { - return livenessRatio; - } - - /// @dev Checks if the service multisig liveness ratio passes the defined liveness threshold. - /// @notice The formula for calculating the ratio is the following: - /// currentNonces - [service multisig nonce at time now (block.timestamp), requests count at time now]; - /// lastNonces - [service multisig nonce at the previous checkpoint or staking time (tsStart), requests count at time tsStart]; - /// Requests count difference must be smaller or equal to the nonce difference: - /// (currentNonces[1] - lastNonces[1]) <= (currentNonces[0] - lastNonces[0]); - /// ratio = (currentNonces[1] - lastNonce[1]) / (block.timestamp - tsStart), - /// where ratio >= livenessRatio. - /// @param curNonces Current service multisig set of nonce and requests count. - /// @param lastNonces Last service multisig set of nonce and requests count. - /// @param ts Time difference between current and last timestamps. - /// @return ratioPass True, if the liveness ratio passes the check. - function _isRatioPass( - uint256[] memory curNonces, - uint256[] memory lastNonces, - uint256 ts - ) internal view override(ServiceStakingToken, MechAgentMod) returns (bool ratioPass) - { - ratioPass = super._isRatioPass(curNonces, lastNonces, ts); - } -} \ No newline at end of file diff --git a/contracts/test/ABICreator.sol b/contracts/test/ABICreator.sol index c8c17d4..6a728b8 100644 --- a/contracts/test/ABICreator.sol +++ b/contracts/test/ABICreator.sol @@ -11,4 +11,7 @@ import "../../lib/autonolas-registries/contracts/ComponentRegistry.sol"; import "../../lib/autonolas-registries/contracts/AgentRegistry.sol"; import "../../lib/autonolas-registries/contracts/ServiceRegistry.sol"; import "../../lib/autonolas-registries/contracts/ServiceRegistryTokenUtility.sol"; -import "../../lib/autonolas-registries/contracts/multisigs/GnosisSafeMultisig.sol"; \ No newline at end of file +import "../../lib/autonolas-registries/contracts/multisigs/GnosisSafeMultisig.sol"; +import {StakingFactory} from "../../lib/autonolas-registries/contracts/staking/StakingFactory.sol"; +import {StakingToken} from "../../lib/autonolas-registries/contracts/staking/StakingToken.sol"; +import {StakingNativeToken} from "../../lib/autonolas-registries/contracts/staking/StakingNativeToken.sol"; \ No newline at end of file diff --git a/hardhat.config.js b/hardhat.config.js index 8b18484..892f6eb 100644 --- a/hardhat.config.js +++ b/hardhat.config.js @@ -4,7 +4,7 @@ require("hardhat-contract-sizer"); require("hardhat-deploy"); require("hardhat-deploy-ethers"); require("hardhat-gas-reporter"); -require("hardhat-tracer"); +//require("hardhat-tracer"); require("@nomicfoundation/hardhat-chai-matchers"); require("@nomiclabs/hardhat-ethers"); require("@nomiclabs/hardhat-etherscan"); @@ -102,12 +102,13 @@ module.exports = { solidity: { compilers: [ { - version: "0.8.23", + version: "0.8.25", settings: { optimizer: { enabled: true, runs: 1000000, }, + evmVersion: "cancun" }, } ] diff --git a/lib/autonolas-registries b/lib/autonolas-registries index 551027b..4f30273 160000 --- a/lib/autonolas-registries +++ b/lib/autonolas-registries @@ -1 +1 @@ -Subproject commit 551027b3bd24438d5644d334a2f5e21a0fc6bd11 +Subproject commit 4f30273f6ce94917e0fed2ec2bd758de243c23c9 diff --git a/lib/forge-std b/lib/forge-std index 4513bc2..52715a2 160000 --- a/lib/forge-std +++ b/lib/forge-std @@ -1 +1 @@ -Subproject commit 4513bc2063f23c57bee6558799584b518d387a39 +Subproject commit 52715a217dc51d0de15877878ab8213f6cbbbab5 diff --git a/package.json b/package.json index e7587d5..7129f8c 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "chai": "^4.3.10", "eslint": "^8.52.0", "ethers": "^5.7.2", - "hardhat": "^2.18.2", + "hardhat": "^2.22.4", "hardhat-contract-sizer": "^2.10.0", "hardhat-deploy": "^0.11.43", "hardhat-deploy-ethers": "^0.3.0-beta.13", diff --git a/scripts/deployment/README.md b/scripts/deployment/README.md index db2cd5e..f9964ef 100644 --- a/scripts/deployment/README.md +++ b/scripts/deployment/README.md @@ -25,23 +25,20 @@ Parameters of the `globals.json` file: - `useLedger`: a flag whether to use the hardware wallet (`true`) or proceed with the seed-phrase accounts (`false`); - `derivationPath`: a string with the derivation path; - `providerName`: a network type (see `hardhat.config.js` for the network configurations); -- `serviceStakingParams`: a set of service staking parameters, which include: - - `rewardsPerSecond`: amount of token (in wei) per second credited to a service if the service is active enough. Assuming the maximum - number of reward per week is 1 OLAS (in ETH), then the reward per second is calculated by - [this formula](https://www.wolframalpha.com/input?i=1+*+10%5E18+%2F+%283600+*+24+*+7%29); - - `livenessRatio`: number of service multisig transactions per second (with 18 decimals) that are used to measure the service +- `agentMechAddress`: an agent mech address: +- `livenessRatio`: number of service multisig transactions per second (with 18 decimals) that are used to measure the service liveness (activity). In other words, it's the minimum number of transactions the service multisig needs to perform in order - to pass the liveness check. To check this `rewardsPerSecond* livenessPeriod/1e18` should approximate the number of txs required per livenessPeriod. Assuming the number of required tx-s per day is 10, the liveness ratio can be checked by means of - [this formula](https://www.wolframalpha.com/input?i=%28115740740740740+*+60+*+60+*+24%29+%2F+10%5E18). + to pass the liveness check. To check this `rewardsPerSecond* livenessPeriod/1e18` should approximate the number of txs required per livenessPeriod. + Assuming the number of required tx-s per day is 10, the liveness ratio can be checked by means of [this formula](https://www.wolframalpha.com/input?i=%28115740740740740+*+60+*+60+*+24%29+%2F+10%5E18). The script file name identifies the number of deployment steps taken from / to the number in the file name. For example: -- `deploy_01_service_staking_token_mech_usage.js` will complete step 1. +- `deploy_01_mech_activity_checker.js` will complete step 1. Export network-related API keys defined in `hardhat.config.js` file that correspond to the required network. To run the script, use the following command: `npx hardhat run scripts/deployment/script_name --network network_type`, -where `script_name` is a script name, i.e. `deploy_01_service_staking_token_mech_usage.js`, `network_type` is a network type corresponding to the `hardhat.config.js` network configuration. +where `script_name` is a script name, i.e. `deploy_01_mech_activity_checker.js`, `network_type` is a network type corresponding to the `hardhat.config.js` network configuration. ## Validity checks and contract verification Each script controls the obtained values by checking them against the expected ones. Also, each script has a contract verification procedure. diff --git a/scripts/deployment/deploy_02_service_staking_mech_usage.js b/scripts/deployment/deploy_01_mech_activity_checker.js similarity index 50% rename from scripts/deployment/deploy_02_service_staking_mech_usage.js rename to scripts/deployment/deploy_01_mech_activity_checker.js index 1e06376..f7a337c 100644 --- a/scripts/deployment/deploy_02_service_staking_mech_usage.js +++ b/scripts/deployment/deploy_01_mech_activity_checker.js @@ -12,40 +12,27 @@ async function main() { const derivationPath = parsedData.derivationPath; const providerName = parsedData.providerName; const gasPriceInGwei = parsedData.gasPriceInGwei; - const serviceStakingParams = parsedData.serviceStakingParams; - const serviceRegistryAddress = parsedData.serviceRegistryAddress; - const multisigProxyHash130 = parsedData.multisigProxyHash130; const agentMechAddress = parsedData.agentMechAddress; - let EOA; + const livenessRatio = parsedData.livenessRatio; - let networkURL; + let networkURL = parsedData.networkURL; if (providerName === "polygon") { if (!process.env.ALCHEMY_API_KEY_MATIC) { console.log("set ALCHEMY_API_KEY_MATIC env variable"); } - networkURL = "https://polygon-mainnet.g.alchemy.com/v2/" + process.env.ALCHEMY_API_KEY_MATIC; - } else if (providerName === "polygonMumbai") { - if (!process.env.ALCHEMY_API_KEY_MUMBAI) { - console.log("set ALCHEMY_API_KEY_MUMBAI env variable"); - return; - } - networkURL = "https://polygon-mumbai.g.alchemy.com/v2/" + process.env.ALCHEMY_API_KEY_MUMBAI; - } else if (providerName === "gnosis") { - if (!process.env.GNOSISSCAN_API_KEY) { - console.log("set GNOSISSCAN_API_KEY env variable"); + networkURL += process.env.ALCHEMY_API_KEY_MATIC; + } else if (providerName === "polygonAmoy") { + if (!process.env.ALCHEMY_API_KEY_AMOY) { + console.log("set ALCHEMY_API_KEY_AMOY env variable"); return; } - networkURL = "https://rpc.gnosischain.com"; - } else if (providerName === "chiado") { - networkURL = "https://rpc.chiadochain.net"; - } else { - console.log("Unknown network provider", providerName); - return; + networkURL += process.env.ALCHEMY_API_KEY_AMOY; } const provider = new ethers.providers.JsonRpcProvider(networkURL); const signers = await ethers.getSigners(); + let EOA; if (useLedger) { EOA = new LedgerSigner(provider, derivationPath); } else { @@ -56,29 +43,29 @@ async function main() { console.log("EOA is:", deployer); // Transaction signing and execution - console.log("2. EOA to deploy ServiceStakingMechUsage"); + console.log("1. EOA to deploy MechActivityChecker"); const gasPrice = ethers.utils.parseUnits(gasPriceInGwei, "gwei"); - const ServiceStakingMechUsage = await ethers.getContractFactory("ServiceStakingMechUsage"); - console.log("You are signing the following transaction: ServiceStakingMechUsage.connect(EOA).deploy()"); - const serviceStakingMechUsage = await ServiceStakingMechUsage.connect(EOA).deploy(serviceStakingParams, - serviceRegistryAddress, multisigProxyHash130, agentMechAddress, { gasPrice }); - const result = await serviceStakingMechUsage.deployed(); + const MechActivityChecker = await ethers.getContractFactory("MechActivityChecker"); + console.log("You are signing the following transaction: MechActivityChecker.connect(EOA).deploy()"); + const mechActivityChecker = await MechActivityChecker.connect(EOA).deploy(agentMechAddress, livenessRatio, + { gasPrice }); + const result = await mechActivityChecker.deployed(); // Transaction details - console.log("Contract deployment: ServiceStakingMechUsage"); - console.log("Contract address:", serviceStakingMechUsage.address); + console.log("Contract deployment: MechActivityChecker"); + console.log("Contract address:", mechActivityChecker.address); console.log("Transaction:", result.deployTransaction.hash); // Wait half a minute for the transaction completion await new Promise(r => setTimeout(r, 30000)); // Writing updated parameters back to the JSON file - parsedData.serviceStakingMechUsageAddress = serviceStakingMechUsage.address; + parsedData.mechActivityCheckerAddress = mechActivityChecker.address; fs.writeFileSync(globalsFile, JSON.stringify(parsedData)); // Contract verification if (parsedData.contractVerification) { const execSync = require("child_process").execSync; - execSync("npx hardhat verify --constructor-args scripts/deployment/verify_02_service_staking_mech_usage.js --network " + providerName + " " + serviceStakingMechUsage.address, { encoding: "utf-8" }); + execSync("npx hardhat verify --constructor-args scripts/deployment/verify_01_mech_activity_checker.js --network " + providerName + " " + mechActivityChecker.address, { encoding: "utf-8" }); } } diff --git a/scripts/deployment/deploy_01_service_staking_token_mech_usage.js b/scripts/deployment/deploy_01_service_staking_token_mech_usage.js deleted file mode 100644 index 4d6df01..0000000 --- a/scripts/deployment/deploy_01_service_staking_token_mech_usage.js +++ /dev/null @@ -1,92 +0,0 @@ -/*global process*/ - -const { ethers } = require("hardhat"); -const { LedgerSigner } = require("@anders-t/ethers-ledger"); - -async function main() { - const fs = require("fs"); - const globalsFile = "globals.json"; - const dataFromJSON = fs.readFileSync(globalsFile, "utf8"); - let parsedData = JSON.parse(dataFromJSON); - const useLedger = parsedData.useLedger; - const derivationPath = parsedData.derivationPath; - const providerName = parsedData.providerName; - const gasPriceInGwei = parsedData.gasPriceInGwei; - const serviceStakingParams = parsedData.serviceStakingParams; - const serviceRegistryAddress = parsedData.serviceRegistryAddress; - const serviceRegistryTokenUtilityAddress = parsedData.serviceRegistryTokenUtilityAddress; - const olasAddress = parsedData.olasAddress; - const multisigProxyHash130 = parsedData.multisigProxyHash130; - const agentMechAddress = parsedData.agentMechAddress; - let EOA; - - let networkURL; - if (providerName === "polygon") { - if (!process.env.ALCHEMY_API_KEY_MATIC) { - console.log("set ALCHEMY_API_KEY_MATIC env variable"); - } - networkURL = "https://polygon-mainnet.g.alchemy.com/v2/" + process.env.ALCHEMY_API_KEY_MATIC; - } else if (providerName === "polygonMumbai") { - if (!process.env.ALCHEMY_API_KEY_MUMBAI) { - console.log("set ALCHEMY_API_KEY_MUMBAI env variable"); - return; - } - networkURL = "https://polygon-mumbai.g.alchemy.com/v2/" + process.env.ALCHEMY_API_KEY_MUMBAI; - } else if (providerName === "gnosis") { - if (!process.env.GNOSISSCAN_API_KEY) { - console.log("set GNOSISSCAN_API_KEY env variable"); - return; - } - networkURL = "https://rpc.gnosischain.com"; - } else if (providerName === "chiado") { - networkURL = "https://rpc.chiadochain.net"; - } else { - console.log("Unknown network provider", providerName); - return; - } - - const provider = new ethers.providers.JsonRpcProvider(networkURL); - const signers = await ethers.getSigners(); - - if (useLedger) { - EOA = new LedgerSigner(provider, derivationPath); - } else { - EOA = signers[0]; - } - // EOA address - const deployer = await EOA.getAddress(); - console.log("EOA is:", deployer); - - // Transaction signing and execution - console.log("1. EOA to deploy ServiceStakingTokenMechUsage"); - const gasPrice = ethers.utils.parseUnits(gasPriceInGwei, "gwei"); - const ServiceStakingTokenMechUsage = await ethers.getContractFactory("ServiceStakingTokenMechUsage"); - console.log("You are signing the following transaction: ServiceStakingTokenMechUsage.connect(EOA).deploy()"); - const serviceStakingTokenMechUsage = await ServiceStakingTokenMechUsage.connect(EOA).deploy(serviceStakingParams, - serviceRegistryAddress, serviceRegistryTokenUtilityAddress, olasAddress, multisigProxyHash130, agentMechAddress, { gasPrice }); - const result = await serviceStakingTokenMechUsage.deployed(); - - // Transaction details - console.log("Contract deployment: ServiceStakingTokenMechUsage"); - console.log("Contract address:", serviceStakingTokenMechUsage.address); - console.log("Transaction:", result.deployTransaction.hash); - // Wait half a minute for the transaction completion - await new Promise(r => setTimeout(r, 30000)); - - // Writing updated parameters back to the JSON file - parsedData.serviceStakingTokenMechUsageAddress = serviceStakingTokenMechUsage.address; - fs.writeFileSync(globalsFile, JSON.stringify(parsedData)); - - // Contract verification - if (parsedData.contractVerification) { - const execSync = require("child_process").execSync; - execSync("npx hardhat verify --constructor-args scripts/deployment/verify_01_service_staking_token_mech_usage.js --network " + providerName + " " + serviceStakingTokenMechUsage.address, { encoding: "utf-8" }); - } -} - -main() - .then(() => process.exit(0)) - .catch((error) => { - console.error(error); - process.exit(1); - }); diff --git a/scripts/deployment/deploy_02_staking_token_instance.js b/scripts/deployment/deploy_02_staking_token_instance.js new file mode 100644 index 0000000..96b4ff1 --- /dev/null +++ b/scripts/deployment/deploy_02_staking_token_instance.js @@ -0,0 +1,85 @@ +/*global process*/ + +const { ethers } = require("hardhat"); +const { LedgerSigner } = require("@anders-t/ethers-ledger"); + +async function main() { + const fs = require("fs"); + const globalsFile = "globals.json"; + const dataFromJSON = fs.readFileSync(globalsFile, "utf8"); + let parsedData = JSON.parse(dataFromJSON); + const useLedger = parsedData.useLedger; + const derivationPath = parsedData.derivationPath; + const providerName = parsedData.providerName; + const stakingParams = parsedData.stakingParams; + const serviceRegistryTokenUtilityAddress = parsedData.serviceRegistryTokenUtilityAddress; + const olasAddress = parsedData.olasAddress; + const stakingTokenAddress = parsedData.stakingTokenAddress; + const stakingFactoryAddress = parsedData.stakingFactoryAddress; + + let networkURL = parsedData.networkURL; + if (providerName === "polygon") { + if (!process.env.ALCHEMY_API_KEY_MATIC) { + console.log("set ALCHEMY_API_KEY_MATIC env variable"); + } + networkURL += process.env.ALCHEMY_API_KEY_MATIC; + } else if (providerName === "polygonAmoy") { + if (!process.env.ALCHEMY_API_KEY_AMOY) { + console.log("set ALCHEMY_API_KEY_AMOY env variable"); + return; + } + networkURL += process.env.ALCHEMY_API_KEY_AMOY; + } + + const provider = new ethers.providers.JsonRpcProvider(networkURL); + const signers = await ethers.getSigners(); + + let EOA; + if (useLedger) { + EOA = new LedgerSigner(provider, derivationPath); + } else { + EOA = signers[0]; + } + // EOA address + const deployer = await EOA.getAddress(); + console.log("EOA is:", deployer); + + // Get StakingFactory contract instance + const stakingFactory = await ethers.getContractAt("StakingFactory", stakingFactoryAddress); + // Get StakingToken implementation contract instance + const stakingToken = await ethers.getContractAt("StakingToken", stakingTokenAddress); + + // Transaction signing and execution + console.log("21. EOA to deploy StakingTokenInstance via the StakingFactory"); + console.log("You are signing the following transaction: StakingFactory.connect(EOA).createStakingInstance()"); + const initPayload = stakingToken.interface.encodeFunctionData("initialize", [stakingParams, + serviceRegistryTokenUtilityAddress, olasAddress]); + const stakingTokenInstanceAddress = await stakingFactory.callStatic.createStakingInstance(stakingTokenAddress, + initPayload); + const result = await stakingFactory.createStakingInstance(stakingTokenAddress, initPayload); + + // Transaction details + console.log("Contract deployment: StakingProxy"); + console.log("Contract address:", stakingTokenInstanceAddress); + console.log("Transaction:", result.hash); + + // Wait half a minute for the transaction completion + await new Promise(r => setTimeout(r, 30000)); + + // Writing updated parameters back to the JSON file + parsedData.stakingTokenInstanceAddress = stakingTokenInstanceAddress; + fs.writeFileSync(globalsFile, JSON.stringify(parsedData)); + + // Contract verification + if (parsedData.contractVerification) { + const execSync = require("child_process").execSync; + execSync("npx hardhat verify --constructor-args scripts/deployment/verify_02_staking_token_instance.js --network " + providerName + " " + stakingTokenInstanceAddress, { encoding: "utf-8" }); + } +} + +main() + .then(() => process.exit(0)) + .catch((error) => { + console.error(error); + process.exit(1); + }); diff --git a/scripts/deployment/deploy_03_staking_native_token_instance.js b/scripts/deployment/deploy_03_staking_native_token_instance.js new file mode 100644 index 0000000..9fcc05b --- /dev/null +++ b/scripts/deployment/deploy_03_staking_native_token_instance.js @@ -0,0 +1,82 @@ +/*global process*/ + +const { ethers } = require("hardhat"); +const { LedgerSigner } = require("@anders-t/ethers-ledger"); + +async function main() { + const fs = require("fs"); + const globalsFile = "globals.json"; + const dataFromJSON = fs.readFileSync(globalsFile, "utf8"); + let parsedData = JSON.parse(dataFromJSON); + const useLedger = parsedData.useLedger; + const derivationPath = parsedData.derivationPath; + const providerName = parsedData.providerName; + const stakingParams = parsedData.stakingParams; + const stakingNativeTokenAddress = parsedData.stakingNativeTokenAddress; + const stakingFactoryAddress = parsedData.stakingFactoryAddress; + + let networkURL = parsedData.networkURL; + if (providerName === "polygon") { + if (!process.env.ALCHEMY_API_KEY_MATIC) { + console.log("set ALCHEMY_API_KEY_MATIC env variable"); + } + networkURL += process.env.ALCHEMY_API_KEY_MATIC; + } else if (providerName === "polygonAmoy") { + if (!process.env.ALCHEMY_API_KEY_AMOY) { + console.log("set ALCHEMY_API_KEY_AMOY env variable"); + return; + } + networkURL += process.env.ALCHEMY_API_KEY_AMOY; + } + + const provider = new ethers.providers.JsonRpcProvider(networkURL); + const signers = await ethers.getSigners(); + + let EOA; + if (useLedger) { + EOA = new LedgerSigner(provider, derivationPath); + } else { + EOA = signers[0]; + } + // EOA address + const deployer = await EOA.getAddress(); + console.log("EOA is:", deployer); + + // Get StakingFactory contract instance + const stakingFactory = await ethers.getContractAt("StakingFactory", stakingFactoryAddress); + // Get StakingToken implementation contract instance + const stakingNativeToken = await ethers.getContractAt("StakingNativeToken", stakingNativeTokenAddress); + + // Transaction signing and execution + console.log("22. EOA to deploy StakingNativeTokenInstance via the StakingFactory"); + console.log("You are signing the following transaction: StakingFactory.connect(EOA).createStakingInstance()"); + const initPayload = stakingNativeToken.interface.encodeFunctionData("initialize", [stakingParams]); + const stakingNativeTokenInstanceAddress = await stakingFactory.callStatic.createStakingInstance( + stakingNativeTokenAddress, initPayload); + const result = await stakingFactory.createStakingInstance(stakingNativeTokenAddress, initPayload); + + // Transaction details + console.log("Contract deployment: StakingProxy"); + console.log("Contract address:", stakingNativeTokenInstanceAddress); + console.log("Transaction:", result.hash); + + // Wait half a minute for the transaction completion + await new Promise(r => setTimeout(r, 30000)); + + // Writing updated parameters back to the JSON file + parsedData.stakingNativeTokenInstanceAddress = stakingNativeTokenInstanceAddress; + fs.writeFileSync(globalsFile, JSON.stringify(parsedData)); + + // Contract verification + if (parsedData.contractVerification) { + const execSync = require("child_process").execSync; + execSync("npx hardhat verify --constructor-args scripts/deployment/verify_03_staking_native_token_instance.js --network " + providerName + " " + stakingNativeTokenInstanceAddress, { encoding: "utf-8" }); + } +} + +main() + .then(() => process.exit(0)) + .catch((error) => { + console.error(error); + process.exit(1); + }); diff --git a/scripts/deployment/globals_gnosis_chiado.json b/scripts/deployment/globals_gnosis_chiado.json index 5ff157e..cf4c4bc 100644 --- a/scripts/deployment/globals_gnosis_chiado.json +++ b/scripts/deployment/globals_gnosis_chiado.json @@ -1 +1 @@ -{"contractVerification":true,"useLedger":false,"derivationPath":"m/44'/60'/2'/0/0","providerName":"chiado","gasPriceInGwei":"5","gnosisSafeAddress":"0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552","gnosisSafeProxyFactoryAddress":"0xa6B71E26C5e0845f74c812102Ca7114b6a896AB2","serviceRegistryAddress":"0x31D3202d8744B16A120117A053459DDFAE93c855","serviceRegistryTokenUtilityAddress":"0xc2c7E40674f1C7Bb99eFe5680Efd79842502bED4","olasAddress":"0xE40AE73aa0Ed3Ec35fdAF56e01FCd0D1Ff1d9AB6","multisigProxyHash130":"0xb89c1b3bdf2cf8827818646bce9a8f6e372885f8c55e5c07acbd307cb133b000","serviceStakingParams":{"maxNumServices":"50","rewardsPerSecond":"826719576719","minStakingDeposit":"25000000000000000000","minNumStakingPeriods":"3","maxNumInactivityPeriods":"3","livenessPeriod":"86400","livenessRatio":"115740740740740","numAgentInstances":"1","agentIds":["12"],"threshold":"0","configHash":"0x0000000000000000000000000000000000000000000000000000000000000000"},"agentMechAddress":"0x0a3cfc6bee9658eda040e6bb366fe963ddce82c9","serviceStakingTokenMechUsageAddress":"0xad152D5C9F6c959386aFf051658129c6e87D2eF7","serviceStakingMechUsageAddress":"0xea930a028793FeBE9F6A2CFb62c95620dB91da71"} \ No newline at end of file +{"contractVerification":true,"useLedger":false,"derivationPath":"m/44'/60'/2'/0/0","providerName":"chiado","networkURL":"https://rpc.chiadochain.net","gasPriceInGwei":"5","gnosisSafeAddress":"0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552","gnosisSafeProxyFactoryAddress":"0xa6B71E26C5e0845f74c812102Ca7114b6a896AB2","serviceRegistryAddress":"0x31D3202d8744B16A120117A053459DDFAE93c855","serviceRegistryTokenUtilityAddress":"0xc2c7E40674f1C7Bb99eFe5680Efd79842502bED4","olasAddress":"0xE40AE73aa0Ed3Ec35fdAF56e01FCd0D1Ff1d9AB6","multisigProxyHash130":"0xb89c1b3bdf2cf8827818646bce9a8f6e372885f8c55e5c07acbd307cb133b000","stakingNativeTokenAddress":"0xAed729d4f4b895d8ca84ba022675bB0C44d2cD52","stakingTokenAddress":"0xf438a9a11902ffecfc2dA2f2224193C6AaBc6346","agentMechAddress":"0x0A3cFc6BEe9658Eda040e6BB366FE963DdCe82C9","livenessRatio":"700000000000000","mechActivityCheckerAddress":"0x7781202B9b09B92F512A0E343F24d349d09bc3A6","stakingVerifierAddress":"0x00000000000000000000000000000000000000000","stakingFactoryAddress":"0xbF6Dd5e87535b8766f4848DE1c13f8d4EDfA86C5","stakingParams":{"metadataHash":"0x0000000000000000000000000000000000000000000000000000000000000001","maxNumServices":"100","rewardsPerSecond":"1000000000000000","minStakingDeposit":"50000000000000000000","minNumStakingPeriods":"3","maxNumInactivityPeriods":"3","livenessPeriod":"86400","timeForEmissions":"86400","numAgentInstances":"1","agentIds":["12"],"threshold":"0","configHash":"0x0000000000000000000000000000000000000000000000000000000000000000","proxyHash":"0xb89c1b3bdf2cf8827818646bce9a8f6e372885f8c55e5c07acbd307cb133b000","serviceRegistry":"0x31D3202d8744B16A120117A053459DDFAE93c855","activityChecker":"0x7781202B9b09B92F512A0E343F24d349d09bc3A6"},"stakingTokenInstanceAddress":"0x3cbf58bcC16d9195c35E01aFE1A57caf257e113a","stakingNativeTokenInstanceAddress":"0x6F67efF5cb5C35a40CdE2eD570f0885fe7De7D6b"} \ No newline at end of file diff --git a/scripts/deployment/globals_gnosis_mainnet.json b/scripts/deployment/globals_gnosis_mainnet.json index c9b6abe..697308b 100644 --- a/scripts/deployment/globals_gnosis_mainnet.json +++ b/scripts/deployment/globals_gnosis_mainnet.json @@ -3,6 +3,7 @@ "useLedger": true, "derivationPath": "m/44'/60'/2'/0/0", "providerName": "gnosis", + "networkURL": "https://rpc.gnosischain.com", "gasPriceInGwei": "5", "gnosisSafeAddress": "0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552", "gnosisSafeProxyFactoryAddress": "0xa6B71E26C5e0845f74c812102Ca7114b6a896AB2", @@ -10,19 +11,29 @@ "serviceRegistryTokenUtilityAddress": "0xa45E64d13A30a51b91ae0eb182e88a40e9b18eD8", "olasAddress": "0xcE11e14225575945b8E6Dc0D4F2dD4C570f79d9f", "multisigProxyHash130": "0xb89c1b3bdf2cf8827818646bce9a8f6e372885f8c55e5c07acbd307cb133b000", - "serviceStakingParams": { + "stakingNativeTokenAddress": "", + "stakingTokenAddress": "", + "agentMechAddress": "0x77af31De935740567Cf4fF1986D04B2c964A786a", + "livenessRatio": "700000000000000", + "mechActivityCheckerAddress": "", + "stakingVerifierAddress": "", + "stakingFactoryAddress": "", + "stakingParams": { + "metadataHash": "0x0000000000000000000000000000000000000000000000000000000000000001", "maxNumServices": "100", - "rewardsPerSecond": "3306878306879", - "minStakingDeposit": "10000000000000000000", - "minNumStakingPeriods":"3", - "maxNumInactivityPeriods": "2", + "rewardsPerSecond": "1000000000000000", + "minStakingDeposit": "50000000000000000000", + "minNumStakingPeriods": "3", + "maxNumInactivityPeriods": "3", "livenessPeriod": "86400", - "livenessRatio": "462962962962963", + "timeForEmissions": "", "numAgentInstances": "1", - "agentIds": ["14"], + "agentIds": ["12"], "threshold": "0", - "configHash": "0x0000000000000000000000000000000000000000000000000000000000000000" + "configHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "proxyHash": "0xb89c1b3bdf2cf8827818646bce9a8f6e372885f8c55e5c07acbd307cb133b000", + "serviceRegistry": "0x9338b5153AE39BB89f50468E608eD9d764B755fD", + "activityChecker": "" }, - "agentMechAddress": "0x77af31De935740567Cf4fF1986D04B2c964A786a", - "serviceStakingTokenMechUsageAddress": "0x43fB32f25dce34EB76c78C7A42C8F40F84BCD237" + "stakingTokenInstanceAddress": "" } diff --git a/scripts/deployment/verify_01_mech_activity_checker.js b/scripts/deployment/verify_01_mech_activity_checker.js new file mode 100644 index 0000000..c44b924 --- /dev/null +++ b/scripts/deployment/verify_01_mech_activity_checker.js @@ -0,0 +1,11 @@ +const fs = require("fs"); +const globalsFile = "globals.json"; +const dataFromJSON = fs.readFileSync(globalsFile, "utf8"); +const parsedData = JSON.parse(dataFromJSON); +const agentMechAddress = parsedData.agentMechAddress; +const livenessRatio = parsedData.livenessRatio; + +module.exports = [ + agentMechAddress, + livenessRatio +]; \ No newline at end of file diff --git a/scripts/deployment/verify_01_service_staking_token_mech_usage.js b/scripts/deployment/verify_01_service_staking_token_mech_usage.js deleted file mode 100644 index 7a48036..0000000 --- a/scripts/deployment/verify_01_service_staking_token_mech_usage.js +++ /dev/null @@ -1,19 +0,0 @@ -const fs = require("fs"); -const globalsFile = "globals.json"; -const dataFromJSON = fs.readFileSync(globalsFile, "utf8"); -const parsedData = JSON.parse(dataFromJSON); -const serviceStakingParams = parsedData.serviceStakingParams; -const serviceRegistryAddress = parsedData.serviceRegistryAddress; -const serviceRegistryTokenUtilityAddress = parsedData.serviceRegistryTokenUtilityAddress; -const olasAddress = parsedData.olasAddress; -const multisigProxyHash130 = parsedData.multisigProxyHash130; -const agentMechAddress = parsedData.agentMechAddress; - -module.exports = [ - serviceStakingParams, - serviceRegistryAddress, - serviceRegistryTokenUtilityAddress, - olasAddress, - multisigProxyHash130, - agentMechAddress -]; \ No newline at end of file diff --git a/scripts/deployment/verify_02_service_staking_mech_usage.js b/scripts/deployment/verify_02_service_staking_mech_usage.js deleted file mode 100644 index ec6d7ed..0000000 --- a/scripts/deployment/verify_02_service_staking_mech_usage.js +++ /dev/null @@ -1,15 +0,0 @@ -const fs = require("fs"); -const globalsFile = "globals.json"; -const dataFromJSON = fs.readFileSync(globalsFile, "utf8"); -const parsedData = JSON.parse(dataFromJSON); -const serviceStakingParams = parsedData.serviceStakingParams; -const serviceRegistryAddress = parsedData.serviceRegistryAddress; -const multisigProxyHash130 = parsedData.multisigProxyHash130; -const agentMechAddress = parsedData.agentMechAddress; - -module.exports = [ - serviceStakingParams, - serviceRegistryAddress, - multisigProxyHash130, - agentMechAddress -]; \ No newline at end of file diff --git a/scripts/deployment/verify_02_staking_token_instance.js b/scripts/deployment/verify_02_staking_token_instance.js new file mode 100644 index 0000000..be8c1e6 --- /dev/null +++ b/scripts/deployment/verify_02_staking_token_instance.js @@ -0,0 +1,9 @@ +const fs = require("fs"); +const globalsFile = "globals.json"; +const dataFromJSON = fs.readFileSync(globalsFile, "utf8"); +const parsedData = JSON.parse(dataFromJSON); +const stakingTokenAddress = parsedData.stakingTokenAddress; + +module.exports = [ + stakingTokenAddress +]; \ No newline at end of file diff --git a/scripts/deployment/verify_03_staking_native_token_instance.js b/scripts/deployment/verify_03_staking_native_token_instance.js new file mode 100644 index 0000000..fa72a22 --- /dev/null +++ b/scripts/deployment/verify_03_staking_native_token_instance.js @@ -0,0 +1,9 @@ +const fs = require("fs"); +const globalsFile = "globals.json"; +const dataFromJSON = fs.readFileSync(globalsFile, "utf8"); +const parsedData = JSON.parse(dataFromJSON); +const stakingNativeTokenAddress = parsedData.stakingNativeTokenAddress; + +module.exports = [ + stakingNativeTokenAddress +]; \ No newline at end of file diff --git a/test/ServiceStakingMechUsage.js b/test/StakingMechUsage.js similarity index 75% rename from test/ServiceStakingMechUsage.js rename to test/StakingMechUsage.js index 875991f..a902991 100644 --- a/test/ServiceStakingMechUsage.js +++ b/test/StakingMechUsage.js @@ -4,7 +4,7 @@ const { ethers } = require("hardhat"); const helpers = require("@nomicfoundation/hardhat-network-helpers"); const safeContracts = require("@gnosis.pm/safe-contracts"); -describe("ServiceStakingMechUsage", function () { +describe("StakingMechUsage", function () { let componentRegistry; let agentRegistry; let serviceRegistry; @@ -14,17 +14,20 @@ describe("ServiceStakingMechUsage", function () { let gnosisSafe; let gnosisSafeProxyFactory; let gnosisSafeMultisig; - let multiSend; - let serviceStakingMechUsage; - let serviceStakingTokenMechUsage; + let stakingFactory; + let stakingImplementation; + let stakingTokenImplementation; + let stakingNativeToken; + let stakingToken; + let stakingActivityChecker; let signers; let deployer; let operator; let agentInstances; let bytecodeHash; const AddressZero = ethers.constants.AddressZero; + const HashZero = ethers.constants.HashZero; const defaultHash = "0x" + "5".repeat(64); - const bytes32Zero = "0x" + "0".repeat(64); const regDeposit = 1000; const regBond = 1000; const serviceId = 1; @@ -34,18 +37,23 @@ describe("ServiceStakingMechUsage", function () { const livenessPeriod = 10; // Ten seconds const initSupply = "5" + "0".repeat(26); const payload = "0x"; - const serviceParams = { - maxNumServices: 10, + const livenessRatio = "1" + "0".repeat(16); // 0.01 transaction per second (TPS) + let serviceParams = { + metadataHash: defaultHash, + maxNumServices: 3, rewardsPerSecond: "1" + "0".repeat(15), minStakingDeposit: 10, minNumStakingPeriods: 3, maxNumInactivityPeriods: 3, livenessPeriod: livenessPeriod, // Ten seconds - livenessRatio: "1" + "0".repeat(16), // 0.01 transaction per second (TPS) + timeForEmissions: 100, numAgentInstances: 1, agentIds: [], threshold: 0, - configHash: bytes32Zero + configHash: HashZero, + proxyHash: HashZero, + serviceRegistry: AddressZero, + activityChecker: AddressZero }; const maxInactivity = serviceParams.maxNumInactivityPeriods * livenessPeriod + 1; @@ -66,6 +74,7 @@ describe("ServiceStakingMechUsage", function () { serviceRegistry = await ServiceRegistry.deploy("service registry", "SERVICE", "https://localhost/service/", agentRegistry.address); await serviceRegistry.deployed(); + serviceParams.serviceRegistry = serviceRegistry.address; const ServiceRegistryTokenUtility = await ethers.getContractFactory("ServiceRegistryTokenUtility"); serviceRegistryTokenUtility = await ServiceRegistryTokenUtility.deploy(serviceRegistry.address); @@ -96,20 +105,34 @@ describe("ServiceStakingMechUsage", function () { await gnosisSafeProxy.deployed(); const bytecode = await ethers.provider.getCode(gnosisSafeProxy.address); bytecodeHash = ethers.utils.keccak256(bytecode); - - const MultiSend = await ethers.getContractFactory("MultiSendCallOnly"); - multiSend = await MultiSend.deploy(); - await multiSend.deployed(); - - const ServiceStakingMechUsage = await ethers.getContractFactory("ServiceStakingMechUsage"); - serviceStakingMechUsage = await ServiceStakingMechUsage.deploy(serviceParams, serviceRegistry.address, - bytecodeHash, agentMech.address); - await serviceStakingMechUsage.deployed(); - - const ServiceStakingTokenMechUsage = await ethers.getContractFactory("ServiceStakingTokenMechUsage"); - serviceStakingTokenMechUsage = await ServiceStakingTokenMechUsage.deploy(serviceParams, serviceRegistry.address, - serviceRegistryTokenUtility.address, token.address, bytecodeHash, agentMech.address); - await serviceStakingTokenMechUsage.deployed(); + serviceParams.proxyHash = bytecodeHash; + + const StakingFactory = await ethers.getContractFactory("StakingFactory"); + stakingFactory = await StakingFactory.deploy(AddressZero); + await stakingFactory.deployed(); + + const StakingActivityChecker = await ethers.getContractFactory("MechActivityChecker"); + stakingActivityChecker = await StakingActivityChecker.deploy(agentMech.address, livenessRatio); + await stakingActivityChecker.deployed(); + serviceParams.activityChecker = stakingActivityChecker.address; + + const StakingNativeToken = await ethers.getContractFactory("StakingNativeToken"); + stakingImplementation = await StakingNativeToken.deploy(); + let initPayload = stakingImplementation.interface.encodeFunctionData("initialize", + [serviceParams]); + const stakingAddress = await stakingFactory.callStatic.createStakingInstance( + stakingImplementation.address, initPayload); + await stakingFactory.createStakingInstance(stakingImplementation.address, initPayload); + stakingNativeToken = await ethers.getContractAt("StakingNativeToken", stakingAddress); + + const StakingToken = await ethers.getContractFactory("StakingToken"); + stakingTokenImplementation = await StakingToken.deploy(); + initPayload = stakingTokenImplementation.interface.encodeFunctionData("initialize", + [serviceParams, serviceRegistryTokenUtility.address, token.address]); + const stakingTokenAddress = await stakingFactory.callStatic.createStakingInstance( + stakingTokenImplementation.address, initPayload); + await stakingFactory.createStakingInstance(stakingTokenImplementation.address, initPayload); + stakingToken = await ethers.getContractAt("StakingToken", stakingTokenAddress); // Set the deployer to be the unit manager by default await componentRegistry.changeManager(deployer.address); @@ -148,16 +171,10 @@ describe("ServiceStakingMechUsage", function () { context("Initialization", function () { it("Should fail when deploying the contract with a zero agent mech address", async function () { - const ServiceStakingMechUsage = await ethers.getContractFactory("ServiceStakingMechUsage"); - await expect( - ServiceStakingMechUsage.deploy(serviceParams, serviceRegistry.address, bytecodeHash, AddressZero) - ).to.be.revertedWithCustomError(ServiceStakingMechUsage, "ZeroMechAgentAddress"); - - const ServiceStakingTokenMechUsage = await ethers.getContractFactory("ServiceStakingTokenMechUsage"); + const StakingActivityChecker = await ethers.getContractFactory("MechActivityChecker"); await expect( - ServiceStakingTokenMechUsage.deploy(serviceParams, serviceRegistry.address, - serviceRegistryTokenUtility.address, token.address, bytecodeHash, AddressZero) - ).to.be.revertedWithCustomError(ServiceStakingTokenMechUsage, "ZeroMechAgentAddress"); + StakingActivityChecker.deploy(AddressZero, livenessRatio) + ).to.be.revertedWithCustomError(StakingActivityChecker, "ZeroMechAgentAddress"); }); }); @@ -167,16 +184,16 @@ describe("ServiceStakingMechUsage", function () { const snapshot = await helpers.takeSnapshot(); // Deposit to the contract - await deployer.sendTransaction({to: serviceStakingMechUsage.address, value: ethers.utils.parseEther("1")}); + await deployer.sendTransaction({to: stakingNativeToken.address, value: ethers.utils.parseEther("1")}); // Approve services - await serviceRegistry.approve(serviceStakingMechUsage.address, serviceId); + await serviceRegistry.approve(stakingNativeToken.address, serviceId); // Stake the service - await serviceStakingMechUsage.stake(serviceId); + await stakingNativeToken.stake(serviceId); // Check that the service is staked - const stakingState = await serviceStakingMechUsage.getServiceStakingState(serviceId); + const stakingState = await stakingNativeToken.getStakingState(serviceId); expect(stakingState).to.equal(1); // Get the service multisig contract @@ -187,19 +204,19 @@ describe("ServiceStakingMechUsage", function () { await helpers.time.increase(maxInactivity); // Calculate service staking reward that must be zero - const reward = await serviceStakingMechUsage.calculateServiceStakingReward(serviceId); + const reward = await stakingNativeToken.calculateStakingReward(serviceId); expect(reward).to.equal(0); // Unstake the service const balanceBefore = await ethers.provider.getBalance(multisig.address); - await serviceStakingMechUsage.unstake(serviceId); + await stakingNativeToken.unstake(serviceId); const balanceAfter = await ethers.provider.getBalance(multisig.address); // The multisig balance before and after unstake must be the same (zero reward) expect(balanceBefore).to.equal(balanceAfter); // Check the final serviceIds set to be empty - const serviceIds = await serviceStakingMechUsage.getServiceIds(); + const serviceIds = await stakingNativeToken.getServiceIds(); expect(serviceIds.length).to.equal(0); // Restore a previous state of blockchain @@ -211,16 +228,16 @@ describe("ServiceStakingMechUsage", function () { const snapshot = await helpers.takeSnapshot(); // Deposit to the contract - await deployer.sendTransaction({to: serviceStakingMechUsage.address, value: ethers.utils.parseEther("1")}); + await deployer.sendTransaction({to: stakingNativeToken.address, value: ethers.utils.parseEther("1")}); // Approve services - await serviceRegistry.approve(serviceStakingMechUsage.address, serviceId); + await serviceRegistry.approve(stakingNativeToken.address, serviceId); // Stake the service - await serviceStakingMechUsage.stake(serviceId); + await stakingNativeToken.stake(serviceId); // Check that the service is staked - const stakingState = await serviceStakingMechUsage.getServiceStakingState(serviceId); + const stakingState = await stakingNativeToken.getStakingState(serviceId); expect(stakingState).to.equal(1); // Get the service multisig contract @@ -234,19 +251,19 @@ describe("ServiceStakingMechUsage", function () { await helpers.time.increase(maxInactivity); // Calculate service staking reward that must be zero - const reward = await serviceStakingMechUsage.calculateServiceStakingReward(serviceId); + const reward = await stakingNativeToken.calculateStakingReward(serviceId); expect(reward).to.equal(0); // Unstake the service const balanceBefore = await ethers.provider.getBalance(multisig.address); - await serviceStakingMechUsage.unstake(serviceId); + await stakingNativeToken.unstake(serviceId); const balanceAfter = await ethers.provider.getBalance(multisig.address); // The multisig balance before and after unstake must be the same (zero reward) expect(balanceBefore).to.equal(balanceAfter); // Check the final serviceIds set to be empty - const serviceIds = await serviceStakingMechUsage.getServiceIds(); + const serviceIds = await stakingNativeToken.getServiceIds(); expect(serviceIds.length).to.equal(0); // Restore a previous state of blockchain @@ -258,13 +275,13 @@ describe("ServiceStakingMechUsage", function () { const snapshot = await helpers.takeSnapshot(); // Deposit to the contract - await deployer.sendTransaction({to: serviceStakingMechUsage.address, value: ethers.utils.parseEther("1")}); + await deployer.sendTransaction({to: stakingNativeToken.address, value: ethers.utils.parseEther("1")}); // Approve services - await serviceRegistry.approve(serviceStakingMechUsage.address, serviceId); + await serviceRegistry.approve(stakingNativeToken.address, serviceId); // Stake the first service - await serviceStakingMechUsage.stake(serviceId); + await stakingNativeToken.stake(serviceId); // Get the service multisig contract const service = await serviceRegistry.getService(serviceId); @@ -272,7 +289,8 @@ describe("ServiceStakingMechUsage", function () { // Make transactions by the service multisig to increase the requests count let nonce = await multisig.nonce(); - let txHashData = await safeContracts.buildContractCall(agentMech, "increaseRequestsCount", [multisig.address], nonce, 0, 0); + let txHashData = await safeContracts.buildContractCall(agentMech, "increaseRequestsCount", + [multisig.address], nonce, 0, 0); let signMessageData = await safeContracts.safeSignMessage(agentInstances[0], multisig, txHashData, 0); await safeContracts.executeTx(multisig, txHashData, [signMessageData], 0); @@ -286,7 +304,7 @@ describe("ServiceStakingMechUsage", function () { await helpers.time.increase(maxInactivity); // Call the checkpoint at this time - await serviceStakingMechUsage.checkpoint(); + await stakingNativeToken.checkpoint(); // Execute one more multisig tx nonce = await multisig.nonce(); @@ -298,19 +316,19 @@ describe("ServiceStakingMechUsage", function () { await helpers.time.increase(maxInactivity); // Calculate service staking reward that must be greater than zero - const reward = await serviceStakingMechUsage.calculateServiceStakingReward(serviceId); + const reward = await stakingNativeToken.calculateStakingReward(serviceId); expect(reward).to.greaterThan(0); // Unstake the service const balanceBefore = ethers.BigNumber.from(await ethers.provider.getBalance(multisig.address)); - await serviceStakingMechUsage.unstake(serviceId); + await stakingNativeToken.unstake(serviceId); const balanceAfter = ethers.BigNumber.from(await ethers.provider.getBalance(multisig.address)); // The balance before and after the unstake call must be different expect(balanceAfter).to.gt(balanceBefore); // Check the final serviceIds set to be empty - const serviceIds = await serviceStakingMechUsage.getServiceIds(); + const serviceIds = await stakingNativeToken.getServiceIds(); expect(serviceIds.length).to.equal(0); // Restore a previous state of blockchain @@ -325,8 +343,8 @@ describe("ServiceStakingMechUsage", function () { await token.approve(serviceRegistryTokenUtility.address, initSupply); await token.connect(operator).approve(serviceRegistryTokenUtility.address, initSupply); // Approve and deposit token to the staking contract - await token.approve(serviceStakingTokenMechUsage.address, initSupply); - await serviceStakingTokenMechUsage.deposit(ethers.utils.parseEther("1")); + await token.approve(stakingToken.address, initSupply); + await stakingToken.deposit(ethers.utils.parseEther("1")); // Create a service with the token2 (service Id == 3) const sId = 3; @@ -342,10 +360,10 @@ describe("ServiceStakingMechUsage", function () { await serviceRegistry.deploy(deployer.address, sId, gnosisSafeMultisig.address, payload); // Approve services - await serviceRegistry.approve(serviceStakingTokenMechUsage.address, sId); + await serviceRegistry.approve(stakingToken.address, sId); // Stake the first service - await serviceStakingTokenMechUsage.stake(sId); + await stakingToken.stake(sId); // Get the service multisig contract const service = await serviceRegistry.getService(sId); @@ -353,7 +371,8 @@ describe("ServiceStakingMechUsage", function () { // Make transactions by the service multisig to increase the requests count let nonce = await multisig.nonce(); - let txHashData = await safeContracts.buildContractCall(agentMech, "increaseRequestsCount", [multisig.address], nonce, 0, 0); + let txHashData = await safeContracts.buildContractCall(agentMech, "increaseRequestsCount", + [multisig.address], nonce, 0, 0); let signMessageData = await safeContracts.safeSignMessage(agentInstances[2], multisig, txHashData, 0); await safeContracts.executeTx(multisig, txHashData, [signMessageData], 0); @@ -367,7 +386,7 @@ describe("ServiceStakingMechUsage", function () { await helpers.time.increase(livenessPeriod); // Call the checkpoint at this time - await serviceStakingTokenMechUsage.checkpoint(); + await stakingToken.checkpoint(); // Execute one more multisig tx nonce = await multisig.nonce(); @@ -379,19 +398,19 @@ describe("ServiceStakingMechUsage", function () { await helpers.time.increase(maxInactivity); // Calculate service staking reward that must be greater than zero - const reward = await serviceStakingTokenMechUsage.calculateServiceStakingReward(sId); + const reward = await stakingToken.calculateStakingReward(sId); expect(reward).to.greaterThan(0); // Unstake the service const balanceBefore = ethers.BigNumber.from(await token.balanceOf(multisig.address)); - await serviceStakingTokenMechUsage.unstake(sId); + await stakingToken.unstake(sId); const balanceAfter = ethers.BigNumber.from(await token.balanceOf(multisig.address)); // The balance before and after the unstake call must be different expect(balanceAfter.gt(balanceBefore)); // Check the final serviceIds set to be empty - const serviceIds = await serviceStakingTokenMechUsage.getServiceIds(); + const serviceIds = await stakingToken.getServiceIds(); expect(serviceIds.length).to.equal(0); // Restore a previous state of blockchain diff --git a/test/ServiceStakingMechUsages.t.sol b/test/StakingMechUsages.t.sol similarity index 79% rename from test/ServiceStakingMechUsages.t.sol rename to test/StakingMechUsages.t.sol index 83f3a29..646e159 100644 --- a/test/ServiceStakingMechUsages.t.sol +++ b/test/StakingMechUsages.t.sol @@ -1,4 +1,4 @@ -pragma solidity =0.8.23; +pragma solidity =0.8.25; import {IService} from "../lib/autonolas-registries/contracts/interfaces/IService.sol"; import "@gnosis.pm/safe-contracts/contracts/GnosisSafe.sol"; @@ -12,11 +12,14 @@ import {ServiceRegistryTokenUtility} from "../lib/autonolas-registries/contracts import {ServiceManagerToken} from "../lib/autonolas-registries/contracts/ServiceManagerToken.sol"; import {OperatorWhitelist} from "../lib/autonolas-registries/contracts/utils/OperatorWhitelist.sol"; import {GnosisSafeMultisig} from "../lib/autonolas-registries/contracts/multisigs/GnosisSafeMultisig.sol"; -import {ServiceStakingMechUsage} from "../contracts/mech_usage/ServiceStakingMechUsage.sol"; -import {ServiceStakingTokenMechUsage} from "../contracts/mech_usage/ServiceStakingTokenMechUsage.sol"; import {MockAgentMech} from "../contracts/test/MockAgentMech.sol"; import {SafeNonceLib} from "../contracts/test/SafeNonceLib.sol"; -import {ServiceStakingBase} from "../lib/autonolas-registries/contracts/staking/ServiceStakingBase.sol"; +import {StakingNativeToken} from "../lib/autonolas-registries/contracts/staking/StakingNativeToken.sol"; +import {StakingToken} from "../lib/autonolas-registries/contracts/staking/StakingToken.sol"; +import {StakingBase} from "../lib/autonolas-registries/contracts/staking/StakingBase.sol"; +import {StakingVerifier} from "../lib/autonolas-registries/contracts/staking/StakingVerifier.sol"; +import {StakingFactory} from "../lib/autonolas-registries/contracts/staking/StakingFactory.sol"; +import {MechActivityChecker} from "../contracts/mech_usage/MechActivityChecker.sol"; contract BaseSetup is Test { Utils internal utils; @@ -29,8 +32,13 @@ contract BaseSetup is Test { GnosisSafeProxy internal gnosisSafeProxy; GnosisSafeProxyFactory internal gnosisSafeProxyFactory; GnosisSafeMultisig internal gnosisSafeMultisig; - ServiceStakingMechUsage internal serviceStakingMechUsage; - ServiceStakingTokenMechUsage internal serviceStakingTokenMechUsage; + StakingNativeToken internal stakingNativeTokenImplementation; + StakingNativeToken internal stakingNativeToken; + StakingToken internal stakingTokenImplementation; + StakingToken internal stakingToken; + StakingVerifier internal stakingVerifier; + StakingFactory internal stakingFactory; + MechActivityChecker internal mechActivityChecker; MockAgentMech internal agentMech; SafeNonceLib internal safeNonceLib; @@ -65,6 +73,8 @@ contract BaseSetup is Test { uint256 internal maxNumInactivityPeriods = 3; // Liveness period uint256 internal livenessPeriod = 1 days; + // Time for emissions + uint256 internal timeForEmissions = 1 weeks; // Liveness ratio in the format of 1e18 uint256 internal livenessRatio = 0.0001 ether; // One nonce in 3 hours // Number of agent instances in the service @@ -109,15 +119,39 @@ contract BaseSetup is Test { // Get the multisig proxy bytecode hash bytes32 multisigProxyHash = keccak256(address(gnosisSafeProxy).code); - // Deploy service staking native token and arbitrary ERC20 token - ServiceStakingBase.StakingParams memory stakingParams = ServiceStakingBase.StakingParams(maxNumServices, - rewardsPerSecond, minStakingDeposit, minNumStakingPeriods, maxNumInactivityPeriods, livenessPeriod, - livenessRatio, numAgentInstances, emptyArray, 0, bytes32(0)); + // Agent mech agentMech = new MockAgentMech(); - serviceStakingMechUsage = new ServiceStakingMechUsage(stakingParams, address(serviceRegistry), - multisigProxyHash, address(agentMech)); - serviceStakingTokenMechUsage = new ServiceStakingTokenMechUsage(stakingParams, address(serviceRegistry), - address(serviceRegistryTokenUtility), address(token), multisigProxyHash, address(agentMech)); + + // Deploy service staking verifier + stakingVerifier = new StakingVerifier(address(token), rewardsPerSecond, timeForEmissions, maxNumServices); + + // Deploy service staking factory + stakingFactory = new StakingFactory(address(0)); + + // Deploy MechActivityChecker (staking activity checker) + mechActivityChecker = new MechActivityChecker(address(agentMech), livenessRatio); + + // Deploy service staking native token and arbitrary ERC20 token + StakingBase.StakingParams memory stakingParams = StakingBase.StakingParams( + bytes32(uint256(uint160(address(msg.sender)))), maxNumServices, rewardsPerSecond, minStakingDeposit, + minNumStakingPeriods, maxNumInactivityPeriods, livenessPeriod, timeForEmissions, numAgentInstances, + emptyArray, 0, bytes32(0), multisigProxyHash, address(serviceRegistry), address(mechActivityChecker)); + stakingNativeTokenImplementation = new StakingNativeToken(); + stakingTokenImplementation = new StakingToken(); + + // Initialization payload and deployment of stakingNativeToken + bytes memory initPayload = abi.encodeWithSelector(stakingNativeTokenImplementation.initialize.selector, + stakingParams, address(serviceRegistry), multisigProxyHash); + stakingNativeToken = StakingNativeToken(stakingFactory.createStakingInstance( + address(stakingNativeTokenImplementation), initPayload)); + + // Set the stakingVerifier + stakingFactory.changeVerifier(address(stakingVerifier)); + // Initialization payload and deployment of stakingToken + initPayload = abi.encodeWithSelector(stakingTokenImplementation.initialize.selector, + stakingParams, address(serviceRegistryTokenUtility), address(token)); + stakingToken = StakingToken(stakingFactory.createStakingInstance( + address(stakingTokenImplementation), initPayload)); // Whitelist multisig implementations serviceRegistry.changeMultisigPermission(address(gnosisSafeMultisig), true); @@ -175,7 +209,7 @@ contract BaseSetup is Test { } } -contract ServiceStakingMechUsages is BaseSetup { +contract StakingMechUsages is BaseSetup { function setUp() public override { super.setUp(); } @@ -185,14 +219,14 @@ contract ServiceStakingMechUsages is BaseSetup { /// @param numNonces Number of nonces per day. function testNoncesLimited(uint8 numNonces) external { // Send funds to a native token staking contract - address(serviceStakingMechUsage).call{value: 100 ether}(""); + address(stakingNativeToken).call{value: 100 ether}(""); // Stake services for (uint256 i = 0; i < numServices; ++i) { uint256 serviceId = i + 1; vm.startPrank(deployer); - serviceRegistry.approve(address(serviceStakingMechUsage), serviceId); - serviceStakingMechUsage.stake(serviceId); + serviceRegistry.approve(address(stakingNativeToken), serviceId); + stakingNativeToken.stake(serviceId); vm.stopPrank(); } @@ -241,19 +275,19 @@ contract ServiceStakingMechUsages is BaseSetup { } // Move one day ahead - vm.warp(block.timestamp + serviceStakingMechUsage.maxInactivityDuration() + 1); + vm.warp(block.timestamp + stakingNativeToken.maxInactivityDuration() + 1); // Call the checkpoint - serviceStakingMechUsage.checkpoint(); + stakingNativeToken.checkpoint(); // Unstake if there are no available rewards - if (serviceStakingMechUsage.availableRewards() == 0) { + if (stakingNativeToken.availableRewards() == 0) { for (uint256 j = 0; j < numServices; ++j) { uint256 serviceId = j + 1; // Unstake if the service is not yet unstaked, otherwise ignore - if (uint8(serviceStakingMechUsage.getServiceStakingState(serviceId)) > 0) { + if (uint8(stakingNativeToken.getStakingState(serviceId)) > 0) { vm.startPrank(deployer); - serviceStakingMechUsage.unstake(serviceId); + stakingNativeToken.unstake(serviceId); vm.stopPrank(); } } @@ -265,14 +299,14 @@ contract ServiceStakingMechUsages is BaseSetup { /// @param numNonces Number of nonces to increase / decrease per day. function testManipulateNonces(uint128 numNonces) external { // Send funds to a native token staking contract - address(serviceStakingMechUsage).call{value: 100 ether}(""); + address(stakingNativeToken).call{value: 100 ether}(""); // Stake services for (uint256 i = 0; i < numServices; ++i) { uint256 serviceId = i + 1; vm.startPrank(deployer); - serviceRegistry.approve(address(serviceStakingMechUsage), serviceId); - serviceStakingMechUsage.stake(serviceId); + serviceRegistry.approve(address(stakingNativeToken), serviceId); + stakingNativeToken.stake(serviceId); vm.stopPrank(); } @@ -312,19 +346,19 @@ contract ServiceStakingMechUsages is BaseSetup { } // Move one day ahead - vm.warp(block.timestamp + serviceStakingMechUsage.maxInactivityDuration() + 1); + vm.warp(block.timestamp + stakingNativeToken.maxInactivityDuration() + 1); // Call the checkpoint - serviceStakingMechUsage.checkpoint(); + stakingNativeToken.checkpoint(); // Unstake if there are no available rewards - if (serviceStakingMechUsage.availableRewards() == 0) { + if (stakingNativeToken.availableRewards() == 0) { for (uint256 j = 0; j < numServices; ++j) { uint256 serviceId = j + 1; // Unstake if the service is not yet unstaked, otherwise ignore - if (uint8(serviceStakingMechUsage.getServiceStakingState(serviceId)) > 0) { + if (uint8(stakingNativeToken.getStakingState(serviceId)) > 0) { vm.startPrank(deployer); - serviceStakingMechUsage.unstake(serviceId); + stakingNativeToken.unstake(serviceId); vm.stopPrank(); } } @@ -336,14 +370,14 @@ contract ServiceStakingMechUsages is BaseSetup { /// @param numNonces Number of nonces per day. function testNoncesAgentMech(uint8 numNonces) external { // Send funds to a native token staking contract - address(serviceStakingMechUsage).call{value: 100 ether}(""); + address(stakingNativeToken).call{value: 100 ether}(""); // Stake services for (uint256 i = 0; i < numServices; ++i) { uint256 serviceId = i + 1; vm.startPrank(deployer); - serviceRegistry.approve(address(serviceStakingMechUsage), serviceId); - serviceStakingMechUsage.stake(serviceId); + serviceRegistry.approve(address(stakingNativeToken), serviceId); + stakingNativeToken.stake(serviceId); vm.stopPrank(); } @@ -392,19 +426,19 @@ contract ServiceStakingMechUsages is BaseSetup { } // Move one day ahead - vm.warp(block.timestamp + serviceStakingMechUsage.maxInactivityDuration() + 1); + vm.warp(block.timestamp + stakingNativeToken.maxInactivityDuration() + 1); // Call the checkpoint - serviceStakingMechUsage.checkpoint(); + stakingNativeToken.checkpoint(); // Unstake if there are no available rewards - if (serviceStakingMechUsage.availableRewards() == 0) { + if (stakingNativeToken.availableRewards() == 0) { for (uint256 j = 0; j < numServices; ++j) { uint256 serviceId = j + 1; // Unstake if the service is not yet unstaked, otherwise ignore - if (uint8(serviceStakingMechUsage.getServiceStakingState(serviceId)) > 0) { + if (uint8(stakingNativeToken.getStakingState(serviceId)) > 0) { vm.startPrank(deployer); - serviceStakingMechUsage.unstake(serviceId); + stakingNativeToken.unstake(serviceId); vm.stopPrank(); } } @@ -416,15 +450,15 @@ contract ServiceStakingMechUsages is BaseSetup { /// @param numNonces Number of nonces per day. function testNoncesTokenAgentMech(uint8 numNonces) external { // Send tokens to a ERC20 token staking contract - token.approve(address(serviceStakingTokenMechUsage), 100 ether); - serviceStakingTokenMechUsage.deposit(100 ether); + token.approve(address(stakingToken), 100 ether); + stakingToken.deposit(100 ether); // Stake services for (uint256 i = 0; i < numServices; ++i) { uint256 serviceId = i + numServices + 1; vm.startPrank(deployer); - serviceRegistry.approve(address(serviceStakingTokenMechUsage), serviceId); - serviceStakingTokenMechUsage.stake(serviceId); + serviceRegistry.approve(address(stakingToken), serviceId); + stakingToken.stake(serviceId); vm.stopPrank(); } @@ -472,19 +506,19 @@ contract ServiceStakingMechUsages is BaseSetup { } // Move one day ahead - vm.warp(block.timestamp + serviceStakingMechUsage.maxInactivityDuration() + 1); + vm.warp(block.timestamp + stakingNativeToken.maxInactivityDuration() + 1); // Call the checkpoint - serviceStakingTokenMechUsage.checkpoint(); + stakingToken.checkpoint(); // Unstake if there are no available rewards - if (serviceStakingTokenMechUsage.availableRewards() == 0) { + if (stakingToken.availableRewards() == 0) { for (uint256 j = 0; j < numServices; ++j) { uint256 serviceId = j + numServices + 1; // Unstake if the service is not yet unstaked, otherwise ignore - if (uint8(serviceStakingTokenMechUsage.getServiceStakingState(serviceId)) > 0) { + if (uint8(stakingToken.getStakingState(serviceId)) > 0) { vm.startPrank(deployer); - serviceStakingTokenMechUsage.unstake(serviceId); + stakingToken.unstake(serviceId); vm.stopPrank(); } } diff --git a/yarn.lock b/yarn.lock index db5aa60..8967b49 100644 --- a/yarn.lock +++ b/yarn.lock @@ -45,42 +45,6 @@ dependencies: regenerator-runtime "^0.14.0" -"@chainsafe/as-sha256@^0.3.1": - version "0.3.1" - resolved "https://registry.yarnpkg.com/@chainsafe/as-sha256/-/as-sha256-0.3.1.tgz#3639df0e1435cab03f4d9870cc3ac079e57a6fc9" - integrity sha512-hldFFYuf49ed7DAakWVXSJODuq3pzJEguD8tQ7h+sGkM18vja+OFoJI9krnGmgzyuZC2ETX0NOIcCTy31v2Mtg== - -"@chainsafe/persistent-merkle-tree@^0.4.2": - version "0.4.2" - resolved "https://registry.yarnpkg.com/@chainsafe/persistent-merkle-tree/-/persistent-merkle-tree-0.4.2.tgz#4c9ee80cc57cd3be7208d98c40014ad38f36f7ff" - integrity sha512-lLO3ihKPngXLTus/L7WHKaw9PnNJWizlOF1H9NNzHP6Xvh82vzg9F2bzkXhYIFshMZ2gTCEz8tq6STe7r5NDfQ== - dependencies: - "@chainsafe/as-sha256" "^0.3.1" - -"@chainsafe/persistent-merkle-tree@^0.5.0": - version "0.5.0" - resolved "https://registry.yarnpkg.com/@chainsafe/persistent-merkle-tree/-/persistent-merkle-tree-0.5.0.tgz#2b4a62c9489a5739dedd197250d8d2f5427e9f63" - integrity sha512-l0V1b5clxA3iwQLXP40zYjyZYospQLZXzBVIhhr9kDg/1qHZfzzHw0jj4VPBijfYCArZDlPkRi1wZaV2POKeuw== - dependencies: - "@chainsafe/as-sha256" "^0.3.1" - -"@chainsafe/ssz@^0.10.0": - version "0.10.2" - resolved "https://registry.yarnpkg.com/@chainsafe/ssz/-/ssz-0.10.2.tgz#c782929e1bb25fec66ba72e75934b31fd087579e" - integrity sha512-/NL3Lh8K+0q7A3LsiFq09YXS9fPE+ead2rr7vM2QK8PLzrNsw3uqrif9bpRX5UxgeRjM+vYi+boCM3+GM4ovXg== - dependencies: - "@chainsafe/as-sha256" "^0.3.1" - "@chainsafe/persistent-merkle-tree" "^0.5.0" - -"@chainsafe/ssz@^0.9.2": - version "0.9.4" - resolved "https://registry.yarnpkg.com/@chainsafe/ssz/-/ssz-0.9.4.tgz#696a8db46d6975b600f8309ad3a12f7c0e310497" - integrity sha512-77Qtg2N1ayqs4Bg/wvnWfg5Bta7iy7IRh8XqXh7oNMeP2HBbBwx8m6yTpA8p0EHItWPEBkgZd5S5/LSlp3GXuQ== - dependencies: - "@chainsafe/as-sha256" "^0.3.1" - "@chainsafe/persistent-merkle-tree" "^0.4.2" - case "^1.6.3" - "@colors/colors@1.5.0": version "1.5.0" resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" @@ -323,7 +287,7 @@ dependencies: "@ethersproject/logger" "^5.7.0" -"@ethersproject/providers@5.7.2", "@ethersproject/providers@^5.7.1", "@ethersproject/providers@^5.7.2": +"@ethersproject/providers@5.7.2", "@ethersproject/providers@^5.7.2": version "5.7.2" resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.7.2.tgz#f8b1a4f275d7ce58cf0a2eec222269a08beb18cb" integrity sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg== @@ -711,139 +675,83 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@nomicfoundation/ethereumjs-block@5.0.2": - version "5.0.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-block/-/ethereumjs-block-5.0.2.tgz#13a7968f5964f1697da941281b7f7943b0465d04" - integrity sha512-hSe6CuHI4SsSiWWjHDIzWhSiAVpzMUcDRpWYzN0T9l8/Rz7xNn3elwVOJ/tAyS0LqL6vitUD78Uk7lQDXZun7Q== - dependencies: - "@nomicfoundation/ethereumjs-common" "4.0.2" - "@nomicfoundation/ethereumjs-rlp" "5.0.2" - "@nomicfoundation/ethereumjs-trie" "6.0.2" - "@nomicfoundation/ethereumjs-tx" "5.0.2" - "@nomicfoundation/ethereumjs-util" "9.0.2" - ethereum-cryptography "0.1.3" - ethers "^5.7.1" - -"@nomicfoundation/ethereumjs-blockchain@7.0.2": - version "7.0.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-blockchain/-/ethereumjs-blockchain-7.0.2.tgz#45323b673b3d2fab6b5008535340d1b8fea7d446" - integrity sha512-8UUsSXJs+MFfIIAKdh3cG16iNmWzWC/91P40sazNvrqhhdR/RtGDlFk2iFTGbBAZPs2+klZVzhRX8m2wvuvz3w== - dependencies: - "@nomicfoundation/ethereumjs-block" "5.0.2" - "@nomicfoundation/ethereumjs-common" "4.0.2" - "@nomicfoundation/ethereumjs-ethash" "3.0.2" - "@nomicfoundation/ethereumjs-rlp" "5.0.2" - "@nomicfoundation/ethereumjs-trie" "6.0.2" - "@nomicfoundation/ethereumjs-tx" "5.0.2" - "@nomicfoundation/ethereumjs-util" "9.0.2" - abstract-level "^1.0.3" - debug "^4.3.3" - ethereum-cryptography "0.1.3" - level "^8.0.0" - lru-cache "^5.1.1" - memory-level "^1.0.0" - -"@nomicfoundation/ethereumjs-common@4.0.2": - version "4.0.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-4.0.2.tgz#a15d1651ca36757588fdaf2a7d381a150662a3c3" - integrity sha512-I2WGP3HMGsOoycSdOTSqIaES0ughQTueOsddJ36aYVpI3SN8YSusgRFLwzDJwRFVIYDKx/iJz0sQ5kBHVgdDwg== - dependencies: - "@nomicfoundation/ethereumjs-util" "9.0.2" - crc-32 "^1.2.0" - -"@nomicfoundation/ethereumjs-ethash@3.0.2": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-ethash/-/ethereumjs-ethash-3.0.2.tgz#da77147f806401ee996bfddfa6487500118addca" - integrity sha512-8PfoOQCcIcO9Pylq0Buijuq/O73tmMVURK0OqdjhwqcGHYC2PwhbajDh7GZ55ekB0Px197ajK3PQhpKoiI/UPg== - dependencies: - "@nomicfoundation/ethereumjs-block" "5.0.2" - "@nomicfoundation/ethereumjs-rlp" "5.0.2" - "@nomicfoundation/ethereumjs-util" "9.0.2" - abstract-level "^1.0.3" - bigint-crypto-utils "^3.0.23" - ethereum-cryptography "0.1.3" - -"@nomicfoundation/ethereumjs-evm@2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-evm/-/ethereumjs-evm-2.0.2.tgz#4c2f4b84c056047102a4fa41c127454e3f0cfcf6" - integrity sha512-rBLcUaUfANJxyOx9HIdMX6uXGin6lANCulIm/pjMgRqfiCRMZie3WKYxTSd8ZE/d+qT+zTedBF4+VHTdTSePmQ== - dependencies: - "@ethersproject/providers" "^5.7.1" - "@nomicfoundation/ethereumjs-common" "4.0.2" - "@nomicfoundation/ethereumjs-tx" "5.0.2" - "@nomicfoundation/ethereumjs-util" "9.0.2" - debug "^4.3.3" +"@nomicfoundation/edr-darwin-arm64@0.3.8": + version "0.3.8" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.3.8.tgz#09de1f03c0336670fce959f376f0fe9137545836" + integrity sha512-eB0leCexS8sQEmfyD72cdvLj9djkBzQGP4wSQw6SNf2I4Sw4Cnzb3d45caG2FqFFjbvfqL0t+badUUIceqQuMw== + +"@nomicfoundation/edr-darwin-x64@0.3.8": + version "0.3.8" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-darwin-x64/-/edr-darwin-x64-0.3.8.tgz#c3ca237c74ed3b6fb800fd7f1de7174f4ad24f72" + integrity sha512-JksVCS1N5ClwVF14EvO25HCQ+Laljh/KRfHERMVAC9ZwPbTuAd/9BtKvToCBi29uCHWqsXMI4lxCApYQv2nznw== + +"@nomicfoundation/edr-linux-arm64-gnu@0.3.8": + version "0.3.8" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-arm64-gnu/-/edr-linux-arm64-gnu-0.3.8.tgz#08bd367789e745f4e78a8a87368fc470eea8a7de" + integrity sha512-raCE+fOeNXhVBLUo87cgsHSGvYYRB6arih4eG6B9KGACWK5Veebtm9xtKeiD8YCsdUlUfat6F7ibpeNm91fpsA== + +"@nomicfoundation/edr-linux-arm64-musl@0.3.8": + version "0.3.8" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-arm64-musl/-/edr-linux-arm64-musl-0.3.8.tgz#9cab5cbec0052cb5812c6c66c463d28a756cd916" + integrity sha512-PwiDp4wBZWMCIy29eKkv8moTKRrpiSDlrc+GQMSZLhOAm8T33JKKXPwD/2EbplbhCygJDGXZdtEKl9x9PaH66A== + +"@nomicfoundation/edr-linux-x64-gnu@0.3.8": + version "0.3.8" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-x64-gnu/-/edr-linux-x64-gnu-0.3.8.tgz#d4a11b6ebcd1b29d7431d185c6df3e65a2cd4bde" + integrity sha512-6AcvA/XKoipGap5jJmQ9Y6yT7Uf39D9lu2hBcDCXnXbMcXaDGw4mn1/L4R63D+9VGZyu1PqlcJixCUZlGGIWlg== + +"@nomicfoundation/edr-linux-x64-musl@0.3.8": + version "0.3.8" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-x64-musl/-/edr-linux-x64-musl-0.3.8.tgz#b8eef960d06380a365866ddd1e97ecb7fbf6bd70" + integrity sha512-cxb0sEmZjlwhYWO28sPsV64VDx31ekskhC1IsDXU1p9ntjHSJRmW4KEIqJ2O3QwJap/kLKfMS6TckvY10gjc6w== + +"@nomicfoundation/edr-win32-x64-msvc@0.3.8": + version "0.3.8" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-win32-x64-msvc/-/edr-win32-x64-msvc-0.3.8.tgz#ac7061aeb07cc847c429513080b76bb05297a869" + integrity sha512-yVuVPqRRNLZk7TbBMkKw7lzCvI8XO8fNTPTYxymGadjr9rEGRuNTU1yBXjfJ59I1jJU/X2TSkRk1OFX0P5tpZQ== + +"@nomicfoundation/edr@^0.3.7": + version "0.3.8" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr/-/edr-0.3.8.tgz#28fe7ae4f462ae74a16cd1a714ff7b1cd9c22b4c" + integrity sha512-u2UJ5QpznSHVkZRh6ePWoeVb6kmPrrqh08gCnZ9FHlJV9CITqlrTQHJkacd+INH31jx88pTAJnxePE4XAiH5qg== + dependencies: + "@nomicfoundation/edr-darwin-arm64" "0.3.8" + "@nomicfoundation/edr-darwin-x64" "0.3.8" + "@nomicfoundation/edr-linux-arm64-gnu" "0.3.8" + "@nomicfoundation/edr-linux-arm64-musl" "0.3.8" + "@nomicfoundation/edr-linux-x64-gnu" "0.3.8" + "@nomicfoundation/edr-linux-x64-musl" "0.3.8" + "@nomicfoundation/edr-win32-x64-msvc" "0.3.8" + +"@nomicfoundation/ethereumjs-common@4.0.4": + version "4.0.4" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-4.0.4.tgz#9901f513af2d4802da87c66d6f255b510bef5acb" + integrity sha512-9Rgb658lcWsjiicr5GzNCjI1llow/7r0k50dLL95OJ+6iZJcVbi15r3Y0xh2cIO+zgX0WIHcbzIu6FeQf9KPrg== + dependencies: + "@nomicfoundation/ethereumjs-util" "9.0.4" + +"@nomicfoundation/ethereumjs-rlp@5.0.4": + version "5.0.4" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-5.0.4.tgz#66c95256fc3c909f6fb18f6a586475fc9762fa30" + integrity sha512-8H1S3s8F6QueOc/X92SdrA4RDenpiAEqMg5vJH99kcQaCy/a3Q6fgseo75mgWlbanGJXSlAPtnCeG9jvfTYXlw== + +"@nomicfoundation/ethereumjs-tx@5.0.4": + version "5.0.4" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-5.0.4.tgz#b0ceb58c98cc34367d40a30d255d6315b2f456da" + integrity sha512-Xjv8wAKJGMrP1f0n2PeyfFCCojHd7iS3s/Ab7qzF1S64kxZ8Z22LCMynArYsVqiFx6rzYy548HNVEyI+AYN/kw== + dependencies: + "@nomicfoundation/ethereumjs-common" "4.0.4" + "@nomicfoundation/ethereumjs-rlp" "5.0.4" + "@nomicfoundation/ethereumjs-util" "9.0.4" ethereum-cryptography "0.1.3" - mcl-wasm "^0.7.1" - rustbn.js "~0.2.0" -"@nomicfoundation/ethereumjs-rlp@5.0.2": - version "5.0.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-5.0.2.tgz#4fee8dc58a53ac6ae87fb1fca7c15dc06c6b5dea" - integrity sha512-QwmemBc+MMsHJ1P1QvPl8R8p2aPvvVcKBbvHnQOKBpBztEo0omN0eaob6FeZS/e3y9NSe+mfu3nNFBHszqkjTA== - -"@nomicfoundation/ethereumjs-statemanager@2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-statemanager/-/ethereumjs-statemanager-2.0.2.tgz#3ba4253b29b1211cafe4f9265fee5a0d780976e0" - integrity sha512-dlKy5dIXLuDubx8Z74sipciZnJTRSV/uHG48RSijhgm1V7eXYFC567xgKtsKiVZB1ViTP9iFL4B6Je0xD6X2OA== +"@nomicfoundation/ethereumjs-util@9.0.4": + version "9.0.4" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-9.0.4.tgz#84c5274e82018b154244c877b76bc049a4ed7b38" + integrity sha512-sLOzjnSrlx9Bb9EFNtHzK/FJFsfg2re6bsGqinFinH1gCqVfz9YYlXiMWwDM4C/L4ywuHFCYwfKTVr/QHQcU0Q== dependencies: - "@nomicfoundation/ethereumjs-common" "4.0.2" - "@nomicfoundation/ethereumjs-rlp" "5.0.2" - debug "^4.3.3" + "@nomicfoundation/ethereumjs-rlp" "5.0.4" ethereum-cryptography "0.1.3" - ethers "^5.7.1" - js-sdsl "^4.1.4" - -"@nomicfoundation/ethereumjs-trie@6.0.2": - version "6.0.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-trie/-/ethereumjs-trie-6.0.2.tgz#9a6dbd28482dca1bc162d12b3733acab8cd12835" - integrity sha512-yw8vg9hBeLYk4YNg5MrSJ5H55TLOv2FSWUTROtDtTMMmDGROsAu+0tBjiNGTnKRi400M6cEzoFfa89Fc5k8NTQ== - dependencies: - "@nomicfoundation/ethereumjs-rlp" "5.0.2" - "@nomicfoundation/ethereumjs-util" "9.0.2" - "@types/readable-stream" "^2.3.13" - ethereum-cryptography "0.1.3" - readable-stream "^3.6.0" - -"@nomicfoundation/ethereumjs-tx@5.0.2": - version "5.0.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-5.0.2.tgz#117813b69c0fdc14dd0446698a64be6df71d7e56" - integrity sha512-T+l4/MmTp7VhJeNloMkM+lPU3YMUaXdcXgTGCf8+ZFvV9NYZTRLFekRwlG6/JMmVfIfbrW+dRRJ9A6H5Q/Z64g== - dependencies: - "@chainsafe/ssz" "^0.9.2" - "@ethersproject/providers" "^5.7.2" - "@nomicfoundation/ethereumjs-common" "4.0.2" - "@nomicfoundation/ethereumjs-rlp" "5.0.2" - "@nomicfoundation/ethereumjs-util" "9.0.2" - ethereum-cryptography "0.1.3" - -"@nomicfoundation/ethereumjs-util@9.0.2": - version "9.0.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-9.0.2.tgz#16bdc1bb36f333b8a3559bbb4b17dac805ce904d" - integrity sha512-4Wu9D3LykbSBWZo8nJCnzVIYGvGCuyiYLIJa9XXNVt1q1jUzHdB+sJvx95VGCpPkCT+IbLecW6yfzy3E1bQrwQ== - dependencies: - "@chainsafe/ssz" "^0.10.0" - "@nomicfoundation/ethereumjs-rlp" "5.0.2" - ethereum-cryptography "0.1.3" - -"@nomicfoundation/ethereumjs-vm@7.0.2": - version "7.0.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-vm/-/ethereumjs-vm-7.0.2.tgz#3b0852cb3584df0e18c182d0672a3596c9ca95e6" - integrity sha512-Bj3KZT64j54Tcwr7Qm/0jkeZXJMfdcAtRBedou+Hx0dPOSIgqaIr0vvLwP65TpHbak2DmAq+KJbW2KNtIoFwvA== - dependencies: - "@nomicfoundation/ethereumjs-block" "5.0.2" - "@nomicfoundation/ethereumjs-blockchain" "7.0.2" - "@nomicfoundation/ethereumjs-common" "4.0.2" - "@nomicfoundation/ethereumjs-evm" "2.0.2" - "@nomicfoundation/ethereumjs-rlp" "5.0.2" - "@nomicfoundation/ethereumjs-statemanager" "2.0.2" - "@nomicfoundation/ethereumjs-trie" "6.0.2" - "@nomicfoundation/ethereumjs-tx" "5.0.2" - "@nomicfoundation/ethereumjs-util" "9.0.2" - debug "^4.3.3" - ethereum-cryptography "0.1.3" - mcl-wasm "^0.7.1" - rustbn.js "~0.2.0" "@nomicfoundation/hardhat-chai-matchers@^1.0.6": version "1.0.6" @@ -1183,14 +1091,6 @@ resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.9.tgz#66f7b26288f6799d279edf13da7ccd40d2fa9197" integrity sha512-wYLxw35euwqGvTDx6zfY1vokBFnsK0HNrzc6xNHchxfO2hpuRg74GbkEW7e3sSmPvj0TjCDT1VCa6OtHXnubsg== -"@types/readable-stream@^2.3.13": - version "2.3.15" - resolved "https://registry.yarnpkg.com/@types/readable-stream/-/readable-stream-2.3.15.tgz#3d79c9ceb1b6a57d5f6e6976f489b9b5384321ae" - integrity sha512-oM5JSKQCcICF1wvGgmecmHldZ48OZamtMxcGGVICOJA8o8cahXC1zEVAif8iwoc5j8etxFaRFnf095+CDsuoFQ== - dependencies: - "@types/node" "*" - safe-buffer "~5.1.1" - "@types/secp256k1@^4.0.1": version "4.0.5" resolved "https://registry.yarnpkg.com/@types/secp256k1/-/secp256k1-4.0.5.tgz#14b1766b4fbc198b0af5599d9fd21c89056633ce" @@ -1218,19 +1118,6 @@ abbrev@1.0.x: resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135" integrity sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q== -abstract-level@^1.0.0, abstract-level@^1.0.2, abstract-level@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/abstract-level/-/abstract-level-1.0.3.tgz#78a67d3d84da55ee15201486ab44c09560070741" - integrity sha512-t6jv+xHy+VYwc4xqZMn2Pa9DjcdzvzZmQGRjTFc8spIbRGHgBrEKbPq+rYXc7CCo0lxgYvSgKVg9qZAhpVQSjA== - dependencies: - 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-jsx@^5.3.2: version "5.3.2" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" @@ -1296,6 +1183,13 @@ amdefine@>=0.0.4: resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" integrity sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg== +ansi-align@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.1.tgz#0cdf12e111ace773a86e9a1fad1225c43cb19a59" + integrity sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w== + dependencies: + string-width "^4.1.0" + ansi-colors@4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" @@ -1457,11 +1351,6 @@ bech32@1.1.4: resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9" integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ== -bigint-crypto-utils@^3.0.23: - version "3.3.0" - resolved "https://registry.yarnpkg.com/bigint-crypto-utils/-/bigint-crypto-utils-3.3.0.tgz#72ad00ae91062cf07f2b1def9594006c279c1d77" - integrity sha512-jOTSb+drvEDxEq6OuUybOAv/xxoh3cuYRUIPyu8sSHQNKM303UQ2R1DAo45o1AkcIXw6fzbaFI1+xGGdaXs2lg== - bignumber.js@^9.1.2: version "9.1.2" resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.2.tgz#b7c4242259c008903b13707983b5f4bbd31eda0c" @@ -1508,6 +1397,20 @@ bn.js@^5.1.2, bn.js@^5.2.0, bn.js@^5.2.1: resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== +boxen@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-5.1.2.tgz#788cb686fc83c1f486dfa8a40c68fc2b831d2b50" + integrity sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ== + dependencies: + ansi-align "^3.0.0" + camelcase "^6.2.0" + chalk "^4.1.0" + cli-boxes "^2.2.1" + string-width "^4.2.2" + type-fest "^0.20.2" + widest-line "^3.1.0" + wrap-ansi "^7.0.0" + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -1535,16 +1438,6 @@ brorand@^1.1.0: resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== -browser-level@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/browser-level/-/browser-level-1.0.1.tgz#36e8c3183d0fe1c405239792faaab5f315871011" - integrity sha512-XECYKJ+Dbzw0lbydyQuJzwNXtOpbMSq737qxJN11sIRTErOMShvDpbzTlgju7orJKvx4epULolZAuJGLzCmWRQ== - dependencies: - abstract-level "^1.0.2" - catering "^2.1.1" - module-error "^1.0.2" - run-parallel-limit "^1.1.0" - browser-stdout@1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" @@ -1596,14 +1489,6 @@ buffer@^5.5.0: base64-js "^1.3.1" ieee754 "^1.1.13" -buffer@^6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" - integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.2.1" - bytes@3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" @@ -1623,26 +1508,16 @@ callsites@^3.0.0: resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== -camelcase@^6.0.0: +camelcase@^6.0.0, camelcase@^6.2.0: version "6.3.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== -case@^1.6.3: - version "1.6.3" - resolved "https://registry.yarnpkg.com/case/-/case-1.6.3.tgz#0a4386e3e9825351ca2e6216c60467ff5f1ea1c9" - integrity sha512-mzDSXIPaFwVDvZAHqZ9VlbyF4yyXRuX6IvB06WvPYkqJVO24kX1PPhv9bfpKNFZyxYFmmgo03HUiD8iklmJYRQ== - caseless@^0.12.0, caseless@~0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" integrity sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw== -catering@^2.1.0, catering@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/catering/-/catering-2.1.1.tgz#66acba06ed5ee28d5286133982a927de9a04b510" - integrity sha512-K7Qy8O9p76sL3/3m7/zLKbRkyOlSZAgzEaLhyj2mXS8PsCud2Eo4hAb8aLtZqHh0QGqLcb9dlJSu6lHRVENm1w== - cbor@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/cbor/-/cbor-8.1.0.tgz#cfc56437e770b73417a2ecbfc9caf6b771af60d5" @@ -1732,22 +1607,16 @@ cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: inherits "^2.0.1" safe-buffer "^5.0.1" -classic-level@^1.2.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/classic-level/-/classic-level-1.3.0.tgz#5e36680e01dc6b271775c093f2150844c5edd5c8" - integrity sha512-iwFAJQYtqRTRM0F6L8h4JCt00ZSGdOyqh7yVrhhjrOpFhmBjNlRUey64MCiyo6UmQHMJ+No3c81nujPv+n9yrg== - dependencies: - abstract-level "^1.0.2" - catering "^2.1.0" - module-error "^1.0.1" - napi-macros "^2.2.2" - node-gyp-build "^4.3.0" - clean-stack@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== +cli-boxes@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f" + integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw== + cli-table3@^0.5.0: version "0.5.1" resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.5.1.tgz#0252372d94dfc40dbd8df06005f48f31f656f202" @@ -1867,11 +1736,6 @@ cosmiconfig@^8.0.0: parse-json "^5.2.0" path-type "^4.0.0" -crc-32@^1.2.0: - version "1.2.2" - resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.2.tgz#3cad35a934b8bf71f25ca524b6da51fb7eace2ff" - integrity sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ== - create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" @@ -1919,7 +1783,7 @@ death@^1.1.0: resolved "https://registry.yarnpkg.com/death/-/death-1.1.0.tgz#01aa9c401edd92750514470b8266390c66c67318" integrity sha512-vsV6S4KVHvTGxbEcij7hkWRv0It+sGGWVOM67dQde/o5Xjnr+KmLjxWJii2uEObIrt1CcM9w0Yaovx+iOlIL+w== -debug@4, debug@4.3.4, debug@^4.1.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4: +debug@4, debug@4.3.4, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -2322,7 +2186,7 @@ ethereumjs-util@^7.1.4: ethereum-cryptography "^0.1.3" rlp "^2.2.4" -ethers@5.7.2, ethers@^5.5.4, ethers@^5.6.1, ethers@^5.7.0, ethers@^5.7.1, ethers@^5.7.2: +ethers@5.7.2, ethers@^5.5.4, ethers@^5.6.1, ethers@^5.7.0, ethers@^5.7.2: version "5.7.2" resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.7.2.tgz#3a7deeabbb8c030d4126b24f84e525466145872e" integrity sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg== @@ -2596,11 +2460,6 @@ function-bind@^1.1.2: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== -functional-red-black-tree@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - integrity sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g== - get-caller-file@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" @@ -2827,23 +2686,17 @@ hardhat-tracer@^2.6.0: debug "^4.3.4" ethers "^5.6.1" -hardhat@^2.18.2: - version "2.18.2" - resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.18.2.tgz#e82169bafc83c4b2af9b33ac38bae6da5603074e" - integrity sha512-lUVmJg7DsKcUCDpqv57CJl6vHqo/1PeHSfM3+WIa8UtRKmXyVTj1qQK01TDiuetkZBVg9Dn52qU+ZwaJQynaKA== +hardhat@^2.22.4: + version "2.22.4" + resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.22.4.tgz#766227b6cefca5dbf4fd15ab5b5a68138fa13baf" + integrity sha512-09qcXJFBHQUaraJkYNr7XlmwjOj27xBB0SL2rYS024hTj9tPMbp26AFjlf5quBMO9SR4AJFg+4qWahcYcvXBuQ== dependencies: "@ethersproject/abi" "^5.1.2" "@metamask/eth-sig-util" "^4.0.0" - "@nomicfoundation/ethereumjs-block" "5.0.2" - "@nomicfoundation/ethereumjs-blockchain" "7.0.2" - "@nomicfoundation/ethereumjs-common" "4.0.2" - "@nomicfoundation/ethereumjs-evm" "2.0.2" - "@nomicfoundation/ethereumjs-rlp" "5.0.2" - "@nomicfoundation/ethereumjs-statemanager" "2.0.2" - "@nomicfoundation/ethereumjs-trie" "6.0.2" - "@nomicfoundation/ethereumjs-tx" "5.0.2" - "@nomicfoundation/ethereumjs-util" "9.0.2" - "@nomicfoundation/ethereumjs-vm" "7.0.2" + "@nomicfoundation/edr" "^0.3.7" + "@nomicfoundation/ethereumjs-common" "4.0.4" + "@nomicfoundation/ethereumjs-tx" "5.0.4" + "@nomicfoundation/ethereumjs-util" "9.0.4" "@nomicfoundation/solidity-analyzer" "^0.1.0" "@sentry/node" "^5.18.1" "@types/bn.js" "^5.1.0" @@ -2851,6 +2704,7 @@ hardhat@^2.18.2: adm-zip "^0.4.16" aggregate-error "^3.0.0" ansi-escapes "^4.3.0" + boxen "^5.1.2" chalk "^2.4.2" chokidar "^3.4.0" ci-info "^2.0.0" @@ -2999,7 +2853,7 @@ iconv-lite@0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" -ieee754@^1.1.13, ieee754@^1.2.1: +ieee754@^1.1.13: version "1.2.1" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== @@ -3086,11 +2940,6 @@ is-binary-path@~2.1.0: dependencies: binary-extensions "^2.0.0" -is-buffer@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191" - integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ== - is-core-module@^2.13.0: version "2.13.1" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384" @@ -3155,11 +3004,6 @@ isexe@^2.0.0: resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== -js-sdsl@^4.1.4: - version "4.4.2" - resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.4.2.tgz#2e3c031b1f47d3aca8b775532e3ebb0818e7f847" - integrity sha512-dwXFwByc/ajSV6m5bcKAPwe4yDDF6D614pxmIi5odytzxRlwqF6nwoiCek80Ixc7Cvma5awClxrzFtxCQvcM8w== - js-sha3@0.8.0, js-sha3@^0.8.0: version "0.8.0" resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" @@ -3266,27 +3110,6 @@ klaw@^1.0.0: optionalDependencies: graceful-fs "^4.1.9" -level-supports@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/level-supports/-/level-supports-4.0.1.tgz#431546f9d81f10ff0fea0e74533a0e875c08c66a" - integrity sha512-PbXpve8rKeNcZ9C1mUicC9auIYFyGpkV9/i6g76tLgANwWhtG2v7I4xNBUlkn3lE2/dZF3Pi0ygYGtLc4RXXdA== - -level-transcoder@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/level-transcoder/-/level-transcoder-1.0.1.tgz#f8cef5990c4f1283d4c86d949e73631b0bc8ba9c" - integrity sha512-t7bFwFtsQeD8cl8NIoQ2iwxA0CL/9IFw7/9gAjOonH0PWTTiRfY7Hq+Ejbsxh86tXobDQ6IOiddjNYIfOBs06w== - dependencies: - buffer "^6.0.3" - module-error "^1.0.1" - -level@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/level/-/level-8.0.0.tgz#41b4c515dabe28212a3e881b61c161ffead14394" - integrity sha512-ypf0jjAk2BWI33yzEaaotpq7fkOPALKAgDBxggO6Q9HGX2MRXn0wbP1Jn/tJv1gtL867+YOjOB49WaUF3UoJNQ== - dependencies: - browser-level "^1.0.1" - classic-level "^1.2.0" - levn@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" @@ -3360,13 +3183,6 @@ loupe@^2.3.6: dependencies: get-func-name "^2.0.1" -lru-cache@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" - integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== - dependencies: - yallist "^3.0.2" - lru-cache@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" @@ -3402,11 +3218,6 @@ match-sorter@^6.3.1: "@babel/runtime" "^7.12.5" remove-accents "0.4.2" -mcl-wasm@^0.7.1: - version "0.7.9" - resolved "https://registry.yarnpkg.com/mcl-wasm/-/mcl-wasm-0.7.9.tgz#c1588ce90042a8700c3b60e40efb339fc07ab87f" - integrity sha512-iJIUcQWA88IJB/5L15GnJVnSQJmf/YaxxV6zRavv83HILHaJQb6y0iFyDMdDO0gN8X37tdxmAOrH/P8B6RB8sQ== - md5.js@^1.3.4: version "1.3.5" resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" @@ -3416,15 +3227,6 @@ md5.js@^1.3.4: inherits "^2.0.1" safe-buffer "^5.1.2" -memory-level@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/memory-level/-/memory-level-1.0.0.tgz#7323c3fd368f9af2f71c3cd76ba403a17ac41692" - integrity sha512-UXzwewuWeHBz5krr7EvehKcmLFNoXxGcvuYhC41tRnkrTbJohtS7kVn9akmgirtRygg+f7Yjsfi8Uu5SGSQ4Og== - dependencies: - abstract-level "^1.0.0" - functional-red-black-tree "^1.0.1" - module-error "^1.0.1" - memorystream@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" @@ -3547,11 +3349,6 @@ mocha@10.2.0, mocha@^10.0.0, mocha@^10.2.0: yargs-parser "20.2.4" yargs-unparser "2.0.0" -module-error@^1.0.1, module-error@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/module-error/-/module-error-1.0.2.tgz#8d1a48897ca883f47a45816d4fb3e3c6ba404d86" - integrity sha512-0yuvsqSCv8LbaOKhnsQ/T5JhyFlCYLPXK3U2sgV10zoKQwzs/MyfuQUOZQ1V/6OCOJsK/TRgNVrPuPDqtdMFtA== - ms@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" @@ -3581,11 +3378,6 @@ napi-build-utils@^1.0.1: resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806" integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg== -napi-macros@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/napi-macros/-/napi-macros-2.2.2.tgz#817fef20c3e0e40a963fbf7b37d1600bd0201044" - integrity sha512-hmEVtAGYzVQpCKdbQea4skABsdXW4RUh5t5mJ2zzqowJS2OyXZTU1KhDVFhx+NlWZ4ap9mqR9TcDO3LTTttd+g== - natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" @@ -3632,7 +3424,7 @@ node-fetch@^2.6.1: dependencies: whatwg-url "^5.0.0" -node-gyp-build@^4.2.0, node-gyp-build@^4.3.0, node-gyp-build@^4.5.0: +node-gyp-build@^4.2.0, node-gyp-build@^4.5.0: version "4.6.1" resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.6.1.tgz#24b6d075e5e391b8d5539d98c7fc5c210cac8a3e" integrity sha512-24vnklJmyRS8ViBNI8KbtK/r/DmXQMRiOMXTNz2nrTnAYUwjmEEbnnpB/+kt+yWRv73bPsSPRFddrcIbAxSiMQ== @@ -3930,7 +3722,7 @@ qs@^6.4.0, qs@^6.9.4: dependencies: side-channel "^1.0.4" -queue-microtask@^1.2.2, queue-microtask@^1.2.3: +queue-microtask@^1.2.2: version "1.2.3" resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== @@ -4121,13 +3913,6 @@ rlp@^2.2.3, rlp@^2.2.4: dependencies: bn.js "^5.2.0" -run-parallel-limit@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/run-parallel-limit/-/run-parallel-limit-1.1.0.tgz#be80e936f5768623a38a963262d6bef8ff11e7ba" - integrity sha512-jJA7irRNM91jaKc3Hcl1npHsFLOXOoTkPCUL1JEa1R82O2miplXXRaGdjW/KM/98YQWDhJLiSs793CnXfblJUw== - dependencies: - queue-microtask "^1.2.2" - run-parallel@^1.1.9: version "1.2.0" resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" @@ -4135,11 +3920,6 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" -rustbn.js@~0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/rustbn.js/-/rustbn.js-0.2.0.tgz#8082cb886e707155fd1cb6f23bd591ab8d55d0ca" - integrity sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA== - rxjs@6, rxjs@^6.6.7: version "6.6.7" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9" @@ -4433,7 +4213,7 @@ string-width@^2.1.1: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" -string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -4799,6 +4579,13 @@ which@^2.0.1: dependencies: isexe "^2.0.0" +widest-line@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca" + integrity sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg== + dependencies: + string-width "^4.0.0" + word-wrap@~1.2.3: version "1.2.5" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34" @@ -4843,11 +4630,6 @@ y18n@^5.0.5: resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== -yallist@^3.0.2: - version "3.1.1" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" - integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== - yallist@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"