diff --git a/.circleci/config.yml b/.circleci/config.yml index a3e13bdae..d24f2f3c0 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,13 +1,13 @@ version: 2.1 orbs: - node: circleci/node@4.7.0 + node: circleci/node@6.1.0 codecov: codecov/codecov@3.2.4 defaults: &defaults working_directory: ~/repo docker: - - image: cimg/node:18.15.0 + - image: cimg/node:20.17.0 - image: mongo:7.0.0-rc5-jammy jobs: diff --git a/.env.sample b/.env.sample index 085892c89..cf4d5a693 100644 --- a/.env.sample +++ b/.env.sample @@ -32,9 +32,9 @@ SILENT_LOGGER="false" | "true" # Boolean value for if we deploy the mock # true = we deploy the mock # false = we use a hard coded address and pull data from chain -MOCK_MEOW_TOKEN= -# Address of the MEOW Token deployed to the network PRIOR to running Campaign or any other EXISTING token -# This is only used if MOCK_MEOW_TOKEN is set to false (`test` and `prod` environments) +MOCK_Z_TOKEN= +# Address of the Z Token deployed to the network PRIOR to running Campaign or any other EXISTING token +# This is only used if MOCK_Z_TOKEN is set to false (`test` and `prod` environments) STAKING_TOKEN_ADDRESS= # Environment variables to create an entirely custom config when `env_level` above is not dev diff --git a/.eslintrc b/.eslintrc index 67dd7deb3..5bfb76c6d 100644 --- a/.eslintrc +++ b/.eslintrc @@ -5,6 +5,7 @@ "files": ["src/**/*.ts", "test/**/*.ts", "./*.ts"], "extends": ["@zero-tech/eslint-config-cpt/node-ts/.eslintrc.json"], "rules": { + "jsdoc/newline-after-description": "off", "no-unused-expressions": "off", "no-console": "off", "no-shadow": "warn", diff --git a/.gitignore b/.gitignore index a9de5f05c..387691055 100644 --- a/.gitignore +++ b/.gitignore @@ -1,22 +1,26 @@ -node_modules -.env -coverage -coverage.json -typechain -typechain-types -.idea -dist - -# Hardhat files -cache -artifacts - -# hardhat-tenderly plugin -deployments - -*.env -docker -docker*.tgz - -# We don't ever use the generated manifests -.openzeppelin +node_modules +.env +coverage +coverage.json +typechain +typechain-types +.idea +dist + +# Hardhat files +cache +artifacts + +# hardhat-tenderly plugin +deployments + +*.env +docker +docker*.tgz + +# We don't ever use the generated manifests +.openzeppelin +/.vscode + +# Don't source control log files from deployment +deploy-*.log diff --git a/.solcover.js b/.solcover.js index d4924e9a2..cc58f8471 100644 --- a/.solcover.js +++ b/.solcover.js @@ -1,4 +1,8 @@ module.exports = { + mocha: { + grep: "@skip-on-coverage", // Find everything with this tag + invert: true // Run the grep's inverse set. + }, skipFiles: [ 'utils/StringUtils.sol', 'token/mocks', diff --git a/README.md b/README.md index e2b290de4..8695d5d40 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ Create `.env` file in the root directory and add the following variables: ENV_LEVEL: "dev" # local dev environment MONGO_DB_URI: "mongodb://localhost:27018" # local instance of MongoDB in the Docker MONGO_DB_NAME: "zns-campaign" # name of the database -MOCK_MEOW_TOKEN: "true" # use mock MeowToken contract for local testing +MOCK_Z_TOKEN: "true" # use mock ZToken contract for local testing SILENT_LOGGER: "true" # disable logging for tests ``` diff --git a/contracts/access/AAccessControlled.sol b/contracts/access/AAccessControlled.sol index 19de2287c..fa2897fcf 100644 --- a/contracts/access/AAccessControlled.sol +++ b/contracts/access/AAccessControlled.sol @@ -1,7 +1,8 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.18; +pragma solidity 0.8.26; import { IZNSAccessController } from "./IZNSAccessController.sol"; +import { ZeroAddressPassed } from "../utils/CommonErrors.sol"; /** @@ -11,7 +12,6 @@ import { IZNSAccessController } from "./IZNSAccessController.sol"; * this contract needs to be inherited by the module. */ abstract contract AAccessControlled { - /** * @notice Emitted when the access controller contract address is set. */ @@ -66,7 +66,7 @@ abstract contract AAccessControlled { * @param _accessController Address of the ZNSAccessController contract. */ function _setAccessController(address _accessController) internal { - require(_accessController != address(0), "AC: _accessController is 0x0 address"); + if (_accessController == address(0)) revert ZeroAddressPassed(); accessController = IZNSAccessController(_accessController); emit AccessControllerSet(_accessController); } diff --git a/contracts/access/IZNSAccessController.sol b/contracts/access/IZNSAccessController.sol index 4008a1780..bf687e76b 100644 --- a/contracts/access/IZNSAccessController.sol +++ b/contracts/access/IZNSAccessController.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.18; +pragma solidity 0.8.26; import { IAccessControl } from "@openzeppelin/contracts/access/IAccessControl.sol"; @@ -15,10 +15,14 @@ interface IZNSAccessController is IAccessControl { function checkRegistrar(address account) external view; + function checkDomainToken(address account) external view; + function isAdmin(address account) external view returns (bool); function isRegistrar(address account) external view returns (bool); + function isDomainToken(address account) external view returns (bool); + function isGovernor(address account) external view returns (bool); function isExecutor(address account) external view returns (bool); diff --git a/contracts/access/ZNSAccessController.sol b/contracts/access/ZNSAccessController.sol index 06357fe4e..af29625c5 100644 --- a/contracts/access/ZNSAccessController.sol +++ b/contracts/access/ZNSAccessController.sol @@ -1,9 +1,10 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.18; +pragma solidity 0.8.26; import { AccessControl } from "@openzeppelin/contracts/access/AccessControl.sol"; import { IZNSAccessController } from "./IZNSAccessController.sol"; import { ZNSRoles } from "./ZNSRoles.sol"; +import { ZeroAddressPassed } from "../utils/CommonErrors.sol"; /** @@ -33,6 +34,8 @@ contract ZNSAccessController is AccessControl, ZNSRoles, IZNSAccessController { _setRoleAdmin(GOVERNOR_ROLE, GOVERNOR_ROLE); // all of the admins control registrar _setRoleAdmin(REGISTRAR_ROLE, ADMIN_ROLE); + // all of the admins control domain token + _setRoleAdmin(DOMAIN_TOKEN_ROLE, ADMIN_ROLE); } // ** Access Validators ** @@ -53,6 +56,10 @@ contract ZNSAccessController is AccessControl, ZNSRoles, IZNSAccessController { _checkRole(REGISTRAR_ROLE, account); } + function checkDomainToken(address account) external view override { + _checkRole(DOMAIN_TOKEN_ROLE, account); + } + // "is...()" functions return a boolean function isAdmin(address account) external view override returns (bool) { return hasRole(ADMIN_ROLE, account); @@ -62,6 +69,10 @@ contract ZNSAccessController is AccessControl, ZNSRoles, IZNSAccessController { return hasRole(REGISTRAR_ROLE, account); } + function isDomainToken(address account) external view override returns (bool) { + return hasRole(DOMAIN_TOKEN_ROLE, account); + } + function isGovernor(address account) external view override returns (bool) { return hasRole(GOVERNOR_ROLE, account); } @@ -77,10 +88,8 @@ contract ZNSAccessController is AccessControl, ZNSRoles, IZNSAccessController { function _grantRoleToMany(bytes32 role, address[] memory addresses) internal { uint256 length = addresses.length; for (uint256 i = 0; i < length; ++i) { - require( - addresses[i] != address(0), - "ZNSAccessController: Can't grant role to zero address" - ); + if (addresses[i] == address(0)) revert ZeroAddressPassed(); + _grantRole(role, addresses[i]); } } diff --git a/contracts/access/ZNSRoles.sol b/contracts/access/ZNSRoles.sol index 48a920620..d92522233 100644 --- a/contracts/access/ZNSRoles.sol +++ b/contracts/access/ZNSRoles.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.18; +pragma solidity 0.8.26; /** @@ -22,6 +22,11 @@ abstract contract ZNSRoles { */ bytes32 public constant REGISTRAR_ROLE = keccak256("REGISTRAR_ROLE"); + /** + * @notice This role is here specifically for the ZNSDomainToken.sol contract + */ + bytes32 public constant DOMAIN_TOKEN_ROLE = keccak256("DOMAIN_TOKEN_ROLE"); + /** * @notice Executor can be here to future proof, if we need a new role * so we don't have to upgrade all contracts diff --git a/contracts/oz-proxies/ERC1967ProxyAcc.sol b/contracts/oz-proxies/ERC1967ProxyAcc.sol index 67824c9c9..5ccb57862 100644 --- a/contracts/oz-proxies/ERC1967ProxyAcc.sol +++ b/contracts/oz-proxies/ERC1967ProxyAcc.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.18; +pragma solidity 0.8.26; // solhint-disable-next-line no-global-import import "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; diff --git a/contracts/oz-proxies/TransparentUpgradeableProxyAcc.sol b/contracts/oz-proxies/TransparentUpgradeableProxyAcc.sol index a3d6f86a3..3275c8120 100644 --- a/contracts/oz-proxies/TransparentUpgradeableProxyAcc.sol +++ b/contracts/oz-proxies/TransparentUpgradeableProxyAcc.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.18; +pragma solidity 0.8.26; // solhint-disable-next-line no-global-import import "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; diff --git a/contracts/price/IZNSCurvePricer.sol b/contracts/price/IZNSCurvePricer.sol index 1b029f435..0551a4c25 100644 --- a/contracts/price/IZNSCurvePricer.sol +++ b/contracts/price/IZNSCurvePricer.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.18; +pragma solidity 0.8.26; import { ICurvePriceConfig } from "../types/ICurvePriceConfig.sol"; import { IZNSPricer } from "../types/IZNSPricer.sol"; @@ -8,16 +8,16 @@ import { IZNSPricer } from "../types/IZNSPricer.sol"; interface IZNSCurvePricer is ICurvePriceConfig, IZNSPricer { /** - * @notice Emitted when the `maxPrice` is set in `CurvePriceConfig` - * @param price The new maxPrice value + * @notice Reverted when multiplier passed by the domain owner + * is equal to 0 or more than 10^18, which is too large. */ - event MaxPriceSet(bytes32 domainHash, uint256 price); + error InvalidPrecisionMultiplierPassed(bytes32 domainHash); /** - * @notice Emitted when the `minPrice` is set in `CurvePriceConfig` - * @param price The new minPrice value + * @notice Emitted when the `maxPrice` is set in `CurvePriceConfig` + * @param price The new maxPrice value */ - event MinPriceSet(bytes32 domainHash, uint256 price); + event MaxPriceSet(bytes32 domainHash, uint256 price); /** * @notice Emitted when the `baseLength` is set in `CurvePriceConfig` @@ -43,10 +43,17 @@ interface IZNSCurvePricer is ICurvePriceConfig, IZNSPricer { */ event FeePercentageSet(bytes32 domainHash, uint256 feePercentage); + /** + * @notice Emitted when the `curveMultiplier` is set in state + * @param curveMultiplier The new curveMultiplier value + */ + event CurveMultiplierSet(bytes32 domainHash, uint256 curveMultiplier); + + /** * @notice Emitted when the full `CurvePriceConfig` is set in state * @param maxPrice The new `maxPrice` value - * @param minPrice The new `minPrice` value + * @param curveMultiplier The new `curveMultiplier` value * @param maxLength The new `maxLength` value * @param baseLength The new `baseLength` value * @param precisionMultiplier The new `precisionMultiplier` value @@ -54,7 +61,7 @@ interface IZNSCurvePricer is ICurvePriceConfig, IZNSPricer { event PriceConfigSet( bytes32 domainHash, uint256 maxPrice, - uint256 minPrice, + uint256 curveMultiplier, uint256 maxLength, uint256 baseLength, uint256 precisionMultiplier, @@ -94,12 +101,12 @@ interface IZNSCurvePricer is ICurvePriceConfig, IZNSPricer { function setMaxPrice(bytes32 domainHash, uint256 maxPrice) external; - function setMinPrice(bytes32 domainHash, uint256 minPrice) external; - function setBaseLength(bytes32 domainHash, uint256 length) external; function setMaxLength(bytes32 domainHash, uint256 length) external; + function setCurveMultiplier(bytes32 domainHash, uint256 curveMultiplier) external; + function setPrecisionMultiplier(bytes32 domainHash, uint256 multiplier) external; function setFeePercentage(bytes32 domainHash, uint256 feePercentage) external; diff --git a/contracts/price/IZNSFixedPricer.sol b/contracts/price/IZNSFixedPricer.sol index cf09360db..69cdfad8b 100644 --- a/contracts/price/IZNSFixedPricer.sol +++ b/contracts/price/IZNSFixedPricer.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.18; +pragma solidity 0.8.26; import { IZNSPricer } from "../types/IZNSPricer.sol"; diff --git a/contracts/price/ZNSCurvePricer.sol b/contracts/price/ZNSCurvePricer.sol index 67a22c880..87a067429 100644 --- a/contracts/price/ZNSCurvePricer.sol +++ b/contracts/price/ZNSCurvePricer.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.18; +pragma solidity 0.8.26; import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; import { IZNSCurvePricer } from "./IZNSCurvePricer.sol"; @@ -7,15 +7,17 @@ import { StringUtils } from "../utils/StringUtils.sol"; import { AAccessControlled } from "../access/AAccessControlled.sol"; import { ARegistryWired } from "../registry/ARegistryWired.sol"; - /** * @title Implementation of the Curve Pricing, module that calculates the price of a domain * based on its length and the rules set by Zero ADMIN. - * This module uses an asymptotic curve that starts from `maxPrice` for all domains <= `baseLength`. - * It then decreases in price, using the calculated price function below, until it reaches `minPrice` - * at `maxLength` length of the domain name. Price after `maxLength` is fixed and always equal to `minPrice`. + * This module uses an hyperbolic curve that starts at (`baseLength`; `maxPrice`) + * for all domains <= `baseLength`. + * Then the price is reduced using the price calculation function below. + * The price after `maxLength` is fixed and equals the price on the hyperbola graph at the point `maxLength` + * and is determined using the formula where `length` = `maxLength`. */ contract ZNSCurvePricer is AAccessControlled, ARegistryWired, UUPSUpgradeable, IZNSCurvePricer { + using StringUtils for string; /** @@ -24,6 +26,13 @@ contract ZNSCurvePricer is AAccessControlled, ARegistryWired, UUPSUpgradeable, I */ uint256 public constant PERCENTAGE_BASIS = 10000; + /** + * @notice Multiply the entire hyperbola formula by this number to be able to reduce the `curveMultiplier` + * by 3 digits, which gives us more flexibility in defining the hyperbola function. + * @dev > Canot be "0". + */ + uint256 public constant FACTOR_SCALE = 1000; + /** * @notice Mapping of domainHash to the price config for that domain set by the parent domain owner. * @dev Zero, for pricing root domains, uses this mapping as well under 0x0 hash. @@ -41,7 +50,6 @@ contract ZNSCurvePricer is AAccessControlled, ARegistryWired, UUPSUpgradeable, I * @dev > Note the for PriceConfig we set each value individually and calling * 2 important functions that validate all of the config's values against the formula: * - `setPrecisionMultiplier()` to validate precision multiplier - * - `_validateConfig()` to validate the whole config in order to avoid price spikes * @param accessController_ the address of the ZNSAccessController contract. * @param registry_ the address of the ZNSRegistry contract. * @param zeroPriceConfig_ a number of variables that participate in the price calculation for subdomains. @@ -75,10 +83,7 @@ contract ZNSCurvePricer is AAccessControlled, ARegistryWired, UUPSUpgradeable, I string calldata label, bool skipValidityCheck ) public view override returns (uint256) { - require( - priceConfigs[parentHash].isSet, - "ZNSCurvePricer: parent's price config has not been set properly through IZNSPricer.setPriceConfig()" - ); + if (!priceConfigs[parentHash].isSet) revert ParentPriceConfigNotSet(parentHash); if (!skipValidityCheck) { // Confirms string values are only [a-z0-9-] @@ -125,9 +130,9 @@ contract ZNSCurvePricer is AAccessControlled, ARegistryWired, UUPSUpgradeable, I /** * @notice Setter for `priceConfigs[domainHash]`. Only domain owner/operator can call this function. - * @dev Validates the value of the `precisionMultiplier` and the whole config in order to avoid price spikes, + * @dev Validates the value of the `precisionMultiplier`. * fires `PriceConfigSet` event. - * Only the owner of the domain or an allowed operator can call this function + * Only the owner of the domain or an allowed operator can call this function. * > This function should ALWAYS be used to set the config, since it's the only place where `isSet` is set to true. * > Use the other individual setters to modify only, since they do not set this variable! * @param domainHash The domain hash to set the price config for @@ -137,20 +142,18 @@ contract ZNSCurvePricer is AAccessControlled, ARegistryWired, UUPSUpgradeable, I bytes32 domainHash, CurvePriceConfig calldata priceConfig ) public override { - setPrecisionMultiplier(domainHash, priceConfig.precisionMultiplier); - priceConfigs[domainHash].baseLength = priceConfig.baseLength; + _setPrecisionMultiplier(domainHash, priceConfig.precisionMultiplier); + _validateSetBaseLength(domainHash, priceConfig.baseLength, priceConfig); priceConfigs[domainHash].maxPrice = priceConfig.maxPrice; - priceConfigs[domainHash].minPrice = priceConfig.minPrice; - priceConfigs[domainHash].maxLength = priceConfig.maxLength; - setFeePercentage(domainHash, priceConfig.feePercentage); + _validateSetCurveMultiplier(domainHash, priceConfig.curveMultiplier, priceConfig); + _validateSetMaxLength(domainHash, priceConfig.maxLength, priceConfig); + _validateSetFeePercentage(domainHash, priceConfig.feePercentage); priceConfigs[domainHash].isSet = true; - _validateConfig(domainHash); - emit PriceConfigSet( domainHash, priceConfig.maxPrice, - priceConfig.minPrice, + priceConfig.curveMultiplier, priceConfig.maxLength, priceConfig.baseLength, priceConfig.precisionMultiplier, @@ -162,9 +165,12 @@ contract ZNSCurvePricer is AAccessControlled, ARegistryWired, UUPSUpgradeable, I * @notice Sets the max price for domains. Validates the config with the new price. * Fires `MaxPriceSet` event. * Only domain owner can call this function. - * > `maxPrice` can be set to 0 along with `baseLength` or `minPrice` to make all domains free! - * @dev We are checking here for possible price spike at `maxLength` if the `maxPrice` values is NOT 0. - * In the case of 0 we do not validate, since setting it to 0 will make all subdomains free. + * > `maxPrice` can be set to 0 along with `baseLength` to make all domains free! + * > `maxPrice` cannot be 0 when: + * - `maxLength` is 0; + * - `baseLength` AND `curveMultiplier` are 0; + * @dev In the case of 0 we do not validate, since setting it to 0 will make all subdomains free. + * @param domainHash The domain hash to set the `maxPrice` for it * @param maxPrice The maximum price to set */ function setMaxPrice( @@ -172,28 +178,40 @@ contract ZNSCurvePricer is AAccessControlled, ARegistryWired, UUPSUpgradeable, I uint256 maxPrice ) external override onlyOwnerOrOperator(domainHash) { priceConfigs[domainHash].maxPrice = maxPrice; - - if (maxPrice != 0) _validateConfig(domainHash); - emit MaxPriceSet(domainHash, maxPrice); } /** - * @notice Sets the minimum price for domains. Validates the config with the new price. - * Fires `MinPriceSet` event. - * Only domain owner/operator can call this function. - * @param domainHash The domain hash to set the `minPrice` for - * @param minPrice The minimum price to set in $ZERO + * @notice Sets the multiplier for domains calculations + * to allow the hyperbolic price curve to be bent all the way to a straight line. + * Validates the config with the new multiplier in case where `baseLength` is 0 too. + * Fires `CurveMultiplier` event. + * Only domain owner can call this function. + * - If `curveMultiplier` = 1.000 - default. Makes a canonical hyperbola fucntion. + * - It can be "0", which makes all domain prices max. + * - If it is less than 1.000, then it pulls the bend towards the straight line. + * - If it is bigger than 1.000, then it makes bigger slope on the chart. + * @param domainHash The domain hash to set the price config for + * @param curveMultiplier Multiplier for bending the price function (graph) */ - function setMinPrice( + function setCurveMultiplier( bytes32 domainHash, - uint256 minPrice + uint256 curveMultiplier ) external override onlyOwnerOrOperator(domainHash) { - priceConfigs[domainHash].minPrice = minPrice; + CurvePriceConfig memory config = priceConfigs[domainHash]; + _validateSetCurveMultiplier(domainHash, curveMultiplier, config); + emit CurveMultiplierSet(domainHash, curveMultiplier); + } - _validateConfig(domainHash); + function _validateSetCurveMultiplier( + bytes32 domainHash, + uint256 curveMultiplier, + CurvePriceConfig memory config + ) internal onlyOwnerOrOperator(domainHash) { + if (curveMultiplier == 0 && config.baseLength == 0) + revert DivisionByZero(domainHash); - emit MinPriceSet(domainHash, minPrice); + priceConfigs[domainHash].curveMultiplier = curveMultiplier; } /** @@ -201,44 +219,69 @@ contract ZNSCurvePricer is AAccessControlled, ARegistryWired, UUPSUpgradeable, I * e.g. A value of '5' means all domains <= 5 in length cost the `maxPrice` price * Validates the config with the new length. Fires `BaseLengthSet` event. * Only domain owner/operator can call this function. - * > `baseLength` can be set to 0 to make all domains cost `maxPrice`! + * > `baseLength` can be set to 0 to make all domains free. + * > `baseLength` can be = `maxLength` to make all domain prices max. * > This indicates to the system that we are * > currently in a special phase where we define an exact price for all domains * > e.g. promotions or sales * @param domainHash The domain hash to set the `baseLength` for - * @param length Boundary to set + * @param baseLength Boundary to set */ function setBaseLength( bytes32 domainHash, - uint256 length + uint256 baseLength ) external override onlyOwnerOrOperator(domainHash) { - priceConfigs[domainHash].baseLength = length; + CurvePriceConfig memory config = priceConfigs[domainHash]; + _validateSetBaseLength(domainHash, baseLength, config); + emit BaseLengthSet(domainHash, baseLength); + } - _validateConfig(domainHash); + function _validateSetBaseLength( + bytes32 domainHash, + uint256 baseLength, + CurvePriceConfig memory config + ) internal onlyOwnerOrOperator(domainHash) { - emit BaseLengthSet(domainHash, length); + if (config.maxLength < baseLength) + revert MaxLengthSmallerThanBaseLength(domainHash); + + if (baseLength == 0 && config.curveMultiplier == 0) + revert DivisionByZero(domainHash); + + priceConfigs[domainHash].baseLength = baseLength; } /** * @notice Set the maximum length of a domain name to which price formula applies. - * All domain names (labels) that are longer than this value will cost the fixed price of `minPrice`, - * and the pricing formula will not apply to them. + * All domain names (labels) that are longer than this value will cost the lowest price at maxLength. * Validates the config with the new length. * Fires `MaxLengthSet` event. * Only domain owner/operator can call this function. - * > `maxLength` can be set to 0 to make all domains cost `minPrice`! + * > `maxLength` can't be set to 0 or less than `baseLength`! + * > If `maxLength` = `baseLength` it makes all domain prices max. * @param domainHash The domain hash to set the `maxLength` for - * @param length The maximum length to set + * @param maxLength The maximum length to set */ function setMaxLength( bytes32 domainHash, - uint256 length + uint256 maxLength ) external override onlyOwnerOrOperator(domainHash) { - priceConfigs[domainHash].maxLength = length; - - if (length != 0) _validateConfig(domainHash); + CurvePriceConfig memory config = priceConfigs[domainHash]; + _validateSetMaxLength(domainHash, maxLength, config); + emit MaxLengthSet(domainHash, maxLength); + } - emit MaxLengthSet(domainHash, length); + function _validateSetMaxLength( + bytes32 domainHash, + uint256 maxLength, + CurvePriceConfig memory config + ) internal onlyOwnerOrOperator(domainHash) { + if ( + (maxLength < config.baseLength) || + maxLength == 0 + ) revert MaxLengthSmallerThanBaseLength(domainHash); + + priceConfigs[domainHash].maxLength = maxLength; } /** @@ -250,19 +293,26 @@ contract ZNSCurvePricer is AAccessControlled, ARegistryWired, UUPSUpgradeable, I * Fires `PrecisionMultiplierSet` event. * Only domain owner/operator can call this function. * > Multiplier should be less or equal to 10^18 and greater than 0! + * @param domainHash The domain hash to set `PrecisionMultiplier` * @param multiplier The multiplier to set */ function setPrecisionMultiplier( bytes32 domainHash, uint256 multiplier ) public override onlyOwnerOrOperator(domainHash) { - require(multiplier != 0, "ZNSCurvePricer: precisionMultiplier cannot be 0"); - require(multiplier <= 10**18, "ZNSCurvePricer: precisionMultiplier cannot be greater than 10^18"); - priceConfigs[domainHash].precisionMultiplier = multiplier; - + _setPrecisionMultiplier(domainHash, multiplier); emit PrecisionMultiplierSet(domainHash, multiplier); } + function _setPrecisionMultiplier( + bytes32 domainHash, + uint256 multiplier + ) internal { + if (multiplier == 0 || multiplier > 10**18) revert InvalidPrecisionMultiplierPassed(domainHash); + + priceConfigs[domainHash].precisionMultiplier = multiplier; + } + /** * @notice Sets the fee percentage for domain registration. * @dev Fee percentage is set according to the basis of 10000, outlined in `PERCENTAGE_BASIS`. @@ -271,17 +321,25 @@ contract ZNSCurvePricer is AAccessControlled, ARegistryWired, UUPSUpgradeable, I * @param domainHash The domain hash to set the fee percentage for * @param feePercentage The fee percentage to set */ - function setFeePercentage(bytes32 domainHash, uint256 feePercentage) - public - override - onlyOwnerOrOperator(domainHash) { - require( - feePercentage <= PERCENTAGE_BASIS, - "ZNSCurvePricer: feePercentage cannot be greater than PERCENTAGE_BASIS" - ); + function setFeePercentage( + bytes32 domainHash, + uint256 feePercentage + ) public override onlyOwnerOrOperator(domainHash) { + _validateSetFeePercentage(domainHash, feePercentage); + emit FeePercentageSet(domainHash, feePercentage); + } + + function _validateSetFeePercentage( + bytes32 domainHash, + uint256 feePercentage + ) internal onlyOwnerOrOperator(domainHash) { + if (feePercentage > PERCENTAGE_BASIS) + revert FeePercentageValueTooLarge( + feePercentage, + PERCENTAGE_BASIS + ); priceConfigs[domainHash].feePercentage = feePercentage; - emit FeePercentageSet(domainHash, feePercentage); } /** @@ -295,17 +353,25 @@ contract ZNSCurvePricer is AAccessControlled, ARegistryWired, UUPSUpgradeable, I /** * @notice Internal function to calculate price based on the config set, * and the length of the domain label. - * @dev Before we calculate the price, 4 different cases are possible: + * @dev Before we calculate the price, 6 different cases are possible: * 1. `maxPrice` is 0, which means all subdomains under this parent are free - * 2. `baseLength` is 0, which means we are returning `maxPrice` as a specific price for all domains - * 3. `length` is less than or equal to `baseLength`, which means a domain will cost `maxPrice` - * 4. `length` is greater than `maxLength`, which means a domain will cost `minPrice` + * 2. `baseLength` is 0, which means prices for all domains = 0 (free). + * 3. `length` is less or equal to `baseLength`, which means a domain will cost `maxPrice` + * 4. `length` is greater than `maxLength`, which means a domain will cost price by fomula at `maxLength` + * 5. The numerator can be less than the denominator, which is achieved by setting a huge value + * for `curveMultiplier` or by decreasing the `baseLength` and `maxPrice`, which means all domains + * which are longer than `baseLength` will be free. + * 6. `curveMultiplier` is 0, which means all domains will cost `maxPrice`. * - * The formula itself creates an asymptotic curve that decreases in pricing based on domain name length, - * base length and max price, the result is divided by the precision multiplier to remove numbers beyond + * The formula itself creates an hyperbolic curve that decreases in pricing based on domain name length, + * base length, max price and curve multiplier. + * `FACTOR_SCALE` allows to perceive `curveMultiplier` as fraction number in regular formula, + * which helps to bend a curve of price chart. + * The result is divided by the precision multiplier to remove numbers beyond * what we care about, then multiplied by the same precision multiplier to get the actual value * with truncated values past precision. So having a value of `15.235234324234512365 * 10^18` * with precision `2` would give us `15.230000000000000000 * 10^18` + * @param parentHash The parent hash * @param length The length of the domain name */ function _getPrice( @@ -320,27 +386,13 @@ contract ZNSCurvePricer is AAccessControlled, ARegistryWired, UUPSUpgradeable, I // Setting baseLength to 0 indicates to the system that we are // currently in a special phase where we define an exact price for all domains // e.g. promotions or sales - if (config.baseLength == 0) return config.maxPrice; if (length <= config.baseLength) return config.maxPrice; - if (length > config.maxLength) return config.minPrice; - return (config.baseLength * config.maxPrice / length) - / config.precisionMultiplier * config.precisionMultiplier; - } + if (length > config.maxLength) length = config.maxLength; - /** - * @notice Internal function called every time we set props of `priceConfigs[domainHash]` - * to make sure that values being set can not disrupt the price curve or zero out prices - * for domains. If this validation fails, the parent function will revert. - * @dev We are checking here for possible price spike at `maxLength` - * which can occur if some of the config values are not properly chosen and set. - */ - function _validateConfig(bytes32 domainHash) internal view { - uint256 prevToMinPrice = _getPrice(domainHash, priceConfigs[domainHash].maxLength); - require( - priceConfigs[domainHash].minPrice <= prevToMinPrice, - "ZNSCurvePricer: incorrect value set causes the price spike at maxLength." - ); + return ((config.baseLength * config.maxPrice * FACTOR_SCALE) / + (config.baseLength * FACTOR_SCALE + config.curveMultiplier * (length - config.baseLength))) / + config.precisionMultiplier * config.precisionMultiplier; } /** diff --git a/contracts/price/ZNSFixedPricer.sol b/contracts/price/ZNSFixedPricer.sol index b345a8059..e3be189a9 100644 --- a/contracts/price/ZNSFixedPricer.sol +++ b/contracts/price/ZNSFixedPricer.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.18; +pragma solidity 0.8.26; import { AAccessControlled } from "../access/AAccessControlled.sol"; import { ARegistryWired } from "../registry/ARegistryWired.sol"; @@ -60,10 +60,7 @@ contract ZNSFixedPricer is AAccessControlled, ARegistryWired, UUPSUpgradeable, I string calldata label, bool skipValidityCheck ) public override view returns (uint256) { - require( - priceConfigs[parentHash].isSet, - "ZNSFixedPricer: parent's price config has not been set properly through IZNSPricer.setPriceConfig()" - ); + if (!priceConfigs[parentHash].isSet) revert ParentPriceConfigNotSet(parentHash); if (!skipValidityCheck) { // Confirms string values are only [a-z0-9-] @@ -161,10 +158,8 @@ contract ZNSFixedPricer is AAccessControlled, ARegistryWired, UUPSUpgradeable, I * @param feePercentage The new feePercentage */ function _setFeePercentage(bytes32 domainHash, uint256 feePercentage) internal { - require( - feePercentage <= PERCENTAGE_BASIS, - "ZNSFixedPricer: feePercentage cannot be greater than PERCENTAGE_BASIS" - ); + if (feePercentage > PERCENTAGE_BASIS) + revert FeePercentageValueTooLarge(feePercentage, PERCENTAGE_BASIS); priceConfigs[domainHash].feePercentage = feePercentage; emit FeePercentageSet(domainHash, feePercentage); diff --git a/contracts/registrar/IZNSRootRegistrar.sol b/contracts/registrar/IZNSRootRegistrar.sol index 365efbbf4..b98da35ce 100644 --- a/contracts/registrar/IZNSRootRegistrar.sol +++ b/contracts/registrar/IZNSRootRegistrar.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.18; +pragma solidity 0.8.26; import { IDistributionConfig } from "../types/IDistributionConfig.sol"; import { PaymentConfig } from "../treasury/IZNSTreasury.sol"; @@ -42,13 +42,19 @@ struct CoreRegisterArgs { * + `isStakePayment`: A flag for whether the payment is a stake payment or not */ interface IZNSRootRegistrar is IDistributionConfig { + error NotTheOwnerOf( + OwnerOf ownerOf, + address candidate, + bytes32 domainHash + ); + + error InvalidOwnerOfEnumValue(OwnerOf value); enum OwnerOf { NAME, TOKEN, BOTH } - /** * @notice Emitted when a NEW domain is registered. * @dev `domainAddress` parameter is the address to which a domain name will relate to in ZNS. diff --git a/contracts/registrar/IZNSSubRegistrar.sol b/contracts/registrar/IZNSSubRegistrar.sol index 1c6574bdd..ae5bc7bdd 100644 --- a/contracts/registrar/IZNSSubRegistrar.sol +++ b/contracts/registrar/IZNSSubRegistrar.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.18; +pragma solidity 0.8.26; import { IDistributionConfig } from "../types/IDistributionConfig.sol"; import { PaymentConfig } from "../treasury/IZNSTreasury.sol"; @@ -8,27 +8,41 @@ import { IZNSPricer } from "../types/IZNSPricer.sol"; /** * @title IZNSSubRegistrar.sol - Interface for the ZNSSubRegistrar contract responsible for registering subdomains. -*/ + */ interface IZNSSubRegistrar is IDistributionConfig { + /** + * @notice Reverted when someone other than parent owner is trying to buy + * a subdomain under the parent that is locked + * or when the parent provided does not exist. + */ + error ParentLockedOrDoesntExist(bytes32 parentHash); + + /** + * @notice Reverted when the buyer of subdomain is not approved by the parent in it's mintlist. + */ + error SenderNotApprovedForPurchase(bytes32 parentHash, address sender); /** * @notice Emitted when a new `DistributionConfig.pricerContract` is set for a domain. - */ - event PricerContractSet(bytes32 indexed domainHash, address indexed pricerContract); + */ + event PricerContractSet( + bytes32 indexed domainHash, + address indexed pricerContract + ); /** * @notice Emitted when a new `DistributionConfig.paymentType` is set for a domain. - */ + */ event PaymentTypeSet(bytes32 indexed domainHash, PaymentType paymentType); /** * @notice Emitted when a new `DistributionConfig.accessType` is set for a domain. - */ + */ event AccessTypeSet(bytes32 indexed domainHash, AccessType accessType); /** * @notice Emitted when a new full `DistributionConfig` is set for a domain at once. - */ + */ event DistributionConfigSet( bytes32 indexed domainHash, IZNSPricer pricerContract, @@ -38,7 +52,7 @@ interface IZNSSubRegistrar is IDistributionConfig { /** * @notice Emitted when a `mintlist` is updated for a domain. - */ + */ event MintlistUpdated( bytes32 indexed domainHash, uint256 indexed ownerIndex, @@ -54,7 +68,7 @@ interface IZNSSubRegistrar is IDistributionConfig { /** * @notice Emitted when the ZNSRootRegistrar address is set in state. - */ + */ event RootRegistrarSet(address registrar); function distrConfigs( diff --git a/contracts/registrar/ZNSRootRegistrar.sol b/contracts/registrar/ZNSRootRegistrar.sol index fc7442020..5cb841e91 100644 --- a/contracts/registrar/ZNSRootRegistrar.sol +++ b/contracts/registrar/ZNSRootRegistrar.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.18; +pragma solidity 0.8.26; import { AAccessControlled } from "../access/AAccessControlled.sol"; import { ARegistryWired } from "../registry/ARegistryWired.sol"; @@ -11,6 +11,7 @@ import { IZNSSubRegistrar } from "../registrar/IZNSSubRegistrar.sol"; import { IZNSPricer } from "../types/IZNSPricer.sol"; import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; import { StringUtils } from "../utils/StringUtils.sol"; +import { ZeroAddressPassed, DomainAlreadyExists } from "../utils/CommonErrors.sol"; /** @@ -100,10 +101,8 @@ contract ZNSRootRegistrar is // Create hash for given domain name bytes32 domainHash = keccak256(bytes(name)); - require( - !registry.exists(domainHash), - "ZNSRootRegistrar: Domain already exists" - ); + if (registry.exists(domainHash)) + revert DomainAlreadyExists(domainHash); // Get price for the domain uint256 domainPrice = rootPricer.getPrice(0x0, name, true); @@ -256,10 +255,8 @@ contract ZNSRootRegistrar is external override { - require( - isOwnerOf(domainHash, msg.sender, OwnerOf.BOTH), - "ZNSRootRegistrar: Not the owner of both Name and Token" - ); + if (!isOwnerOf(domainHash, msg.sender, OwnerOf.BOTH)) + revert NotTheOwnerOf(OwnerOf.BOTH, msg.sender, domainHash); subRegistrar.clearMintlistAndLock(domainHash); _coreRevoke(domainHash, msg.sender); @@ -305,10 +302,9 @@ contract ZNSRootRegistrar is external override { - require( - isOwnerOf(domainHash, msg.sender, OwnerOf.TOKEN), - "ZNSRootRegistrar: Not the owner of the Token" - ); + if (!isOwnerOf(domainHash, msg.sender, OwnerOf.TOKEN)) + revert NotTheOwnerOf(OwnerOf.TOKEN, msg.sender, domainHash); + registry.updateDomainOwner(domainHash, msg.sender); emit DomainReclaimed(domainHash, msg.sender); @@ -330,7 +326,7 @@ contract ZNSRootRegistrar is && candidate == domainToken.ownerOf(uint256(domainHash)); } - revert("Wrong enum value for `ownerOf`"); + revert InvalidOwnerOfEnumValue(ownerOf); } /** @@ -348,10 +344,9 @@ contract ZNSRootRegistrar is * @param rootPricer_ Address of the IZNSPricer type contract to set as pricer of Root Domains */ function setRootPricer(address rootPricer_) public override onlyAdmin { - require( - rootPricer_ != address(0), - "ZNSRootRegistrar: rootPricer_ is 0x0 address" - ); + if (rootPricer_ == address(0)) + revert ZeroAddressPassed(); + rootPricer = IZNSPricer(rootPricer_); emit RootPricerSet(rootPricer_); @@ -363,10 +358,9 @@ contract ZNSRootRegistrar is * @param treasury_ Address of the `ZNSTreasury` contract */ function setTreasury(address treasury_) public override onlyAdmin { - require( - treasury_ != address(0), - "ZNSRootRegistrar: treasury_ is 0x0 address" - ); + if (treasury_ == address(0)) + revert ZeroAddressPassed(); + treasury = IZNSTreasury(treasury_); emit TreasurySet(treasury_); @@ -378,10 +372,9 @@ contract ZNSRootRegistrar is * @param domainToken_ Address of the `ZNSDomainToken` contract */ function setDomainToken(address domainToken_) public override onlyAdmin { - require( - domainToken_ != address(0), - "ZNSRootRegistrar: domainToken_ is 0x0 address" - ); + if (domainToken_ == address(0)) + revert ZeroAddressPassed(); + domainToken = IZNSDomainToken(domainToken_); emit DomainTokenSet(domainToken_); @@ -392,7 +385,8 @@ contract ZNSRootRegistrar is * @param subRegistrar_ Address of the `ZNSSubRegistrar` contract */ function setSubRegistrar(address subRegistrar_) external override onlyAdmin { - require(subRegistrar_ != address(0), "ZNSRootRegistrar: subRegistrar_ is 0x0 address"); + if (subRegistrar_ == address(0)) + revert ZeroAddressPassed(); subRegistrar = IZNSSubRegistrar(subRegistrar_); emit SubRegistrarSet(subRegistrar_); diff --git a/contracts/registrar/ZNSSubRegistrar.sol b/contracts/registrar/ZNSSubRegistrar.sol index cd01d86a5..b1b8a65a8 100644 --- a/contracts/registrar/ZNSSubRegistrar.sol +++ b/contracts/registrar/ZNSSubRegistrar.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.18; +pragma solidity 0.8.26; import { IZNSPricer } from "../types/IZNSPricer.sol"; import { IZNSRootRegistrar, CoreRegisterArgs } from "./IZNSRootRegistrar.sol"; @@ -9,6 +9,7 @@ import { ARegistryWired } from "../registry/ARegistryWired.sol"; import { StringUtils } from "../utils/StringUtils.sol"; import { PaymentConfig } from "../treasury/IZNSTreasury.sol"; import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; +import { DomainAlreadyExists, ZeroAddressPassed, NotAuthorizedForDomain } from "../utils/CommonErrors.sol"; /** @@ -45,11 +46,10 @@ contract ZNSSubRegistrar is AAccessControlled, ARegistryWired, UUPSUpgradeable, mapping(bytes32 domainHash => Mintlist mintStruct) public mintlist; modifier onlyOwnerOperatorOrRegistrar(bytes32 domainHash) { - require( - registry.isOwnerOrOperator(domainHash, msg.sender) - || accessController.isRegistrar(msg.sender), - "ZNSSubRegistrar: Not authorized" - ); + if ( + !registry.isOwnerOrOperator(domainHash, msg.sender) + && !accessController.isRegistrar(msg.sender) + ) revert NotAuthorizedForDomain(msg.sender, domainHash); _; } @@ -95,27 +95,22 @@ contract ZNSSubRegistrar is AAccessControlled, ARegistryWired, UUPSUpgradeable, label.validate(); bytes32 domainHash = hashWithParent(parentHash, label); - require( - !registry.exists(domainHash), - "ZNSSubRegistrar: Subdomain already exists" - ); + if (registry.exists(domainHash)) + revert DomainAlreadyExists(domainHash); DistributionConfig memory parentConfig = distrConfigs[parentHash]; bool isOwnerOrOperator = registry.isOwnerOrOperator(parentHash, msg.sender); - require( - parentConfig.accessType != AccessType.LOCKED || isOwnerOrOperator, - "ZNSSubRegistrar: Parent domain's distribution is locked or parent does not exist" - ); + if (parentConfig.accessType == AccessType.LOCKED && !isOwnerOrOperator) + revert ParentLockedOrDoesntExist(parentHash); if (parentConfig.accessType == AccessType.MINTLIST) { - require( - mintlist[parentHash] + if ( + !mintlist[parentHash] .list [mintlist[parentHash].ownerIndex] - [msg.sender], - "ZNSSubRegistrar: Sender is not approved for purchase" - ); + [msg.sender] + ) revert SenderNotApprovedForPurchase(parentHash, msg.sender); } CoreRegisterArgs memory coreRegisterArgs = CoreRegisterArgs({ @@ -188,10 +183,8 @@ contract ZNSSubRegistrar is AAccessControlled, ARegistryWired, UUPSUpgradeable, bytes32 domainHash, DistributionConfig calldata config ) public override onlyOwnerOperatorOrRegistrar(domainHash) { - require( - address(config.pricerContract) != address(0), - "ZNSSubRegistrar: pricerContract can not be 0x0 address" - ); + if (address(config.pricerContract) == address(0)) + revert ZeroAddressPassed(); distrConfigs[domainHash] = config; @@ -215,15 +208,11 @@ contract ZNSSubRegistrar is AAccessControlled, ARegistryWired, UUPSUpgradeable, bytes32 domainHash, IZNSPricer pricerContract ) public override { - require( - registry.isOwnerOrOperator(domainHash, msg.sender), - "ZNSSubRegistrar: Not authorized" - ); + if (!registry.isOwnerOrOperator(domainHash, msg.sender)) + revert NotAuthorizedForDomain(msg.sender, domainHash); - require( - address(pricerContract) != address(0), - "ZNSSubRegistrar: pricerContract can not be 0x0 address" - ); + if (address(pricerContract) == address(0)) + revert ZeroAddressPassed(); distrConfigs[domainHash].pricerContract = pricerContract; @@ -242,10 +231,8 @@ contract ZNSSubRegistrar is AAccessControlled, ARegistryWired, UUPSUpgradeable, bytes32 domainHash, PaymentType paymentType ) public override { - require( - registry.isOwnerOrOperator(domainHash, msg.sender), - "ZNSSubRegistrar: Not authorized" - ); + if (!registry.isOwnerOrOperator(domainHash, msg.sender)) + revert NotAuthorizedForDomain(msg.sender, domainHash); distrConfigs[domainHash].paymentType = paymentType; @@ -283,10 +270,8 @@ contract ZNSSubRegistrar is AAccessControlled, ARegistryWired, UUPSUpgradeable, address[] calldata candidates, bool[] calldata allowed ) external override { - require( - registry.isOwnerOrOperator(domainHash, msg.sender), - "ZNSSubRegistrar: Not authorized" - ); + if (!registry.isOwnerOrOperator(domainHash, msg.sender)) + revert NotAuthorizedForDomain(msg.sender, domainHash); Mintlist storage mintlistForDomain = mintlist[domainHash]; uint256 ownerIndex = mintlistForDomain.ownerIndex; @@ -344,7 +329,7 @@ contract ZNSSubRegistrar is AAccessControlled, ARegistryWired, UUPSUpgradeable, * @param registrar_ The new address of the ZNSRootRegistrar contract */ function setRootRegistrar(address registrar_) public override onlyAdmin { - require(registrar_ != address(0), "ZNSSubRegistrar: _registrar can not be 0x0 address"); + if (registrar_ == address(0)) revert ZeroAddressPassed(); rootRegistrar = IZNSRootRegistrar(registrar_); emit RootRegistrarSet(registrar_); diff --git a/contracts/registry/ARegistryWired.sol b/contracts/registry/ARegistryWired.sol index c4b0de706..259b04e85 100644 --- a/contracts/registry/ARegistryWired.sol +++ b/contracts/registry/ARegistryWired.sol @@ -1,7 +1,8 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.18; +pragma solidity 0.8.26; import { IZNSRegistry } from "./IZNSRegistry.sol"; +import { ZeroAddressPassed, NotAuthorizedForDomain } from "../utils/CommonErrors.sol"; /** @@ -10,7 +11,6 @@ import { IZNSRegistry } from "./IZNSRegistry.sol"; * and is able to get AC and domain data from it or write to it. */ abstract contract ARegistryWired { - /** * @notice Emitted when the ZNSRegistry address is set in state of the child contract. */ @@ -22,10 +22,8 @@ abstract contract ARegistryWired { IZNSRegistry public registry; modifier onlyOwnerOrOperator(bytes32 domainHash) { - require( - registry.isOwnerOrOperator(domainHash, msg.sender), - "ARegistryWired: Not authorized. Only Owner or Operator allowed" - ); + if (!registry.isOwnerOrOperator(domainHash, msg.sender)) + revert NotAuthorizedForDomain(msg.sender, domainHash); _; } @@ -33,7 +31,7 @@ abstract contract ARegistryWired { * @notice Internal function to set the ZNSRegistry address in the state of the child contract. */ function _setRegistry(address registry_) internal { - require(registry_ != address(0), "ARegistryWired: _registry can not be 0x0 address"); + if (registry_ == address(0)) revert ZeroAddressPassed(); registry = IZNSRegistry(registry_); emit RegistrySet(registry_); } diff --git a/contracts/registry/IZNSRegistry.sol b/contracts/registry/IZNSRegistry.sol index f6df6e3f3..f73a74ff6 100644 --- a/contracts/registry/IZNSRegistry.sol +++ b/contracts/registry/IZNSRegistry.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.18; +pragma solidity 0.8.26; /** @@ -14,7 +14,7 @@ pragma solidity 0.8.18; interface IZNSRegistry { /** - * @notice Description of a domain record, pointing to the + * @notice Description of a domain record, pointing to the * owner address of that record as well as the address of * its resolver */ @@ -123,7 +123,7 @@ interface IZNSRegistry { function getResolverType( string calldata resolverType - ) external returns (address); + ) external returns (address); function addResolverType( string calldata resolverType, diff --git a/contracts/registry/ZNSRegistry.sol b/contracts/registry/ZNSRegistry.sol index 2b79a8113..555770557 100644 --- a/contracts/registry/ZNSRegistry.sol +++ b/contracts/registry/ZNSRegistry.sol @@ -1,9 +1,10 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.18; +pragma solidity 0.8.26; import { IZNSRegistry } from "./IZNSRegistry.sol"; import { AAccessControlled } from "../access/AAccessControlled.sol"; import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; +import { ZeroAddressPassed, NotAuthorizedForDomain } from "../utils/CommonErrors.sol"; /** @@ -36,10 +37,8 @@ contract ZNSRegistry is AAccessControlled, UUPSUpgradeable, IZNSRegistry { * @param domainHash the hash of a domain's name */ modifier onlyOwnerOrOperator(bytes32 domainHash) { - require( - isOwnerOrOperator(domainHash, msg.sender), - "ZNSRegistry: Not authorized" - ); + if (!isOwnerOrOperator(domainHash, msg.sender)) + revert NotAuthorizedForDomain(msg.sender, domainHash); _; } @@ -48,10 +47,8 @@ contract ZNSRegistry is AAccessControlled, UUPSUpgradeable, IZNSRegistry { * @param domainHash the hash of a domain's name */ modifier onlyOwner(bytes32 domainHash) { - require( - records[domainHash].owner == msg.sender, - "ZNSRegistry: Not the Name Owner" - ); + if (records[domainHash].owner != msg.sender) + revert NotAuthorizedForDomain(msg.sender, domainHash); _; } @@ -183,7 +180,7 @@ contract ZNSRegistry is AAccessControlled, UUPSUpgradeable, IZNSRegistry { /** * @notice Add a new resolver type option to the mapping of types - * This function can also be used to update the resolver mapping for an existing resolver + * This function can also be used to update the resolver mapping for an existing resolver * simple by using an existing key like "address" with a new address * @param resolverType The type of the resolver to add * @param resolver The address of the new resolver contract @@ -234,11 +231,11 @@ contract ZNSRegistry is AAccessControlled, UUPSUpgradeable, IZNSRegistry { bytes32 domainHash, address owner ) external override { - require( - msg.sender == records[domainHash].owner || - accessController.isRegistrar(msg.sender), - "ZNSRegistry: Only Name Owner or Registrar allowed to call" - ); + if ( + msg.sender != records[domainHash].owner && + !accessController.isRegistrar(msg.sender) && + !accessController.isDomainToken(msg.sender) + ) revert NotAuthorizedForDomain(msg.sender, domainHash); _setDomainOwner(domainHash, owner); } @@ -286,7 +283,7 @@ contract ZNSRegistry is AAccessControlled, UUPSUpgradeable, IZNSRegistry { * @param owner The owner to set */ function _setDomainOwner(bytes32 domainHash, address owner) internal { - require(owner != address(0), "ZNSRegistry: Owner cannot be zero address"); + if (owner == address(0)) revert ZeroAddressPassed(); records[domainHash].owner = owner; emit DomainOwnerSet(domainHash, owner); } diff --git a/contracts/resolver/IZNSAddressResolver.sol b/contracts/resolver/IZNSAddressResolver.sol index 28711f29c..d4e3df1b8 100644 --- a/contracts/resolver/IZNSAddressResolver.sol +++ b/contracts/resolver/IZNSAddressResolver.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.18; +pragma solidity 0.8.26; interface IZNSAddressResolver { diff --git a/contracts/resolver/IZNSStringResolver.sol b/contracts/resolver/IZNSStringResolver.sol new file mode 100644 index 000000000..81ac436fd --- /dev/null +++ b/contracts/resolver/IZNSStringResolver.sol @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.26; + + +interface IZNSStringResolver { + /** + * @param domainHash The identifying hash of a domain's name + * @param newString - content of string type set by the owner/operator to which a domain will resolve to + */ + event StringSet(bytes32 indexed domainHash, string indexed newString); + + function supportsInterface(bytes4 interfaceId) external view returns (bool); + + function resolveDomainString(bytes32 domainHash) external view returns (string memory); + + function setString( + bytes32 domainHash, + string calldata newString + ) external; + + function getInterfaceId() external pure returns (bytes4); + + function setRegistry(address _registry) external; + + function initialize(address _accessController, address _registry) external; +} diff --git a/contracts/resolver/ZNSAddressResolver.sol b/contracts/resolver/ZNSAddressResolver.sol index f20298e43..e07762837 100644 --- a/contracts/resolver/ZNSAddressResolver.sol +++ b/contracts/resolver/ZNSAddressResolver.sol @@ -1,11 +1,12 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.18; +pragma solidity 0.8.26; import { ERC165 } from "@openzeppelin/contracts/utils/introspection/ERC165.sol"; import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; import { IZNSAddressResolver } from "./IZNSAddressResolver.sol"; import { AAccessControlled } from "../access/AAccessControlled.sol"; import { ARegistryWired } from "../registry/ARegistryWired.sol"; +import { NotAuthorizedForDomain } from "../utils/CommonErrors.sol"; /** @@ -67,11 +68,10 @@ contract ZNSAddressResolver is ) external override { // only owner or operator of the current domain can set the address // also, ZNSRootRegistrar.sol can set the address as part of the registration process - require( - registry.isOwnerOrOperator(domainHash, msg.sender) || - accessController.isRegistrar(msg.sender), - "ZNSAddressResolver: Not authorized for this domain" - ); + if ( + !registry.isOwnerOrOperator(domainHash, msg.sender) && + !accessController.isRegistrar(msg.sender) + ) revert NotAuthorizedForDomain(msg.sender, domainHash); domainAddresses[domainHash] = newAddress; diff --git a/contracts/resolver/ZNSStringResolver.sol b/contracts/resolver/ZNSStringResolver.sol new file mode 100644 index 000000000..36d932569 --- /dev/null +++ b/contracts/resolver/ZNSStringResolver.sol @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.26; + +import { ERC165 } from "@openzeppelin/contracts/utils/introspection/ERC165.sol"; +import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; +import { IZNSStringResolver } from "./IZNSStringResolver.sol"; +import { AAccessControlled } from "../access/AAccessControlled.sol"; +import { ARegistryWired } from "../registry/ARegistryWired.sol"; +import { NotAuthorizedForDomain } from "../utils/CommonErrors.sol"; + + +/** + * @title The specific Resolver for ZNS that maps domain hashes to strings. + */ +contract ZNSStringResolver is + UUPSUpgradeable, + AAccessControlled, + ARegistryWired, + ERC165, + IZNSStringResolver { + + mapping(bytes32 domainHash => string resolvedString) internal resolvedStrings; + + /// @custom:oz-upgrades-unsafe-allow constructor + constructor() { + _disableInitializers(); + } + + /** + * @notice Initializer for the `ZNSStringResolver` proxy. + * Note that setter functions are used instead of direct state variable assignments + * to use access control at deploy time. Only ADMIN can call this function. + * @param accessController_ The address of the `ZNSAccessController` contract + * @param registry_ The address of the `ZNSRegistry` contract + */ + function initialize(address accessController_, address registry_) external override initializer { + _setAccessController(accessController_); + setRegistry(registry_); + } + + /** + * @dev Returns string associated with a given domain name hash. + * @param domainHash The identifying hash of a domain's name + */ + function resolveDomainString( + bytes32 domainHash + ) external view override returns (string memory) { + return resolvedStrings[domainHash]; + } + + /** + * @dev Sets the string for a domain name hash. + * @param domainHash The identifying hash of a domain's name + * @param newString The new string to map the domain to + */ + function setString( + bytes32 domainHash, + string calldata newString + ) external override { + // only owner or operator of the current domain can set the string + + if (!registry.isOwnerOrOperator(domainHash, msg.sender)) { + revert NotAuthorizedForDomain(msg.sender, domainHash); + } + + resolvedStrings[domainHash] = newString; + + emit StringSet(domainHash, newString); + } + + /** + * @dev ERC-165 check for implementation identifier + * @dev Supports interfaces IZNSStringResolver and IERC165 + * @param interfaceId ID to check, XOR of the first 4 bytes of each function signature + */ + function supportsInterface( + bytes4 interfaceId + ) public view virtual override(ERC165, IZNSStringResolver) returns (bool) { + return + interfaceId == getInterfaceId() || + super.supportsInterface(interfaceId); + } + + /** + * @dev Exposes IZNSStringResolver interfaceId + */ + function getInterfaceId() public pure override returns (bytes4) { + return type(IZNSStringResolver).interfaceId; + } + + /** + * @dev Sets the address of the `ZNSRegistry` contract that holds all crucial data + * for every domain in the system. This function can only be called by the ADMIN. + * @param _registry The address of the `ZNSRegistry` contract + */ + function setRegistry(address _registry) public override(ARegistryWired, IZNSStringResolver) onlyAdmin { + _setRegistry(_registry); + } + + /** + * @notice To use UUPS proxy we override this function and revert if `msg.sender` isn't authorized + * @param newImplementation The implementation contract to upgrade to + */ + // solhint-disable-next-line no-unused-vars + function _authorizeUpgrade(address newImplementation) internal view override { + accessController.checkGovernor(msg.sender); + } +} diff --git a/contracts/token/IZNSDomainToken.sol b/contracts/token/IZNSDomainToken.sol index 4e288c8c7..295756407 100644 --- a/contracts/token/IZNSDomainToken.sol +++ b/contracts/token/IZNSDomainToken.sol @@ -1,11 +1,10 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.18; +pragma solidity 0.8.26; -import { IERC721Upgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol"; -import { IERC2981Upgradeable } from "@openzeppelin/contracts-upgradeable/interfaces/IERC2981Upgradeable.sol"; +import { IERC721 } from "@openzeppelin/contracts/token/ERC721/IERC721.sol"; +import { IERC2981 } from "@openzeppelin/contracts/interfaces/IERC2981.sol"; - -interface IZNSDomainToken is IERC2981Upgradeable, IERC721Upgradeable { +interface IZNSDomainToken is IERC2981, IERC721 { /** * @notice Emitted when a Default Royalty (for all tokens) is set. @@ -26,12 +25,15 @@ interface IZNSDomainToken is IERC2981Upgradeable, IERC721Upgradeable { */ event TokenURISet(uint256 indexed tokenId, string indexed tokenURI); + error CallerNotOwner(); + function initialize( address accessController, string calldata tokenName, string calldata tokenSymbol, address defaultRoyaltyReceiver, - uint96 defaultRoyaltyFraction + uint96 defaultRoyaltyFraction, + address registry ) external; function totalSupply() external view returns (uint256); @@ -55,11 +57,15 @@ interface IZNSDomainToken is IERC2981Upgradeable, IERC721Upgradeable { function setDefaultRoyalty(address receiver, uint96 royaltyFraction) external; + function updateTokenOwner(address from, address to, uint256 tokenId) external; + function setTokenRoyalty( uint256 tokenId, address receiver, uint96 royaltyFraction ) external; + function setRegistry(address registry_) external; + function supportsInterface(bytes4 interfaceId) external view returns (bool); } diff --git a/contracts/token/ZNSDomainToken.sol b/contracts/token/ZNSDomainToken.sol index ec3cc1ecd..fbab61a54 100644 --- a/contracts/token/ZNSDomainToken.sol +++ b/contracts/token/ZNSDomainToken.sol @@ -1,12 +1,14 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.18; +pragma solidity 0.8.26; -import { ERC721Upgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol"; import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; import { ERC2981Upgradeable } from "@openzeppelin/contracts-upgradeable/token/common/ERC2981Upgradeable.sol"; +import { IERC721 } from "@openzeppelin/contracts/token/ERC721/IERC721.sol"; +import { ERC721Upgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol"; import { ERC721URIStorageUpgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol"; import { IZNSDomainToken } from "./IZNSDomainToken.sol"; +import { ARegistryWired } from "../registry/ARegistryWired.sol"; import { AAccessControlled } from "../access/AAccessControlled.sol"; @@ -18,10 +20,10 @@ import { AAccessControlled } from "../access/AAccessControlled.sol"; */ contract ZNSDomainToken is AAccessControlled, - ERC721Upgradeable, - ERC2981Upgradeable, ERC721URIStorageUpgradeable, + ERC2981Upgradeable, UUPSUpgradeable, + ARegistryWired, IZNSDomainToken { /** @@ -53,11 +55,13 @@ contract ZNSDomainToken is string memory name_, string memory symbol_, address defaultRoyaltyReceiver, - uint96 defaultRoyaltyFraction + uint96 defaultRoyaltyFraction, + address registry_ ) external override initializer { __ERC721_init(name_, symbol_); _setAccessController(accessController_); _setDefaultRoyalty(defaultRoyaltyReceiver, defaultRoyaltyFraction); + _setRegistry(registry_); } /** @@ -89,6 +93,7 @@ contract ZNSDomainToken is */ function revoke(uint256 tokenId) external override onlyRegistrar { _burn(tokenId); + --_totalSupply; _resetTokenRoyalty(tokenId); } @@ -98,7 +103,7 @@ contract ZNSDomainToken is function tokenURI(uint256 tokenId) public view - override(ERC721URIStorageUpgradeable, ERC721Upgradeable, IZNSDomainToken) + override(ERC721URIStorageUpgradeable, IZNSDomainToken) returns (string memory) { return super.tokenURI(tokenId); @@ -161,6 +166,15 @@ contract ZNSDomainToken is emit TokenRoyaltySet(tokenId, royaltyFraction); } + /** + * @notice Setter function for the `ZNSRegistry` address in state. + * Only ADMIN in `ZNSAccessController` can call this function. + * @param registry_ Address of the `ZNSRegistry` contract + */ + function setRegistry(address registry_) public override(ARegistryWired, IZNSDomainToken) onlyAdmin { + _setRegistry(registry_); + } + /** * @notice To allow for user extension of the protocol we have to * enable checking acceptance of new interfaces to ensure they are supported @@ -170,21 +184,40 @@ contract ZNSDomainToken is public view virtual - override(ERC721Upgradeable, ERC721URIStorageUpgradeable, ERC2981Upgradeable, IZNSDomainToken) + override(ERC721URIStorageUpgradeable, ERC2981Upgradeable, IZNSDomainToken) returns (bool) { return super.supportsInterface(interfaceId); } /** - * @notice ERC721 `_burn` function - * @param tokenId The ID of the token to burn + * @notice We override the standard transfer function to update the owner for both the `registry` and `token` + * This non-standard transfer is to behave similarly to the default transfer that only updates the `token` + * + * @param from Owner of the token + * @param to Address to send the token to + * @param tokenId The token being transferred */ - function _burn(uint256 tokenId) - internal - override(ERC721URIStorageUpgradeable, ERC721Upgradeable) - { - super._burn(tokenId); - --_totalSupply; + function updateTokenOwner(address from, address to, uint256 tokenId) public override { + super.transferFrom(from, to, tokenId); + } + + /** + * @notice Override the standard transferFrom function to update the owner for both the `registry` and `token` + * + * @dev See {IERC721-transferFrom} + */ + function transferFrom( + address from, + address to, + uint256 tokenId + ) public override(ERC721Upgradeable, IERC721) { + // Transfer the token + super.transferFrom(from, to, tokenId); + + // Update the registry + // because `_transfer` already checks for `to == address(0)` we don't need to check it here + // We `encodePacked` here to ensure that any values that result in leading zeros are converted correctly + registry.updateDomainOwner(bytes32(abi.encodePacked(tokenId)), to); } /** diff --git a/contracts/token/mocks/CustomDecimalTokenMock.sol b/contracts/token/mocks/CustomDecimalTokenMock.sol index 3d5c46b0b..507a1adf0 100644 --- a/contracts/token/mocks/CustomDecimalTokenMock.sol +++ b/contracts/token/mocks/CustomDecimalTokenMock.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.18; +pragma solidity 0.8.26; // solhint-disable import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; @@ -9,9 +9,9 @@ contract CustomDecimalTokenMock is ERC20 { uint256 private _totalSupplyBase = 10000000000000000000000; - constructor(address owner, uint256 decimals) ERC20("VariedDecimalTokenMock", "VDTM") { - _decimals = uint8(decimals); - _mint(owner, totalSupply()); + constructor(address owner_, uint256 decimals_) ERC20("VariedDecimalTokenMock", "VDTM") { + _decimals = uint8(decimals_); + _mint(owner_, totalSupply()); } function decimals() public view override returns (uint8) { diff --git a/contracts/token/mocks/MeowTokenMock.sol b/contracts/token/mocks/MeowTokenMock.sol deleted file mode 100644 index 7465f6a21..000000000 --- a/contracts/token/mocks/MeowTokenMock.sol +++ /dev/null @@ -1,13 +0,0 @@ -// SPDX-License-Identifier: MIT -/* solhint-disable */ -pragma solidity 0.8.3; - -import { MeowToken } from "@zero-tech/ztoken/contracts/MeowToken.sol"; -import { MeowTokenTest } from "@zero-tech/ztoken/contracts/MeowTokenTest.sol"; - - -contract MeowTokenMock is MeowToken { - function mint(address account, uint256 amount) public { - _mint(account, amount); - } -} diff --git a/contracts/token/mocks/ZTokenMock.sol b/contracts/token/mocks/ZTokenMock.sol new file mode 100644 index 000000000..7474e398b --- /dev/null +++ b/contracts/token/mocks/ZTokenMock.sol @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.26; + +import { ZToken } from "@zero-tech/z-token/contracts/ZToken.sol"; + + +contract ZTokenMock is ZToken { + constructor( + string memory _name, + string memory _symbol, + address _defaultAdmin, + uint48 _initialAdminDelay, + address _minter, + address _mintBeneficiary, + uint256 _initialSupplyBase, + uint16[] memory _inflationRates, + uint16 _finalInflationRate + ) ZToken( + _name, + _symbol, + _defaultAdmin, + _initialAdminDelay, + _minter, + _mintBeneficiary, + _initialSupplyBase, + _inflationRates, + _finalInflationRate + ) {} + + // for tests, to identify mock contract + function identifyMock() external pure returns (string memory) { + return "This is a mock token"; + } +} \ No newline at end of file diff --git a/contracts/treasury/IZNSTreasury.sol b/contracts/treasury/IZNSTreasury.sol index 28acd8461..bd2ed85d0 100644 --- a/contracts/treasury/IZNSTreasury.sol +++ b/contracts/treasury/IZNSTreasury.sol @@ -1,9 +1,9 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.18; +pragma solidity 0.8.26; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -/** +/** * @notice The `PaymentConfig` struct describes the two pieces of information * needed to create a payment configuration for a domain. The address of the * user to send funds to in a sale, and what token those funds are in. @@ -26,9 +26,10 @@ struct PaymentConfig { * + `amount`: The amount of the staking token above deposited by the user */ interface IZNSTreasury { + error NoBeneficiarySetForParent(bytes32 domainHash); /** - * @notice Describe a stake for a domain. This could be + * @notice Describe a stake for a domain. This could be * in any ERC20 token so the address of the specific token * as well as the amount is required. */ diff --git a/contracts/treasury/ZNSTreasury.sol b/contracts/treasury/ZNSTreasury.sol index b9d8dfb48..51bb39bdc 100644 --- a/contracts/treasury/ZNSTreasury.sol +++ b/contracts/treasury/ZNSTreasury.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.18; +pragma solidity 0.8.26; import { IZNSTreasury } from "./IZNSTreasury.sol"; import { AAccessControlled } from "../access/AAccessControlled.sol"; @@ -8,6 +8,7 @@ import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/utils import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import { PaymentConfig } from "./IZNSTreasury.sol"; import { ARegistryWired } from "../registry/ARegistryWired.sol"; +import { ZeroAddressPassed, NotAuthorizedForDomain } from "../utils/CommonErrors.sol"; /** @@ -62,14 +63,8 @@ contract ZNSTreasury is AAccessControlled, ARegistryWired, UUPSUpgradeable, IZNS _setAccessController(accessController_); _setRegistry(registry_); - require( - paymentToken_ != address(0), - "ZNSTreasury: paymentToken_ passed as 0x0 address" - ); - require( - zeroVault_ != address(0), - "ZNSTreasury: zeroVault_ passed as 0x0 address" - ); + if (paymentToken_ == address(0) || zeroVault_ == address(0)) + revert ZeroAddressPassed(); paymentConfigs[0x0] = PaymentConfig({ token: IERC20(paymentToken_), @@ -120,10 +115,8 @@ contract ZNSTreasury is AAccessControlled, ARegistryWired, UUPSUpgradeable, IZNS // transfer stake fee to the parent beneficiary if it's > 0 if (stakeFee > 0) { - require( - parentConfig.beneficiary != address(0), - "ZNSTreasury: parent domain has no beneficiary set" - ); + if (parentConfig.beneficiary == address(0)) + revert NoBeneficiarySetForParent(parentHash); parentConfig.token.safeTransfer( parentConfig.beneficiary, @@ -206,10 +199,8 @@ contract ZNSTreasury is AAccessControlled, ARegistryWired, UUPSUpgradeable, IZNS ) external override onlyRegistrar { PaymentConfig memory parentConfig = paymentConfigs[parentHash]; - require( - parentConfig.beneficiary != address(0), - "ZNSTreasury: parent domain has no beneficiary set" - ); + if (parentConfig.beneficiary == address(0)) + revert NoBeneficiarySetForParent(parentHash); // Transfer payment to parent beneficiary from payer parentConfig.token.safeTransferFrom( @@ -245,10 +236,11 @@ contract ZNSTreasury is AAccessControlled, ARegistryWired, UUPSUpgradeable, IZNS bytes32 domainHash, PaymentConfig memory paymentConfig ) external override { - require( - registry.isOwnerOrOperator(domainHash, msg.sender) || accessController.isRegistrar(msg.sender), - "ZNSTreasury: Not authorized." - ); + if ( + !registry.isOwnerOrOperator(domainHash, msg.sender) + && !accessController.isRegistrar(msg.sender) + ) revert NotAuthorizedForDomain(msg.sender, domainHash); + _setBeneficiary(domainHash, paymentConfig.beneficiary); _setPaymentToken(domainHash, address(paymentConfig.token)); } @@ -291,14 +283,16 @@ contract ZNSTreasury is AAccessControlled, ARegistryWired, UUPSUpgradeable, IZNS } function _setBeneficiary(bytes32 domainHash, address beneficiary) internal { - require(beneficiary != address(0), "ZNSTreasury: beneficiary passed as 0x0 address"); + if (beneficiary == address(0)) + revert ZeroAddressPassed(); paymentConfigs[domainHash].beneficiary = beneficiary; emit BeneficiarySet(domainHash, beneficiary); } function _setPaymentToken(bytes32 domainHash, address paymentToken) internal { - require(paymentToken != address(0), "ZNSTreasury: paymentToken passed as 0x0 address"); + if (paymentToken == address(0)) + revert ZeroAddressPassed(); paymentConfigs[domainHash].token = IERC20(paymentToken); emit PaymentTokenSet(domainHash, paymentToken); diff --git a/contracts/types/ICurvePriceConfig.sol b/contracts/types/ICurvePriceConfig.sol index 295b44462..4a3fd5af7 100644 --- a/contracts/types/ICurvePriceConfig.sol +++ b/contracts/types/ICurvePriceConfig.sol @@ -1,13 +1,13 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.18; +pragma solidity 0.8.26; /** * @dev **`CurvePriceConfig` struct properties:** * * - `maxPrice` (uint256): Maximum price for a domain returned at <= `baseLength` - * - `minPrice` (uint256): Minimum price for a domain returned at > `maxLength` - * - `maxLength` (uint256): Maximum length of a domain name. If the name is longer - we return the `minPrice` + * - `maxLength` (uint256): Maximum length of a domain name. If the name is longer - + * we return the price that was at the `maxLength`. * - `baseLength` (uint256): Base length of a domain name. If the name is shorter or equal - we return the `maxPrice` * - `precisionMultiplier` (uint256): The precision multiplier of the price. This multiplier * should be picked based on the number of token decimals to calculate properly. @@ -25,12 +25,12 @@ interface ICurvePriceConfig { */ uint256 maxPrice; /** - * @notice Minimum price for a domain returned at > `maxLength` + * @notice Multiplier which we use to bend a curve of price on interval from `baseLength` to `maxLength`. */ - uint256 minPrice; + uint256 curveMultiplier; /** * @notice Maximum length of a domain name. If the name is longer than this - * value we return the `minPrice` + * value we return the price that was at the `maxLength` */ uint256 maxLength; /** diff --git a/contracts/types/IDistributionConfig.sol b/contracts/types/IDistributionConfig.sol index 02adc7419..084f07826 100644 --- a/contracts/types/IDistributionConfig.sol +++ b/contracts/types/IDistributionConfig.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.18; +pragma solidity 0.8.26; import { IZNSPricer } from "../types/IZNSPricer.sol"; diff --git a/contracts/types/IZNSPricer.sol b/contracts/types/IZNSPricer.sol index c10900c7b..c6b7a711c 100644 --- a/contracts/types/IZNSPricer.sol +++ b/contracts/types/IZNSPricer.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.18; +pragma solidity 0.8.26; /** @@ -7,6 +7,28 @@ pragma solidity 0.8.18; * @notice Base interface required to be inherited by all Pricing contracts to work with zNS */ interface IZNSPricer { + /** + * @notice Reverted when someone is trying to buy a subdomain under a parent that is not set up for distribution. + * Specifically it's prices for subdomains. + */ + error ParentPriceConfigNotSet(bytes32 parentHash); + + /** + * @notice Reverted when domain owner is trying to set it's stake fee percentage + * higher than 100% (uint256 "10,000"). + */ + error FeePercentageValueTooLarge(uint256 feePercentage, uint256 maximum); + + /** + * @notice Reverted when `maxLength` smaller than `baseLength`. + */ + error MaxLengthSmallerThanBaseLength(bytes32 domainHash); + + /** + * @notice Reverted when `curveMultiplier` AND `baseLength` are 0. + */ + error DivisionByZero(bytes32 domainHash); + /** * @dev `parentHash` param is here to allow pricer contracts * to have different price configs for different subdomains @@ -38,7 +60,7 @@ interface IZNSPricer { /** * @notice Returns the fee for a given price. * @dev Fees are only supported for PaymentType.STAKE ! - */ + */ function getFeeForPrice( bytes32 parentHash, uint256 price diff --git a/contracts/upgrade-test-mocks/UpgradeMock.sol b/contracts/upgrade-test-mocks/UpgradeMock.sol index 20393f216..38b7957ce 100644 --- a/contracts/upgrade-test-mocks/UpgradeMock.sol +++ b/contracts/upgrade-test-mocks/UpgradeMock.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.18; +pragma solidity 0.8.26; /* solhint-disable */ contract UpgradeMock { diff --git a/contracts/upgrade-test-mocks/distribution/ZNSCurvePricerMock.sol b/contracts/upgrade-test-mocks/distribution/ZNSCurvePricerMock.sol index 507650178..f3bade036 100644 --- a/contracts/upgrade-test-mocks/distribution/ZNSCurvePricerMock.sol +++ b/contracts/upgrade-test-mocks/distribution/ZNSCurvePricerMock.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.18; +pragma solidity 0.8.26; import { ZNSCurvePricer } from "../../price/ZNSCurvePricer.sol"; import { UpgradeMock } from "../UpgradeMock.sol"; diff --git a/contracts/upgrade-test-mocks/distribution/ZNSFixedPricerMock.sol b/contracts/upgrade-test-mocks/distribution/ZNSFixedPricerMock.sol index 85565a732..25ff6ea39 100644 --- a/contracts/upgrade-test-mocks/distribution/ZNSFixedPricerMock.sol +++ b/contracts/upgrade-test-mocks/distribution/ZNSFixedPricerMock.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.18; +pragma solidity 0.8.26; import { ZNSFixedPricer } from "../../price/ZNSFixedPricer.sol"; import { UpgradeMock } from "../UpgradeMock.sol"; diff --git a/contracts/upgrade-test-mocks/distribution/ZNSRootRegistrarMock.sol b/contracts/upgrade-test-mocks/distribution/ZNSRootRegistrarMock.sol index f153db525..76fd2d202 100644 --- a/contracts/upgrade-test-mocks/distribution/ZNSRootRegistrarMock.sol +++ b/contracts/upgrade-test-mocks/distribution/ZNSRootRegistrarMock.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.18; +pragma solidity 0.8.26; import { ZNSRootRegistrar } from "../../registrar/ZNSRootRegistrar.sol"; import { UpgradeMock } from "../UpgradeMock.sol"; diff --git a/contracts/upgrade-test-mocks/distribution/ZNSSubRegistrarMock.sol b/contracts/upgrade-test-mocks/distribution/ZNSSubRegistrarMock.sol index 95269a9fe..eaf21610c 100644 --- a/contracts/upgrade-test-mocks/distribution/ZNSSubRegistrarMock.sol +++ b/contracts/upgrade-test-mocks/distribution/ZNSSubRegistrarMock.sol @@ -1,9 +1,10 @@ // SPDX-License-Identifier: MIT /* solhint-disable */ -pragma solidity 0.8.18; +pragma solidity 0.8.26; // solhint-disable import { ZNSSubRegistrar } from "../../registrar/ZNSSubRegistrar.sol"; +import { IZNSSubRegistrar } from "../../registrar/IZNSSubRegistrar.sol"; import { UpgradeMock } from "../UpgradeMock.sol"; import { IZNSPricer } from "../../types/IZNSPricer.sol"; import { IZNSRootRegistrar, CoreRegisterArgs } from "../../registrar/IZNSRootRegistrar.sol"; @@ -12,6 +13,7 @@ import { ARegistryWired } from "../../registry/ARegistryWired.sol"; import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; import { StringUtils } from "../../utils/StringUtils.sol"; import { PaymentConfig } from "../../treasury/IZNSTreasury.sol"; +import { NotAuthorizedForDomain, ZeroAddressPassed, DomainAlreadyExists } from "../../utils/CommonErrors.sol"; enum AccessType { @@ -39,7 +41,12 @@ contract ZNSSubRegistrarMainState { mapping(bytes32 domainHash => DistributionConfig config) public distrConfigs; - mapping(bytes32 domainHash => mapping(address candidate => bool allowed)) public mintlist; + struct Mintlist { + mapping(uint256 idx => mapping(address candidate => bool allowed)) list; + uint256 ownerIndex; + } + + mapping(bytes32 domainHash => Mintlist mintStruct) public mintlist; } @@ -49,18 +56,25 @@ contract ZNSSubRegistrarUpgradeMock is UUPSUpgradeable, ZNSSubRegistrarMainState, UpgradeMock { - using StringUtils for string; + error ParentLockedOrDoesntExist(bytes32 parentHash); + + error SenderNotApprovedForPurchase(bytes32 parentHash, address sender); + modifier onlyOwnerOperatorOrRegistrar(bytes32 domainHash) { - require( - registry.isOwnerOrOperator(domainHash, msg.sender) - || accessController.isRegistrar(msg.sender), - "ZNSSubRegistrar: Not authorized" - ); + if ( + !registry.isOwnerOrOperator(domainHash, msg.sender) + && !accessController.isRegistrar(msg.sender) + ) revert NotAuthorizedForDomain(msg.sender, domainHash); _; } + /// @custom:oz-upgrades-unsafe-allow constructor + constructor() { + _disableInitializers(); + } + function initialize( address _accessController, address _registry, @@ -75,30 +89,35 @@ contract ZNSSubRegistrarUpgradeMock is bytes32 parentHash, string calldata label, address domainAddress, - string memory tokenURI, + string calldata tokenURI, DistributionConfig calldata distrConfig, PaymentConfig calldata paymentConfig ) external returns (bytes32) { + // Confirms string values are only [a-z0-9-] label.validate(); + bytes32 domainHash = hashWithParent(parentHash, label); + if (registry.exists(domainHash)) + revert DomainAlreadyExists(domainHash); + DistributionConfig memory parentConfig = distrConfigs[parentHash]; bool isOwnerOrOperator = registry.isOwnerOrOperator(parentHash, msg.sender); - require( - parentConfig.accessType != AccessType.LOCKED || isOwnerOrOperator, - "ZNSSubRegistrar: Parent domain's distribution is locked or parent does not exist" - ); + if (parentConfig.accessType == AccessType.LOCKED && !isOwnerOrOperator) + revert ParentLockedOrDoesntExist(parentHash); if (parentConfig.accessType == AccessType.MINTLIST) { - require( - mintlist[parentHash][msg.sender], - "ZNSSubRegistrar: Sender is not approved for purchase" - ); + if ( + !mintlist[parentHash] + .list + [mintlist[parentHash].ownerIndex] + [msg.sender] + ) revert SenderNotApprovedForPurchase(parentHash, msg.sender); } CoreRegisterArgs memory coreRegisterArgs = CoreRegisterArgs({ parentHash: parentHash, - domainHash: hashWithParent(parentHash, label), + domainHash: domainHash, label: label, registrant: msg.sender, price: 0, @@ -109,11 +128,6 @@ contract ZNSSubRegistrarUpgradeMock is paymentConfig: paymentConfig }); - require( - !registry.exists(coreRegisterArgs.domainHash), - "ZNSSubRegistrar: Subdomain already exists" - ); - if (!isOwnerOrOperator) { if (coreRegisterArgs.isStakePayment) { (coreRegisterArgs.price, coreRegisterArgs.stakeFee) = IZNSPricer(address(parentConfig.pricerContract)) @@ -138,7 +152,7 @@ contract ZNSSubRegistrarUpgradeMock is setDistributionConfigForDomain(coreRegisterArgs.domainHash, distrConfig); } - return coreRegisterArgs.domainHash; + return domainHash; } function hashWithParent( @@ -157,10 +171,8 @@ contract ZNSSubRegistrarUpgradeMock is bytes32 domainHash, DistributionConfig calldata config ) public onlyOwnerOperatorOrRegistrar(domainHash) { - require( - address(config.pricerContract) != address(0), - "ZNSSubRegistrar: pricerContract can not be 0x0 address" - ); + if (address(config.pricerContract) == address(0)) + revert ZeroAddressPassed(); distrConfigs[domainHash] = config; } @@ -169,15 +181,11 @@ contract ZNSSubRegistrarUpgradeMock is bytes32 domainHash, IZNSPricer pricerContract ) public { - require( - registry.isOwnerOrOperator(domainHash, msg.sender), - "ZNSSubRegistrar: Not authorized" - ); + if (!registry.isOwnerOrOperator(domainHash, msg.sender)) + revert NotAuthorizedForDomain(msg.sender, domainHash); - require( - address(pricerContract) != address(0), - "ZNSSubRegistrar: pricerContract can not be 0x0 address" - ); + if (address(pricerContract) == address(0)) + revert ZeroAddressPassed(); distrConfigs[domainHash].pricerContract = pricerContract; } @@ -186,26 +194,17 @@ contract ZNSSubRegistrarUpgradeMock is bytes32 domainHash, PaymentType paymentType ) public { - require( - registry.isOwnerOrOperator(domainHash, msg.sender), - "ZNSSubRegistrar: Not authorized" - ); + if (!registry.isOwnerOrOperator(domainHash, msg.sender)) + revert NotAuthorizedForDomain(msg.sender, domainHash); distrConfigs[domainHash].paymentType = paymentType; } - function _setAccessTypeForDomain( - bytes32 domainHash, - AccessType accessType - ) internal { - distrConfigs[domainHash].accessType = accessType; - } - function setAccessTypeForDomain( bytes32 domainHash, AccessType accessType - ) external onlyOwnerOperatorOrRegistrar(domainHash) { - _setAccessTypeForDomain(domainHash, accessType); + ) public onlyOwnerOperatorOrRegistrar(domainHash) { + distrConfigs[domainHash].accessType = accessType; } function updateMintlistForDomain( @@ -213,29 +212,47 @@ contract ZNSSubRegistrarUpgradeMock is address[] calldata candidates, bool[] calldata allowed ) external { - require( - registry.isOwnerOrOperator(domainHash, msg.sender), - "ZNSSubRegistrar: Not authorized" - ); + if (!registry.isOwnerOrOperator(domainHash, msg.sender)) + revert NotAuthorizedForDomain(msg.sender, domainHash); + + Mintlist storage mintlistForDomain = mintlist[domainHash]; + uint256 ownerIndex = mintlistForDomain.ownerIndex; for (uint256 i; i < candidates.length; i++) { - mintlist[domainHash][candidates[i]] = allowed[i]; + mintlistForDomain.list[ownerIndex][candidates[i]] = allowed[i]; } } + function isMintlistedForDomain( + bytes32 domainHash, + address candidate + ) external view returns (bool) { + uint256 ownerIndex = mintlist[domainHash].ownerIndex; + return mintlist[domainHash].list[ownerIndex][candidate]; + } + + function clearMintlistForDomain(bytes32 domainHash) + public + onlyOwnerOperatorOrRegistrar(domainHash) { + mintlist[domainHash].ownerIndex = mintlist[domainHash].ownerIndex + 1; + } + + function clearMintlistAndLock(bytes32 domainHash) + external + onlyOwnerOperatorOrRegistrar(domainHash) { + setAccessTypeForDomain(domainHash, AccessType.LOCKED); + clearMintlistForDomain(domainHash); + } + function setRegistry(address registry_) public override onlyAdmin { _setRegistry(registry_); } function setRootRegistrar(address registrar_) public onlyAdmin { - require(registrar_ != address(0), "ZNSSubRegistrar: _registrar can not be 0x0 address"); + if (registrar_ == address(0)) revert ZeroAddressPassed(); rootRegistrar = IZNSRootRegistrar(registrar_); } - /** - * @notice To use UUPS proxy we override this function and revert if `msg.sender` isn't authorized - * @param newImplementation The implementation contract to upgrade to - */ // solhint-disable-next-line function _authorizeUpgrade(address newImplementation) internal view override { accessController.checkGovernor(msg.sender); diff --git a/contracts/upgrade-test-mocks/distribution/ZNSTreasuryMock.sol b/contracts/upgrade-test-mocks/distribution/ZNSTreasuryMock.sol index 292bbb424..e6c07bf68 100644 --- a/contracts/upgrade-test-mocks/distribution/ZNSTreasuryMock.sol +++ b/contracts/upgrade-test-mocks/distribution/ZNSTreasuryMock.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.18; +pragma solidity 0.8.26; import { ZNSTreasury } from "../../treasury/ZNSTreasury.sol"; import { UpgradeMock } from "../UpgradeMock.sol"; diff --git a/contracts/upgrade-test-mocks/registry/ZNSRegistryMock.sol b/contracts/upgrade-test-mocks/registry/ZNSRegistryMock.sol index 0193e0e3a..9158a59d5 100644 --- a/contracts/upgrade-test-mocks/registry/ZNSRegistryMock.sol +++ b/contracts/upgrade-test-mocks/registry/ZNSRegistryMock.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.18; +pragma solidity 0.8.26; import { ZNSRegistry } from "../../registry/ZNSRegistry.sol"; import { UpgradeMock } from "../UpgradeMock.sol"; diff --git a/contracts/upgrade-test-mocks/resolver/ZNSAddressResolverMock.sol b/contracts/upgrade-test-mocks/resolver/ZNSAddressResolverMock.sol index eb8027589..00cb37dbd 100644 --- a/contracts/upgrade-test-mocks/resolver/ZNSAddressResolverMock.sol +++ b/contracts/upgrade-test-mocks/resolver/ZNSAddressResolverMock.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.18; +pragma solidity 0.8.26; import { ZNSAddressResolver } from "../../resolver/ZNSAddressResolver.sol"; import { UpgradeMock } from "../UpgradeMock.sol"; diff --git a/contracts/upgrade-test-mocks/resolver/ZNSStringResolverMock.sol b/contracts/upgrade-test-mocks/resolver/ZNSStringResolverMock.sol new file mode 100644 index 000000000..e971a5374 --- /dev/null +++ b/contracts/upgrade-test-mocks/resolver/ZNSStringResolverMock.sol @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.26; + +import { ZNSStringResolver } from "../../resolver/ZNSStringResolver.sol"; +import { UpgradeMock } from "../UpgradeMock.sol"; + +/* solhint-disable-next-line */ +contract ZNSStringResolverUpgradeMock is ZNSStringResolver, UpgradeMock {} \ No newline at end of file diff --git a/contracts/upgrade-test-mocks/token/ZNSDomainTokenMock.sol b/contracts/upgrade-test-mocks/token/ZNSDomainTokenMock.sol index 34facac9a..1089e37cc 100644 --- a/contracts/upgrade-test-mocks/token/ZNSDomainTokenMock.sol +++ b/contracts/upgrade-test-mocks/token/ZNSDomainTokenMock.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.18; +pragma solidity 0.8.26; import { ZNSDomainToken } from "../../token/ZNSDomainToken.sol"; import { UpgradeMock } from "../UpgradeMock.sol"; diff --git a/contracts/utils/CommonErrors.sol b/contracts/utils/CommonErrors.sol new file mode 100644 index 000000000..11b22462f --- /dev/null +++ b/contracts/utils/CommonErrors.sol @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.26; + + +error ZeroAddressPassed(); + +error DomainAlreadyExists(bytes32 domainHash); + +error NotAuthorizedForDomain(address caller, bytes32 domainHash); diff --git a/contracts/utils/StringUtils.sol b/contracts/utils/StringUtils.sol index 99ac5b36f..158ef9197 100644 --- a/contracts/utils/StringUtils.sol +++ b/contracts/utils/StringUtils.sol @@ -1,10 +1,14 @@ // SPDX-License-Identifier: MIT -// Source: +// Forked from: // https://github.com/ensdomains/ens-contracts/blob/master/contracts/ethregistrar/StringUtils.sol -pragma solidity 0.8.18; +pragma solidity 0.8.26; library StringUtils { + error DomainLabelTooLongOrNonexistent(string label); + + error DomainLabelContainsInvalidCharacters(string label); + /** * @dev Returns the length of a given string * @@ -44,21 +48,14 @@ library StringUtils { // solhint-disable-next-line var-name-mixedcase uint256 MAX_INT = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff; - require( - length > 0 && length < MAX_INT, - "StringUtils: Domain label too long or nonexistent" - ); + if (length == 0 || length >= MAX_INT) + revert DomainLabelTooLongOrNonexistent(s); - for (uint256 i; i < length;) { + for (uint256 i; i < length; ++i) { bytes1 b = nameBytes[i]; // Valid strings are lower case a-z, 0-9, or a hyphen - require( - (b > 0x60 && b < 0x7B) || (b > 0x2F && b < 0x3A) || b == 0x2D, - "StringUtils: Invalid domain label" - ); - unchecked { - ++i; - } + if (!((b > 0x60 && b < 0x7B) || (b > 0x2F && b < 0x3A) || b == 0x2D)) + revert DomainLabelContainsInvalidCharacters(s); } } -} \ No newline at end of file +} diff --git a/hardhat.config.ts b/hardhat.config.ts index c50ac76ca..d82597ab5 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -36,18 +36,16 @@ subtask(TASK_TEST_RUN_MOCHA_TESTS) // does not work properly locally or in CI, so we // keep it commented out and uncomment when using DevNet // locally. -// !!! Uncomment this when using Tenderly !!! -tenderly.setup({ automaticVerifications: false }); const config : HardhatUserConfig = { solidity: { compilers: [ { - version: "0.8.18", + version: "0.8.26", settings: { optimizer: { enabled: true, - runs: 200, + runs: 20000, }, }, }, @@ -56,27 +54,27 @@ const config : HardhatUserConfig = { settings: { optimizer: { enabled: true, - runs: 200, + runs: 20000, }, }, }, ], overrides: { "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol": { - version: "0.8.9", + version: "0.8.20", settings: { optimizer: { enabled: true, - runs: 200, + runs: 20000, }, }, }, "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol": { - version: "0.8.9", + version: "0.8.20", settings: { optimizer: { enabled: true, - runs: 200, + runs: 20000, }, }, }, @@ -121,15 +119,26 @@ const config : HardhatUserConfig = { url: `${process.env.DEVNET_RPC_URL}`, chainId: 1, }, + // meowtestnet: { + // url: `${process.env.MEOWTESTNET_RPC_URL}`, + // accounts: [ + // `${process.env.DEPLOYER_PRIVATE_KEY}`, + // ], + // }, }, - defender: { - useDefenderDeploy: false, - apiKey: `${process.env.DEFENDER_KEY}`, - apiSecret: `${process.env.DEFENDER_SECRET}`, - }, - etherscan: { - apiKey: `${process.env.ETHERSCAN_API_KEY}`, - }, + // etherscan: { + // apiKey: `${process.env.ETHERSCAN_API_KEY}`, + // customChains: [ + // { + // network: "meowtestnet", + // chainId: 883424730, + // urls: { + // apiURL: "https://meowchain-testnet-blockscout.eu-north-2.gateway.fm/api/", + // browserURL: "https://meowchain-testnet-blockscout.eu-north-2.gateway.fm/", + // }, + // }, + // ], + // }, sourcify: { // If set to "true", will try to verify the contracts after deployment enabled: false, @@ -150,6 +159,20 @@ const config : HardhatUserConfig = { "oz-proxies/", ], }, + // meowtestnet: { + // url: `${process.env.MEOWTESTNET_RPC_URL}`, + // chainId: 883424730, + // accounts: [ // Comment out for CI, uncomment this when using Sepolia + // `${process.env.DEPLOYER_PRIVATE_KEY}`, + // `${process.env.ZERO_VAULT_PRIVATE_KEY}`, + // `${process.env.TESTNET_PRIVATE_KEY_A}`, + // `${process.env.TESTNET_PRIVATE_KEY_B}`, + // `${process.env.TESTNET_PRIVATE_KEY_C}`, + // `${process.env.TESTNET_PRIVATE_KEY_D}`, + // `${process.env.TESTNET_PRIVATE_KEY_E}`, + // `${process.env.TESTNET_PRIVATE_KEY_F}`, + // ], + // }, }; export default config; diff --git a/package.json b/package.json index 8a525aeae..e4ef41ee3 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "repository": "https://github.com/zer0-os/zNS.git", "engines": { "node": ">=18", - "npm": ">=9" + "npm": ">=10" }, "scripts": { "compile": "hardhat compile", @@ -15,7 +15,7 @@ "lint-ts": "yarn eslint ./test/** ./src/**", "lint": "yarn lint-sol & yarn lint-ts --no-error-on-unmatched-pattern", "clean": "hardhat clean", - "build": "yarn run clean && yarn run compile", + "build": "yarn run clean && yarn run compile && tsc", "postbuild": "yarn save-tag", "typechain": "hardhat typechain", "pretest": "yarn mongo:start", @@ -34,7 +34,9 @@ "mongo:stop": "docker-compose stop", "mongo:down": "docker-compose down", "mongo:drop": "ts-node src/utils/drop-db.ts", - "run-sepolia": "hardhat run src/deploy/run-campaign.ts --network sepolia" + "run-sepolia": "hardhat run src/deploy/run-campaign.ts --network sepolia", + "run-hardhat": "hardhat run src/deploy/run-campaign.ts --network hardhat", + "run-meowtestnet": "hardhat run src/deploy/run-campaign.ts --network meowtestnet" }, "pre-commit": [ "lint" @@ -42,16 +44,16 @@ "devDependencies": { "@ensdomains/ensjs": "2.1.0", "@nomicfoundation/hardhat-chai-matchers": "^2.0.2", - "@nomicfoundation/hardhat-ethers": "^3.0.5", - "@nomicfoundation/hardhat-network-helpers": "^1.0.9", + "@nomicfoundation/hardhat-ethers": "^3.0.6", + "@nomicfoundation/hardhat-network-helpers": "^1.0.11", "@nomicfoundation/hardhat-toolbox": "^4.0.0", - "@nomicfoundation/hardhat-verify": "^2.0.0", - "@openzeppelin/contracts": "4.9.3", + "@nomicfoundation/hardhat-verify": "^2.0.8", + "@openzeppelin/contracts": "^5.0.2", "@openzeppelin/contracts-400": "npm:@openzeppelin/contracts@4.0.0", - "@openzeppelin/contracts-upgradeable": "4.9.3", + "@openzeppelin/contracts-upgradeable": "^5.0.2", "@openzeppelin/contracts-upgradeable-400": "npm:@openzeppelin/contracts-upgradeable@4.0.0", "@openzeppelin/defender-sdk": "^1.7.0", - "@openzeppelin/hardhat-upgrades": "2.5.0", + "@openzeppelin/hardhat-upgrades": "^3.1.1", "@semantic-release/git": "^10.0.1", "@tenderly/hardhat-tenderly": "^2.0.1", "@typechain/ethers-v6": "^0.5.1", @@ -59,23 +61,23 @@ "@types/chai": "^4.3.11", "@types/mocha": "^9.1.0", "@types/node": "^18.15.11", - "@zero-tech/eslint-config-cpt": "0.2.7", - "@zero-tech/ztoken": "2.0.0", + "@zero-tech/eslint-config-cpt": "0.2.8", + "@zero-tech/z-token": "1.0.0", "chai": "^4.3.10", "eslint": "^8.37.0", "ethers": "^6.9.0", - "hardhat": "^2.19.1", + "hardhat": "^2.22.6", "hardhat-gas-reporter": "^1.0.9", "semantic-release": "^21.0.1", - "solhint": "^4.0.0", - "solidity-coverage": "^0.8.5", + "solhint": "^5.0.1", + "solidity-coverage": "^0.8.12", "solidity-docgen": "^0.6.0-beta.36", "ts-node": "10.9.1", "typechain": "^8.3.2", "typescript": "^5.0.2" }, "dependencies": { - "@zero-tech/zdc": "0.1.3", + "@zero-tech/zdc": "0.1.6", "axios": "^1.4.0", "dotenv": "16.0.3", "mongodb": "^6.1.0", diff --git a/src/deploy/campaign/environments.ts b/src/deploy/campaign/environments.ts index 2df9609a1..3ca1ab452 100644 --- a/src/deploy/campaign/environments.ts +++ b/src/deploy/campaign/environments.ts @@ -1,265 +1,306 @@ -import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; -import { IZNSCampaignConfig } from "./types"; -import { - DEFAULT_PROTOCOL_FEE_PERCENT, - DEFAULT_ROYALTY_FRACTION, - ZNS_DOMAIN_TOKEN_NAME, - ZNS_DOMAIN_TOKEN_SYMBOL, - DEFAULT_DECIMALS, - DECAULT_PRECISION, - DEFAULT_PRICE_CONFIG, - getCurvePrice, - NO_MOCK_PROD_ERR, - STAKING_TOKEN_ERR, - INVALID_CURVE_ERR, - MONGO_URI_ERR, - INVALID_ENV_ERR, NO_ZERO_VAULT_ERR, -} from "../../../test/helpers"; -import { ethers } from "ethers"; -import { ICurvePriceConfig } from "../missions/types"; -import { MeowMainnet } from "../missions/contracts/meow-token/mainnet-data"; - - -const getCustomAddresses = ( - key : string, - deployerAddress : string, - accounts ?: Array -) => { - const addresses = []; - - if (process.env[key]) { - /* eslint-disable @typescript-eslint/no-non-null-assertion */ - const decoded = atob(process.env[key]!); - - // Check if there is more than one custom governor - if (decoded.includes(",")) { - addresses.push(...decoded.split(",")); - } else { - addresses.push(decoded); - } - } - - if (accounts && accounts.length > 0) { - addresses.push(...accounts); // The user provided custom governors / admins as a param for testing - } - - if (!addresses.includes(deployerAddress)) { - // No custom governors / admins provided, use the deployer as the default - addresses.push(deployerAddress); - } - - - return addresses; -}; - -// This function builds a config with default values but overrides them with any values that are set -export const getConfig = async ({ - deployer, - governors, - admins, - zeroVaultAddress, - env, // this is ONLY used for tests! -} : { - deployer : SignerWithAddress; - governors ?: Array; - admins ?: Array; - zeroVaultAddress ?: string; - env ?: string; -}) : Promise> => { - // Will throw an error based on any invalid setup, given the `ENV_LEVEL` set - const priceConfig = validateEnv(env); - - let deployerAddress; - if (deployer && Object.keys(deployer).includes("address")) { - deployerAddress = deployer.address; - } else { - deployerAddress = await deployer.getAddress(); - } - - if (process.env.ENV_LEVEL === "dev") { - requires(!!zeroVaultAddress, "Must pass `zeroVaultAddress` to `getConfig()` for `dev` environment"); - } - - const zeroVaultAddressConf = process.env.ENV_LEVEL === "dev" - ? zeroVaultAddress! - : process.env.ZERO_VAULT_ADDRESS!; - - // Domain Token Values - const royaltyReceiver = process.env.ENV_LEVEL !== "dev" ? process.env.ROYALTY_RECEIVER! : zeroVaultAddressConf; - const royaltyFraction = - process.env.ROYALTY_FRACTION - ? BigInt(process.env.ROYALTY_FRACTION) - : DEFAULT_ROYALTY_FRACTION; - - // Get governor addresses set through env, if any - const governorAddresses = getCustomAddresses("GOVERNOR_ADDRESSES", deployerAddress, governors); - - // Get admin addresses set through env, if any - const adminAddresses = getCustomAddresses("ADMIN_ADDRESSES", deployerAddress, admins); - - const config : IZNSCampaignConfig = { - env: process.env.ENV_LEVEL!, - deployAdmin: deployer, - governorAddresses, - adminAddresses, - domainToken: { - name: process.env.DOMAIN_TOKEN_NAME ? process.env.DOMAIN_TOKEN_NAME : ZNS_DOMAIN_TOKEN_NAME, - symbol: process.env.DOMAIN_TOKEN_SYMBOL ? process.env.DOMAIN_TOKEN_SYMBOL : ZNS_DOMAIN_TOKEN_SYMBOL, - defaultRoyaltyReceiver: royaltyReceiver, - defaultRoyaltyFraction: royaltyFraction, - }, - rootPriceConfig: priceConfig, - zeroVaultAddress: zeroVaultAddressConf, - mockMeowToken: process.env.MOCK_MEOW_TOKEN === "true", - stakingTokenAddress: process.env.STAKING_TOKEN_ADDRESS!, - postDeploy: { - tenderlyProjectSlug: process.env.TENDERLY_PROJECT_SLUG!, - monitorContracts: process.env.MONITOR_CONTRACTS === "true", - verifyContracts: process.env.VERIFY_CONTRACTS === "true", - }, - }; - - return config; -}; - -// For testing the behaviour when we manipulate, we have an optional "env" string param -export const validateEnv = ( - env ?: string, // this is ONLY used for tests! -) : ICurvePriceConfig => { - // Prioritize reading from the env variable first, and only then fallback to the param - let envLevel = process.env.ENV_LEVEL; - - if (env) { - // We only ever specify an `env` param in tests - // So if there is a value we must use that instead - // otherwise only ever use the ENV_LEVEL above - envLevel = env; - } - - // Validate price config first since we have to return it - const priceConfig = getValidateRootPriceConfig(); - - if (envLevel === "dev") return priceConfig; - - if (envLevel === "test" || envLevel === "dev") { - if (process.env.MOCK_MEOW_TOKEN === "false" && !process.env.STAKING_TOKEN_ADDRESS) { - throw new Error("Must provide a staking token address if not mocking MEOW token in `dev` environment"); - } - } - - if (envLevel !== "test" && envLevel !== "prod") { - // If we reach this code, there is an env variable, but it's not valid. - throw new Error(INVALID_ENV_ERR); - } - - if (!process.env.ROYALTY_RECEIVER) { - throw new Error("Must provide a default royalty receiver"); - } - - if (!process.env.ROYALTY_FRACTION) { - throw new Error("Must provide a default royalty fraction"); - } - - if (!process.env.MONGO_DB_URI) { - throw new Error(`Must provide a Mongo URI used for ${envLevel} environment!`); - } - - requires(!!process.env.ZERO_VAULT_ADDRESS, NO_ZERO_VAULT_ERR); - - // Mainnet - if (envLevel === "prod") { - requires(process.env.MOCK_MEOW_TOKEN === "false", NO_MOCK_PROD_ERR); - requires(process.env.STAKING_TOKEN_ADDRESS === MeowMainnet.address, STAKING_TOKEN_ERR); - requires(!process.env.MONGO_DB_URI.includes("localhost"), MONGO_URI_ERR); - } - - if (process.env.VERIFY_CONTRACTS === "true") { - requires(!!process.env.ETHERSCAN_API_KEY, "Must provide an Etherscan API Key to verify contracts"); - } - - if (process.env.MONITOR_CONTRACTS === "true") { - requires(!!process.env.TENDERLY_PROJECT_SLUG, "Must provide a Tenderly Project Slug to monitor contracts"); - requires(!!process.env.TENDERLY_ACCOUNT_ID, "Must provide a Tenderly Account ID to monitor contracts"); - requires(!!process.env.TENDERLY_ACCESS_KEY, "Must provide a Tenderly Access Key to monitor contracts"); - } - - return priceConfig; -}; - -const getValidateRootPriceConfig = () => { - - if (process.env.ENV_LEVEL === "prod") { - requires( - !!process.env.MAX_PRICE - && !!process.env.MIN_PRICE - && !!process.env.MAX_LENGTH - && !!process.env.BASE_LENGTH - && !!process.env.DECIMALS - && !!process.env.PRECISION - && !!process.env.PROTOCOL_FEE_PERC, - "Must provide all price config variables for prod environment!" - ); - } - - // Price config variables - const maxPrice = - process.env.MAX_PRICE - ? ethers.parseEther(process.env.MAX_PRICE) - : DEFAULT_PRICE_CONFIG.maxPrice; - - const minPrice = - process.env.MIN_PRICE - ? ethers.parseEther(process.env.MIN_PRICE) - : DEFAULT_PRICE_CONFIG.minPrice; - - const maxLength = - process.env.MAX_LENGTH - ? BigInt(process.env.MAX_LENGTH) - : DEFAULT_PRICE_CONFIG.maxLength; - - const baseLength = - process.env.BASE_LENGTH - ? BigInt(process.env.BASE_LENGTH) - : DEFAULT_PRICE_CONFIG.baseLength; - - const decimals = process.env.DECIMALS ? BigInt(process.env.DECIMALS) : DEFAULT_DECIMALS; - const precision = process.env.PRECISION ? BigInt(process.env.PRECISION) : DECAULT_PRECISION; - const precisionMultiplier = BigInt(10) ** (decimals - precision); - - const feePercentage = - process.env.PROTOCOL_FEE_PERC - ? BigInt(process.env.PROTOCOL_FEE_PERC) - : DEFAULT_PROTOCOL_FEE_PERCENT; - - const priceConfig : ICurvePriceConfig = { - maxPrice, - minPrice, - maxLength, - baseLength, - precisionMultiplier, - feePercentage, - isSet: true, - }; - - requires(validatePrice(priceConfig), INVALID_CURVE_ERR); - - return priceConfig; -}; - -const requires = (condition : boolean, message : string) => { - if (!condition) { - throw new Error(message); - } -}; - -// No price spike before `minPrice` kicks in at `maxLength` -const validatePrice = (config : ICurvePriceConfig) => { - const strA = "a".repeat(Number(config.maxLength)); - const strB = "b".repeat(Number(config.maxLength + 1n)); - - const priceA = getCurvePrice(strA, config); - const priceB = getCurvePrice(strB, config); - - // if B > A, then the price spike is invalid - return (priceB <= priceA); -}; +import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; +import { IZNSCampaignConfig } from "./types"; +import { + DEFAULT_PROTOCOL_FEE_PERCENT, + DEFAULT_ROYALTY_FRACTION, + ZNS_DOMAIN_TOKEN_NAME, + ZNS_DOMAIN_TOKEN_SYMBOL, + DEFAULT_DECIMALS, + DEFAULT_PRECISION, + DEFAULT_PRICE_CONFIG, + NO_MOCK_PROD_ERR, + STAKING_TOKEN_ERR, + INVALID_CURVE_ERR, + MONGO_URI_ERR, + INVALID_ENV_ERR, NO_ZERO_VAULT_ERR, + INITIAL_ADMIN_DELAY_DEFAULT, + INITIAL_SUPPLY_DEFAULT, + INFLATION_RATES_DEFAULT, + FINAL_INFLATION_RATE_DEFAULT, + Z_NAME_DEFAULT, + Z_SYMBOL_DEFAULT, +} from "../../../test/helpers"; +import { ethers } from "ethers"; +import { ICurvePriceConfig, IZTokenConfig } from "../missions/types"; +import process from "process"; +import { ZSepolia } from "../missions/contracts/z-token/mainnet-data"; + + +const getCustomAddresses = ( + key : string, + deployerAddress : string, + accounts ?: Array +) => { + const addresses = []; + + if (process.env[key]) { + /* eslint-disable @typescript-eslint/no-non-null-assertion */ + const decoded = atob(process.env[key]!); + + // Check if there is more than one custom governor + if (decoded.includes(",")) { + addresses.push(...decoded.split(",")); + } else { + addresses.push(decoded); + } + } + + if (accounts && accounts.length > 0) { + addresses.push(...accounts); // The user provided custom governors / admins as a param for testing + } + + if (!addresses.includes(deployerAddress)) { + // No custom governors / admins provided, use the deployer as the default + addresses.push(deployerAddress); + } + + + return addresses; +}; + +// This function builds a config with default values but overrides them with any values that are set +export const getConfig = async ({ + deployer, + governors, + admins, + zeroVaultAddress, + env, // this is ONLY used for tests! + zTokenConfig, +} : { + deployer : SignerWithAddress; + governors ?: Array; + admins ?: Array; + zeroVaultAddress ?: string; + env ?: string; + zTokenConfig ?: IZTokenConfig; +}) : Promise> => { + // Will throw an error based on any invalid setup, given the `ENV_LEVEL` set + const priceConfig = validateEnv(env); + + let deployerAddress; + if (deployer && Object.keys(deployer).includes("address")) { + deployerAddress = deployer.address; + } else { + deployerAddress = await deployer.getAddress(); + } + + let zeroVaultAddressConf; + + const zeroVaultAddressEnv = process.env.ZERO_VAULT_ADDRESS; + const mockZTokenEnv = process.env.MOCK_Z_TOKEN; + const envLevel = process.env.ENV_LEVEL; + + + // Get governor addresses set through env, if any + const governorAddresses = getCustomAddresses("GOVERNOR_ADDRESSES", deployerAddress, governors); + // Get admin addresses set through env, if any + const adminAddresses = getCustomAddresses("ADMIN_ADDRESSES", deployerAddress, admins); + + let zConfig : IZTokenConfig | undefined; + + if (envLevel === "dev") { + requires( + !!zeroVaultAddress || !!zeroVaultAddressEnv, + "Must pass `zeroVaultAddress` to `getConfig()` for `dev` environment" + ); + zeroVaultAddressConf = zeroVaultAddress || zeroVaultAddressEnv; + + if (!zTokenConfig) { + // in case, we didn't provide addresses, it will choose the governon as `admin` argument, + // deployAdmin as `minter` and first passed admin as `mintBeneficiary`. + zConfig = { + name: Z_NAME_DEFAULT, + symbol: Z_SYMBOL_DEFAULT, + defaultAdmin: governorAddresses[0], + initialAdminDelay: INITIAL_ADMIN_DELAY_DEFAULT, + minter: deployer.address, + mintBeneficiary: adminAddresses[0], + initialSupplyBase: INITIAL_SUPPLY_DEFAULT, + inflationRates: INFLATION_RATES_DEFAULT, + finalInflationRate: FINAL_INFLATION_RATE_DEFAULT, + }; + } else { + zConfig = zTokenConfig; + } + } else { + zeroVaultAddressConf = zeroVaultAddressEnv; + } + + // Domain Token Values + const royaltyReceiver = envLevel !== "dev" ? process.env.ROYALTY_RECEIVER! : zeroVaultAddressConf; + const royaltyFraction = + process.env.ROYALTY_FRACTION + ? BigInt(process.env.ROYALTY_FRACTION) + : DEFAULT_ROYALTY_FRACTION; + + const config : IZNSCampaignConfig = { + env: envLevel!, + deployAdmin: deployer, + governorAddresses, + adminAddresses, + domainToken: { + name: process.env.DOMAIN_TOKEN_NAME ? process.env.DOMAIN_TOKEN_NAME : ZNS_DOMAIN_TOKEN_NAME, + symbol: process.env.DOMAIN_TOKEN_SYMBOL ? process.env.DOMAIN_TOKEN_SYMBOL : ZNS_DOMAIN_TOKEN_SYMBOL, + defaultRoyaltyReceiver: royaltyReceiver!, + defaultRoyaltyFraction: royaltyFraction, + }, + rootPriceConfig: priceConfig, + zTokenConfig: zConfig, + zeroVaultAddress: zeroVaultAddressConf as string, + mockZToken: mockZTokenEnv === "true", + stakingTokenAddress: process.env.STAKING_TOKEN_ADDRESS!, + postDeploy: { + tenderlyProjectSlug: process.env.TENDERLY_PROJECT_SLUG!, + monitorContracts: process.env.MONITOR_CONTRACTS === "true", + verifyContracts: process.env.VERIFY_CONTRACTS === "true", + }, + }; + + return config; +}; + +// For testing the behaviour when we manipulate, we have an optional "env" string param +export const validateEnv = ( + env ?: string, // this is ONLY used for tests! +) : ICurvePriceConfig => { + // Prioritize reading from the env variable first, and only then fallback to the param + let envLevel = process.env.ENV_LEVEL; + + if (env) { + // We only ever specify an `env` param in tests + // So if there is a value we must use that instead + // otherwise only ever use the ENV_LEVEL above + envLevel = env; + } + + // Validate price config first since we have to return it + const priceConfig = getValidateRootPriceConfig(); + + const mockZTokenEnv = process.env.MOCK_Z_TOKEN; + + if (envLevel === "dev") return priceConfig; + + if (envLevel === "test" || envLevel === "dev") { + if (mockZTokenEnv === "false" && !process.env.STAKING_TOKEN_ADDRESS) { + throw new Error("Must provide a staking token address if not mocking Z token in `dev` environment"); + } + } + + if (envLevel !== "test" && envLevel !== "prod") { + // If we reach this code, there is an env variable, but it's not valid. + throw new Error(INVALID_ENV_ERR); + } + + if (!process.env.ROYALTY_RECEIVER) { + throw new Error("Must provide a default royalty receiver"); + } + + if (!process.env.ROYALTY_FRACTION) { + throw new Error("Must provide a default royalty fraction"); + } + + if (!process.env.MONGO_DB_URI) { + throw new Error(`Must provide a Mongo URI used for ${envLevel} environment!`); + } + + requires(!!process.env.ZERO_VAULT_ADDRESS, NO_ZERO_VAULT_ERR); + + // Mainnet + if (envLevel === "prod") { + requires(!process.env.MONGO_DB_URI.includes("localhost"), MONGO_URI_ERR); + requires(mockZTokenEnv === "false", NO_MOCK_PROD_ERR); + requires(process.env.STAKING_TOKEN_ADDRESS === ZSepolia.address, STAKING_TOKEN_ERR); + } + + if (process.env.VERIFY_CONTRACTS === "true") { + requires(process.env.ETHERSCAN_API_KEY === "true", "Must provide an Etherscan API Key to verify contracts"); + } + + if (process.env.MONITOR_CONTRACTS === "true") { + requires(process.env.TENDERLY_PROJECT_SLUG === "true", "Must provide a Tenderly Project Slug to monitor contracts"); + requires(process.env.TENDERLY_ACCOUNT_ID === "true", "Must provide a Tenderly Account ID to monitor contracts"); + requires(process.env.TENDERLY_ACCESS_KEY === "true", "Must provide a Tenderly Access Key to monitor contracts"); + } + + return priceConfig; +}; + +const getValidateRootPriceConfig = () => { + + if (process.env.ENV_LEVEL === "prod") { + requires( + !!process.env.MAX_PRICE + && !!process.env.MIN_PRICE + && !!process.env.MAX_LENGTH + && !!process.env.BASE_LENGTH + && !!process.env.DECIMALS + && !!process.env.PRECISION + && !!process.env.PROTOCOL_FEE_PERC, + "Must provide all price config variables for prod environment!" + ); + } + + // Price config variables + const maxPrice = + process.env.MAX_PRICE + ? ethers.parseEther(process.env.MAX_PRICE) + : DEFAULT_PRICE_CONFIG.maxPrice; + + const curveMultiplier = + process.env.curveMultiplier + ? process.env.curveMultiplier + : DEFAULT_PRICE_CONFIG.curveMultiplier; + + const maxLength = + process.env.MAX_LENGTH + ? BigInt(process.env.MAX_LENGTH) + : DEFAULT_PRICE_CONFIG.maxLength; + + const baseLength = + process.env.BASE_LENGTH + ? BigInt(process.env.BASE_LENGTH) + : DEFAULT_PRICE_CONFIG.baseLength; + + const decimals = process.env.DECIMALS ? BigInt(process.env.DECIMALS) : DEFAULT_DECIMALS; + const precision = process.env.PRECISION ? BigInt(process.env.PRECISION) : DEFAULT_PRECISION; + const precisionMultiplier = BigInt(10) ** (decimals - precision); + + const feePercentage = + process.env.PROTOCOL_FEE_PERC + ? BigInt(process.env.PROTOCOL_FEE_PERC) + : DEFAULT_PROTOCOL_FEE_PERCENT; + + const priceConfig : ICurvePriceConfig = { + maxPrice, + curveMultiplier: BigInt(curveMultiplier), + maxLength, + baseLength, + precisionMultiplier, + feePercentage, + isSet: true, + }; + + validateConfig(priceConfig); + + return priceConfig; +}; + +const requires = (condition : boolean, message : string) => { + if (!condition) { + throw new Error(message); + } +}; + +const validateConfig = (config : ICurvePriceConfig) => { + const PERCENTAGE_BASIS = 10000n; + + if ( + (config.curveMultiplier === 0n && config.baseLength === 0n) || + (config.maxLength < config.baseLength) || + ((config.maxLength < config.baseLength) || config.maxLength === 0n) || + (config.curveMultiplier === 0n || config.curveMultiplier > 10n**18n) || + (config.feePercentage > PERCENTAGE_BASIS) + ) { + requires(false, INVALID_CURVE_ERR); + } +}; diff --git a/src/deploy/campaign/types.ts b/src/deploy/campaign/types.ts index f32096341..7bb75fd15 100644 --- a/src/deploy/campaign/types.ts +++ b/src/deploy/campaign/types.ts @@ -1,67 +1,71 @@ -import { HardhatEthersSigner, SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; -import { DefenderRelaySigner } from "@openzeppelin/defender-sdk-relay-signer-client/lib/ethers"; -import { ICurvePriceConfig } from "../missions/types"; -import { IContractState, IDeployCampaignConfig } from "@zero-tech/zdc"; -import { - MeowTokenMock, - ZNSAccessController, - ZNSAddressResolver, - ZNSCurvePricer, - ZNSDomainToken, - ZNSFixedPricer, - ZNSRegistry, - ZNSRootRegistrar, - ZNSSubRegistrar, - ZNSTreasury, - MeowToken, -} from "../../../typechain"; - -export type IZNSSigner = HardhatEthersSigner | DefenderRelaySigner | SignerWithAddress; - -export interface IZNSCampaignConfig extends IDeployCampaignConfig { - env : string; - deployAdmin : Signer; - governorAddresses : Array; - adminAddresses : Array; - domainToken : { - name : string; - symbol : string; - defaultRoyaltyReceiver : string; - defaultRoyaltyFraction : bigint; - }; - rootPriceConfig : ICurvePriceConfig; - zeroVaultAddress : string; - mockMeowToken : boolean; - stakingTokenAddress : string; - postDeploy : { - tenderlyProjectSlug : string; - monitorContracts : boolean; - verifyContracts : boolean; - }; -} - -export type ZNSContract = - ZNSAccessController | - ZNSRegistry | - ZNSDomainToken | - MeowTokenMock | - MeowToken | - ZNSAddressResolver | - ZNSCurvePricer | - ZNSTreasury | - ZNSRootRegistrar | - ZNSFixedPricer | - ZNSSubRegistrar; - -export interface IZNSContracts extends IContractState { - accessController : ZNSAccessController; - registry : ZNSRegistry; - domainToken : ZNSDomainToken; - meowToken : MeowTokenMock; - addressResolver : ZNSAddressResolver; - curvePricer : ZNSCurvePricer; - treasury : ZNSTreasury; - rootRegistrar : ZNSRootRegistrar; - fixedPricer : ZNSFixedPricer; - subRegistrar : ZNSSubRegistrar; -} \ No newline at end of file +import { HardhatEthersSigner, SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; +import { DefenderRelaySigner } from "@openzeppelin/defender-sdk-relay-signer-client/lib/ethers"; +import { ICurvePriceConfig, IZTokenConfig } from "../missions/types"; +import { IContractState, IDeployCampaignConfig } from "@zero-tech/zdc"; +import { + ZNSAccessController, + ZNSAddressResolver, + ZNSCurvePricer, + ZNSDomainToken, + ZNSFixedPricer, + ZNSRegistry, + ZNSRootRegistrar, + ZNSSubRegistrar, + ZNSTreasury, + ZToken, + ZTokenMock, + ZNSStringResolver, +} from "../../../typechain"; + +export type IZNSSigner = HardhatEthersSigner | DefenderRelaySigner | SignerWithAddress; + +export interface IZNSCampaignConfig extends IDeployCampaignConfig { + env : string; + deployAdmin : Signer; + governorAddresses : Array; + adminAddresses : Array; + domainToken : { + name : string; + symbol : string; + defaultRoyaltyReceiver : string; + defaultRoyaltyFraction : bigint; + }; + rootPriceConfig : ICurvePriceConfig; + zTokenConfig ?: IZTokenConfig; + zeroVaultAddress : string; + mockZToken : boolean; + stakingTokenAddress : string; + postDeploy : { + tenderlyProjectSlug : string; + monitorContracts : boolean; + verifyContracts : boolean; + }; +} + +export type ZNSContract = + ZNSAccessController | + ZNSRegistry | + ZNSDomainToken | + ZTokenMock | + ZToken | + ZNSAddressResolver | + ZNSStringResolver | + ZNSCurvePricer | + ZNSTreasury | + ZNSRootRegistrar | + ZNSFixedPricer | + ZNSSubRegistrar; + +export interface IZNSContracts extends IContractState { + accessController : ZNSAccessController; + registry : ZNSRegistry; + domainToken : ZNSDomainToken; + zToken : ZTokenMock; + addressResolver : ZNSAddressResolver; + stringResolver : ZNSStringResolver; + curvePricer : ZNSCurvePricer; + treasury : ZNSTreasury; + rootRegistrar : ZNSRootRegistrar; + fixedPricer : ZNSFixedPricer; + subRegistrar : ZNSSubRegistrar; +} diff --git a/src/deploy/constants.ts b/src/deploy/constants.ts index 3b0bdad4d..c31511520 100644 --- a/src/deploy/constants.ts +++ b/src/deploy/constants.ts @@ -21,6 +21,10 @@ export const REGISTRAR_ROLE = ethers.solidityPackedKeccak256( ["string"], ["REGISTRAR_ROLE"], ); +export const DOMAIN_TOKEN_ROLE = ethers.solidityPackedKeccak256( + ["string"], + ["DOMAIN_TOKEN_ROLE"], +); export const EXECUTOR_ROLE = ethers.solidityPackedKeccak256( ["string"], ["EXECUTOR_ROLE"], @@ -28,4 +32,7 @@ export const EXECUTOR_ROLE = ethers.solidityPackedKeccak256( export const ResolverTypes = { address: "address", + // TODO: Which word to use for a string type of resolver?? + // eslint-disable-next-line id-blacklist + string: "string", }; diff --git a/src/deploy/missions/contracts/access-controller.ts b/src/deploy/missions/contracts/access-controller.ts index 5c537bfce..60586a16d 100644 --- a/src/deploy/missions/contracts/access-controller.ts +++ b/src/deploy/missions/contracts/access-controller.ts @@ -4,14 +4,13 @@ import { import { znsNames } from "./names"; import { HardhatRuntimeEnvironment } from "hardhat/types"; import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; -import { DefenderRelayProvider } from "@openzeppelin/defender-sdk-relay-signer-client/lib/ethers"; -import { IZNSContracts } from "../../campaign/types"; +import { IZNSCampaignConfig, IZNSContracts } from "../../campaign/types"; export class ZNSAccessControllerDM extends BaseDeployMission< HardhatRuntimeEnvironment, SignerWithAddress, -DefenderRelayProvider, +IZNSCampaignConfig, IZNSContracts > { proxyData = { @@ -27,6 +26,6 @@ IZNSContracts adminAddresses, } = this.config; - return [ governorAddresses, adminAddresses ]; + return [governorAddresses, adminAddresses]; } } diff --git a/src/deploy/missions/contracts/address-resolver.ts b/src/deploy/missions/contracts/address-resolver.ts index a31950656..be22147f6 100644 --- a/src/deploy/missions/contracts/address-resolver.ts +++ b/src/deploy/missions/contracts/address-resolver.ts @@ -5,15 +5,14 @@ import { import { ProxyKinds, ResolverTypes } from "../../constants"; import { znsNames } from "./names"; import { HardhatRuntimeEnvironment } from "hardhat/types"; -import { DefenderRelayProvider } from "@openzeppelin/defender-sdk-relay-signer-client/lib/ethers"; -import { IZNSContracts } from "../../campaign/types"; +import { IZNSCampaignConfig, IZNSContracts } from "../../campaign/types"; import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; export class ZNSAddressResolverDM extends BaseDeployMission< HardhatRuntimeEnvironment, SignerWithAddress, -DefenderRelayProvider, +IZNSCampaignConfig, IZNSContracts > { proxyData = { diff --git a/src/deploy/missions/contracts/curve-pricer.ts b/src/deploy/missions/contracts/curve-pricer.ts index ff81b5cab..8dee27dd2 100644 --- a/src/deploy/missions/contracts/curve-pricer.ts +++ b/src/deploy/missions/contracts/curve-pricer.ts @@ -6,14 +6,13 @@ import { ProxyKinds } from "../../constants"; import { znsNames } from "./names"; import { HardhatRuntimeEnvironment } from "hardhat/types"; import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; -import { DefenderRelayProvider } from "@openzeppelin/defender-sdk-relay-signer-client/lib/ethers"; -import { IZNSContracts } from "../../campaign/types"; +import { IZNSCampaignConfig, IZNSContracts } from "../../campaign/types"; export class ZNSCurvePricerDM extends BaseDeployMission< HardhatRuntimeEnvironment, SignerWithAddress, -DefenderRelayProvider, +IZNSCampaignConfig, IZNSContracts > { proxyData = { diff --git a/src/deploy/missions/contracts/domain-token.ts b/src/deploy/missions/contracts/domain-token.ts index 2112a7e26..833368ae2 100644 --- a/src/deploy/missions/contracts/domain-token.ts +++ b/src/deploy/missions/contracts/domain-token.ts @@ -2,18 +2,17 @@ import { BaseDeployMission, TDeployArgs, } from "@zero-tech/zdc"; -import { ProxyKinds } from "../../constants"; +import { DOMAIN_TOKEN_ROLE, ProxyKinds } from "../../constants"; import { znsNames } from "./names"; import { HardhatRuntimeEnvironment } from "hardhat/types"; import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; -import { DefenderRelayProvider } from "@openzeppelin/defender-sdk-relay-signer-client/lib/ethers"; import { IZNSCampaignConfig, IZNSContracts } from "../../campaign/types"; export class ZNSDomainTokenDM extends BaseDeployMission< HardhatRuntimeEnvironment, SignerWithAddress, -DefenderRelayProvider, +IZNSCampaignConfig, IZNSContracts > { proxyData = { @@ -25,7 +24,7 @@ IZNSContracts instanceName = znsNames.domainToken.instance; async deployArgs () : Promise { - const { accessController } = this.campaign; + const { accessController, registry } = this.campaign; const { domainToken: { name, @@ -33,8 +32,49 @@ IZNSContracts defaultRoyaltyReceiver, defaultRoyaltyFraction, }, - } = this.config as IZNSCampaignConfig; + } = this.config; - return [ await accessController.getAddress(), name, symbol, defaultRoyaltyReceiver, defaultRoyaltyFraction ]; + return [ + await accessController.getAddress(), + name, + symbol, + defaultRoyaltyReceiver, + defaultRoyaltyFraction, + await registry.getAddress(), + ]; + } + + async needsPostDeploy () { + const { + accessController, + domainToken, + config: { deployAdmin }, + } = this.campaign; + + const isDomainToken = await accessController + .connect(deployAdmin) + .isDomainToken(await domainToken.getAddress()); + + const msg = !isDomainToken ? "needs" : "doesn't need"; + + this.logger.debug(`${this.contractName} ${msg} post deploy sequence`); + + return !isDomainToken; + } + + async postDeploy () { + const { + accessController, + domainToken, + config: { + deployAdmin, + }, + } = this.campaign; + + await accessController + .connect(deployAdmin) + .grantRole(DOMAIN_TOKEN_ROLE, await domainToken.getAddress()); + + this.logger.debug(`${this.contractName} post deploy sequence completed`); } } diff --git a/src/deploy/missions/contracts/fixed-pricer.ts b/src/deploy/missions/contracts/fixed-pricer.ts index 63308608f..3f6e5e263 100644 --- a/src/deploy/missions/contracts/fixed-pricer.ts +++ b/src/deploy/missions/contracts/fixed-pricer.ts @@ -6,14 +6,12 @@ import { import { znsNames } from "./names"; import { HardhatRuntimeEnvironment } from "hardhat/types"; import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; -import { DefenderRelayProvider } from "@openzeppelin/defender-sdk-relay-signer-client/lib/ethers"; -import { IZNSContracts } from "../../campaign/types"; - +import { IZNSCampaignConfig, IZNSContracts } from "../../campaign/types"; export class ZNSFixedPricerDM extends BaseDeployMission< HardhatRuntimeEnvironment, SignerWithAddress, -DefenderRelayProvider, +IZNSCampaignConfig, IZNSContracts > { proxyData = { diff --git a/src/deploy/missions/contracts/index.ts b/src/deploy/missions/contracts/index.ts index 9d86beae1..ef0972558 100644 --- a/src/deploy/missions/contracts/index.ts +++ b/src/deploy/missions/contracts/index.ts @@ -1,10 +1,11 @@ export * from "./address-resolver"; +export * from "./string-resolver"; export * from "./registry"; export * from "./root-registrar"; export * from "./domain-token"; export * from "./treasury"; export * from "./curve-pricer"; export * from "./access-controller"; -export * from "./meow-token/meow-token"; +export * from "./z-token/z-token"; export * from "./fixed-pricer"; export * from "./sub-registrar"; diff --git a/src/deploy/missions/contracts/meow-token/mainnet-data.ts b/src/deploy/missions/contracts/meow-token/mainnet-data.ts deleted file mode 100644 index 9e8569ed1..000000000 --- a/src/deploy/missions/contracts/meow-token/mainnet-data.ts +++ /dev/null @@ -1,513 +0,0 @@ - -export const MeowMainnet = { - address: "0x0eC78ED49C2D27b315D462d43B5BAB94d2C79bf8", - implementation: "0xcDb3C5e9b4760f93437aBaD33dBEC9a2cE3704f6", - abi: [ - { - "inputs": [], - "stateMutability": "nonpayable", - "type": "constructor", - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address", - }, - { - "indexed": true, - "internalType": "address", - "name": "spender", - "type": "address", - }, - { - "indexed": false, - "internalType": "uint256", - "name": "value", - "type": "uint256", - }, - ], - "name": "Approval", - "type": "event", - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint8", - "name": "version", - "type": "uint8", - }, - ], - "name": "Initialized", - "type": "event", - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "previousOwner", - "type": "address", - }, - { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address", - }, - ], - "name": "OwnershipTransferred", - "type": "event", - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "account", - "type": "address", - }, - ], - "name": "Paused", - "type": "event", - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "id", - "type": "uint256", - }, - ], - "name": "Snapshot", - "type": "event", - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address", - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address", - }, - { - "indexed": false, - "internalType": "uint256", - "name": "value", - "type": "uint256", - }, - ], - "name": "Transfer", - "type": "event", - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "account", - "type": "address", - }, - ], - "name": "Unpaused", - "type": "event", - }, - { - "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address", - }, - { - "internalType": "address", - "name": "spender", - "type": "address", - }, - ], - "name": "allowance", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256", - }, - ], - "stateMutability": "view", - "type": "function", - }, - { - "inputs": [ - { - "internalType": "address", - "name": "spender", - "type": "address", - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256", - }, - ], - "name": "approve", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool", - }, - ], - "stateMutability": "nonpayable", - "type": "function", - }, - { - "inputs": [ - { - "internalType": "address", - "name": "account", - "type": "address", - }, - ], - "name": "balanceOf", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256", - }, - ], - "stateMutability": "view", - "type": "function", - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address", - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256", - }, - ], - "name": "balanceOfAt", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256", - }, - ], - "stateMutability": "view", - "type": "function", - }, - { - "inputs": [], - "name": "decimals", - "outputs": [ - { - "internalType": "uint8", - "name": "", - "type": "uint8", - }, - ], - "stateMutability": "view", - "type": "function", - }, - { - "inputs": [ - { - "internalType": "address", - "name": "spender", - "type": "address", - }, - { - "internalType": "uint256", - "name": "subtractedValue", - "type": "uint256", - }, - ], - "name": "decreaseAllowance", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool", - }, - ], - "stateMutability": "nonpayable", - "type": "function", - }, - { - "inputs": [ - { - "internalType": "address", - "name": "spender", - "type": "address", - }, - { - "internalType": "uint256", - "name": "addedValue", - "type": "uint256", - }, - ], - "name": "increaseAllowance", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool", - }, - ], - "stateMutability": "nonpayable", - "type": "function", - }, - { - "inputs": [ - { - "internalType": "string", - "name": "name_", - "type": "string", - }, - { - "internalType": "string", - "name": "symbol_", - "type": "string", - }, - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function", - }, - { - "inputs": [], - "name": "name", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string", - }, - ], - "stateMutability": "view", - "type": "function", - }, - { - "inputs": [], - "name": "owner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address", - }, - ], - "stateMutability": "view", - "type": "function", - }, - { - "inputs": [], - "name": "paused", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool", - }, - ], - "stateMutability": "view", - "type": "function", - }, - { - "inputs": [], - "name": "renounceOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function", - }, - { - "inputs": [], - "name": "symbol", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string", - }, - ], - "stateMutability": "view", - "type": "function", - }, - { - "inputs": [], - "name": "totalSupply", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256", - }, - ], - "stateMutability": "view", - "type": "function", - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256", - }, - ], - "name": "totalSupplyAt", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256", - }, - ], - "stateMutability": "view", - "type": "function", - }, - { - "inputs": [ - { - "internalType": "address", - "name": "to", - "type": "address", - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256", - }, - ], - "name": "transfer", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool", - }, - ], - "stateMutability": "nonpayable", - "type": "function", - }, - { - "inputs": [ - { - "internalType": "address[]", - "name": "recipients", - "type": "address[]", - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256", - }, - ], - "name": "transferBulk", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool", - }, - ], - "stateMutability": "nonpayable", - "type": "function", - }, - { - "inputs": [ - { - "internalType": "address", - "name": "from", - "type": "address", - }, - { - "internalType": "address", - "name": "to", - "type": "address", - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256", - }, - ], - "name": "transferFrom", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool", - }, - ], - "stateMutability": "nonpayable", - "type": "function", - }, - { - "inputs": [ - { - "internalType": "address", - "name": "sender", - "type": "address", - }, - { - "internalType": "address[]", - "name": "recipients", - "type": "address[]", - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256", - }, - ], - "name": "transferFromBulk", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool", - }, - ], - "stateMutability": "nonpayable", - "type": "function", - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newOwner", - "type": "address", - }, - ], - "name": "transferOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function", - }, - ], -}; diff --git a/src/deploy/missions/contracts/meow-token/meow-token.ts b/src/deploy/missions/contracts/meow-token/meow-token.ts deleted file mode 100644 index bb7f167ff..000000000 --- a/src/deploy/missions/contracts/meow-token/meow-token.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { - BaseDeployMission, - IDeployMissionArgs, - TDeployArgs, -} from "@zero-tech/zdc"; -import { ProxyKinds } from "../../../constants"; -import { ethers } from "ethers"; -import { znsNames } from "../names"; -import { HardhatRuntimeEnvironment } from "hardhat/types"; -import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; -import { DefenderRelayProvider } from "@openzeppelin/defender-sdk-relay-signer-client/lib/ethers"; -import { IZNSContracts } from "../../../campaign/types"; - - -export const meowTokenName = "MEOW"; -export const meowTokenSymbol = "MEOW"; - - -export class MeowTokenDM extends BaseDeployMission< -HardhatRuntimeEnvironment, -SignerWithAddress, -DefenderRelayProvider, -IZNSContracts -> { - proxyData = { - isProxy: true, - kind: ProxyKinds.transparent, - }; - - contractName = znsNames.meowToken.contract; - instanceName = znsNames.meowToken.instance; - - constructor (args : IDeployMissionArgs< - HardhatRuntimeEnvironment, - SignerWithAddress, - DefenderRelayProvider, - IZNSContracts - >) { - super(args); - - if (this.config.mockMeowToken) { - this.contractName = znsNames.meowToken.contractMock; - } else { - this.contractName = znsNames.meowToken.contract; - } - } - - async deploy () { - if (!this.config.mockMeowToken) { - this.logger.info("Using MEOW token from Mainnet"); - - // TODO dep: add proper bytecode comparison here and throw if different! - // const bytecodeFromChain = await this.campaign.deployer.getBytecodeFromChain(this.config.stakingTokenAddress); - - // const { - // bytecode, - // } = this.getArtifact(); - - // if (!compareBytecodeStrict(bytecode, bytecodeFromChain)) { - // this.logger.error("MEOW token bytecode compiled in this module differs from Mainnet"); - // throw new Error( - // "MEOW token bytecode compiled in this module differs from Mainnet" - // ); - // } - - this.logger.debug(`Writing ${this.contractName} to DB...`); - - const baseContract = await this.campaign.deployer.getContractObject( - this.contractName, - this.config.stakingTokenAddress as string, - ); - - await this.saveToDB(baseContract); - - this.campaign.updateStateContract(this.instanceName, this.contractName, baseContract); - - // eslint-disable-next-line max-len - this.logger.info(`Successfully created ${this.contractName} contract from Mainnet data at ${await baseContract.getAddress()}`); - } else { - await super.deploy(); - } - } - - async deployArgs () : Promise { - return [meowTokenName, meowTokenSymbol]; - } - - async needsPostDeploy () { - const msg = this.config.mockMeowToken ? "needs" : "doesn't need"; - - this.logger.debug(`${this.contractName} ${msg} post deploy sequence`); - - return this.config.mockMeowToken as boolean; - } - - async postDeploy () { - const { - meowToken, - config: { - deployAdmin, - }, - } = this.campaign; - - // Mint 100,000 MEOW to the deployer - await meowToken.connect(deployAdmin).mint( - await deployAdmin.getAddress?.(), - ethers.parseEther("100000") - ); - - this.logger.debug(`${this.contractName} post deploy sequence completed`); - } -} diff --git a/src/deploy/missions/contracts/names.ts b/src/deploy/missions/contracts/names.ts index d92727652..099d4020d 100644 --- a/src/deploy/missions/contracts/names.ts +++ b/src/deploy/missions/contracts/names.ts @@ -14,15 +14,19 @@ export const znsNames = { contract: "ZNSDomainToken", instance: "domainToken", }, - meowToken: { - contract: "MeowToken", - contractMock: "MeowTokenMock", - instance: "meowToken", + zToken: { + contract: "ZToken", + contractMock: "ZTokenMock", + instance: "zToken", }, addressResolver: { contract: "ZNSAddressResolver", instance: "addressResolver", }, + stringResolver: { + contract: "ZNSStringResolver", + instance: "stringResolver", + }, curvePricer: { contract: "ZNSCurvePricer", instance: "curvePricer", diff --git a/src/deploy/missions/contracts/registry.ts b/src/deploy/missions/contracts/registry.ts index 649359e9d..f9b99f6bd 100644 --- a/src/deploy/missions/contracts/registry.ts +++ b/src/deploy/missions/contracts/registry.ts @@ -6,14 +6,13 @@ import { ProxyKinds } from "../../constants"; import { znsNames } from "./names"; import { HardhatRuntimeEnvironment } from "hardhat/types"; import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; -import { DefenderRelayProvider } from "@openzeppelin/defender-sdk-relay-signer-client/lib/ethers"; -import { IZNSContracts } from "../../campaign/types"; +import { IZNSCampaignConfig, IZNSContracts } from "../../campaign/types"; export class ZNSRegistryDM extends BaseDeployMission< HardhatRuntimeEnvironment, SignerWithAddress, -DefenderRelayProvider, +IZNSCampaignConfig, IZNSContracts > { proxyData = { diff --git a/src/deploy/missions/contracts/root-registrar.ts b/src/deploy/missions/contracts/root-registrar.ts index 6c1a7bae5..0bfd60b59 100644 --- a/src/deploy/missions/contracts/root-registrar.ts +++ b/src/deploy/missions/contracts/root-registrar.ts @@ -6,14 +6,13 @@ import { ProxyKinds, REGISTRAR_ROLE } from "../../constants"; import { znsNames } from "./names"; import { HardhatRuntimeEnvironment } from "hardhat/types"; import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; -import { DefenderRelayProvider } from "@openzeppelin/defender-sdk-relay-signer-client/lib/ethers"; -import { IZNSContracts } from "../../campaign/types"; +import { IZNSCampaignConfig, IZNSContracts } from "../../campaign/types"; export class ZNSRootRegistrarDM extends BaseDeployMission< HardhatRuntimeEnvironment, SignerWithAddress, -DefenderRelayProvider, +IZNSCampaignConfig, IZNSContracts > { proxyData = { diff --git a/src/deploy/missions/contracts/string-resolver.ts b/src/deploy/missions/contracts/string-resolver.ts new file mode 100644 index 000000000..305aaf5f4 --- /dev/null +++ b/src/deploy/missions/contracts/string-resolver.ts @@ -0,0 +1,66 @@ +import { BaseDeployMission, TDeployArgs } from "@zero-tech/zdc"; +import { HardhatRuntimeEnvironment } from "hardhat/types"; +import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; +import { IZNSCampaignConfig, IZNSContracts } from "../../campaign/types"; +import { ProxyKinds, ResolverTypes } from "../../constants"; +import { znsNames } from "./names"; + + +export class ZNSStringResolverDM extends BaseDeployMission< +HardhatRuntimeEnvironment, +SignerWithAddress, +IZNSCampaignConfig, +IZNSContracts +> { + proxyData = { + isProxy: true, + kind: ProxyKinds.uups, + }; + + contractName = znsNames.stringResolver.contract; + instanceName = znsNames.stringResolver.instance; + + async deployArgs () : Promise { + const { accessController, registry } = this.campaign; + + return [ + await accessController.getAddress(), + await registry.getAddress(), + ]; + } + + async needsPostDeploy () { + const { + registry, + stringResolver, + } = this.campaign; + + const resolverInReg = await registry.getResolverType( + ResolverTypes.string, + ); + + const needs = resolverInReg !== await stringResolver.getAddress(); + const msg = needs ? "needs" : "doesn't need"; + + this.logger.debug(`${this.contractName} ${msg} post deploy sequence`); + + return needs; + } + + async postDeploy () { + const { + registry, + stringResolver, + config: { + deployAdmin, + }, + } = this.campaign; + + await registry.connect(deployAdmin).addResolverType( + ResolverTypes.string, + await stringResolver.getAddress(), + ); + + this.logger.debug(`${this.contractName} post deploy sequence completed`); + } +} diff --git a/src/deploy/missions/contracts/sub-registrar.ts b/src/deploy/missions/contracts/sub-registrar.ts index 6f62a6463..b1d0b0594 100644 --- a/src/deploy/missions/contracts/sub-registrar.ts +++ b/src/deploy/missions/contracts/sub-registrar.ts @@ -6,14 +6,13 @@ import { ProxyKinds, REGISTRAR_ROLE } from "../../constants"; import { znsNames } from "./names"; import { HardhatRuntimeEnvironment } from "hardhat/types"; import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; -import { DefenderRelayProvider } from "@openzeppelin/defender-sdk-relay-signer-client/lib/ethers"; -import { IZNSContracts } from "../../campaign/types"; +import { IZNSCampaignConfig, IZNSContracts } from "../../campaign/types"; export class ZNSSubRegistrarDM extends BaseDeployMission< HardhatRuntimeEnvironment, SignerWithAddress, -DefenderRelayProvider, +IZNSCampaignConfig, IZNSContracts > { proxyData = { diff --git a/src/deploy/missions/contracts/treasury.ts b/src/deploy/missions/contracts/treasury.ts index 829dcdf83..5a356ee3a 100644 --- a/src/deploy/missions/contracts/treasury.ts +++ b/src/deploy/missions/contracts/treasury.ts @@ -6,14 +6,13 @@ import { ProxyKinds } from "../../constants"; import { znsNames } from "./names"; import { HardhatRuntimeEnvironment } from "hardhat/types"; import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; -import { DefenderRelayProvider } from "@openzeppelin/defender-sdk-relay-signer-client/lib/ethers"; -import { IZNSContracts } from "../../campaign/types"; +import { IZNSCampaignConfig, IZNSContracts } from "../../campaign/types"; export class ZNSTreasuryDM extends BaseDeployMission< HardhatRuntimeEnvironment, SignerWithAddress, -DefenderRelayProvider, +IZNSCampaignConfig, IZNSContracts > { proxyData = { @@ -28,7 +27,7 @@ IZNSContracts const { accessController, registry, - meowToken, + zToken, config: { zeroVaultAddress, }, @@ -37,7 +36,7 @@ IZNSContracts return [ await accessController.getAddress(), await registry.getAddress(), - await meowToken.getAddress(), + await zToken.getAddress(), zeroVaultAddress, ]; } diff --git a/src/deploy/missions/contracts/z-token/mainnet-data.ts b/src/deploy/missions/contracts/z-token/mainnet-data.ts new file mode 100644 index 000000000..bc2879a8c --- /dev/null +++ b/src/deploy/missions/contracts/z-token/mainnet-data.ts @@ -0,0 +1,4 @@ + +export const ZSepolia = { + address: "0x7148Db73c78Ded8e4f81784A121Bbe7E163f4834", +}; diff --git a/src/deploy/missions/contracts/z-token/z-token.ts b/src/deploy/missions/contracts/z-token/z-token.ts new file mode 100644 index 000000000..adabaa128 --- /dev/null +++ b/src/deploy/missions/contracts/z-token/z-token.ts @@ -0,0 +1,107 @@ +/* eslint-disable prefer-const */ +import { + BaseDeployMission, + IDeployMissionArgs, + TDeployArgs, +} from "@zero-tech/zdc"; +import { znsNames } from "../names"; +import { HardhatRuntimeEnvironment } from "hardhat/types"; +import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; +import { IZNSCampaignConfig, IZNSContracts } from "../../../campaign/types"; +import { IZTokenConfig } from "../../types"; +import { ZToken__factory } from "../../../../../typechain"; + + +export class ZTokenDM extends BaseDeployMission< +HardhatRuntimeEnvironment, +SignerWithAddress, +IZNSCampaignConfig, +IZNSContracts +> { + proxyData = { + isProxy: false, + }; + + contractName = znsNames.zToken.contract; + instanceName = znsNames.zToken.instance; + + constructor (args : IDeployMissionArgs< + HardhatRuntimeEnvironment, + SignerWithAddress, + IZNSCampaignConfig, + IZNSContracts + >) { + super(args); + + if (this.config.mockZToken) { + this.contractName = znsNames.zToken.contractMock; + } else { + this.contractName = znsNames.zToken.contract; + } + } + + async deploy () { + if (!this.config.mockZToken) { + this.logger.info("Using Z token from Mainnet"); + + // TODO dep: add proper bytecode comparison here and throw if different! + // const bytecodeFromChain = await this.campaign.deployer.getBytecodeFromChain(this.config.stakingTokenAddress); + + // const { + // bytecode, + // } = this.getArtifact(); + + // if (!compareBytecodeStrict(bytecode, bytecodeFromChain)) { + // this.logger.error("Z token bytecode compiled in this module differs from Mainnet"); + // throw new Error( + // "Z token bytecode compiled in this module differs from Mainnet" + // ); + // } + + this.logger.debug(`Writing ${this.contractName} to DB...`); + + const factory = new ZToken__factory(this.config.deployAdmin); + const baseContract = factory.attach(this.config.stakingTokenAddress); + // TODO remove! + // const baseContract = await this.campaign.deployer.getContractObject( + // this.contractName, + // this.config.stakingTokenAddress as string, + // ); + + await this.saveToDB(baseContract); + + this.campaign.updateStateContract(this.instanceName, this.contractName, baseContract); + + // eslint-disable-next-line max-len + this.logger.info(`Successfully created ${this.contractName} contract from Mainnet data at ${await baseContract.getAddress()}`); + } else { + await super.deploy(); + } + } + + async deployArgs () : Promise { + let { + name, + symbol, + defaultAdmin, + initialAdminDelay, + minter, + mintBeneficiary, + initialSupplyBase, + inflationRates, + finalInflationRate, + } = this.config.zTokenConfig as IZTokenConfig; + + return [ + name, + symbol, + defaultAdmin, + initialAdminDelay, + minter, + mintBeneficiary, + initialSupplyBase, + inflationRates, + finalInflationRate, + ]; + } +} diff --git a/src/deploy/missions/types.ts b/src/deploy/missions/types.ts index 70470545a..0599a9c6e 100644 --- a/src/deploy/missions/types.ts +++ b/src/deploy/missions/types.ts @@ -1,10 +1,22 @@ export interface ICurvePriceConfig { maxPrice : bigint; - minPrice : bigint; + curveMultiplier : bigint; maxLength : bigint; baseLength : bigint; precisionMultiplier : bigint; feePercentage : bigint; isSet : boolean; } + +export interface IZTokenConfig { + name : string; + symbol : string; + defaultAdmin : string; + initialAdminDelay : bigint; + minter : string; + mintBeneficiary : string; + initialSupplyBase : bigint; + inflationRates : Array; + finalInflationRate : bigint; +} \ No newline at end of file diff --git a/src/deploy/run-campaign.ts b/src/deploy/run-campaign.ts index da08f8450..c11d57554 100644 --- a/src/deploy/run-campaign.ts +++ b/src/deploy/run-campaign.ts @@ -1,23 +1,14 @@ import { getConfig } from "./campaign/environments"; import { runZnsCampaign } from "./zns-campaign"; -import { Defender } from "@openzeppelin/defender-sdk"; +import * as hre from "hardhat"; import { getLogger } from "@zero-tech/zdc"; import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; const logger = getLogger(); const runCampaign = async () => { - const credentials = { - apiKey: process.env.DEFENDER_KEY, - apiSecret: process.env.DEFENDER_SECRET, - relayerApiKey: process.env.RELAYER_KEY, - relayerApiSecret: process.env.RELAYER_SECRET, - }; - const client = new Defender(credentials); - - const provider = client.relaySigner.getProvider(); - const deployer = client.relaySigner.getSigner(provider, { speed: "fast" }); + const [ deployer ] = await hre.ethers.getSigners(); const config = await getConfig({ deployer: deployer as unknown as SignerWithAddress, @@ -25,7 +16,6 @@ const runCampaign = async () => { await runZnsCampaign({ config, - provider, }); }; diff --git a/src/deploy/zns-campaign.ts b/src/deploy/zns-campaign.ts index d3bebab49..38cfb0497 100644 --- a/src/deploy/zns-campaign.ts +++ b/src/deploy/zns-campaign.ts @@ -1,15 +1,15 @@ import * as hre from "hardhat"; import { HardhatRuntimeEnvironment } from "hardhat/types"; -import { DefenderRelayProvider } from "@openzeppelin/defender-sdk-relay-signer-client/lib/ethers"; import { HardhatDeployer, DeployCampaign, getLogger, } from "@zero-tech/zdc"; import { - MeowTokenDM, + ZTokenDM, ZNSAccessControllerDM, ZNSAddressResolverDM, + ZNSStringResolverDM, ZNSDomainTokenDM, ZNSCurvePricerDM, ZNSRootRegistrarDM, ZNSRegistryDM, ZNSTreasuryDM, ZNSFixedPricerDM, ZNSSubRegistrarDM, } from "./missions/contracts"; @@ -20,14 +20,12 @@ import { getZnsMongoAdapter } from "./mongo"; export const runZnsCampaign = async ({ config, - provider, dbVersion, deployer, } : { config : IZNSCampaignConfig; - provider ?: DefenderRelayProvider; dbVersion ?: string; - deployer ?: HardhatDeployer; + deployer ?: HardhatDeployer; }) => { hre.upgrades.silenceWarnings(); @@ -38,7 +36,6 @@ export const runZnsCampaign = async ({ hre, signer: config.deployAdmin, env: config.env, - provider, }); } @@ -47,15 +44,16 @@ export const runZnsCampaign = async ({ const campaign = new DeployCampaign< HardhatRuntimeEnvironment, SignerWithAddress, - DefenderRelayProvider, + IZNSCampaignConfig, IZNSContracts >({ missions: [ ZNSAccessControllerDM, ZNSRegistryDM, ZNSDomainTokenDM, - MeowTokenDM, + ZTokenDM, ZNSAddressResolverDM, + ZNSStringResolverDM, ZNSCurvePricerDM, ZNSTreasuryDM, ZNSRootRegistrarDM, diff --git a/src/tenderly/devnet/run-all-flows.ts b/src/tenderly/devnet/run-all-flows.ts index 15ba04d89..bb8f4dfad 100644 --- a/src/tenderly/devnet/run-all-flows.ts +++ b/src/tenderly/devnet/run-all-flows.ts @@ -37,7 +37,7 @@ export const runAllFlows = async () => { accessType: AccessType.OPEN, }, paymentConfig: { - token: await zns.meowToken.getAddress(), + token: await zns.zToken.getAddress(), beneficiary: governor.address, }, priceConfig: { @@ -47,7 +47,7 @@ export const runAllFlows = async () => { }; // get some funds and approve funds for treasury - await zns.meowToken.connect(governor).approve(await zns.treasury.getAddress(), ethers.MaxUint256); + await zns.zToken.connect(governor).approve(await zns.treasury.getAddress(), ethers.MaxUint256); const rootHash = await registrationWithSetup({ zns, @@ -64,14 +64,14 @@ export const runAllFlows = async () => { accessType: AccessType.OPEN, }, paymentConfig: { - token: await zns.meowToken.getAddress(), + token: await zns.zToken.getAddress(), beneficiary: user.address, }, priceConfig: DEFAULT_PRICE_CONFIG, }; - await zns.meowToken.transfer(user.address, ethers.parseEther("10000")); - await zns.meowToken.connect(user).approve(await zns.treasury.getAddress(), ethers.MaxUint256); + await zns.zToken.transfer(user.address, ethers.parseEther("10000")); + await zns.zToken.connect(user).approve(await zns.treasury.getAddress(), ethers.MaxUint256); await registrationWithSetup({ zns, diff --git a/src/utils/compare-bytecode.ts b/src/utils/compare-bytecode.ts index 4eddba822..4ce3a0b8b 100644 --- a/src/utils/compare-bytecode.ts +++ b/src/utils/compare-bytecode.ts @@ -1,5 +1,4 @@ -// TODO dep: this does not work. find a better way and uncomment the call in meow-token.ts const replacePattern = /a165627a7a72305820.{64}0029.*/g; export const compareBytecodeStrict = (bytecodeA : string, bytecodeB : string) => { diff --git a/test/DeployCampaign.integration.test.ts b/test/DeployCampaign.integration.test.ts index 55ec96846..c7aee5c49 100644 --- a/test/DeployCampaign.integration.test.ts +++ b/test/DeployCampaign.integration.test.ts @@ -5,18 +5,16 @@ import * as hre from "hardhat"; import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; import { getConfig } from "../src/deploy/campaign/environments"; import { runZnsCampaign } from "../src/deploy/zns-campaign"; -import { ethers } from "ethers"; import { IDistributionConfig } from "./helpers/types"; import { expect } from "chai"; import { hashDomainLabel, PaymentType, AccessType } from "./helpers"; import { approveBulk, getPriceBulk, - mintBulk, + transferBulk, registerRootDomainBulk, registerSubdomainBulk, } from "./helpers/deploy-helpers"; -import { Defender } from "@openzeppelin/defender-sdk"; import { IZNSCampaignConfig, IZNSContracts } from "../src/deploy/campaign/types"; @@ -65,8 +63,6 @@ describe("zNS + zDC Single Integration Test", () => { let paidMediumSubHash : string; let paidLongSubHash : string; - const mintAmount = ethers.parseEther("10000000"); - const domains = [shortDomain, mediumDomain, longDomain]; before(async () => { @@ -74,31 +70,12 @@ describe("zNS + zDC Single Integration Test", () => { // Reads `ENV_LEVEL` environment variable to determine rules to be enforced - let deployer; - let provider; - - if (hre.network.name === "hardhat") { - deployer = deployAdmin; - provider = new hre.ethers.JsonRpcProvider(process.env.SEPOLIA_RPC_URL); - } else { - const credentials = { - apiKey: process.env.DEFENDER_KEY, - apiSecret: process.env.DEFENDER_SECRET, - relayerApiKey: process.env.RELAYER_KEY, - relayerApiSecret: process.env.RELAYER_SECRET, - }; - - const client = new Defender(credentials); - provider = client.relaySigner.getProvider(); - deployer = client.relaySigner.getSigner(provider, { speed: "fast" }); - } - config = await getConfig({ - deployer: deployer as unknown as SignerWithAddress, + deployer: deployAdmin, zeroVaultAddress: zeroVault.address, }); - config.mockMeowToken = hre.network.name === "hardhat"; + config.mockZToken = hre.network.name === "hardhat"; // First run the `run-campaign` script, then modify the `MONGO_DB_VERSION` environment variable // Then run this test. The campaign won't be run, but those addresses will be picked up from the DB @@ -139,10 +116,12 @@ describe("zNS + zDC Single Integration Test", () => { await approveBulk(users, zns); // Give the user funds - if (hre.network.name === "hardhat" && config.mockMeowToken) { - await mintBulk( + if (hre.network.name === "hardhat" && config.mockZToken) { + const userBalanceInitial = await zns.zToken.balanceOf(deployAdmin.address) / BigInt(users.length); + await transferBulk( users, - mintAmount, + deployAdmin, + userBalanceInitial, zns ); } @@ -218,9 +197,9 @@ describe("zNS + zDC Single Integration Test", () => { const subdomains = [paidShortSubdomain, paidMediumSubdomain, paidLongSubdomain]; const balancePromises = [ - zns.meowToken.balanceOf(userD.address), - zns.meowToken.balanceOf(userE.address), - zns.meowToken.balanceOf(userF.address), + zns.zToken.balanceOf(userD.address), + zns.zToken.balanceOf(userE.address), + zns.zToken.balanceOf(userF.address), ]; const [ @@ -259,9 +238,9 @@ describe("zNS + zDC Single Integration Test", () => { ); const balanceAfterPromises = [ - zns.meowToken.balanceOf(userD.address), - zns.meowToken.balanceOf(userE.address), - zns.meowToken.balanceOf(userF.address), + zns.zToken.balanceOf(userD.address), + zns.zToken.balanceOf(userE.address), + zns.zToken.balanceOf(userF.address), ]; const [ diff --git a/test/DeployCampaignInt.test.ts b/test/DeployCampaignInt.test.ts index 2b546ad85..332b16155 100644 --- a/test/DeployCampaignInt.test.ts +++ b/test/DeployCampaignInt.test.ts @@ -1,1183 +1,1140 @@ -/* eslint-disable @typescript-eslint/no-empty-function, @typescript-eslint/ban-ts-comment, max-classes-per-file */ -import * as hre from "hardhat"; -import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; -import { expect } from "chai"; -import { - TLogger, - HardhatDeployer, - DeployCampaign, - resetMongoAdapter, - TDeployMissionCtor, - MongoDBAdapter, - ITenderlyContractData, - TDeployArgs, - VERSION_TYPES, -} from "@zero-tech/zdc"; -import { - DEFAULT_ROYALTY_FRACTION, - DEFAULT_PRICE_CONFIG, - ZNS_DOMAIN_TOKEN_NAME, - ZNS_DOMAIN_TOKEN_SYMBOL, - INVALID_ENV_ERR, - NO_MOCK_PROD_ERR, - STAKING_TOKEN_ERR, - INVALID_CURVE_ERR, - MONGO_URI_ERR, -} from "./helpers"; -import { - MeowTokenDM, - meowTokenName, - meowTokenSymbol, - ZNSAccessControllerDM, - ZNSAddressResolverDM, - ZNSCurvePricerDM, - ZNSDomainTokenDM, ZNSFixedPricerDM, - ZNSRegistryDM, ZNSRootRegistrarDM, ZNSSubRegistrarDM, ZNSTreasuryDM, -} from "../src/deploy/missions/contracts"; -import { znsNames } from "../src/deploy/missions/contracts/names"; -import { runZnsCampaign } from "../src/deploy/zns-campaign"; -import { MeowMainnet } from "../src/deploy/missions/contracts/meow-token/mainnet-data"; -import { ResolverTypes } from "../src/deploy/constants"; -import { getConfig } from "../src/deploy/campaign/environments"; -import { ethers } from "ethers"; -import { promisify } from "util"; -import { exec } from "child_process"; -import { saveTag } from "../src/utils/git-tag/save-tag"; -import { IZNSCampaignConfig, IZNSContracts } from "../src/deploy/campaign/types"; -import { HardhatRuntimeEnvironment } from "hardhat/types"; -import { DefenderRelayProvider } from "@openzeppelin/defender-sdk-relay-signer-client/lib/ethers"; -import { getZnsMongoAdapter } from "../src/deploy/mongo"; - - -const execAsync = promisify(exec); - -describe("Deploy Campaign Test", () => { - let deployAdmin : SignerWithAddress; - let admin : SignerWithAddress; - let governor : SignerWithAddress; - - // eslint-disable-next-line @typescript-eslint/no-unused-vars - let userA : SignerWithAddress; - let userB : SignerWithAddress; - let zeroVault : SignerWithAddress; - let campaignConfig : IZNSCampaignConfig; - - let mongoAdapter : MongoDBAdapter; - - const env = "dev"; - - before(async () => { - [deployAdmin, admin, governor, zeroVault, userA, userB] = await hre.ethers.getSigners(); - }); - - describe("MEOW Token Ops", () => { - before(async () => { - campaignConfig = { - env, - deployAdmin, - governorAddresses: [deployAdmin.address], - adminAddresses: [deployAdmin.address, admin.address], - domainToken: { - name: ZNS_DOMAIN_TOKEN_NAME, - symbol: ZNS_DOMAIN_TOKEN_SYMBOL, - defaultRoyaltyReceiver: deployAdmin.address, - defaultRoyaltyFraction: DEFAULT_ROYALTY_FRACTION, - }, - rootPriceConfig: DEFAULT_PRICE_CONFIG, - zeroVaultAddress: zeroVault.address, - stakingTokenAddress: MeowMainnet.address, - mockMeowToken: true, - postDeploy: { - tenderlyProjectSlug: "", - monitorContracts: false, - verifyContracts: false, - }, - }; - }); - - it("should deploy new MeowTokenMock when `mockMeowToken` is true", async () => { - const campaign = await runZnsCampaign({ - config: campaignConfig, - }); - - const { meowToken, dbAdapter } = campaign; - - const toMint = hre.ethers.parseEther("972315"); - - const balanceBefore = await meowToken.balanceOf(userA.address); - // `mint()` only exists on the Mocked contract - await meowToken.connect(deployAdmin).mint( - userA.address, - toMint - ); - - const balanceAfter = await meowToken.balanceOf(userA.address); - expect(balanceAfter - balanceBefore).to.equal(toMint); - - await dbAdapter.dropDB(); - }); - - it("should use existing deployed non-mocked MeowToken contract when `mockMeowToken` is false", async () => { - campaignConfig.mockMeowToken = false; - - // deploy MeowToken contract - const factory = await hre.ethers.getContractFactory("MeowToken"); - const meow = await hre.upgrades.deployProxy( - factory, - [meowTokenName, meowTokenSymbol], - { - kind: "transparent", - }); - - await meow.waitForDeployment(); - - campaignConfig.stakingTokenAddress = await meow.getAddress(); - - const campaign = await runZnsCampaign({ - config: campaignConfig, - }); - - const { - meowToken, - dbAdapter, - state: { - instances: { - meowToken: meowDMInstance, - }, - }, - } = campaign; - - expect(meowToken.address).to.equal(meow.address); - expect(meowDMInstance.contractName).to.equal(znsNames.meowToken.contract); - - const toMint = hre.ethers.parseEther("972315"); - // `mint()` only exists on the Mocked contract - try { - await meowToken.connect(deployAdmin).mint( - userA.address, - toMint - ); - } catch (e) { - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - expect(e.message).to.include( - ".mint is not a function" - ); - } - - // Cannot call to real db to - await dbAdapter.dropDB(); - }); - }); - - describe("Failure Recovery", () => { - const errorMsgDeploy = "FailMissionDeploy"; - const errorMsgPostDeploy = "FailMissionPostDeploy"; - - const loggerMock = { - info: () => { - }, - debug: () => { - }, - error: () => { - }, - }; - - interface IDeployedData { - contract : string; - instance : string; - address ?: string; - } - - const runTest = async ({ - missionList, - placeOfFailure, - deployedNames, - undeployedNames, - failingInstanceName, - callback, - } : { - missionList : Array>; - placeOfFailure : string; - deployedNames : Array<{ contract : string; instance : string; }>; - undeployedNames : Array<{ contract : string; instance : string; }>; - failingInstanceName : string; - // eslint-disable-next-line no-shadow - callback ?: (failingCampaign : DeployCampaign< - HardhatRuntimeEnvironment, - SignerWithAddress, - DefenderRelayProvider, - IZNSContracts - >) => Promise; - }) => { - const deployer = new HardhatDeployer< - HardhatRuntimeEnvironment, - SignerWithAddress, - DefenderRelayProvider - >({ - hre, - signer: deployAdmin, - env, - }); - let dbAdapter = await getZnsMongoAdapter(); - - let toMatchErr = errorMsgDeploy; - if (placeOfFailure === "postDeploy") { - toMatchErr = errorMsgPostDeploy; - } - - const failingCampaign = new DeployCampaign< - HardhatRuntimeEnvironment, - SignerWithAddress, - DefenderRelayProvider, - IZNSContracts - >({ - missions: missionList, - deployer, - dbAdapter, - // @ts-ignore - logger: loggerMock, - config: campaignConfig, - }); - - try { - await failingCampaign.execute(); - } catch (e) { - // @ts-ignore - expect(e.message).to.include(toMatchErr); - } - - // check the correct amount of contracts in state - const { contracts } = failingCampaign.state; - expect(Object.keys(contracts).length).to.equal(deployedNames.length); - - if (placeOfFailure === "deploy") { - // it should not deploy AddressResolver - expect(contracts[failingInstanceName]).to.be.undefined; - } else { - // it should deploy AddressResolver - expect(await contracts[failingInstanceName].getAddress()).to.be.properAddress; - } - - // check DB to verify we only deployed half - const firstRunDeployed = await deployedNames.reduce( - async ( - acc : Promise>, - { contract, instance } : { contract : string; instance : string; } - ) : Promise> => { - const akk = await acc; - const fromDB = await dbAdapter.getContract(contract); - expect(fromDB?.address).to.be.properAddress; - - return [...akk, { contract, instance, address: fromDB?.address }]; - }, - Promise.resolve([]) - ); - - await undeployedNames.reduce( - async ( - acc : Promise, - { contract, instance } : { contract : string; instance : string; } - ) : Promise => { - await acc; - const fromDB = await dbAdapter.getContract(contract); - const fromState = failingCampaign[instance]; - - expect(fromDB).to.be.null; - expect(fromState).to.be.undefined; - }, - Promise.resolve() - ); - - // call whatever callback we passed before the next campaign run - await callback?.(failingCampaign); - - const { curVersion: initialDbVersion } = dbAdapter; - - // reset mongoAdapter instance to make sure we pick up the correct DB version - resetMongoAdapter(); - - // run Campaign again, but normally - const nextCampaign = await runZnsCampaign({ - config: campaignConfig, - }); - - ({ dbAdapter } = nextCampaign); - - // make sure MongoAdapter is using the correct TEMP version - const { curVersion: nextDbVersion } = dbAdapter; - expect(nextDbVersion).to.equal(initialDbVersion); - - // state should have 10 contracts in it - const { state } = nextCampaign; - expect(Object.keys(state.contracts).length).to.equal(10); - expect(Object.keys(state.instances).length).to.equal(10); - expect(state.missions.length).to.equal(10); - // it should deploy AddressResolver - expect(await state.contracts.addressResolver.getAddress()).to.be.properAddress; - - // check DB to verify we deployed everything - const allNames = deployedNames.concat(undeployedNames); - - await allNames.reduce( - async ( - acc : Promise, - { contract } : { contract : string; } - ) : Promise => { - await acc; - const fromDB = await dbAdapter.getContract(contract); - expect(fromDB?.address).to.be.properAddress; - }, - Promise.resolve() - ); - - // check that previously deployed contracts were NOT redeployed - await firstRunDeployed.reduce( - async (acc : Promise, { contract, instance, address } : IDeployedData) : Promise => { - await acc; - const fromDB = await nextCampaign.dbAdapter.getContract(contract); - const fromState = nextCampaign[instance]; - - expect(fromDB?.address).to.equal(address); - expect(await fromState.getAddress()).to.equal(address); - }, - Promise.resolve() - ); - - return { - failingCampaign, - nextCampaign, - firstRunDeployed, - }; - }; - - beforeEach(async () => { - [deployAdmin, admin, zeroVault] = await hre.ethers.getSigners(); - - campaignConfig = { - env, - deployAdmin, - governorAddresses: [deployAdmin.address], - adminAddresses: [deployAdmin.address, admin.address], - domainToken: { - name: ZNS_DOMAIN_TOKEN_NAME, - symbol: ZNS_DOMAIN_TOKEN_SYMBOL, - defaultRoyaltyReceiver: deployAdmin.address, - defaultRoyaltyFraction: DEFAULT_ROYALTY_FRACTION, - }, - rootPriceConfig: DEFAULT_PRICE_CONFIG, - zeroVaultAddress: zeroVault.address, - // TODO dep: what do we pass here for test flow? we don't have a deployed MeowToken contract - stakingTokenAddress: "", - mockMeowToken: true, // 1700083028872 - postDeploy: { - tenderlyProjectSlug: "", - monitorContracts: false, - verifyContracts: false, - }, - }; - - mongoAdapter = await getZnsMongoAdapter({ - logger: loggerMock as TLogger, - }); - }); - - afterEach(async () => { - await mongoAdapter.dropDB(); - }); - - // eslint-disable-next-line max-len - it("[in AddressResolver.deploy() hook] should ONLY deploy undeployed contracts in the run following a failed run", async () => { - // ZNSAddressResolverDM sits in the middle of the Campaign deploy list - // we override this class to add a failure to the deploy() method - class FailingZNSAddressResolverDM extends ZNSAddressResolverDM { - async deploy () { - throw new Error(errorMsgDeploy); - } - } - - const deployedNames = [ - znsNames.accessController, - znsNames.registry, - znsNames.domainToken, - { - contract: znsNames.meowToken.contractMock, - instance: znsNames.meowToken.instance, - }, - ]; - - const undeployedNames = [ - znsNames.addressResolver, - znsNames.curvePricer, - znsNames.treasury, - znsNames.rootRegistrar, - znsNames.fixedPricer, - znsNames.subRegistrar, - ]; - - // call test flow runner - await runTest({ - missionList: [ - ZNSAccessControllerDM, - ZNSRegistryDM, - ZNSDomainTokenDM, - MeowTokenDM, - FailingZNSAddressResolverDM, // failing DM - ZNSCurvePricerDM, - ZNSTreasuryDM, - ZNSRootRegistrarDM, - ZNSFixedPricerDM, - ZNSSubRegistrarDM, - ], - placeOfFailure: "deploy", - deployedNames, - undeployedNames, - failingInstanceName: "addressResolver", - }); - }); - - // eslint-disable-next-line max-len - it("[in AddressResolver.postDeploy() hook] should start from post deploy sequence that failed on the previous run", async () => { - class FailingZNSAddressResolverDM extends ZNSAddressResolverDM { - async postDeploy () { - throw new Error(errorMsgPostDeploy); - } - } - - const deployedNames = [ - znsNames.accessController, - znsNames.registry, - znsNames.domainToken, - { - contract: znsNames.meowToken.contractMock, - instance: znsNames.meowToken.instance, - }, - znsNames.addressResolver, - ]; - - const undeployedNames = [ - znsNames.curvePricer, - znsNames.treasury, - znsNames.rootRegistrar, - znsNames.fixedPricer, - znsNames.subRegistrar, - ]; - - const checkPostDeploy = async (failingCampaign : DeployCampaign< - HardhatRuntimeEnvironment, - SignerWithAddress, - DefenderRelayProvider, - IZNSContracts - >) => { - const { - // eslint-disable-next-line no-shadow - registry, - } = failingCampaign; - - // we are checking that postDeploy did not add resolverType to Registry - expect(await registry.getResolverType(ResolverTypes.address)).to.be.equal(ethers.ZeroAddress); - }; - - // check contracts are deployed correctly - const { - nextCampaign, - } = await runTest({ - missionList: [ - ZNSAccessControllerDM, - ZNSRegistryDM, - ZNSDomainTokenDM, - MeowTokenDM, - FailingZNSAddressResolverDM, // failing DM - ZNSCurvePricerDM, - ZNSTreasuryDM, - ZNSRootRegistrarDM, - ZNSFixedPricerDM, - ZNSSubRegistrarDM, - ], - placeOfFailure: "postDeploy", - deployedNames, - undeployedNames, - failingInstanceName: "addressResolver", - callback: checkPostDeploy, - }); - - // make sure postDeploy() ran properly on the next run - const { - registry, - addressResolver, - } = nextCampaign; - expect(await registry.getResolverType(ResolverTypes.address)).to.be.equal(await addressResolver.getAddress()); - }); - - // eslint-disable-next-line max-len - it("[in RootRegistrar.deploy() hook] should ONLY deploy undeployed contracts in the run following a failed run", async () => { - class FailingZNSRootRegistrarDM extends ZNSRootRegistrarDM { - async deploy () { - throw new Error(errorMsgDeploy); - } - } - - const deployedNames = [ - znsNames.accessController, - znsNames.registry, - znsNames.domainToken, - { - contract: znsNames.meowToken.contractMock, - instance: znsNames.meowToken.instance, - }, - znsNames.addressResolver, - znsNames.curvePricer, - znsNames.treasury, - ]; - - const undeployedNames = [ - znsNames.rootRegistrar, - znsNames.fixedPricer, - znsNames.subRegistrar, - ]; - - // call test flow runner - await runTest({ - missionList: [ - ZNSAccessControllerDM, - ZNSRegistryDM, - ZNSDomainTokenDM, - MeowTokenDM, - ZNSAddressResolverDM, - ZNSCurvePricerDM, - ZNSTreasuryDM, - FailingZNSRootRegistrarDM, // failing DM - ZNSFixedPricerDM, - ZNSSubRegistrarDM, - ], - placeOfFailure: "deploy", - deployedNames, - undeployedNames, - failingInstanceName: "rootRegistrar", - }); - }); - - // eslint-disable-next-line max-len - it("[in RootRegistrar.postDeploy() hook] should start from post deploy sequence that failed on the previous run", async () => { - class FailingZNSRootRegistrarDM extends ZNSRootRegistrarDM { - async postDeploy () { - throw new Error(errorMsgPostDeploy); - } - } - - const deployedNames = [ - znsNames.accessController, - znsNames.registry, - znsNames.domainToken, - { - contract: znsNames.meowToken.contractMock, - instance: znsNames.meowToken.instance, - }, - znsNames.addressResolver, - znsNames.curvePricer, - znsNames.treasury, - znsNames.rootRegistrar, - ]; - - const undeployedNames = [ - znsNames.fixedPricer, - znsNames.subRegistrar, - ]; - - const checkPostDeploy = async (failingCampaign : DeployCampaign< - HardhatRuntimeEnvironment, - SignerWithAddress, - DefenderRelayProvider, - IZNSContracts - >) => { - const { - // eslint-disable-next-line no-shadow - accessController, - // eslint-disable-next-line no-shadow - rootRegistrar, - } = failingCampaign; - - // we are checking that postDeploy did not grant REGISTRAR_ROLE to RootRegistrar - expect(await accessController.isRegistrar(await rootRegistrar.getAddress())).to.be.false; - }; - - // check contracts are deployed correctly - const { - nextCampaign, - } = await runTest({ - missionList: [ - ZNSAccessControllerDM, - ZNSRegistryDM, - ZNSDomainTokenDM, - MeowTokenDM, - ZNSAddressResolverDM, - ZNSCurvePricerDM, - ZNSTreasuryDM, - FailingZNSRootRegistrarDM, // failing DM - ZNSFixedPricerDM, - ZNSSubRegistrarDM, - ], - placeOfFailure: "postDeploy", - deployedNames, - undeployedNames, - failingInstanceName: "rootRegistrar", - callback: checkPostDeploy, - }); - - // make sure postDeploy() ran properly on the next run - const { - accessController, - rootRegistrar, - } = nextCampaign; - expect(await accessController.isRegistrar(await rootRegistrar.getAddress())).to.be.true; - }); - }); - - describe("Configurable Environment & Validation", () => { - let envInitial : string; - - beforeEach(async () => { - envInitial = JSON.stringify(process.env); - }); - - afterEach(async () => { - process.env = JSON.parse(envInitial); - }); - - // The `validate` function accepts the environment parameter only for the - // purpose of testing here as manipulating actual environment variables - // like `process.env. = "value"` is not possible in a test environment - // because the Hardhat process for running these tests will not respect these - // changes. `getConfig` calls to `validate` on its own, but never passes a value - // for the environment specifically, that is ever only inferred from the `process.env.ENV_LEVEL` - it("Gets the default configuration correctly", async () => { - // set the environment to get the appropriate variables - const localConfig : IZNSCampaignConfig = await getConfig({ - deployer: deployAdmin, - zeroVaultAddress: zeroVault.address, - governors: [governor.address], - admins: [admin.address], - }); - - expect(await localConfig.deployAdmin.getAddress()).to.eq(deployAdmin.address); - expect(localConfig.governorAddresses[0]).to.eq(governor.address); - expect(localConfig.governorAddresses[1]).to.eq(deployAdmin.address); - expect(localConfig.adminAddresses[0]).to.eq(admin.address); - expect(localConfig.adminAddresses[1]).to.eq(deployAdmin.address); - expect(localConfig.domainToken.name).to.eq(ZNS_DOMAIN_TOKEN_NAME); - expect(localConfig.domainToken.symbol).to.eq(ZNS_DOMAIN_TOKEN_SYMBOL); - expect(localConfig.domainToken.defaultRoyaltyReceiver).to.eq(zeroVault.address); - expect(localConfig.domainToken.defaultRoyaltyFraction).to.eq(DEFAULT_ROYALTY_FRACTION); - expect(localConfig.rootPriceConfig).to.deep.eq(DEFAULT_PRICE_CONFIG); - }); - - it("Confirms encoding functionality works for env variables", async () => { - const sample = "0x123,0x456,0x789"; - const sampleFormatted = ["0x123", "0x456", "0x789"]; - const encoded = btoa(sample); - const decoded = atob(encoded).split(","); - expect(decoded).to.deep.eq(sampleFormatted); - }); - - it("Modifies config to use a random account as the deployer", async () => { - // Run the deployment a second time, clear the DB so everything is deployed - - let zns : IZNSContracts; - - const config : IZNSCampaignConfig = await getConfig({ - deployer: userB, - zeroVaultAddress: userA.address, - governors: [userB.address, admin.address], // governors - admins: [userB.address, governor.address], // admins - }); - - const campaign = await runZnsCampaign({ - config, - }); - - const { dbAdapter } = campaign; - - /* eslint-disable-next-line prefer-const */ - zns = campaign.state.contracts; - - const rootPaymentConfig = await zns.treasury.paymentConfigs(ethers.ZeroHash); - - expect(await zns.accessController.isAdmin(userB.address)).to.be.true; - expect(await zns.accessController.isAdmin(governor.address)).to.be.true; - expect(await zns.accessController.isGovernor(admin.address)).to.be.true; - expect(rootPaymentConfig.token).to.eq(await zns.meowToken.getAddress()); - expect(rootPaymentConfig.beneficiary).to.eq(userA.address); - - await dbAdapter.dropDB(); - }); - - it("Fails when governor or admin addresses are given wrong", async () => { - // Custom addresses must given as the base64 encoded string of comma separated addresses - // e.g. btoa("0x123,0x456,0x789") = 'MHgxMjMsMHg0NTYsMHg3ODk=', which is what should be provided - // We could manipulate envariables through `process.env.` for this test and call `getConfig()` - // but the async nature of HH mocha tests causes this to mess up other tests - // Instead we use the same encoding functions used in `getConfig()` to test the functionality - - /* eslint-disable @typescript-eslint/no-explicit-any */ - try { - atob("[0x123,0x456]"); - } catch (e : any) { - expect(e.message).includes("Invalid character"); - } - - try { - atob("0x123, 0x456"); - } catch (e : any) { - expect(e.message).includes("Invalid character"); - } - - try { - atob("0x123 0x456"); - } catch (e : any) { - expect(e.message).includes("Invalid character"); - } - - try { - atob("'MHgxM jMsMHg0 NTYs MHg3ODk='"); - } catch (e : any) { - expect(e.message).includes("Invalid character"); - } - }); - - it("Throws if env variable is invalid", async () => { - try { - await getConfig({ - deployer: deployAdmin, - zeroVaultAddress: zeroVault.address, - governors: [deployAdmin.address, governor.address], - admins: [deployAdmin.address, admin.address], - }); - - /* eslint-disable @typescript-eslint/no-explicit-any */ - } catch (e : any) { - expect(e.message).includes(INVALID_ENV_ERR); - } - }); - - it("Fails to validate when mocking MEOW on prod", async () => { - process.env.MOCK_MEOW_TOKEN = "true"; - - try { - await getConfig({ - deployer: deployAdmin, - zeroVaultAddress: zeroVault.address, - governors: [deployAdmin.address, governor.address], - admins: [deployAdmin.address, admin.address], - }); - - /* eslint-disable @typescript-eslint/no-explicit-any */ - } catch (e : any) { - expect(e.message).includes(NO_MOCK_PROD_ERR); - } - }); - - it("Fails to validate if not using the MEOW token on prod", async () => { - process.env.MOCK_MEOW_TOKEN = "false"; - process.env.STAKING_TOKEN_ADDRESS = "0x123"; - - try { - await getConfig({ - deployer: deployAdmin, - zeroVaultAddress: zeroVault.address, - governors: [deployAdmin.address, governor.address], - admins: [deployAdmin.address, admin.address], - }); - /* eslint-disable @typescript-eslint/no-explicit-any */ - } catch (e : any) { - expect(e.message).includes(STAKING_TOKEN_ERR); - } - }); - - it("Fails to validate if invalid curve for pricing", async () => { - process.env.MOCK_MEOW_TOKEN = "false"; - process.env.STAKING_TOKEN_ADDRESS = MeowMainnet.address; - process.env.BASE_LENGTH = "3"; - process.env.MAX_LENGTH = "5"; - process.env.MAX_PRICE = "0"; - process.env.MIN_PRICE = ethers.parseEther("3").toString(); - - try { - await getConfig({ - env: "prod", - deployer: deployAdmin, - zeroVaultAddress: zeroVault.address, - governors: [deployAdmin.address, governor.address], - admins: [deployAdmin.address, admin.address], - }); - /* eslint-disable @typescript-eslint/no-explicit-any */ - } catch (e : any) { - expect(e.message).includes(INVALID_CURVE_ERR); - } - }); - - it("Fails to validate if no mongo uri or local URI in prod", async () => { - process.env.MOCK_MEOW_TOKEN = "false"; - process.env.STAKING_TOKEN_ADDRESS = MeowMainnet.address; - // Falls back onto the default URI which is for localhost and fails in prod - process.env.MONGO_DB_URI = ""; - process.env.ROYALTY_RECEIVER = "0x123"; - process.env.ROYALTY_FRACTION = "100"; - - try { - await getConfig({ - env: "prod", - deployer: deployAdmin, - zeroVaultAddress: zeroVault.address, - governors: [deployAdmin.address, governor.address], - admins: [deployAdmin.address, admin.address], - }); - /* eslint-disable @typescript-eslint/no-explicit-any */ - } catch (e : any) { - expect(e.message).includes("Must provide a Mongo URI used for prod environment!"); - } - - process.env.MOCK_MEOW_TOKEN = "false"; - process.env.STAKING_TOKEN_ADDRESS = MeowMainnet.address; - process.env.MONGO_DB_URI = "mongodb://localhost:27018"; - process.env.ZERO_VAULT_ADDRESS = "0x123"; - - try { - await getConfig({ - env: "prod", - deployer: deployAdmin, - zeroVaultAddress: zeroVault.address, - governors: [deployAdmin.address, governor.address], - admins: [deployAdmin.address, admin.address], - }); - /* eslint-disable @typescript-eslint/no-explicit-any */ - } catch (e : any) { - expect(e.message).includes(MONGO_URI_ERR); - } - }); - }); - - describe("Versioning", () => { - let campaign : DeployCampaign< - HardhatRuntimeEnvironment, - SignerWithAddress, - DefenderRelayProvider, - IZNSContracts - >; - - before(async () => { - await saveTag(); - - campaignConfig = { - env, - deployAdmin, - governorAddresses: [deployAdmin.address, governor.address], - adminAddresses: [deployAdmin.address, admin.address], - domainToken: { - name: ZNS_DOMAIN_TOKEN_NAME, - symbol: ZNS_DOMAIN_TOKEN_SYMBOL, - defaultRoyaltyReceiver: deployAdmin.address, - defaultRoyaltyFraction: DEFAULT_ROYALTY_FRACTION, - }, - rootPriceConfig: DEFAULT_PRICE_CONFIG, - zeroVaultAddress: zeroVault.address, - stakingTokenAddress: MeowMainnet.address, - mockMeowToken: true, - postDeploy: { - tenderlyProjectSlug: "", - monitorContracts: false, - verifyContracts: false, - }, - }; - - campaign = await runZnsCampaign({ - config: campaignConfig, - }); - }); - - it("should get the correct git tag + commit hash and write to DB", async () => { - const latestGitTag = (await execAsync("git describe --tags --abbrev=0")).stdout.trim(); - const latestCommit = (await execAsync(`git rev-list -n 1 ${latestGitTag}`)).stdout.trim(); - - const fullGitTag = `${latestGitTag}:${latestCommit}`; - - const { dbAdapter } = campaign; - - const versionDoc = await dbAdapter.versioner.getLatestVersion(); - expect(versionDoc?.contractsVersion).to.equal(fullGitTag); - - const deployedVersion = await dbAdapter.versioner.getDeployedVersion(); - expect(deployedVersion?.contractsVersion).to.equal(fullGitTag); - }); - - // eslint-disable-next-line max-len - it("should create new DB version and KEEP old data if ARCHIVE is true and no TEMP versions currently exist", async () => { - const { dbAdapter } = campaign; - - const versionDocInitial = await dbAdapter.versioner.getLatestVersion(); - const initialDBVersion = versionDocInitial?.dbVersion; - const registryDocInitial = await dbAdapter.getContract(znsNames.registry.contract); - - expect( - process.env.MONGO_DB_VERSION === undefined - || process.env.MONGO_DB_VERSION === "" - ).to.be.true; - - // set archiving for the new mongo adapter - const initialArchiveVal = process.env.ARCHIVE_PREVIOUS_DB_VERSION; - process.env.ARCHIVE_PREVIOUS_DB_VERSION = "true"; - - // run a new campaign - const { dbAdapter: newDbAdapter } = await runZnsCampaign({ - config: campaignConfig, - }); - - expect(newDbAdapter.curVersion).to.not.equal(initialDBVersion); - - // get some data from new DB version - const registryDocNew = await newDbAdapter.getContract(znsNames.registry.contract); - expect(registryDocNew?.version).to.not.equal(registryDocInitial?.version); - - const versionDocNew = await newDbAdapter.versioner.getLatestVersion(); - expect(versionDocNew?.dbVersion).to.not.equal(initialDBVersion); - expect(versionDocNew?.type).to.equal(VERSION_TYPES.deployed); - - // make sure old contracts from previous DB version are still there - const oldRegistryDocFromNewDB = await newDbAdapter.getContract( - znsNames.registry.contract, - initialDBVersion - ); - - expect(oldRegistryDocFromNewDB?.version).to.equal(registryDocInitial?.version); - expect(oldRegistryDocFromNewDB?.address).to.equal(registryDocInitial?.address); - expect(oldRegistryDocFromNewDB?.name).to.equal(registryDocInitial?.name); - expect(oldRegistryDocFromNewDB?.abi).to.equal(registryDocInitial?.abi); - expect(oldRegistryDocFromNewDB?.bytecode).to.equal(registryDocInitial?.bytecode); - - // reset back to default - process.env.ARCHIVE_PREVIOUS_DB_VERSION = initialArchiveVal; - }); - - // eslint-disable-next-line max-len - it("should create new DB version and WIPE all existing data if ARCHIVE is false and no TEMP versions currently exist", async () => { - const { dbAdapter } = campaign; - - const versionDocInitial = await dbAdapter.versioner.getLatestVersion(); - const initialDBVersion = versionDocInitial?.dbVersion; - const registryDocInitial = await dbAdapter.getContract(znsNames.registry.contract); - - expect( - process.env.MONGO_DB_VERSION === undefined - || process.env.MONGO_DB_VERSION === "" - ).to.be.true; - - // set archiving for the new mongo adapter - const initialArchiveVal = process.env.ARCHIVE_PREVIOUS_DB_VERSION; - process.env.ARCHIVE_PREVIOUS_DB_VERSION = "false"; - - // run a new campaign - const { dbAdapter: newDbAdapter } = await runZnsCampaign({ - config: campaignConfig, - }); - - expect(newDbAdapter.curVersion).to.not.equal(initialDBVersion); - - // get some data from new DB version - const registryDocNew = await newDbAdapter.getContract(znsNames.registry.contract); - expect(registryDocNew?.version).to.not.equal(registryDocInitial?.version); - - const versionDocNew = await newDbAdapter.versioner.getLatestVersion(); - expect(versionDocNew?.dbVersion).to.not.equal(initialDBVersion); - expect(versionDocNew?.type).to.equal(VERSION_TYPES.deployed); - - // make sure old contracts from previous DB version are NOT there - const oldRegistryDocFromNewDB = await newDbAdapter.getContract( - znsNames.registry.contract, - initialDBVersion - ); - - expect(oldRegistryDocFromNewDB).to.be.null; - - // reset back to default - process.env.ARCHIVE_PREVIOUS_DB_VERSION = initialArchiveVal; - }); - - // eslint-disable-next-line max-len - it("should pick up existing contracts and NOT deploy new ones into state if MONGO_DB_VERSION is specified", async () => { - const { dbAdapter } = campaign; - - const versionDocInitial = await dbAdapter.versioner.getLatestVersion(); - const initialDBVersion = versionDocInitial?.dbVersion; - const registryDocInitial = await dbAdapter.getContract(znsNames.registry.contract); - - // set DB version for the new mongo adapter - const initialDBVersionVal = process.env.MONGO_DB_VERSION; - process.env.MONGO_DB_VERSION = initialDBVersion; - - // run a new campaign - const { state: { contracts: newContracts } } = await runZnsCampaign({ - config: campaignConfig, - }); - - // make sure we picked up the correct DB version - const versionDocNew = await dbAdapter.versioner.getLatestVersion(); - expect(versionDocNew?.dbVersion).to.equal(initialDBVersion); - - // make sure old contracts from previous DB version are still there - const oldRegistryDocFromNewDB = await dbAdapter.getContract( - znsNames.registry.contract, - initialDBVersion - ); - - expect(oldRegistryDocFromNewDB?.version).to.equal(registryDocInitial?.version); - expect(oldRegistryDocFromNewDB?.address).to.equal(registryDocInitial?.address); - expect(oldRegistryDocFromNewDB?.name).to.equal(registryDocInitial?.name); - expect(oldRegistryDocFromNewDB?.abi).to.equal(registryDocInitial?.abi); - expect(oldRegistryDocFromNewDB?.bytecode).to.equal(registryDocInitial?.bytecode); - - // make sure contracts in state have been picked up correctly from DB - expect(await newContracts.registry.getAddress()).to.equal(registryDocInitial?.address); - - // reset back to default - process.env.MONGO_DB_VERSION = initialDBVersionVal; - }); - }); - - describe("Verify - Monitor", () => { - let config : IZNSCampaignConfig; - - before (async () => { - [deployAdmin, admin, governor, zeroVault] = await hre.ethers.getSigners(); - - config = { - env: "dev", - deployAdmin, - governorAddresses: [deployAdmin.address, governor.address], - adminAddresses: [deployAdmin.address, admin.address], - domainToken: { - name: ZNS_DOMAIN_TOKEN_NAME, - symbol: ZNS_DOMAIN_TOKEN_SYMBOL, - defaultRoyaltyReceiver: deployAdmin.address, - defaultRoyaltyFraction: DEFAULT_ROYALTY_FRACTION, - }, - rootPriceConfig: DEFAULT_PRICE_CONFIG, - zeroVaultAddress: zeroVault.address, - stakingTokenAddress: MeowMainnet.address, - mockMeowToken: true, - postDeploy: { - tenderlyProjectSlug: "", - monitorContracts: false, - verifyContracts: true, - }, - }; - }); - - afterEach(async () => { - await mongoAdapter.dropDB(); - }); - - it("should prepare the correct data for each contract when verifying on Etherscan", async () => { - const verifyData : Array<{ address : string; ctorArgs ?: TDeployArgs; }> = []; - class HardhatDeployerMock extends HardhatDeployer< - HardhatRuntimeEnvironment, - SignerWithAddress, - DefenderRelayProvider - > { - async etherscanVerify (args : { - address : string; - ctorArgs ?: TDeployArgs; - }) { - verifyData.push(args); - } - } - - const deployer = new HardhatDeployerMock({ - hre, - signer: deployAdmin, - env, - }); - - const campaign = await runZnsCampaign({ - config, - deployer, - }); - - const { state: { contracts } } = campaign; - ({ dbAdapter: mongoAdapter } = campaign); - - await Object.values(contracts).reduce( - async (acc, contract, idx) => { - await acc; - - if (idx === 0) { - expect(verifyData[idx].ctorArgs).to.be.deep.eq([config.governorAddresses, config.adminAddresses]); - } - - expect(verifyData[idx].address).to.equal(await contract.getAddress()); - }, - Promise.resolve() - ); - }); - - it("should prepare the correct contract data when pushing to Tenderly Project", async () => { - let tenderlyData : Array = []; - class HardhatDeployerMock extends HardhatDeployer< - HardhatRuntimeEnvironment, - SignerWithAddress, - DefenderRelayProvider - > { - async tenderlyPush (contracts : Array) { - tenderlyData = contracts; - } - } - - const deployer = new HardhatDeployerMock({ - hre, - signer: deployAdmin, - env, - }); - - config.postDeploy.monitorContracts = true; - config.postDeploy.verifyContracts = false; - - const campaign = await runZnsCampaign({ - config, - deployer, - }); - - const { state: { instances } } = campaign; - ({ dbAdapter: mongoAdapter } = campaign); - - let idx = 0; - await Object.values(instances).reduce( - async (acc, instance) => { - await acc; - - const dbData = await instance.getFromDB(); - - if (instance.proxyData.isProxy) { - // check proxy - expect(tenderlyData[idx].address).to.be.eq(dbData?.address); - expect(tenderlyData[idx].display_name).to.be.eq(`${instance.contractName}Proxy`); - - // check impl - expect(tenderlyData[idx + 1].address).to.be.eq(dbData?.implementation); - expect(tenderlyData[idx + 1].display_name).to.be.eq(`${dbData?.name}Impl`); - expect(tenderlyData[idx + 1].display_name).to.be.eq(`${instance.contractName}Impl`); - idx += 2; - } else { - expect(tenderlyData[idx].address).to.equal(dbData?.address); - expect(tenderlyData[idx].display_name).to.equal(dbData?.name); - expect(tenderlyData[idx].display_name).to.equal(instance.contractName); - idx++; - } - }, - Promise.resolve() - ); - }); - }); -}); +/* eslint-disable @typescript-eslint/no-empty-function, @typescript-eslint/ban-ts-comment, max-classes-per-file */ +import * as hre from "hardhat"; +import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; +import { expect } from "chai"; +import { + TLogger, + HardhatDeployer, + DeployCampaign, + resetMongoAdapter, + TDeployMissionCtor, + MongoDBAdapter, + ITenderlyContractData, + TDeployArgs, + VERSION_TYPES, +} from "@zero-tech/zdc"; +import { + DEFAULT_ROYALTY_FRACTION, + DEFAULT_PRICE_CONFIG, + ZNS_DOMAIN_TOKEN_NAME, + ZNS_DOMAIN_TOKEN_SYMBOL, + INVALID_ENV_ERR, + NO_MOCK_PROD_ERR, + STAKING_TOKEN_ERR, + MONGO_URI_ERR, + INFLATION_RATES_DEFAULT, + FINAL_INFLATION_RATE_DEFAULT, + INITIAL_SUPPLY_DEFAULT, + INITIAL_ADMIN_DELAY_DEFAULT, + Z_NAME_DEFAULT, + Z_SYMBOL_DEFAULT, +} from "./helpers"; +import { + ZTokenDM, + ZNSAccessControllerDM, + ZNSAddressResolverDM, + ZNSCurvePricerDM, + ZNSDomainTokenDM, ZNSFixedPricerDM, + ZNSRegistryDM, ZNSRootRegistrarDM, ZNSSubRegistrarDM, ZNSTreasuryDM, +} from "../src/deploy/missions/contracts"; +import { ZNSStringResolverDM } from "../src/deploy/missions/contracts/string-resolver"; +import { znsNames } from "../src/deploy/missions/contracts/names"; +import { runZnsCampaign } from "../src/deploy/zns-campaign"; +// TODO multi: why does this have Sepolia in the name ?! Check and validate ! +import { ZSepolia } from "../src/deploy/missions/contracts/z-token/mainnet-data"; +import { ResolverTypes } from "../src/deploy/constants"; +import { getConfig } from "../src/deploy/campaign/environments"; +import { ethers } from "ethers"; +import { promisify } from "util"; +import { exec } from "child_process"; +import { saveTag } from "../src/utils/git-tag/save-tag"; +import { IZNSCampaignConfig, IZNSContracts } from "../src/deploy/campaign/types"; +import { HardhatRuntimeEnvironment } from "hardhat/types"; +import { getZnsMongoAdapter } from "../src/deploy/mongo"; +import { IZTokenConfig } from "../src/deploy/missions/types"; + + +const execAsync = promisify(exec); + +describe("Deploy Campaign Test", () => { + let deployAdmin : SignerWithAddress; + let admin : SignerWithAddress; + let governor : SignerWithAddress; + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + let userA : SignerWithAddress; + let userB : SignerWithAddress; + let zeroVault : SignerWithAddress; + let campaignConfig : IZNSCampaignConfig; + + let mongoAdapter : MongoDBAdapter; + + const env = "dev"; + + before(async () => { + [deployAdmin, admin, governor, zeroVault, userA, userB] = await hre.ethers.getSigners(); + }); + + describe("Z Token Ops", () => { + before(async () => { + campaignConfig = await getConfig( + { + deployer: deployAdmin, + governors: [deployAdmin.address], + admins: [deployAdmin.address, admin.address], + zeroVaultAddress: zeroVault.address, + env, + } + ); + campaignConfig.domainToken.defaultRoyaltyReceiver = deployAdmin.address; + campaignConfig.postDeploy.tenderlyProjectSlug = ""; + }); + + it("should deploy new ZTokenMock when `mockZToken` is true", async () => { + const campaign = await runZnsCampaign({ + config: campaignConfig, + }); + + const { zToken, dbAdapter } = campaign; + + expect( + campaignConfig.mockZToken + ).to.equal(true); + + expect( + await zToken.getAddress() + ).to.properAddress; + + expect( + await zToken.name() + ).to.equal("ZERO Token"); + + expect( + await zToken.symbol() + ).to.equal("Z"); + + // one of deploy args + expect( + await zToken.INITIAL_SUPPLY_BASE() + ).to.equal( + (campaignConfig.zTokenConfig as IZTokenConfig).initialSupplyBase + ); + + // function, which exist only on mock contract + expect( + await zToken.identifyMock() + ).to.equal("This is a mock token"); + + await dbAdapter.dropDB(); + }); + + it("should use existing deployed non-mocked ZToken contract when `mockZToken` is false", async () => { + campaignConfig.mockZToken = false; + + // deploy ZToken contract + const Factory = await hre.ethers.getContractFactory("ZTokenMock"); + const z = await Factory.deploy( + Z_NAME_DEFAULT, + Z_SYMBOL_DEFAULT, + admin.address, + INITIAL_ADMIN_DELAY_DEFAULT, + admin.address, + userA.address, + INITIAL_SUPPLY_DEFAULT, + INFLATION_RATES_DEFAULT, + FINAL_INFLATION_RATE_DEFAULT, + ); + + await z.waitForDeployment(); + + campaignConfig.stakingTokenAddress = await z.getAddress(); + + const campaign = await runZnsCampaign({ + config: campaignConfig, + }); + + const { + zToken, + dbAdapter, + state: { + instances: { + zToken: zDMInstance, + }, + }, + } = campaign; + + expect( + await zToken.getAddress() + ).to.equal( + await z.getAddress() + ); + expect(zDMInstance.contractName).to.equal(znsNames.zToken.contract); + + // Cannot call to real db to + await dbAdapter.dropDB(); + }); + }); + + describe("Failure Recovery", () => { + const errorMsgDeploy = "FailMissionDeploy"; + const errorMsgPostDeploy = "FailMissionPostDeploy"; + + const loggerMock = { + info: () => { + }, + debug: () => { + }, + error: () => { + }, + }; + + interface IDeployedData { + contract : string; + instance : string; + address ?: string; + } + + const runTest = async ({ + missionList, + placeOfFailure, + deployedNames, + undeployedNames, + failingInstanceName, + callback, + } : { + missionList : Array, + IZNSContracts + >>; + placeOfFailure : string; + deployedNames : Array<{ contract : string; instance : string; }>; + undeployedNames : Array<{ contract : string; instance : string; }>; + failingInstanceName : string; + // eslint-disable-next-line no-shadow + callback ?: (failingCampaign : DeployCampaign< + HardhatRuntimeEnvironment, + SignerWithAddress, + IZNSCampaignConfig, + IZNSContracts + >) => Promise; + }) => { + const deployer = new HardhatDeployer< + HardhatRuntimeEnvironment, + SignerWithAddress + >({ + hre, + signer: deployAdmin, + env, + }); + let dbAdapter = await getZnsMongoAdapter(); + + let toMatchErr = errorMsgDeploy; + if (placeOfFailure === "postDeploy") { + toMatchErr = errorMsgPostDeploy; + } + + const failingCampaign = new DeployCampaign< + HardhatRuntimeEnvironment, + SignerWithAddress, + IZNSCampaignConfig, + IZNSContracts + >({ + missions: missionList, + deployer, + dbAdapter, + // @ts-ignore + logger: loggerMock, + config: campaignConfig, + }); + + try { + await failingCampaign.execute(); + } catch (e) { + // @ts-ignore + expect(e.message).to.include(toMatchErr); + } + + // check the correct amount of contracts in state + const { contracts } = failingCampaign.state; + expect(Object.keys(contracts).length).to.equal(deployedNames.length); + + if (placeOfFailure === "deploy") { + // it should not deploy AddressResolver + expect(contracts[failingInstanceName]).to.be.undefined; + } else { + // it should deploy AddressResolver + expect(await contracts[failingInstanceName].getAddress()).to.be.properAddress; + } + + // check DB to verify we only deployed half + const firstRunDeployed = await deployedNames.reduce( + async ( + acc : Promise>, + { contract, instance } : { contract : string; instance : string; } + ) : Promise> => { + const akk = await acc; + const fromDB = await dbAdapter.getContract(contract); + expect(fromDB?.address).to.be.properAddress; + + return [...akk, { contract, instance, address: fromDB?.address }]; + }, + Promise.resolve([]) + ); + + await undeployedNames.reduce( + async ( + acc : Promise, + { contract, instance } : { contract : string; instance : string; } + ) : Promise => { + await acc; + const fromDB = await dbAdapter.getContract(contract); + const fromState = failingCampaign[instance]; + + expect(fromDB).to.be.null; + expect(fromState).to.be.undefined; + }, + Promise.resolve() + ); + + // call whatever callback we passed before the next campaign run + await callback?.(failingCampaign); + + const { curVersion: initialDbVersion } = dbAdapter; + + // reset mongoAdapter instance to make sure we pick up the correct DB version + resetMongoAdapter(); + + // run Campaign again, but normally + const nextCampaign = await runZnsCampaign({ + config: campaignConfig, + }); + + ({ dbAdapter } = nextCampaign); + + // make sure MongoAdapter is using the correct TEMP version + const { curVersion: nextDbVersion } = dbAdapter; + expect(nextDbVersion).to.equal(initialDbVersion); + + // state should have 11 contracts in it + const { state } = nextCampaign; + expect(Object.keys(state.contracts).length).to.equal(11); + expect(Object.keys(state.instances).length).to.equal(11); + expect(state.missions.length).to.equal(11); + // it should deploy AddressResolver + expect(await state.contracts.addressResolver.getAddress()).to.be.properAddress; + + // check DB to verify we deployed everything + const allNames = deployedNames.concat(undeployedNames); + + await allNames.reduce( + async ( + acc : Promise, + { contract } : { contract : string; } + ) : Promise => { + await acc; + const fromDB = await dbAdapter.getContract(contract); + expect(fromDB?.address).to.be.properAddress; + }, + Promise.resolve() + ); + + // check that previously deployed contracts were NOT redeployed + await firstRunDeployed.reduce( + async (acc : Promise, { contract, instance, address } : IDeployedData) : Promise => { + await acc; + const fromDB = await nextCampaign.dbAdapter.getContract(contract); + const fromState = nextCampaign[instance]; + + expect(fromDB?.address).to.equal(address); + expect(await fromState.getAddress()).to.equal(address); + }, + Promise.resolve() + ); + + return { + failingCampaign, + nextCampaign, + firstRunDeployed, + }; + }; + + beforeEach(async () => { + [deployAdmin, admin, zeroVault] = await hre.ethers.getSigners(); + + campaignConfig = await getConfig( + { + deployer: deployAdmin, + governors: [deployAdmin.address], + admins: [deployAdmin.address, admin.address], + zeroVaultAddress: zeroVault.address, + env, + } + ); + campaignConfig.domainToken.defaultRoyaltyReceiver = deployAdmin.address; + // TODO dep: what do we pass here for test flow? we don't have a deployed ZToken contract + campaignConfig.stakingTokenAddress = ""; + campaignConfig.postDeploy.tenderlyProjectSlug = ""; + + mongoAdapter = await getZnsMongoAdapter({ + logger: loggerMock as TLogger, + }); + }); + + afterEach(async () => { + await mongoAdapter.dropDB(); + }); + + // eslint-disable-next-line max-len + it("[in AddressResolver.deploy() hook] should ONLY deploy undeployed contracts in the run following a failed run", async () => { + // ZNSAddressResolverDM sits in the middle of the Campaign deploy list + // we override this class to add a failure to the deploy() method + class FailingZNSAddressResolverDM extends ZNSAddressResolverDM { + async deploy () { + throw new Error(errorMsgDeploy); + } + } + + const deployedNames = [ + znsNames.accessController, + znsNames.registry, + znsNames.domainToken, + { + contract: znsNames.zToken.contractMock, + instance: znsNames.zToken.instance, + }, + ]; + + const undeployedNames = [ + znsNames.addressResolver, + znsNames.curvePricer, + znsNames.treasury, + znsNames.rootRegistrar, + znsNames.fixedPricer, + znsNames.subRegistrar, + ]; + + // call test flow runner + await runTest({ + missionList: [ + ZNSAccessControllerDM, + ZNSRegistryDM, + ZNSDomainTokenDM, + ZTokenDM, + FailingZNSAddressResolverDM, // failing DM + ZNSStringResolverDM, + ZNSCurvePricerDM, + ZNSTreasuryDM, + ZNSRootRegistrarDM, + ZNSFixedPricerDM, + ZNSSubRegistrarDM, + ], + placeOfFailure: "deploy", + deployedNames, + undeployedNames, + failingInstanceName: "addressResolver", + }); + }); + + // eslint-disable-next-line max-len + it("[in AddressResolver.postDeploy() hook] should start from post deploy sequence that failed on the previous run", async () => { + class FailingZNSAddressResolverDM extends ZNSAddressResolverDM { + async postDeploy () { + throw new Error(errorMsgPostDeploy); + } + } + + const deployedNames = [ + znsNames.accessController, + znsNames.registry, + znsNames.domainToken, + { + contract: znsNames.zToken.contractMock, + instance: znsNames.zToken.instance, + }, + znsNames.addressResolver, + ]; + + const undeployedNames = [ + znsNames.curvePricer, + znsNames.treasury, + znsNames.rootRegistrar, + znsNames.fixedPricer, + znsNames.subRegistrar, + ]; + + const checkPostDeploy = async (failingCampaign : DeployCampaign< + HardhatRuntimeEnvironment, + SignerWithAddress, + IZNSCampaignConfig, + IZNSContracts + >) => { + const { + // eslint-disable-next-line no-shadow + registry, + } = failingCampaign; + + // we are checking that postDeploy did not add resolverType to Registry + expect(await registry.getResolverType(ResolverTypes.address)).to.be.equal(ethers.ZeroAddress); + }; + + // check contracts are deployed correctly + const { + nextCampaign, + } = await runTest({ + missionList: [ + ZNSAccessControllerDM, + ZNSRegistryDM, + ZNSDomainTokenDM, + ZTokenDM, + FailingZNSAddressResolverDM, // failing DM + ZNSCurvePricerDM, + ZNSTreasuryDM, + ZNSRootRegistrarDM, + ZNSFixedPricerDM, + ZNSSubRegistrarDM, + ], + placeOfFailure: "postDeploy", + deployedNames, + undeployedNames, + failingInstanceName: "addressResolver", + callback: checkPostDeploy, + }); + + // make sure postDeploy() ran properly on the next run + const { + registry, + addressResolver, + } = nextCampaign; + expect(await registry.getResolverType(ResolverTypes.address)).to.be.equal(await addressResolver.getAddress()); + }); + + // eslint-disable-next-line max-len + it("[in RootRegistrar.deploy() hook] should ONLY deploy undeployed contracts in the run following a failed run", async () => { + class FailingZNSRootRegistrarDM extends ZNSRootRegistrarDM { + async deploy () { + throw new Error(errorMsgDeploy); + } + } + + const deployedNames = [ + znsNames.accessController, + znsNames.registry, + znsNames.domainToken, + { + contract: znsNames.zToken.contractMock, + instance: znsNames.zToken.instance, + }, + znsNames.addressResolver, + znsNames.curvePricer, + znsNames.treasury, + ]; + + const undeployedNames = [ + znsNames.rootRegistrar, + znsNames.fixedPricer, + znsNames.subRegistrar, + ]; + + // call test flow runner + await runTest({ + missionList: [ + ZNSAccessControllerDM, + ZNSRegistryDM, + ZNSDomainTokenDM, + ZTokenDM, + ZNSAddressResolverDM, + ZNSCurvePricerDM, + ZNSTreasuryDM, + FailingZNSRootRegistrarDM, // failing DM + ZNSFixedPricerDM, + ZNSSubRegistrarDM, + ], + placeOfFailure: "deploy", + deployedNames, + undeployedNames, + failingInstanceName: "rootRegistrar", + }); + }); + + // eslint-disable-next-line max-len + it("[in RootRegistrar.postDeploy() hook] should start from post deploy sequence that failed on the previous run", async () => { + class FailingZNSRootRegistrarDM extends ZNSRootRegistrarDM { + async postDeploy () { + throw new Error(errorMsgPostDeploy); + } + } + + const deployedNames = [ + znsNames.accessController, + znsNames.registry, + znsNames.domainToken, + { + contract: znsNames.zToken.contractMock, + instance: znsNames.zToken.instance, + }, + znsNames.addressResolver, + znsNames.curvePricer, + znsNames.treasury, + znsNames.rootRegistrar, + ]; + + const undeployedNames = [ + znsNames.fixedPricer, + znsNames.subRegistrar, + ]; + + const checkPostDeploy = async (failingCampaign : DeployCampaign< + HardhatRuntimeEnvironment, + SignerWithAddress, + IZNSCampaignConfig, + IZNSContracts + >) => { + const { + // eslint-disable-next-line no-shadow + accessController, + // eslint-disable-next-line no-shadow + rootRegistrar, + } = failingCampaign; + + // we are checking that postDeploy did not grant REGISTRAR_ROLE to RootRegistrar + expect(await accessController.isRegistrar(await rootRegistrar.getAddress())).to.be.false; + }; + + // check contracts are deployed correctly + const { + nextCampaign, + } = await runTest({ + missionList: [ + ZNSAccessControllerDM, + ZNSRegistryDM, + ZNSDomainTokenDM, + ZTokenDM, + ZNSAddressResolverDM, + ZNSCurvePricerDM, + ZNSTreasuryDM, + FailingZNSRootRegistrarDM, // failing DM + ZNSFixedPricerDM, + ZNSSubRegistrarDM, + ], + placeOfFailure: "postDeploy", + deployedNames, + undeployedNames, + failingInstanceName: "rootRegistrar", + callback: checkPostDeploy, + }); + + // make sure postDeploy() ran properly on the next run + const { + accessController, + rootRegistrar, + } = nextCampaign; + expect(await accessController.isRegistrar(await rootRegistrar.getAddress())).to.be.true; + }); + }); + + describe("Configurable Environment & Validation", () => { + let envInitial : string; + + beforeEach(async () => { + envInitial = JSON.stringify(process.env); + }); + + afterEach(async () => { + process.env = JSON.parse(envInitial); + }); + + // The `validate` function accepts the environment parameter only for the + // purpose of testing here as manipulating actual environment variables + // like `process.env. = "value"` is not possible in a test environment + // because the Hardhat process for running these tests will not respect these + // changes. `getConfig` calls to `validate` on its own, but never passes a value + // for the environment specifically, that is ever only inferred from the `process.env.ENV_LEVEL` + it("Gets the default configuration correctly", async () => { + // set the environment to get the appropriate variables + const localConfig : IZNSCampaignConfig = await getConfig({ + deployer: deployAdmin, + zeroVaultAddress: zeroVault.address, + governors: [governor.address], + admins: [admin.address], + }); + + expect(await localConfig.deployAdmin.getAddress()).to.eq(deployAdmin.address); + expect(localConfig.governorAddresses[0]).to.eq(governor.address); + expect(localConfig.governorAddresses[1]).to.eq(deployAdmin.address); + expect(localConfig.adminAddresses[0]).to.eq(admin.address); + expect(localConfig.adminAddresses[1]).to.eq(deployAdmin.address); + expect(localConfig.domainToken.name).to.eq(ZNS_DOMAIN_TOKEN_NAME); + expect(localConfig.domainToken.symbol).to.eq(ZNS_DOMAIN_TOKEN_SYMBOL); + expect(localConfig.domainToken.defaultRoyaltyReceiver).to.eq(zeroVault.address); + expect(localConfig.domainToken.defaultRoyaltyFraction).to.eq(DEFAULT_ROYALTY_FRACTION); + expect(localConfig.rootPriceConfig).to.deep.eq(DEFAULT_PRICE_CONFIG); + }); + + it("Confirms encoding functionality works for env variables", async () => { + const sample = "0x123,0x456,0x789"; + const sampleFormatted = ["0x123", "0x456", "0x789"]; + const encoded = btoa(sample); + const decoded = atob(encoded).split(","); + expect(decoded).to.deep.eq(sampleFormatted); + }); + + it("Modifies config to use a random account as the deployer", async () => { + // Run the deployment a second time, clear the DB so everything is deployed + + let zns : IZNSContracts; + + const config : IZNSCampaignConfig = await getConfig({ + deployer: userB, + zeroVaultAddress: userA.address, + governors: [userB.address, admin.address], // governors + admins: [userB.address, governor.address], // admins + }); + + const campaign = await runZnsCampaign({ + config, + }); + + const { dbAdapter } = campaign; + + /* eslint-disable-next-line prefer-const */ + zns = campaign.state.contracts; + + const rootPaymentConfig = await zns.treasury.paymentConfigs(ethers.ZeroHash); + + expect(await zns.accessController.isAdmin(userB.address)).to.be.true; + expect(await zns.accessController.isAdmin(governor.address)).to.be.true; + expect(await zns.accessController.isGovernor(admin.address)).to.be.true; + expect(rootPaymentConfig.token).to.eq(await zns.zToken.getAddress()); + expect(rootPaymentConfig.beneficiary).to.eq(userA.address); + + await dbAdapter.dropDB(); + }); + + it("Fails when governor or admin addresses are given wrong", async () => { + // Custom addresses must given as the base64 encoded string of comma separated addresses + // e.g. btoa("0x123,0x456,0x789") = 'MHgxMjMsMHg0NTYsMHg3ODk=', which is what should be provided + // We could manipulate envariables through `process.env.` for this test and call `getConfig()` + // but the async nature of HH mocha tests causes this to mess up other tests + // Instead we use the same encoding functions used in `getConfig()` to test the functionality + + /* eslint-disable @typescript-eslint/no-explicit-any */ + try { + atob("[0x123,0x456]"); + } catch (e : any) { + expect(e.message).includes("Invalid character"); + } + + try { + atob("0x123, 0x456"); + } catch (e : any) { + expect(e.message).includes("Invalid character"); + } + + try { + atob("0x123 0x456"); + } catch (e : any) { + expect(e.message).includes("Invalid character"); + } + + try { + atob("'MHgxM jMsMHg0 NTYs MHg3ODk='"); + } catch (e : any) { + expect(e.message).includes("Invalid character"); + } + }); + + it("Throws if env variable is invalid", async () => { + try { + await getConfig({ + deployer: deployAdmin, + zeroVaultAddress: zeroVault.address, + governors: [deployAdmin.address, governor.address], + admins: [deployAdmin.address, admin.address], + }); + + /* eslint-disable @typescript-eslint/no-explicit-any */ + } catch (e : any) { + expect(e.message).includes(INVALID_ENV_ERR); + } + }); + + it("Fails to validate when mocking Z on prod", async () => { + process.env.MOCK_Z_TOKEN = "true"; + + try { + await getConfig({ + deployer: deployAdmin, + zeroVaultAddress: zeroVault.address, + governors: [deployAdmin.address, governor.address], + admins: [deployAdmin.address, admin.address], + }); + + /* eslint-disable @typescript-eslint/no-explicit-any */ + } catch (e : any) { + expect(e.message).includes(NO_MOCK_PROD_ERR); + } + }); + + it("Fails to validate if not using the Z token on prod", async () => { + process.env.MOCK_Z_TOKEN = "false"; + process.env.STAKING_TOKEN_ADDRESS = "0x123"; + + try { + await getConfig({ + deployer: deployAdmin, + zeroVaultAddress: zeroVault.address, + governors: [deployAdmin.address, governor.address], + admins: [deployAdmin.address, admin.address], + }); + /* eslint-disable @typescript-eslint/no-explicit-any */ + } catch (e : any) { + expect(e.message).includes(STAKING_TOKEN_ERR); + } + }); + + it("Fails to validate if no mongo uri or local URI in prod", async () => { + process.env.MOCK_Z_TOKEN = "false"; + process.env.STAKING_TOKEN_ADDRESS = ZSepolia.address; + // Falls back onto the default URI which is for localhost and fails in prod + process.env.MONGO_DB_URI = ""; + process.env.ROYALTY_RECEIVER = "0x123"; + process.env.ROYALTY_FRACTION = "100"; + + try { + await getConfig({ + env: "prod", + deployer: deployAdmin, + zeroVaultAddress: zeroVault.address, + governors: [deployAdmin.address, governor.address], + admins: [deployAdmin.address, admin.address], + }); + /* eslint-disable @typescript-eslint/no-explicit-any */ + } catch (e : any) { + expect(e.message).includes("Must provide a Mongo URI used for prod environment!"); + } + + process.env.MOCK_Z_TOKEN = "false"; + process.env.STAKING_TOKEN_ADDRESS = ZSepolia.address; + process.env.MONGO_DB_URI = "mongodb://localhost:27018"; + process.env.ZERO_VAULT_ADDRESS = "0x123"; + + try { + await getConfig({ + env: "prod", + deployer: deployAdmin, + zeroVaultAddress: zeroVault.address, + governors: [deployAdmin.address, governor.address], + admins: [deployAdmin.address, admin.address], + }); + /* eslint-disable @typescript-eslint/no-explicit-any */ + } catch (e : any) { + expect(e.message).includes(MONGO_URI_ERR); + } + }); + }); + + describe("Versioning", () => { + let campaign : DeployCampaign< + HardhatRuntimeEnvironment, + SignerWithAddress, + IZNSCampaignConfig, + IZNSContracts + >; + + before(async () => { + await saveTag(); + + campaignConfig = await getConfig( + { + deployer: deployAdmin, + governors: [deployAdmin.address, governor.address], + admins: [deployAdmin.address, admin.address], + zeroVaultAddress: zeroVault.address, + env, + } + ); + + campaignConfig.domainToken.defaultRoyaltyReceiver = deployAdmin.address; + // TODO dep: what do we pass here for test flow? we don't have a deployed ZToken contract + campaignConfig.stakingTokenAddress = ZSepolia.address; + campaignConfig.postDeploy.tenderlyProjectSlug = ""; + + campaign = await runZnsCampaign({ + config: campaignConfig, + }); + }); + + it("should get the correct git tag + commit hash and write to DB", async () => { + const latestGitTag = (await execAsync("git describe --tags --abbrev=0")).stdout.trim(); + const latestCommit = (await execAsync(`git rev-list -n 1 ${latestGitTag}`)).stdout.trim(); + + const fullGitTag = `${latestGitTag}:${latestCommit}`; + + const { dbAdapter } = campaign; + + const versionDoc = await dbAdapter.versioner.getLatestVersion(); + expect(versionDoc?.contractsVersion).to.equal(fullGitTag); + + const deployedVersion = await dbAdapter.versioner.getDeployedVersion(); + expect(deployedVersion?.contractsVersion).to.equal(fullGitTag); + }); + + // eslint-disable-next-line max-len + it("should create new DB version and KEEP old data if ARCHIVE is true and no TEMP versions currently exist", async () => { + const { dbAdapter } = campaign; + + const versionDocInitial = await dbAdapter.versioner.getLatestVersion(); + const initialDBVersion = versionDocInitial?.dbVersion; + const registryDocInitial = await dbAdapter.getContract(znsNames.registry.contract); + + expect( + process.env.MONGO_DB_VERSION === undefined + || process.env.MONGO_DB_VERSION === "" + ).to.be.true; + + // set archiving for the new mongo adapter + const initialArchiveVal = process.env.ARCHIVE_PREVIOUS_DB_VERSION; + process.env.ARCHIVE_PREVIOUS_DB_VERSION = "true"; + + // run a new campaign + const { dbAdapter: newDbAdapter } = await runZnsCampaign({ + config: campaignConfig, + }); + + expect(newDbAdapter.curVersion).to.not.equal(initialDBVersion); + + // get some data from new DB version + const registryDocNew = await newDbAdapter.getContract(znsNames.registry.contract); + expect(registryDocNew?.version).to.not.equal(registryDocInitial?.version); + + const versionDocNew = await newDbAdapter.versioner.getLatestVersion(); + expect(versionDocNew?.dbVersion).to.not.equal(initialDBVersion); + expect(versionDocNew?.type).to.equal(VERSION_TYPES.deployed); + + // make sure old contracts from previous DB version are still there + const oldRegistryDocFromNewDB = await newDbAdapter.getContract( + znsNames.registry.contract, + initialDBVersion + ); + + expect(oldRegistryDocFromNewDB?.version).to.equal(registryDocInitial?.version); + expect(oldRegistryDocFromNewDB?.address).to.equal(registryDocInitial?.address); + expect(oldRegistryDocFromNewDB?.name).to.equal(registryDocInitial?.name); + expect(oldRegistryDocFromNewDB?.abi).to.equal(registryDocInitial?.abi); + expect(oldRegistryDocFromNewDB?.bytecode).to.equal(registryDocInitial?.bytecode); + + // reset back to default + process.env.ARCHIVE_PREVIOUS_DB_VERSION = initialArchiveVal; + }); + + // eslint-disable-next-line max-len + it("should create new DB version and WIPE all existing data if ARCHIVE is false and no TEMP versions currently exist", async () => { + const { dbAdapter } = campaign; + + const versionDocInitial = await dbAdapter.versioner.getLatestVersion(); + const initialDBVersion = versionDocInitial?.dbVersion; + const registryDocInitial = await dbAdapter.getContract(znsNames.registry.contract); + + expect( + process.env.MONGO_DB_VERSION === undefined + || process.env.MONGO_DB_VERSION === "" + ).to.be.true; + + // set archiving for the new mongo adapter + const initialArchiveVal = process.env.ARCHIVE_PREVIOUS_DB_VERSION; + process.env.ARCHIVE_PREVIOUS_DB_VERSION = "false"; + + // run a new campaign + const { dbAdapter: newDbAdapter } = await runZnsCampaign({ + config: campaignConfig, + }); + + expect(newDbAdapter.curVersion).to.not.equal(initialDBVersion); + + // get some data from new DB version + const registryDocNew = await newDbAdapter.getContract(znsNames.registry.contract); + expect(registryDocNew?.version).to.not.equal(registryDocInitial?.version); + + const versionDocNew = await newDbAdapter.versioner.getLatestVersion(); + expect(versionDocNew?.dbVersion).to.not.equal(initialDBVersion); + expect(versionDocNew?.type).to.equal(VERSION_TYPES.deployed); + + // make sure old contracts from previous DB version are NOT there + const oldRegistryDocFromNewDB = await newDbAdapter.getContract( + znsNames.registry.contract, + initialDBVersion + ); + + expect(oldRegistryDocFromNewDB).to.be.null; + + // reset back to default + process.env.ARCHIVE_PREVIOUS_DB_VERSION = initialArchiveVal; + }); + + // eslint-disable-next-line max-len + it("should pick up existing contracts and NOT deploy new ones into state if MONGO_DB_VERSION is specified", async () => { + const { dbAdapter } = campaign; + + const versionDocInitial = await dbAdapter.versioner.getLatestVersion(); + const initialDBVersion = versionDocInitial?.dbVersion; + const registryDocInitial = await dbAdapter.getContract(znsNames.registry.contract); + + // set DB version for the new mongo adapter + const initialDBVersionVal = process.env.MONGO_DB_VERSION; + process.env.MONGO_DB_VERSION = initialDBVersion; + + // run a new campaign + const { state: { contracts: newContracts } } = await runZnsCampaign({ + config: campaignConfig, + }); + + // make sure we picked up the correct DB version + const versionDocNew = await dbAdapter.versioner.getLatestVersion(); + expect(versionDocNew?.dbVersion).to.equal(initialDBVersion); + + // make sure old contracts from previous DB version are still there + const oldRegistryDocFromNewDB = await dbAdapter.getContract( + znsNames.registry.contract, + initialDBVersion + ); + + expect(oldRegistryDocFromNewDB?.version).to.equal(registryDocInitial?.version); + expect(oldRegistryDocFromNewDB?.address).to.equal(registryDocInitial?.address); + expect(oldRegistryDocFromNewDB?.name).to.equal(registryDocInitial?.name); + expect(oldRegistryDocFromNewDB?.abi).to.equal(registryDocInitial?.abi); + expect(oldRegistryDocFromNewDB?.bytecode).to.equal(registryDocInitial?.bytecode); + + // make sure contracts in state have been picked up correctly from DB + expect(await newContracts.registry.getAddress()).to.equal(registryDocInitial?.address); + + // reset back to default + process.env.MONGO_DB_VERSION = initialDBVersionVal; + }); + }); + + describe("Verify - Monitor", () => { + let config : IZNSCampaignConfig; + + before (async () => { + [deployAdmin, admin, governor, zeroVault] = await hre.ethers.getSigners(); + + config = await getConfig( + { + deployer: deployAdmin, + governors: [deployAdmin.address, governor.address], + admins: [deployAdmin.address, admin.address], + zeroVaultAddress: zeroVault.address, + env, + } + ); + config.domainToken.defaultRoyaltyReceiver = deployAdmin.address; + config.stakingTokenAddress = ZSepolia.address; + config.postDeploy.tenderlyProjectSlug = ""; + config.postDeploy.verifyContracts = true; + }); + + afterEach(async () => { + await mongoAdapter.dropDB(); + }); + + it("should prepare the correct data for each contract when verifying on Etherscan", async () => { + const verifyData : Array<{ address : string; ctorArgs ?: TDeployArgs; }> = []; + class HardhatDeployerMock extends HardhatDeployer< + HardhatRuntimeEnvironment, + SignerWithAddress + > { + async etherscanVerify (args : { + address : string; + ctorArgs ?: TDeployArgs; + }) { + verifyData.push(args); + } + } + + const deployer = new HardhatDeployerMock({ + hre, + signer: deployAdmin, + env, + }); + + const campaign = await runZnsCampaign({ + config, + deployer, + }); + + const { state: { contracts } } = campaign; + ({ dbAdapter: mongoAdapter } = campaign); + + await Object.values(contracts).reduce( + async (acc, contract, idx) => { + await acc; + + if (idx === 0) { + expect(verifyData[idx].ctorArgs).to.be.deep.eq([config.governorAddresses, config.adminAddresses]); + } + + expect(verifyData[idx].address).to.equal(await contract.getAddress()); + }, + Promise.resolve() + ); + }); + + it("should prepare the correct contract data when pushing to Tenderly Project", async () => { + let tenderlyData : Array = []; + class HardhatDeployerMock extends HardhatDeployer< + HardhatRuntimeEnvironment, + SignerWithAddress + > { + async tenderlyPush (contracts : Array) { + tenderlyData = contracts; + } + } + + const deployer = new HardhatDeployerMock({ + hre, + signer: deployAdmin, + env, + }); + + config.postDeploy.monitorContracts = true; + config.postDeploy.verifyContracts = false; + + const campaign = await runZnsCampaign({ + config, + deployer, + }); + + const { state: { instances } } = campaign; + ({ dbAdapter: mongoAdapter } = campaign); + + let idx = 0; + await Object.values(instances).reduce( + async (acc, instance) => { + await acc; + + const dbData = await instance.getFromDB(); + + if (instance.proxyData.isProxy) { + // check proxy + expect(tenderlyData[idx].address).to.be.eq(dbData?.address); + expect(tenderlyData[idx].display_name).to.be.eq(`${instance.contractName}Proxy`); + + // check impl + expect(tenderlyData[idx + 1].address).to.be.eq(dbData?.implementation); + expect(tenderlyData[idx + 1].display_name).to.be.eq(`${dbData?.name}Impl`); + expect(tenderlyData[idx + 1].display_name).to.be.eq(`${instance.contractName}Impl`); + idx += 2; + } else { + expect(tenderlyData[idx].address).to.equal(dbData?.address); + expect(tenderlyData[idx].display_name).to.equal(dbData?.name); + expect(tenderlyData[idx].display_name).to.equal(instance.contractName); + idx++; + } + }, + Promise.resolve() + ); + }); + }); +}); diff --git a/test/ZNSAccessController.test.ts b/test/ZNSAccessController.test.ts index c2791c6d2..176eda7ed 100644 --- a/test/ZNSAccessController.test.ts +++ b/test/ZNSAccessController.test.ts @@ -1,13 +1,11 @@ import * as hre from "hardhat"; import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; import { ZNSAccessController } from "../typechain"; -import { deployAccessController } from "./helpers"; +import { AC_UNAUTHORIZED_ERR, deployAccessController, ZERO_ADDRESS_ERR } from "./helpers"; import { expect } from "chai"; -import { getAccessRevertMsg } from "./helpers/errors"; -import { ADMIN_ROLE, EXECUTOR_ROLE, GOVERNOR_ROLE, REGISTRAR_ROLE } from "../src/deploy/constants"; +import { ADMIN_ROLE, DOMAIN_TOKEN_ROLE, EXECUTOR_ROLE, GOVERNOR_ROLE, REGISTRAR_ROLE } from "../src/deploy/constants"; import { ethers } from "hardhat"; - describe("ZNSAccessController", () => { let deployer : SignerWithAddress; let accessController : ZNSAccessController; @@ -48,14 +46,14 @@ describe("ZNSAccessController", () => { ); }); - it("Should revert when passing 0x0 address to assing roles", async () => { + it("Should revert when passing 0x0 address to assign roles", async () => { await expect( deployAccessController({ deployer, governorAddresses: [ ethers.ZeroAddress ], adminAddresses: [ ethers.ZeroAddress ], }) - ).to.be.revertedWith("ZNSAccessController: Can't grant role to zero address"); + ).to.be.revertedWithCustomError(accessController, ZERO_ADDRESS_ERR); }); }); @@ -101,9 +99,8 @@ describe("ZNSAccessController", () => { const [ { address: newAdmin } ] = randomAccs; await expect( accessController.connect(admin).grantRole(ADMIN_ROLE, newAdmin) - ).to.be.revertedWith( - getAccessRevertMsg(admin.address, GOVERNOR_ROLE) - ); + ).to.be.revertedWithCustomError(accessController, AC_UNAUTHORIZED_ERR) + .withArgs(admin.address, GOVERNOR_ROLE); }); it("ADMIN_ROLE should NOT be able to revoke ADMIN_ROLE", async () => { @@ -111,9 +108,8 @@ describe("ZNSAccessController", () => { const [ { address: existingAdmin } ] = adminAccs; await expect( accessController.connect(admin).revokeRole(ADMIN_ROLE, existingAdmin) - ).to.be.revertedWith( - getAccessRevertMsg(admin.address, GOVERNOR_ROLE) - ); + ).to.be.revertedWithCustomError(accessController, AC_UNAUTHORIZED_ERR) + .withArgs(admin.address, GOVERNOR_ROLE); }); it("ADMIN_ROLE should NOT be able to grant GOVERNOR_ROLE", async () => { @@ -121,9 +117,8 @@ describe("ZNSAccessController", () => { const [ { address: newGovernor } ] = randomAccs; await expect( accessController.connect(admin).grantRole(GOVERNOR_ROLE, newGovernor) - ).to.be.revertedWith( - getAccessRevertMsg(admin.address, GOVERNOR_ROLE) - ); + ).to.be.revertedWithCustomError(accessController, AC_UNAUTHORIZED_ERR) + .withArgs(admin.address, GOVERNOR_ROLE); }); it("ADMIN_ROLE should NOT be able to revoke GOVERNOR_ROLE", async () => { @@ -131,9 +126,8 @@ describe("ZNSAccessController", () => { const [ { address: existingGovernor } ] = governorAccs; await expect( accessController.connect(admin).revokeRole(GOVERNOR_ROLE, existingGovernor) - ).to.be.revertedWith( - getAccessRevertMsg(admin.address, GOVERNOR_ROLE) - ); + ).to.be.revertedWithCustomError(accessController, AC_UNAUTHORIZED_ERR) + .withArgs(admin.address, GOVERNOR_ROLE); }); it("ADMIN_ROLE should be able to grant REGISTRAR_ROLE", async () => { @@ -144,6 +138,14 @@ describe("ZNSAccessController", () => { expect(has).to.be.true; }); + it("ADMIN_ROLE should be able to grant DOMAIN_TOKEN_ROLE", async () => { + const [ admin ] = adminAccs; + const [ { address: newDomainToken } ] = randomAccs; + await accessController.connect(admin).grantRole(DOMAIN_TOKEN_ROLE, newDomainToken); + const has = await accessController.hasRole(DOMAIN_TOKEN_ROLE, newDomainToken); + expect(has).to.be.true; + }); + it("ADMIN_ROLE should be able to revoke REGISTRAR_ROLE", async () => { const [ admin ] = adminAccs; const [ { address: newRegistrar } ] = randomAccs; @@ -154,6 +156,16 @@ describe("ZNSAccessController", () => { expect(has).to.be.false; }); + it("ADMIN_ROLE should be able to revoke DOMAIN_TOKEN_ROLE", async () => { + const [ admin ] = adminAccs; + const [ { address: newDomainToken } ] = randomAccs; + await accessController.connect(admin).grantRole(DOMAIN_TOKEN_ROLE, newDomainToken); + + await accessController.connect(admin).revokeRole(DOMAIN_TOKEN_ROLE, newDomainToken); + const has = await accessController.hasRole(DOMAIN_TOKEN_ROLE, newDomainToken); + expect(has).to.be.false; + }); + it("GOVERNOR_ROLE should be able to assign new EXECUTOR_ROLE as admin for REGISTRAR_ROLE", async () => { const [ governor ] = governorAccs; await accessController.connect(governor).setRoleAdmin(REGISTRAR_ROLE, EXECUTOR_ROLE); @@ -162,6 +174,13 @@ describe("ZNSAccessController", () => { expect(registrarAdminRole).to.be.equal(EXECUTOR_ROLE); }); + it("GOVERNOR_ROLE should be able to assign new EXECUTOR_ROLE as admin for DOMAIN_TOKEN_ROLE", async () => { + const [ governor ] = governorAccs; + await accessController.connect(governor).setRoleAdmin(DOMAIN_TOKEN_ROLE, EXECUTOR_ROLE); + + const domainTokenAdminRole = await accessController.getRoleAdmin(DOMAIN_TOKEN_ROLE); + expect(domainTokenAdminRole).to.be.equal(EXECUTOR_ROLE); + }); // eslint-disable-next-line max-len it("GOVERNOR_ROLE should be able to make himself a new EXECUTOR_ROLE's admin and assign this role to anyone", async () => { const [ governor ] = governorAccs; @@ -180,9 +199,8 @@ describe("ZNSAccessController", () => { const [ random ] = randomAccs; await expect( accessController.connect(random).setRoleAdmin(REGISTRAR_ROLE, EXECUTOR_ROLE) - ).to.be.revertedWith( - getAccessRevertMsg(random.address, GOVERNOR_ROLE) - ); + ).to.be.revertedWithCustomError(accessController, AC_UNAUTHORIZED_ERR) + .withArgs(random.address, GOVERNOR_ROLE); }); }); @@ -200,6 +218,13 @@ describe("ZNSAccessController", () => { expect(isRegistrar).to.be.true; }); + it("#isDomainToken() should return true for DOMAIN_TOKEN_ROLE", async () => { + const [ domainToken ] = randomAccs; + await accessController.connect(adminAccs[0]).grantRole(DOMAIN_TOKEN_ROLE, domainToken.address); + const isDomainToken = await accessController.isDomainToken(domainToken.address); + expect(isDomainToken).to.be.true; + }); + it("#isGovernor() should return true for GOVERNOR_ROLE", async () => { const [ governor ] = governorAccs; const isGovernor = await accessController.isGovernor(governor.address); @@ -218,36 +243,40 @@ describe("ZNSAccessController", () => { const [ random ] = randomAccs; await expect( accessController.connect(random).checkGovernor(random.address) - ).to.be.revertedWith( - getAccessRevertMsg(random.address, GOVERNOR_ROLE) - ); + ).to.be.revertedWithCustomError(accessController, AC_UNAUTHORIZED_ERR) + .withArgs(random.address, GOVERNOR_ROLE); }); it("Should revert if account does not have ADMIN_ROLE", async () => { const [ random ] = randomAccs; await expect( accessController.connect(random).checkAdmin(random.address) - ).to.be.revertedWith( - getAccessRevertMsg(random.address, ADMIN_ROLE) - ); + ).to.be.revertedWithCustomError(accessController, AC_UNAUTHORIZED_ERR) + .withArgs(random.address, ADMIN_ROLE); }); it("Should revert if account does not have REGISTRAR_ROLE", async () => { const [ random ] = randomAccs; await expect( accessController.connect(random).checkRegistrar(random.address) - ).to.be.revertedWith( - getAccessRevertMsg(random.address, REGISTRAR_ROLE) - ); + ).to.be.revertedWithCustomError(accessController, AC_UNAUTHORIZED_ERR) + .withArgs(random.address, REGISTRAR_ROLE); + }); + + it("Should revert if account does not have DOMAIN_TOKEN_ROLE", async () => { + const [ random ] = randomAccs; + await expect( + accessController.connect(random).checkDomainToken(random.address) + ).to.be.revertedWithCustomError(accessController, AC_UNAUTHORIZED_ERR) + .withArgs(random.address, DOMAIN_TOKEN_ROLE); }); it("Should revert if account does not have EXECUTOR_ROLE", async () => { const [ random ] = randomAccs; await expect( accessController.connect(random).checkExecutor(random.address) - ).to.be.revertedWith( - getAccessRevertMsg(random.address, EXECUTOR_ROLE) - ); + ).to.be.revertedWithCustomError(accessController, AC_UNAUTHORIZED_ERR) + .withArgs(random.address, EXECUTOR_ROLE); }); }); }); diff --git a/test/ZNSAddressResolver.test.ts b/test/ZNSAddressResolver.test.ts index 3b1342810..22893cb7c 100644 --- a/test/ZNSAddressResolver.test.ts +++ b/test/ZNSAddressResolver.test.ts @@ -14,14 +14,14 @@ import { GOVERNOR_ROLE, REGISTRAR_ROLE, deployZNS, - getAccessRevertMsg, - validateUpgrade, INITIALIZED_ERR, + validateUpgrade, INITIALIZED_ERR, AC_UNAUTHORIZED_ERR, NOT_AUTHORIZED_ERR, } from "./helpers"; import { getProxyImplAddress } from "./helpers/utils"; // eslint-disable-next-line @typescript-eslint/no-var-requires const { expect } = require("chai"); + describe("ZNSAddressResolver", () => { let deployer : SignerWithAddress; let mockRegistrar : SignerWithAddress; @@ -71,7 +71,7 @@ describe("ZNSAddressResolver", () => { operator.address, mockRegistrar.address, ) - ).to.be.revertedWith(INITIALIZED_ERR); + ).to.be.revertedWithCustomError(implContract, INITIALIZED_ERR); }); it("Should get the AddressResolver", async () => { // Copy of registry tests @@ -104,9 +104,8 @@ describe("ZNSAddressResolver", () => { it("Should revert when setRegistry() without ADMIN_ROLE", async () => { await expect( zns.addressResolver.connect(operator).setRegistry(operator.address) - ).to.be.revertedWith( - getAccessRevertMsg(operator.address, ADMIN_ROLE) - ); + ).to.be.revertedWithCustomError(zns.accessController, AC_UNAUTHORIZED_ERR) + .withArgs(operator.address, ADMIN_ROLE); }); it("Should setAccessController() correctly with ADMIN_ROLE", async () => { @@ -120,15 +119,14 @@ describe("ZNSAddressResolver", () => { it("Should revert when setAccessController() without ADMIN_ROLE", async () => { await expect( zns.addressResolver.connect(operator).setAccessController(operator.address) - ).to.be.revertedWith( - getAccessRevertMsg(operator.address, ADMIN_ROLE) - ); + ).to.be.revertedWithCustomError(zns.accessController, AC_UNAUTHORIZED_ERR) + .withArgs(operator.address, ADMIN_ROLE); }); it("Should not allow non-owner address to setAddress", async () => { await expect( zns.addressResolver.connect(user).setAddress(wilderDomainHash, user.address) - ).to.be.revertedWith("ZNSAddressResolver: Not authorized for this domain"); + ).to.be.revertedWithCustomError(zns.addressResolver, NOT_AUTHORIZED_ERR); }); it("Should allow owner to setAddress and emit event", async () => { @@ -218,7 +216,10 @@ describe("ZNSAddressResolver", () => { await zns.accessController.hasRole(GOVERNOR_ROLE, deployer.address) ).to.be.true; - const upgradeTx = zns.domainToken.connect(deployer).upgradeTo(await newAddressResolver.getAddress()); + const upgradeTx = zns.domainToken.connect(deployer).upgradeToAndCall( + await newAddressResolver.getAddress(), + "0x" + ); await expect(upgradeTx).to.not.be.reverted; }); @@ -233,15 +234,13 @@ describe("ZNSAddressResolver", () => { // Confirm the operator is not a governor await expect( zns.accessController.checkGovernor(operator.address) - ).to.be.revertedWith( - getAccessRevertMsg(operator.address, GOVERNOR_ROLE) - ); + ).to.be.revertedWithCustomError(zns.accessController, AC_UNAUTHORIZED_ERR) + .withArgs(operator.address, GOVERNOR_ROLE); - const upgradeTx = zns.domainToken.connect(operator).upgradeTo(await newAddressResolver.getAddress()); + const upgradeTx = zns.domainToken.connect(operator).upgradeToAndCall(await newAddressResolver.getAddress(), "0x"); - await expect(upgradeTx).to.be.revertedWith( - getAccessRevertMsg(operator.address, GOVERNOR_ROLE) - ); + await expect(upgradeTx).to.be.revertedWithCustomError(zns.accessController, AC_UNAUTHORIZED_ERR) + .withArgs(operator.address, GOVERNOR_ROLE); }); it("Verifies that variable values are not changed in the upgrade process", async () => { diff --git a/test/ZNSCurvePricer.test.ts b/test/ZNSCurvePricer.test.ts index 3b3d31c65..d9133d641 100644 --- a/test/ZNSCurvePricer.test.ts +++ b/test/ZNSCurvePricer.test.ts @@ -1,1018 +1,1020 @@ -import * as hre from "hardhat"; -import { expect } from "chai"; -import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; -import { ethers } from "ethers"; -import { - deployZNS, - getCurvePrice, - DEFAULT_PRECISION_MULTIPLIER, - CURVE_PRICE_CONFIG_ERR, - validateUpgrade, - PaymentType, - NOT_AUTHORIZED_REG_WIRED_ERR, - CURVE_NO_ZERO_PRECISION_MULTIPLIER_ERR, - INVALID_LENGTH_ERR, - INVALID_NAME_ERR, INITIALIZED_ERR, -} from "./helpers"; -import { - AccessType, - DEFAULT_DECIMALS, - DEFAULT_PRICE_CONFIG, - DEFAULT_PROTOCOL_FEE_PERCENT, -} from "./helpers/constants"; -import { - getAccessRevertMsg, -} from "./helpers/errors"; -import { ADMIN_ROLE, GOVERNOR_ROLE } from "../src/deploy/constants"; -import { ZNSCurvePricer, ZNSCurvePricerUpgradeMock__factory, ZNSCurvePricer__factory } from "../typechain"; -import { registrationWithSetup } from "./helpers/register-setup"; -import { getProxyImplAddress } from "./helpers/utils"; -import { IZNSContractsLocal } from "./helpers/types"; - -require("@nomicfoundation/hardhat-chai-matchers"); - -const { ZeroHash } = ethers; - - -describe("ZNSCurvePricer", () => { - let deployer : SignerWithAddress; - let user : SignerWithAddress; - let admin : SignerWithAddress; - let randomAcc : SignerWithAddress; - - let zns : IZNSContractsLocal; - let domainHash : string; - - const defaultDomain = "wilder"; - - beforeEach(async () => { - [ - deployer, - user, - admin, - randomAcc, - ] = await hre.ethers.getSigners(); - - zns = await deployZNS({ - deployer, - governorAddresses: [deployer.address], - adminAddresses: [admin.address], - }); - - await zns.meowToken.connect(user).approve(await zns.treasury.getAddress(), ethers.MaxUint256); - await zns.meowToken.mint(user.address, DEFAULT_PRICE_CONFIG.maxPrice); - - const fullConfig = { - distrConfig: { - paymentType: PaymentType.DIRECT, - pricerContract: await zns.curvePricer.getAddress(), - accessType: AccessType.OPEN, - }, - paymentConfig: { - token: await zns.meowToken.getAddress(), - beneficiary: user.address, - }, - priceConfig: DEFAULT_PRICE_CONFIG, - }; - - domainHash = await registrationWithSetup({ - zns, - user, - domainLabel: "testdomain", - fullConfig, - }); - }); - - it("Should NOT let initialize the implementation contract", async () => { - const factory = new ZNSCurvePricer__factory(deployer); - const impl = await getProxyImplAddress(await zns.curvePricer.getAddress()); - const implContract = factory.attach(impl) as ZNSCurvePricer; - - await expect( - implContract.initialize( - await zns.accessController.getAddress(), - await zns.registry.getAddress(), - DEFAULT_PRICE_CONFIG - ) - ).to.be.revertedWith(INITIALIZED_ERR); - }); - - it("Confirms values were initially set correctly", async () => { - const valueCalls = [ - zns.curvePricer.priceConfigs(domainHash), - ]; - - const [ - priceConfigFromSC, - ] = await Promise.all(valueCalls); - - const priceConfigArr = Object.values(DEFAULT_PRICE_CONFIG); - - priceConfigArr.forEach( - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - (val, idx) => expect(val).to.eq(priceConfigFromSC[idx]) - ); - - const regFromSC = await zns.curvePricer.registry(); - const acFromSC = await zns.curvePricer.getAccessController(); - - expect(regFromSC).to.eq(await zns.registry.getAddress()); - expect(acFromSC).to.eq(await zns.accessController.getAddress()); - }); - - describe("#getPrice", async () => { - it("Returns 0 price for a label with no length if label validation is skipped", async () => { - const { - price, - stakeFee, - } = await zns.curvePricer.getPriceAndFee(domainHash, "", true); - expect(price).to.eq(0); - expect(stakeFee).to.eq(0); - }); - - it("Reverts for a label with no length if label validation is not skipped", async () => { - await expect(zns.curvePricer.getPrice(domainHash, "", false)).to.be.revertedWith(INVALID_LENGTH_ERR); - }); - - it("Reverts for invalid label if label validation is not skipped", async () => { - await expect(zns.curvePricer.getPrice(domainHash, "wilder!", false)).to.be.revertedWith(INVALID_NAME_ERR); - }); - - it("Returns the base price for domains that are equal to the base length", async () => { - // Using the default length of 3 - const domain = "eth"; - const params = await zns.curvePricer.priceConfigs(domainHash); - - const domainPrice = await zns.curvePricer.getPrice(domainHash, domain, true); - expect(domainPrice).to.eq(params.maxPrice); - }); - - it("Returns the base price for domains that are less than the base length", async () => { - const domainA = "et"; - const domainB = "e"; - const params = await zns.curvePricer.priceConfigs(domainHash); - - let domainPrice = await zns.curvePricer.getPrice(domainHash, domainA, true); - expect(domainPrice).to.eq(params.maxPrice); - - (domainPrice = await zns.curvePricer.getPrice(domainHash, domainB, true)); - expect(domainPrice).to.eq(params.maxPrice); - }); - - it("Returns expected prices for a domain greater than the base length", async () => { - // create a constant string with 22 letters - const domainOne = "abcdefghijklmnopqrstuv"; - const domainTwo = "akkasddaasdas"; - - // these values have been calced separately to validate - // that both forumlas: SC + helper are correct - // this value has been calces with the default priceConfig - const domainOneRefValue = BigInt("4545450000000000000000"); - const domainTwoRefValue = BigInt("7692300000000000000000"); - - const domainOneExpPrice = await getCurvePrice(domainOne, DEFAULT_PRICE_CONFIG); - const domainTwoExpPrice = await getCurvePrice(domainTwo, DEFAULT_PRICE_CONFIG); - - const domainOnePriceSC = await zns.curvePricer.getPrice(domainHash, domainOne, true); - const domainTwoPriceSC = await zns.curvePricer.getPrice(domainHash, domainTwo, true); - - expect(domainOnePriceSC).to.eq(domainOneRefValue); - expect(domainOnePriceSC).to.eq(domainOneExpPrice); - - expect(domainTwoPriceSC).to.eq(domainTwoRefValue); - expect(domainTwoPriceSC).to.eq(domainTwoExpPrice); - }); - - it("Returns a price even if the domain name is very long", async () => { - // 255 length - const domain = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" + - "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" + - "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" + - "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" + - "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstu"; - - const expectedPrice = await getCurvePrice(domain, DEFAULT_PRICE_CONFIG); - const domainPrice = await zns.curvePricer.getPrice(domainHash, domain, true); - - expect(domainPrice).to.eq(expectedPrice); - }); - - it("Returns a price for multiple lengths", async () => { - // Any value less than base length is always base price, so we only check - // domains that are greater than base length + 1 - const short = "wild"; - const medium = "wilderworld"; - const long = "wilderworldbeastspetsnftscatscalicosteve"; - - const expectedShortPrice = await getCurvePrice(short, DEFAULT_PRICE_CONFIG); - const shortPrice = await zns.curvePricer.getPrice(domainHash, short, true); - expect(expectedShortPrice).to.eq(shortPrice); - - const expectedMediumPrice = await getCurvePrice(medium, DEFAULT_PRICE_CONFIG); - const mediumPrice = await zns.curvePricer.getPrice(domainHash, medium, true); - expect(expectedMediumPrice).to.eq(mediumPrice); - - const expectedLongPrice = await getCurvePrice(long, DEFAULT_PRICE_CONFIG); - const longPrice = await zns.curvePricer.getPrice(domainHash, long, true); - expect(expectedLongPrice).to.eq(longPrice); - }); - - it("Can Price Names Longer Than 255 Characters", async () => { - // 261 length - const domain = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" + - "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" + - "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" + - "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" + - "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" + - "a"; - const expectedPrice = getCurvePrice(domain, DEFAULT_PRICE_CONFIG); - const domainPrice = await zns.curvePricer.getPrice(domainHash, domain, true); - expect(domainPrice).to.eq(expectedPrice); - }); - - // eslint-disable-next-line max-len - it.skip("Doesn't create price spikes with any valid combination of values (SLOW TEST, ONLY RUN LOCALLY)", async () => { - // Start by expanding the search space to allow for domains that are up to 1000 characters - await zns.curvePricer.connect(user).setMaxLength(domainHash, BigInt("1000")); - - const promises = []; - let config = await zns.curvePricer.priceConfigs(domainHash); - let domain = "a"; - - // baseLength = 0 is a special case - await zns.curvePricer.connect(user).setBaseLength(domainHash, 0); - const domainPrice = await zns.curvePricer.getPrice(domainHash, domain, true); - expect(domainPrice).to.eq(config.maxPrice); - - let outer = 1; - let inner = outer; - // Long-running loops here to iterate all the variations for baseLength and - while (config.maxLength > outer) { - // Reset "domain" to a single character each outer loop - domain = "a"; - - await zns.curvePricer.connect(user).setBaseLength(domainHash, outer); - config = await zns.curvePricer.priceConfigs(domainHash); - - while (config.maxLength > inner) { - const priceTx = zns.curvePricer.getPrice(domainHash, domain, true); - promises.push(priceTx); - - domain += "a"; - inner++; - } - outer++; - } - - const prices = await Promise.all(promises); - let k = 0; - while (k < prices.length) { - expect(prices[k]).to.be.lte(config.maxPrice); - k++; - } - }); - }); - - describe("#setPriceConfig", () => { - it("Can't price a name that has invalid characters", async () => { - // Valid names must match the pattern [a-z0-9] - const labelA = "WILDER"; - const labelB = "!?w1Id3r!?"; - const labelC = "!%$#^*?!#👍3^29"; - const labelD = "wo.rld"; - - await expect(zns.curvePricer.getPrice(domainHash, labelA, false)).to.be.revertedWith(INVALID_NAME_ERR); - await expect(zns.curvePricer.getPrice(domainHash, labelB, false)).to.be.revertedWith(INVALID_NAME_ERR); - await expect(zns.curvePricer.getPrice(domainHash, labelC, false)).to.be.revertedWith(INVALID_NAME_ERR); - await expect(zns.curvePricer.getPrice(domainHash, labelD, false)).to.be.revertedWith(INVALID_NAME_ERR); - }); - - it("Should set the config for any existing domain hash, including 0x0", async () => { - const newConfig = { - baseLength: BigInt("6"), - maxLength: BigInt("35"), - maxPrice: ethers.parseEther("150"), - minPrice: ethers.parseEther("10"), - precisionMultiplier: DEFAULT_PRECISION_MULTIPLIER, - feePercentage: DEFAULT_PROTOCOL_FEE_PERCENT, - isSet: true, - }; - - // as a user of "domainHash" that's not 0x0 - await zns.curvePricer.connect(user).setPriceConfig(domainHash, newConfig); - - // as a ZNS deployer who owns the 0x0 hash - await zns.curvePricer.connect(deployer).setPriceConfig(ZeroHash, newConfig); - - const configUser = await zns.curvePricer.priceConfigs(domainHash); - - expect(configUser.baseLength).to.eq(newConfig.baseLength); - expect(configUser.maxLength).to.eq(newConfig.maxLength); - expect(configUser.maxPrice).to.eq(newConfig.maxPrice); - expect(configUser.minPrice).to.eq(newConfig.minPrice); - expect(configUser.precisionMultiplier).to.eq(newConfig.precisionMultiplier); - expect(configUser.feePercentage).to.eq(newConfig.feePercentage); - - const configDeployer = await zns.curvePricer.priceConfigs(ZeroHash); - - expect(configDeployer.baseLength).to.eq(newConfig.baseLength); - expect(configDeployer.maxLength).to.eq(newConfig.maxLength); - expect(configDeployer.maxPrice).to.eq(newConfig.maxPrice); - expect(configDeployer.minPrice).to.eq(newConfig.minPrice); - expect(configDeployer.precisionMultiplier).to.eq(newConfig.precisionMultiplier); - expect(configDeployer.feePercentage).to.eq(newConfig.feePercentage); - }); - - it("Should revert if setting a price config where spike is created at maxLength", async () => { - const newConfig = { - baseLength: BigInt("6"), - maxLength: BigInt("20"), - maxPrice: ethers.parseEther("10"), - minPrice: ethers.parseEther("6"), - precisionMultiplier: DEFAULT_PRECISION_MULTIPLIER, - feePercentage: DEFAULT_PROTOCOL_FEE_PERCENT, - isSet: true, - }; - - await expect( - zns.curvePricer.connect(user).setPriceConfig(domainHash, newConfig) - ).to.be.revertedWith(CURVE_PRICE_CONFIG_ERR); - }); - - it("Cannot go below the set minPrice", async () => { - // Using config numbers from audit - const newConfig = { - baseLength: BigInt("5"), - maxLength: BigInt("10"), - maxPrice: ethers.parseEther("10"), - minPrice: ethers.parseEther("5.5"), - precisionMultiplier: DEFAULT_PRECISION_MULTIPLIER, - feePercentage: DEFAULT_PROTOCOL_FEE_PERCENT, - isSet: true, - }; - - await expect( - zns.curvePricer.connect(user).setPriceConfig(domainHash, newConfig) - ).to.be.revertedWith(CURVE_PRICE_CONFIG_ERR); - }); - - it("Should revert if called by anyone other than owner or operator", async () => { - const newConfig = { - baseLength: BigInt("6"), - maxLength: BigInt("20"), - maxPrice: ethers.parseEther("10"), - minPrice: ethers.parseEther("6"), - precisionMultiplier: DEFAULT_PRECISION_MULTIPLIER, - feePercentage: DEFAULT_PROTOCOL_FEE_PERCENT, - isSet: true, - }; - - await expect( - zns.curvePricer.connect(randomAcc).setPriceConfig(domainHash, newConfig) - ).to.be.revertedWith(NOT_AUTHORIZED_REG_WIRED_ERR); - - await expect( - zns.curvePricer.connect(randomAcc).setPriceConfig(ZeroHash, newConfig) - ).to.be.revertedWith(NOT_AUTHORIZED_REG_WIRED_ERR); - }); - - it("Should emit PriceConfigSet event with correct parameters", async () => { - const newConfig = { - baseLength: BigInt("6"), - maxLength: BigInt("35"), - maxPrice: ethers.parseEther("150"), - minPrice: ethers.parseEther("10"), - precisionMultiplier: DEFAULT_PRECISION_MULTIPLIER, - feePercentage: DEFAULT_PROTOCOL_FEE_PERCENT, - isSet: true, - }; - - const tx = zns.curvePricer.connect(user).setPriceConfig(domainHash, newConfig); - - await expect(tx).to.emit(zns.curvePricer, "PriceConfigSet").withArgs( - domainHash, - newConfig.maxPrice, - newConfig.minPrice, - newConfig.maxLength, - newConfig.baseLength, - newConfig.precisionMultiplier, - newConfig.feePercentage, - ); - }); - - it("Fails validation when maxPrice < minPrice", async () => { - const newConfig = { - baseLength: BigInt("3"), - maxLength: BigInt("35"), - maxPrice: ethers.parseEther("1"), - minPrice: ethers.parseEther("2"), - precisionMultiplier: DEFAULT_PRECISION_MULTIPLIER, - feePercentage: DEFAULT_PROTOCOL_FEE_PERCENT, - isSet: true, - }; - - const tx = zns.curvePricer.connect(user).setPriceConfig(domainHash, newConfig); - - await expect(tx).to.be.revertedWith(CURVE_PRICE_CONFIG_ERR); - }); - }); - - describe("#setMaxPrice", () => { - it("Allows an authorized user to set the max price", async () => { - const newMaxPrice = DEFAULT_PRICE_CONFIG.maxPrice + ethers.parseEther("10"); - - await zns.curvePricer.connect(user).setMaxPrice(domainHash, newMaxPrice); - - const params = await zns.curvePricer.priceConfigs(domainHash); - expect(params.maxPrice).to.eq(newMaxPrice); - }); - - it("Disallows an unauthorized user to set the max price", async () => { - const newMaxPrice = ethers.parseEther("0.7"); - - const tx = zns.curvePricer.connect(admin).setMaxPrice(domainHash, newMaxPrice); - await expect(tx).to.be.revertedWith(NOT_AUTHORIZED_REG_WIRED_ERR); - }); - - it("Allows setting the max price to zero", async () => { - const newMaxPrice = BigInt("0"); - - await zns.curvePricer.connect(user).setMaxPrice(domainHash, newMaxPrice); - const params = await zns.curvePricer.priceConfigs(domainHash); - - expect(params.maxPrice).to.eq(newMaxPrice); - }); - - it("Correctly sets max price", async () => { - const newMaxPrice = DEFAULT_PRICE_CONFIG.maxPrice + ethers.parseEther("553"); - await zns.curvePricer.connect(user).setMaxPrice(domainHash, newMaxPrice); - - const params = await zns.curvePricer.priceConfigs(domainHash); - expect(params.maxPrice).to.eq(newMaxPrice); - }); - - it("Should revert when setting maxPrice that causes a spike at maxLength", async () => { - const newMaxPrice = ethers.parseEther("500"); - await expect( - zns.curvePricer.connect(user).setMaxPrice(domainHash, newMaxPrice) - ).to.be.revertedWith(CURVE_PRICE_CONFIG_ERR); - }); - - it("Causes any length domain to have a price of 0 if the maxPrice is 0", async () => { - const newMaxPrice = BigInt("0"); - - await zns.curvePricer.connect(user).setMaxPrice(domainHash, newMaxPrice); - - const shortDomain = "a"; - const longDomain = "abcdefghijklmnopqrstuvwxyz"; - - const shortPrice = await zns.curvePricer.getPrice(domainHash, shortDomain, true); - const longPrice = await zns.curvePricer.getPrice(domainHash, longDomain, true); - - expect(shortPrice).to.eq(BigInt("0")); - expect(longPrice).to.eq(BigInt("0")); - }); - - it("The price of a domain is modified relatively when the basePrice is changed", async () => { - const newMaxPrice = DEFAULT_PRICE_CONFIG.maxPrice + ethers.parseEther("9"); - - const expectedPriceBefore = await getCurvePrice(defaultDomain, DEFAULT_PRICE_CONFIG); - const priceBefore= await zns.curvePricer.getPrice(domainHash, defaultDomain, true); - - expect(expectedPriceBefore).to.eq(priceBefore); - - await zns.curvePricer.connect(user).setMaxPrice(domainHash, newMaxPrice); - - const newConfig = { - ...DEFAULT_PRICE_CONFIG, - maxPrice: newMaxPrice, - }; - - const expectedPriceAfter = await getCurvePrice(defaultDomain, newConfig); - const priceAfter = await zns.curvePricer.getPrice(domainHash, defaultDomain, true); - - expect(expectedPriceAfter).to.eq(priceAfter); - expect(expectedPriceAfter).to.be.gt(expectedPriceBefore); - expect(priceAfter).to.be.gt(priceBefore); - }); - }); - - describe("#setMinPrice", async () => { - it("Allows an authorized user to set the min price", async () => { - const newMinPrice = ethers.parseEther("0.1"); - - await zns.curvePricer.connect(user).setMinPrice(domainHash, newMinPrice); - - const params = await zns.curvePricer.priceConfigs(domainHash); - expect(params.minPrice).to.eq(newMinPrice); - }); - - it("Disallows an unauthorized user from setting the min price", async () => { - const newMinPrice = ethers.parseEther("0.1"); - - const tx = zns.curvePricer.connect(admin).setMinPrice(domainHash, newMinPrice); - await expect(tx).to.be.revertedWith(NOT_AUTHORIZED_REG_WIRED_ERR); - }); - - it("Allows setting to zero", async () => { - const zeroPrice = BigInt("0"); - - await zns.curvePricer.connect(user).setMinPrice(domainHash, zeroPrice); - const params = await zns.curvePricer.priceConfigs(domainHash); - - expect(params.minPrice).to.eq(zeroPrice); - }); - - it("Successfully sets the min price correctly", async () => { - const newMinPrice = ethers.parseEther("0.1"); - await zns.curvePricer.connect(user).setMinPrice(domainHash, newMinPrice); - - const params = await zns.curvePricer.priceConfigs(domainHash); - expect(params.minPrice).to.eq(newMinPrice); - }); - - it("Causes any domain beyond the `maxLength` to always return `minPrice`", async () => { - // All domains longer than 15 characters are the same price - await zns.curvePricer.connect(user).setMaxLength(domainHash, "15"); - - const minPrice = ethers.parseEther("50"); - await zns.curvePricer.connect(user).setMinPrice(domainHash, minPrice); - - // 16 characters - const short = "abcdefghijklmnop"; - // 30 characters - const medium = "abcdefghijklmnoabcdefghijklmno"; - // 60 characters - const long = "abcdefghijklmnoabcdefghijklmnoabcdefghijklmnoabcdefghijklmno"; - - const priceCalls = [ - zns.curvePricer.getPrice(domainHash, short, true), - zns.curvePricer.getPrice(domainHash, medium, true), - zns.curvePricer.getPrice(domainHash, long, true), - ]; - - const [ - shortPrice, - mediumPrice, - longPrice, - ] = await Promise.all(priceCalls); - - expect(shortPrice).to.eq(minPrice); - expect(mediumPrice).to.eq(minPrice); - expect(longPrice).to.eq(minPrice); - }); - - it("Should revert when setting minPrice that causes a spike at maxLength", async () => { - const newMinPrice = DEFAULT_PRICE_CONFIG.minPrice + ethers.parseEther("231"); - await expect( - zns.curvePricer.connect(user).setMinPrice(domainHash, newMinPrice) - ).to.be.revertedWith(CURVE_PRICE_CONFIG_ERR); - }); - }); - - describe("#setPrecisionMultiplier", () => { - it("Allows an authorized user to set the precision multiplier", async () => { - const newMultiplier = BigInt("1"); - - await zns.curvePricer.connect(user).setPrecisionMultiplier(domainHash, newMultiplier); - - const params = await zns.curvePricer.priceConfigs(domainHash); - expect(params.precisionMultiplier).to.eq(newMultiplier); - }); - - it("Disallows an unauthorized user from setting the precision multiplier", async () => { - const newMultiplier = BigInt("1"); - - - const tx = zns.curvePricer.connect(admin).setMinPrice(domainHash, newMultiplier); - await expect(tx).to.be.revertedWith(NOT_AUTHORIZED_REG_WIRED_ERR); - }); - - it("Fails when setting to zero", async () => { - const zeroMultiplier = BigInt("0"); - - const tx = zns.curvePricer.connect(user).setPrecisionMultiplier(domainHash, zeroMultiplier); - await expect(tx).to.be.revertedWith(CURVE_NO_ZERO_PRECISION_MULTIPLIER_ERR); - }); - - it("Successfuly sets the precision multiplier when above 0", async () => { - const newMultiplier = BigInt("3"); - await zns.curvePricer.connect(user).setPrecisionMultiplier(domainHash, newMultiplier); - - const params = await zns.curvePricer.priceConfigs(domainHash); - expect(params.precisionMultiplier).to.eq(newMultiplier); - }); - - it("Verifies new prices are affected after changing the precision multiplier", async () => { - const atIndex = 7; - - const before = await zns.curvePricer.getPrice(domainHash, defaultDomain, true); - const beforePriceString = before.toString(); - - expect(beforePriceString.charAt(atIndex)).to.eq("0"); - - // Default precision is 2 decimals, so increasing this value should represent in prices - // as a non-zero nect decimal place - const newPrecision = BigInt(3); - const newPrecisionMultiplier = BigInt(10) ** DEFAULT_DECIMALS - newPrecision; - - await zns.curvePricer.connect(user).setPrecisionMultiplier(domainHash, newPrecisionMultiplier); - - const after = await zns.curvePricer.getPrice(domainHash, defaultDomain, true); - const afterPriceString = after.toString(); - - expect(afterPriceString.charAt(atIndex)).to.not.eq("0"); - - }); - - it("Should revert when setting precisionMultiplier higher than 10^18", async () => { - const newMultiplier = ethers.parseEther("100"); - await expect( - zns.curvePricer.connect(user).setPrecisionMultiplier(domainHash, newMultiplier) - ).to.be.revertedWith( - "ZNSCurvePricer: precisionMultiplier cannot be greater than 10^18" - ); - }); - }); - - describe("#setBaseLength", () => { - it("Allows an authorized user to set the base length", async () => { - const newLength = 5; - - await zns.curvePricer.connect(user).setBaseLength(domainHash, newLength); - const params = await zns.curvePricer.priceConfigs(domainHash); - - expect(params.baseLength).to.eq(newLength); - }); - - it("Disallows an unauthorized user to set the base length", async () => { - const newLength = 5; - - const tx = zns.curvePricer.connect(admin).setBaseLength(domainHash, newLength); - await expect(tx).to.be.revertedWith(NOT_AUTHORIZED_REG_WIRED_ERR); - }); - - it("Allows setting the base length to zero", async () => { - const newLength = 0; - - await zns.curvePricer.connect(user).setBaseLength(domainHash, newLength); - const params = await zns.curvePricer.priceConfigs(domainHash); - - expect(params.baseLength).to.eq(newLength); - }); - - it("Always returns the minPrice if both baseLength and maxLength are their min values", async () => { - const newConfig = { - baseLength: BigInt(1), - maxLength: BigInt(1), - maxPrice: BigInt(100), - minPrice: BigInt(10), - precisionMultiplier: DEFAULT_PRECISION_MULTIPLIER, - feePercentage: DEFAULT_PROTOCOL_FEE_PERCENT, - isSet: true, - }; - - // We use `baseLength == 0` to indicate a special event like a promo or discount and always - // return `maxPrice` which can be set to whatever we need at the time. - await zns.curvePricer.connect(user).setPriceConfig(domainHash, newConfig); - - const short = "abc"; - const medium = "abcdefghijklmnop"; - const long = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"; - - const priceCalls = [ - zns.curvePricer.getPrice(domainHash, short, true), - zns.curvePricer.getPrice(domainHash, medium, true), - zns.curvePricer.getPrice(domainHash, long, true), - ]; - - const [shortPrice, mediumPrice, longPrice] = await Promise.all(priceCalls); - - expect(shortPrice).to.eq(newConfig.minPrice); - expect(mediumPrice).to.eq(newConfig.minPrice); - expect(longPrice).to.eq(newConfig.minPrice); - }); - - it("Causes any length domain to cost the base fee when set to max length of 255", async () => { - const newLength = 255; - await zns.curvePricer.connect(user).setBaseLength(domainHash, newLength); - const params = await zns.curvePricer.priceConfigs(domainHash); - - const shortDomain = "a"; - const longDomain = "abcdefghijklmnopqrstuvwxyz"; - - const shortPrice = await zns.curvePricer.getPrice(domainHash, shortDomain, true); - const longPrice = await zns.curvePricer.getPrice(domainHash, longDomain, true); - - expect(shortPrice).to.eq(params.maxPrice); - expect(longPrice).to.eq(params.maxPrice); - }); - - it("Causes prices to adjust correctly when length is increased", async () => { - const newLength = 8; - const paramsBefore = await zns.curvePricer.priceConfigs(domainHash); - - const expectedPriceBefore = await getCurvePrice(defaultDomain, DEFAULT_PRICE_CONFIG); - const priceBefore = await zns.curvePricer.getPrice(domainHash, defaultDomain, true); - expect(priceBefore).to.eq(expectedPriceBefore); - expect(priceBefore).to.not.eq(paramsBefore.maxPrice); - - await zns.curvePricer.connect(user).setBaseLength(domainHash, newLength); - - const paramsAfter = await zns.curvePricer.priceConfigs(domainHash); - - const newConfig = { - ...DEFAULT_PRICE_CONFIG, - baseLength: BigInt(newLength), - }; - - const expectedPriceAfter = await getCurvePrice(defaultDomain, newConfig); - const priceAfter = await zns.curvePricer.getPrice(domainHash, defaultDomain, true); - expect(priceAfter).to.eq(expectedPriceAfter); - expect(priceAfter).to.eq(paramsAfter.maxPrice); - }); - - it("Causes prices to adjust correctly when length is decreased", async () => { - const length = 8; - await zns.curvePricer.connect(user).setBaseLength(domainHash, length); - - const newConfig1 = { - ...DEFAULT_PRICE_CONFIG, - baseLength: BigInt(length), - }; - - const paramsBefore = await zns.curvePricer.priceConfigs(domainHash); - - const expectedPriceBefore = await getCurvePrice(defaultDomain, newConfig1); - const priceBefore = await zns.curvePricer.getPrice(domainHash, defaultDomain, true); - expect(priceBefore).to.eq(expectedPriceBefore); - expect(priceBefore).to.eq(paramsBefore.maxPrice); - - const newLength = 5; - await zns.curvePricer.connect(user).setBaseLength(domainHash, newLength); - - const newConfig2 = { - ...DEFAULT_PRICE_CONFIG, - baseLength: BigInt(newLength), - }; - - const paramsAfter = await zns.curvePricer.priceConfigs(domainHash); - - const expectedPriceAfter = await getCurvePrice(defaultDomain, newConfig2); - const priceAfter = await zns.curvePricer.getPrice(domainHash, defaultDomain, true); - expect(priceAfter).to.eq(expectedPriceAfter); - expect(priceAfter).to.not.eq(paramsAfter.maxPrice); - }); - - it("Returns the maxPrice whenever the baseLength is 0", async () => { - const newRootLength = 0; - await zns.curvePricer.connect(user).setBaseLength(domainHash, newRootLength); - - let config = await zns.curvePricer.priceConfigs(domainHash); - let price = await zns.curvePricer.getPrice(domainHash, defaultDomain, true); - - expect(config.maxPrice).to.eq(price); - - // Modify the max price - await zns.curvePricer.connect(user).setMaxPrice( - domainHash, - DEFAULT_PRICE_CONFIG.maxPrice + 15n - ); - - config = await zns.curvePricer.priceConfigs(domainHash); - price = await zns.curvePricer.getPrice(domainHash, defaultDomain, true); - - expect(config.maxPrice).to.eq(price); - }); - - it("Adjusts prices correctly when setting base lengths to different values", async () => { - const newRootLength = 0; - await zns.curvePricer.connect(user).setBaseLength(domainHash, newRootLength); - const newConfig = { - ...DEFAULT_PRICE_CONFIG, - baseLength: BigInt(newRootLength), - }; - - const expectedRootPrice = await getCurvePrice(defaultDomain, newConfig); - const rootPrice = await zns.curvePricer.getPrice(domainHash, defaultDomain, true); - - expect(rootPrice).to.eq(expectedRootPrice); - }); - - it("Should revert when setting baseLength that causes a spike at maxLength", async () => { - const newBaseLength = DEFAULT_PRICE_CONFIG.baseLength - 1n; - await expect( - zns.curvePricer.connect(user).setBaseLength(domainHash, newBaseLength) - ).to.be.revertedWith(CURVE_PRICE_CONFIG_ERR); - }); - }); - - describe("#setMaxLength", () => { - it("Allows an authorized user to set the max length", async () => { - const newLength = 5; - - await zns.curvePricer.connect(user).setMaxLength(domainHash, newLength); - const params = await zns.curvePricer.priceConfigs(domainHash); - - expect(params.maxLength).to.eq(newLength); - }); - - it("Disallows an unauthorized user to set the max length", async () => { - const newLength = 5; - - const tx = zns.curvePricer.connect(admin).setMaxLength(domainHash, newLength); - await expect(tx).to.be.revertedWith(NOT_AUTHORIZED_REG_WIRED_ERR); - }); - - it("Allows setting the max length to zero", async () => { - const newLength = 0; - - await zns.curvePricer.connect(user).setMaxLength(domainHash, newLength); - const params = await zns.curvePricer.priceConfigs(domainHash); - - expect(params.maxLength).to.eq(newLength); - }); - - it("Still returns prices for domains within baseLength if the maxLength is zero", async () => { - const newLength = 0; - - await zns.curvePricer.connect(user).setMaxLength(domainHash, newLength); - - // Default price config sets baseLength to 4 - const short = "a"; - const long = "abcd"; - const beyondBaseLength = "abcde"; - - const priceCalls = [ - zns.curvePricer.getPrice(domainHash, short, true), - zns.curvePricer.getPrice(domainHash, long, true), - zns.curvePricer.getPrice(domainHash, beyondBaseLength, true), - ]; - - const [shortPrice, longPrice, beyondPrice] = await Promise.all(priceCalls); - - expect(shortPrice).to.eq(DEFAULT_PRICE_CONFIG.maxPrice); - expect(longPrice).to.eq(DEFAULT_PRICE_CONFIG.maxPrice); - expect(beyondPrice).to.eq(DEFAULT_PRICE_CONFIG.minPrice); - }); - - it("Should revert when setting maxLength that causes a spike at maxLength", async () => { - const newMaxLength = DEFAULT_PRICE_CONFIG.maxLength + 10n; - await expect( - zns.curvePricer.connect(user).setMaxLength(domainHash, newMaxLength) - ).to.be.revertedWith(CURVE_PRICE_CONFIG_ERR); - }); - }); - - describe("#setFeePercentage", () => { - it("Successfully sets the fee percentage", async () => { - const newFeePerc = BigInt(222); - await zns.curvePricer.connect(user).setFeePercentage(domainHash, newFeePerc); - const { feePercentage: feeFromSC } = await zns.curvePricer.priceConfigs(domainHash); - - expect(feeFromSC).to.eq(newFeePerc); - }); - - it("Disallows an unauthorized user to set the fee percentage", async () => { - const newFeePerc = BigInt(222); - const tx = zns.curvePricer.connect(admin) - .setFeePercentage(domainHash, newFeePerc); - await expect(tx).to.be.revertedWith(NOT_AUTHORIZED_REG_WIRED_ERR); - }); - - it("should revert when trying to set feePercentage higher than PERCENTAGE_BASIS", async () => { - const newFeePerc = BigInt(10001); - await expect( - zns.curvePricer.connect(user).setFeePercentage(domainHash, newFeePerc) - ).to.be.revertedWith("ZNSCurvePricer: feePercentage cannot be greater than PERCENTAGE_BASIS"); - }); - }); - - describe("#getRegistrationFee", () => { - it("Successfully gets the fee for a price", async () => { - const stake = ethers.parseEther("0.2"); - const fee = await zns.curvePricer.getFeeForPrice(domainHash, stake); - const expectedFee = stake * 222n / 10000n; - - expect(fee).to.eq(expectedFee); - }); - }); - - describe("#setAccessController", () => { - it("Successfully sets the access controller", async () => { - const currentAccessController = await zns.curvePricer.getAccessController(); - expect(currentAccessController).to.not.eq(randomAcc.address); - - const tx = await zns.curvePricer.setAccessController(randomAcc.address); - - const newAccessController = await zns.curvePricer.getAccessController(); - expect(newAccessController).to.eq(randomAcc.address); - - await expect(tx).to.emit(zns.curvePricer, "AccessControllerSet").withArgs(randomAcc.address); - }); - - it("Disallows an unauthorized user to set the access controller", async () => { - const tx = zns.curvePricer.connect(user).setAccessController(randomAcc.address); - await expect(tx).to.be.revertedWith( - getAccessRevertMsg(user.address, ADMIN_ROLE) - ); - }); - - it("Disallows setting the access controller to the zero address", async () => { - const tx = zns.curvePricer.connect(admin).setAccessController(ethers.ZeroAddress); - await expect(tx).to.be.revertedWith( - "AC: _accessController is 0x0 address" - ); - }); - }); - - describe("#setRegistry", () => { - it("Should successfully set the registry", async () => { - const currentRegistry = await zns.curvePricer.registry(); - expect(currentRegistry).to.not.eq(randomAcc.address); - - const tx = await zns.curvePricer.connect(admin).setRegistry(randomAcc.address); - - const newRegistry = await zns.curvePricer.registry(); - expect(newRegistry).to.eq(randomAcc.address); - - await expect(tx).to.emit(zns.curvePricer, "RegistrySet").withArgs(randomAcc.address); - }); - - it("Should NOT set the registry if called by anyone other than ADMIN_ROLE", async () => { - const tx = zns.curvePricer.connect(user).setRegistry(randomAcc.address); - await expect(tx).to.be.revertedWith( - getAccessRevertMsg(user.address, ADMIN_ROLE) - ); - }); - }); - - describe("Events", () => { - it("Emits MaxPriceSet", async () => { - const newMaxPrice = DEFAULT_PRICE_CONFIG.maxPrice + 1n; - - const tx = zns.curvePricer.connect(user).setMaxPrice(domainHash, newMaxPrice); - await expect(tx).to.emit(zns.curvePricer, "MaxPriceSet").withArgs(domainHash, newMaxPrice); - }); - - it("Emits BaseLengthSet", async () => { - const newLength = 5; - - const tx = zns.curvePricer.connect(user).setBaseLength(domainHash, newLength); - await expect(tx).to.emit(zns.curvePricer, "BaseLengthSet").withArgs(domainHash, newLength); - }); - }); - - describe("UUPS", () => { - it("Allows an authorized user to upgrade the contract", async () => { - // CurvePricer to upgrade to - const factory = new ZNSCurvePricer__factory(deployer); - const newCurvePricer = await factory.deploy(); - await newCurvePricer.waitForDeployment(); - - // Confirm the deployer is a governor, as set in `deployZNS` helper - await expect(zns.accessController.checkGovernor(deployer.address)).to.not.be.reverted; - - const tx = zns.curvePricer.connect(deployer).upgradeTo(await newCurvePricer.getAddress()); - await expect(tx).to.not.be.reverted; - }); - - it("Fails to upgrade if the caller is not authorized", async () => { - // CurvePricer to upgrade to - const factory = new ZNSCurvePricerUpgradeMock__factory(deployer); - const newCurvePricer = await factory.deploy(); - await newCurvePricer.waitForDeployment(); - - // Confirm the account is not a governor - await expect(zns.accessController.checkGovernor(randomAcc.address)).to.be.reverted; - - const tx = zns.curvePricer.connect(randomAcc).upgradeTo(await newCurvePricer.getAddress()); - - await expect(tx).to.be.revertedWith( - getAccessRevertMsg(randomAcc.address, GOVERNOR_ROLE) - ); - }); - - it("Verifies that variable values are not changed in the upgrade process", async () => { - const factory = new ZNSCurvePricerUpgradeMock__factory(deployer); - const newCurvePricer = await factory.deploy(); - await newCurvePricer.waitForDeployment(); - - await zns.curvePricer.connect(user).setBaseLength(domainHash, "7"); - await zns.curvePricer.connect(user).setMaxPrice( - domainHash, - DEFAULT_PRICE_CONFIG.maxPrice + 15n - ); - - const contractCalls = [ - zns.curvePricer.registry(), - zns.curvePricer.getAccessController(), - zns.curvePricer.priceConfigs(domainHash), - zns.curvePricer.getPrice(domainHash, "wilder", true), - ]; - - await validateUpgrade(deployer, zns.curvePricer, newCurvePricer, factory, contractCalls); - }); - }); -}); +import * as hre from "hardhat"; +import { expect } from "chai"; +import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; +import { ethers } from "ethers"; +import { + deployZNS, + getCurvePrice, + DEFAULT_PRECISION_MULTIPLIER, + validateUpgrade, + PaymentType, + NOT_AUTHORIZED_ERR, + INVALID_PRECISION_MULTIPLIER_ERR, + INVALID_LENGTH_ERR, + INVALID_LABEL_ERR, INITIALIZED_ERR, AC_UNAUTHORIZED_ERR, ZERO_ADDRESS_ERR, FEE_TOO_LARGE_ERR, + INVALID_BASE_OR_MAX_LENGTH_ERR, + DIVISION_BY_ZERO_ERR, +} from "./helpers"; +import { + AccessType, + DEFAULT_DECIMALS, + DEFAULT_PRICE_CONFIG, + DEFAULT_PROTOCOL_FEE_PERCENT, +} from "./helpers/constants"; +import { ADMIN_ROLE, GOVERNOR_ROLE } from "../src/deploy/constants"; +import { ZNSCurvePricer, ZNSCurvePricerUpgradeMock__factory, ZNSCurvePricer__factory } from "../typechain"; +import { registrationWithSetup } from "./helpers/register-setup"; +import { getProxyImplAddress, getRandomString } from "./helpers/utils"; +import { IZNSContractsLocal } from "./helpers/types"; +import { getMongoAdapter } from "@zero-tech/zdc"; + +require("@nomicfoundation/hardhat-chai-matchers"); + +const { ZeroHash } = ethers; + + +describe("ZNSCurvePricer", () => { + let deployer : SignerWithAddress; + let user : SignerWithAddress; + let admin : SignerWithAddress; + let randomAcc : SignerWithAddress; + + let zns : IZNSContractsLocal; + let domainHash : string; + + const defaultDomain = "wilder"; + + beforeEach(async () => { + [ + deployer, + user, + admin, + randomAcc, + ] = await hre.ethers.getSigners(); + + zns = await deployZNS({ + deployer, + governorAddresses: [deployer.address], + adminAddresses: [admin.address], + priceConfig: DEFAULT_PRICE_CONFIG, + }); + + // transfer funds from admin to user + const userBalanceInitial = await zns.zToken.balanceOf(admin.address); + await zns.zToken.connect(user).approve(await zns.treasury.getAddress(), userBalanceInitial); + await zns.zToken.connect(admin).transfer(user.address, userBalanceInitial); + + const fullConfig = { + distrConfig: { + paymentType: PaymentType.DIRECT, + pricerContract: await zns.curvePricer.getAddress(), + accessType: AccessType.OPEN, + }, + paymentConfig: { + token: await zns.zToken.getAddress(), + beneficiary: user.address, + }, + priceConfig: DEFAULT_PRICE_CONFIG, + }; + + domainHash = await registrationWithSetup({ + zns, + user, + domainLabel: "testdomain", + fullConfig, + }); + }); + + after(async () => { + const dbAdapter = await getMongoAdapter(); + await dbAdapter.dropDB(); + }); + + it("Should NOT let initialize the implementation contract", async () => { + const factory = new ZNSCurvePricer__factory(deployer); + const impl = await getProxyImplAddress(await zns.curvePricer.getAddress()); + const implContract = factory.attach(impl) as ZNSCurvePricer; + + await expect( + implContract.initialize( + await zns.accessController.getAddress(), + await zns.registry.getAddress(), + DEFAULT_PRICE_CONFIG + ) + ).to.be.revertedWithCustomError(implContract, INITIALIZED_ERR); + }); + + it("Confirms values were initially set correctly", async () => { + const valueCalls = [ + zns.curvePricer.priceConfigs(domainHash), + ]; + + const [ + priceConfigFromSC, + ] = await Promise.all(valueCalls); + + const priceConfigArr = Object.values(DEFAULT_PRICE_CONFIG); + + priceConfigArr.forEach( + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + (val, idx) => expect(val).to.eq(priceConfigFromSC[idx]) + ); + + const regFromSC = await zns.curvePricer.registry(); + const acFromSC = await zns.curvePricer.getAccessController(); + + expect(regFromSC).to.eq(await zns.registry.getAddress()); + expect(acFromSC).to.eq(await zns.accessController.getAddress()); + }); + + describe("#getPrice", async () => { + it("Returns 0 price for a label with no length if label validation is skipped", async () => { + const { + price, + stakeFee, + } = await zns.curvePricer.getPriceAndFee(domainHash, "", true); + expect(price).to.eq(0); + expect(stakeFee).to.eq(0); + }); + + it("Reverts for a label with no length if label validation is not skipped", async () => { + await expect(zns.curvePricer.getPrice(domainHash, "", false)).to.be.revertedWithCustomError( + zns.curvePricer, + INVALID_LENGTH_ERR + ); + }); + + it("Reverts for invalid label if label validation is not skipped", async () => { + await expect(zns.curvePricer.getPrice(domainHash, "wilder!", false)).to.be.revertedWithCustomError( + zns.curvePricer, + INVALID_LABEL_ERR + ); + }); + + it("Returns the base price for domains that are equal to the base length", async () => { + // Using the default length of 3 + const domain = "eth"; + const params = await zns.curvePricer.priceConfigs(domainHash); + + const domainPrice = await zns.curvePricer.getPrice(domainHash, domain, true); + expect(domainPrice).to.eq(params.maxPrice); + }); + + it("Returns the base price for domains that are less than the base length", async () => { + const domainA = "et"; + const domainB = "e"; + const params = await zns.curvePricer.priceConfigs(domainHash); + + let domainPrice = await zns.curvePricer.getPrice(domainHash, domainA, true); + expect(domainPrice).to.eq(params.maxPrice); + + (domainPrice = await zns.curvePricer.getPrice(domainHash, domainB, true)); + expect(domainPrice).to.eq(params.maxPrice); + }); + + it("Returns expected prices for a domain greater than the base length", async () => { + // create a constant string with 22 letters + const domainOne = "abcdefghijklmnopqrstuv"; + const domainTwo = "akkasddaasdas"; + + // these values have been calced separately to validate + // that both forumlas: SC + helper are correct + // this value has been calces with the default priceConfig + + const domainOneExpPrice = await getCurvePrice(domainOne, DEFAULT_PRICE_CONFIG); + const domainTwoExpPrice = await getCurvePrice(domainTwo, DEFAULT_PRICE_CONFIG); + + const domainOneRefValue = BigInt("4545450000000000000000"); + const domainTwoRefValue = BigInt("7692300000000000000000"); + + const domainOnePriceSC = await zns.curvePricer.getPrice(domainHash, domainOne, true); + const domainTwoPriceSC = await zns.curvePricer.getPrice(domainHash, domainTwo, true); + + expect(domainOnePriceSC).to.eq(domainOneRefValue); + expect(domainOnePriceSC).to.eq(domainOneExpPrice); + + expect(domainTwoPriceSC).to.eq(domainTwoRefValue); + expect(domainTwoPriceSC).to.eq(domainTwoExpPrice); + }); + + it("Returns a price even if the domain name is very long", async () => { + // 255 length + const domain = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" + + "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" + + "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" + + "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" + + "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstu"; + + const expectedPrice = await getCurvePrice(domain, DEFAULT_PRICE_CONFIG); + const domainPrice = await zns.curvePricer.getPrice(domainHash, domain, true); + + expect(domainPrice).to.eq(expectedPrice); + }); + + it("Returns a price for multiple lengths", async () => { + // Any value less than base length is always base price, so we only check + // domains that are greater than base length + 1 + const short = "wild"; + const medium = "wilderworld"; + const long = "wilderworldbeastspetsnftscatscalicosteve"; + + const expectedShortPrice = await getCurvePrice(short, DEFAULT_PRICE_CONFIG); + const shortPrice = await zns.curvePricer.getPrice(domainHash, short, true); + expect(expectedShortPrice).to.eq(shortPrice); + + const expectedMediumPrice = await getCurvePrice(medium, DEFAULT_PRICE_CONFIG); + const mediumPrice = await zns.curvePricer.getPrice(domainHash, medium, true); + expect(expectedMediumPrice).to.eq(mediumPrice); + + const expectedLongPrice = await getCurvePrice(long, DEFAULT_PRICE_CONFIG); + const longPrice = await zns.curvePricer.getPrice(domainHash, long, true); + expect(expectedLongPrice).to.eq(longPrice); + }); + + it("Can Price Names Longer Than 255 Characters", async () => { + // 261 length + const domain = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" + + "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" + + "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" + + "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" + + "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" + + "a"; + const expectedPrice = getCurvePrice(domain, DEFAULT_PRICE_CONFIG); + const domainPrice = await zns.curvePricer.getPrice(domainHash, domain, true); + expect(domainPrice).to.eq(expectedPrice); + }); + }); + + describe("#setPriceConfig", () => { + it("Can't price a name that has invalid characters", async () => { + // Valid names must match the pattern [a-z0-9] + const labelA = "WILDER"; + const labelB = "!?w1Id3r!?"; + const labelC = "!%$#^*?!#👍3^29"; + const labelD = "wo.rld"; + + + await expect(zns.curvePricer.getPrice(domainHash, labelA, false)) + .to.be.revertedWithCustomError(zns.curvePricer, INVALID_LABEL_ERR); + await expect(zns.curvePricer.getPrice(domainHash, labelB, false)) + .to.be.revertedWithCustomError(zns.curvePricer, INVALID_LABEL_ERR); + await expect(zns.curvePricer.getPrice(domainHash, labelC, false)) + .to.be.revertedWithCustomError(zns.curvePricer, INVALID_LABEL_ERR); + await expect(zns.curvePricer.getPrice(domainHash, labelD, false)) + .to.be.revertedWithCustomError(zns.curvePricer, INVALID_LABEL_ERR); + }); + + it("Should set the config for any existing domain hash, including 0x0", async () => { + const newConfig = { + baseLength: BigInt("6"), + maxLength: BigInt("35"), + maxPrice: ethers.parseEther("150"), + curveMultiplier: DEFAULT_PRICE_CONFIG.curveMultiplier, + precisionMultiplier: DEFAULT_PRECISION_MULTIPLIER, + feePercentage: DEFAULT_PROTOCOL_FEE_PERCENT, + isSet: true, + }; + + // as a user of "domainHash" that's not 0x0 + await zns.curvePricer.connect(user).setPriceConfig(domainHash, newConfig); + + // as a ZNS deployer who owns the 0x0 hash + await zns.curvePricer.connect(deployer).setPriceConfig(ZeroHash, newConfig); + + const configUser = await zns.curvePricer.priceConfigs(domainHash); + + expect(configUser.baseLength).to.eq(newConfig.baseLength); + expect(configUser.maxLength).to.eq(newConfig.maxLength); + expect(configUser.maxPrice).to.eq(newConfig.maxPrice); + expect(configUser.curveMultiplier).to.eq(newConfig.curveMultiplier); + expect(configUser.precisionMultiplier).to.eq(newConfig.precisionMultiplier); + expect(configUser.feePercentage).to.eq(newConfig.feePercentage); + + const configDeployer = await zns.curvePricer.priceConfigs(ZeroHash); + + expect(configDeployer.baseLength).to.eq(newConfig.baseLength); + expect(configDeployer.maxLength).to.eq(newConfig.maxLength); + expect(configDeployer.maxPrice).to.eq(newConfig.maxPrice); + expect(configDeployer.curveMultiplier).to.eq(newConfig.curveMultiplier); + expect(configDeployer.precisionMultiplier).to.eq(newConfig.precisionMultiplier); + expect(configDeployer.feePercentage).to.eq(newConfig.feePercentage); + }); + + it("Should revert if called by anyone other than owner or operator", async () => { + const newConfig = { + baseLength: BigInt("6"), + maxLength: BigInt("20"), + maxPrice: ethers.parseEther("10"), + curveMultiplier: DEFAULT_PRICE_CONFIG.curveMultiplier, + precisionMultiplier: DEFAULT_PRECISION_MULTIPLIER, + feePercentage: DEFAULT_PROTOCOL_FEE_PERCENT, + isSet: true, + }; + + await expect( + zns.curvePricer.connect(randomAcc).setPriceConfig(domainHash, newConfig) + ).to.be.revertedWithCustomError( + zns.curvePricer, + NOT_AUTHORIZED_ERR + ); + + await expect( + zns.curvePricer.connect(randomAcc).setPriceConfig(ZeroHash, newConfig) + ).to.be.revertedWithCustomError( + zns.curvePricer, + NOT_AUTHORIZED_ERR + ); + }); + + it("Should emit PriceConfigSet event with correct parameters", async () => { + const newConfig = { + baseLength: BigInt("6"), + maxLength: BigInt("35"), + maxPrice: ethers.parseEther("150"), + curveMultiplier: DEFAULT_PRICE_CONFIG.curveMultiplier, + precisionMultiplier: DEFAULT_PRECISION_MULTIPLIER, + feePercentage: DEFAULT_PROTOCOL_FEE_PERCENT, + isSet: true, + }; + + const tx = zns.curvePricer.connect(user).setPriceConfig(domainHash, newConfig); + + await expect(tx).to.emit(zns.curvePricer, "PriceConfigSet").withArgs( + domainHash, + newConfig.maxPrice, + newConfig.curveMultiplier, + newConfig.maxLength, + newConfig.baseLength, + newConfig.precisionMultiplier, + newConfig.feePercentage, + ); + }); + }); + + describe("#setMaxPrice", () => { + it("Allows an authorized user to set the max price", async () => { + const newMaxPrice = DEFAULT_PRICE_CONFIG.maxPrice + ethers.parseEther("10"); + + await zns.curvePricer.connect(user).setMaxPrice(domainHash, newMaxPrice); + + const params = await zns.curvePricer.priceConfigs(domainHash); + expect(params.maxPrice).to.eq(newMaxPrice); + }); + + it("Disallows an unauthorized user to set the max price", async () => { + const newMaxPrice = ethers.parseEther("0.7"); + + const tx = zns.curvePricer.connect(admin).setMaxPrice(domainHash, newMaxPrice); + await expect(tx).to.be.revertedWithCustomError(zns.curvePricer, NOT_AUTHORIZED_ERR); + }); + + it("Allows setting the max price to zero", async () => { + const newMaxPrice = BigInt("0"); + + await zns.curvePricer.connect(user).setMaxPrice(domainHash, newMaxPrice); + const params = await zns.curvePricer.priceConfigs(domainHash); + + expect(params.maxPrice).to.eq(newMaxPrice); + }); + + it("Return 0 price for any domain when maxPrice is 0", async () => { + const newMaxPrice = BigInt("0"); + + await zns.curvePricer.connect(user).setMaxPrice(domainHash, newMaxPrice); + + // run 5 times to cover it more + for (let i = 1; i < 6; i++) { + const label = getRandomString(i * 2); + expect( + await zns.curvePricer.getPrice( + domainHash, + label, + false + ) + ).to.eq(0n); + } + }); + + it("Correctly sets max price", async () => { + const newMaxPrice = DEFAULT_PRICE_CONFIG.maxPrice + ethers.parseEther("553"); + await zns.curvePricer.connect(user).setMaxPrice(domainHash, newMaxPrice); + + const params = await zns.curvePricer.priceConfigs(domainHash); + expect(params.maxPrice).to.eq(newMaxPrice); + }); + + it("Causes any length domain to have a price of 0 if the maxPrice is 0", async () => { + const newMaxPrice = BigInt("0"); + + await zns.curvePricer.connect(user).setMaxPrice(domainHash, newMaxPrice); + + const shortDomain = "a"; + const longDomain = "abcdefghijklmnopqrstuvwxyz"; + + const shortPrice = await zns.curvePricer.getPrice(domainHash, shortDomain, true); + const longPrice = await zns.curvePricer.getPrice(domainHash, longDomain, true); + + expect(shortPrice).to.eq(BigInt("0")); + expect(longPrice).to.eq(BigInt("0")); + }); + + it("The price of a domain is modified relatively when the basePrice is changed", async () => { + const newMaxPrice = DEFAULT_PRICE_CONFIG.maxPrice + ethers.parseEther("9"); + + const expectedPriceBefore = await getCurvePrice(defaultDomain, DEFAULT_PRICE_CONFIG); + const priceBefore= await zns.curvePricer.getPrice(domainHash, defaultDomain, true); + + expect(expectedPriceBefore).to.eq(priceBefore); + + await zns.curvePricer.connect(user).setMaxPrice(domainHash, newMaxPrice); + + const newConfig = { + ...DEFAULT_PRICE_CONFIG, + maxPrice: newMaxPrice, + }; + + const expectedPriceAfter = await getCurvePrice(defaultDomain, newConfig); + const priceAfter = await zns.curvePricer.getPrice(domainHash, defaultDomain, true); + + expect(expectedPriceAfter).to.eq(priceAfter); + expect(expectedPriceAfter).to.be.gt(expectedPriceBefore); + expect(priceAfter).to.be.gt(priceBefore); + }); + }); + + describe("#setCurveMultiplier", async () => { + it("Return max price if curve multiplier set to 0", async () => { + const newMultiplier = BigInt("0"); + + await zns.curvePricer.connect(user).setCurveMultiplier(domainHash, newMultiplier); + + // run 5 times to cover it more + for (let i = 1; i < 6; i++) { + const domainString = getRandomString(i * i); + + const price = await zns.curvePricer.getPrice( + domainHash, + domainString, + false + ); + + await expect( + price + ).to.be.equal( + DEFAULT_PRICE_CONFIG.maxPrice + ); + } + }); + + it("Reverts when the method is called by a non-owner or operator", async () => { + await expect( + zns.curvePricer.connect(deployer).setCurveMultiplier(domainHash, 2000n) + ).to.be.revertedWithCustomError( + zns.curvePricer, + NOT_AUTHORIZED_ERR + ).withArgs( + deployer, + domainHash + ); + }); + + it("Should revert when `baseLength` is already 0 and we pass `curveMultiplier` as 0", async () => { + await zns.curvePricer.connect(user).setBaseLength( + domainHash, + 0n + ); + + await expect( + zns.curvePricer.connect(user).setCurveMultiplier( + domainHash, + 0n + ) + ).to.be.revertedWithCustomError( + zns.curvePricer, + DIVISION_BY_ZERO_ERR + ); + }); + + it("Should return max price for base length domain labels and 0 for other, which longer", async () => { + // Case where we can set domain strings longer than `baseLength` for free + // (numerator must be less than denominator) + + // constants for playing the scenario (one of many cases): + // `maxPrice` = 25 000 + // `baseLength` <= 40 + // `curveMultiplier` >= 10 000 000 000 + + const newConfig = { + maxPrice: ethers.parseEther("25000"), + curveMultiplier: BigInt("10000000000"), + maxLength: BigInt(100), + baseLength: BigInt(40), + precisionMultiplier: DEFAULT_PRECISION_MULTIPLIER, + feePercentage: DEFAULT_PROTOCOL_FEE_PERCENT, + isSet: true, + }; + + await zns.curvePricer.connect(user).setPriceConfig(domainHash, newConfig); + + const check = async (label : string, res : bigint) => { + const price = await zns.curvePricer.getPrice( + domainHash, + label, + false + ); + + expect( + price + ).to.equal( + res + ); + }; + + // `baseLength` = 40, so run this 4 times + for (let i = 1; i <= newConfig.baseLength / 10n; i++) { + await check( + getRandomString(i * 10), + newConfig.maxPrice + ); + } + + for (let i = 5; i <= 15; i++) { + await check( + getRandomString(i * 10), + 0n + ); + } + + await zns.curvePricer.connect(user).setPriceConfig(domainHash, DEFAULT_PRICE_CONFIG); + + }); + }); + + describe("#setPrecisionMultiplier", () => { + it("Allows an authorized user to set the precision multiplier", async () => { + const newMultiplier = BigInt("1"); + + await zns.curvePricer.connect(user).setPrecisionMultiplier(domainHash, newMultiplier); + + const params = await zns.curvePricer.priceConfigs(domainHash); + expect(params.precisionMultiplier).to.eq(newMultiplier); + }); + + it("Disallows an unauthorized user from setting the precision multiplier", async () => { + const newMultiplier = BigInt("2"); + + const tx = zns.curvePricer.connect(admin).setCurveMultiplier(domainHash, newMultiplier); + await expect(tx).to.be.revertedWithCustomError(zns.curvePricer, NOT_AUTHORIZED_ERR); + }); + + it("Fails when setting `precisionMultiplier` to zero", async () => { + const zeroMultiplier = BigInt("0"); + + await expect( + zns.curvePricer.connect(user).setPrecisionMultiplier( + domainHash, + zeroMultiplier + ) + ).to.be.revertedWithCustomError( + zns.curvePricer, + INVALID_PRECISION_MULTIPLIER_ERR + ).withArgs(domainHash); + }); + + it("Successfuly sets the precision multiplier when above 0", async () => { + const newMultiplier = BigInt("3"); + await zns.curvePricer.connect(user).setPrecisionMultiplier(domainHash, newMultiplier); + + const params = await zns.curvePricer.priceConfigs(domainHash); + expect(params.precisionMultiplier).to.eq(newMultiplier); + }); + + it("Verifies new prices are affected after changing the precision multiplier", async () => { + const atIndex = 7; + + const before = await zns.curvePricer.getPrice(domainHash, defaultDomain, true); + const beforePriceString = before.toString(); + + expect(beforePriceString.charAt(atIndex)).to.eq("0"); + + // Default precision is 2 decimals, so increasing this value should represent in prices + // as a non-zero nect decimal place + const newPrecision = BigInt(3); + const newPrecisionMultiplier = BigInt(10) ** DEFAULT_DECIMALS - newPrecision; + + await zns.curvePricer.connect(user).setPrecisionMultiplier(domainHash, newPrecisionMultiplier); + + const after = await zns.curvePricer.getPrice(domainHash, defaultDomain, true); + const afterPriceString = after.toString(); + + expect(afterPriceString.charAt(atIndex)).to.not.eq("0"); + + }); + + it("Should revert when setting precisionMultiplier higher than 10^18", async () => { + const newMultiplier = ethers.parseEther("100"); + await expect( + zns.curvePricer.connect(user).setPrecisionMultiplier(domainHash, newMultiplier) + ).to.be.revertedWithCustomError( + zns.curvePricer, + INVALID_PRECISION_MULTIPLIER_ERR + ); + }); + }); + + describe("#setBaseLength", () => { + it("Allows an authorized user to set the base length", async () => { + const newLength = 5; + + await zns.curvePricer.connect(user).setBaseLength(domainHash, newLength); + const params = await zns.curvePricer.priceConfigs(domainHash); + + expect(params.baseLength).to.eq(newLength); + }); + + it("Disallows an unauthorized user to set the base length", async () => { + const newLength = 5; + + const tx = zns.curvePricer.connect(admin).setBaseLength(domainHash, newLength); + await expect(tx).to.be.revertedWithCustomError(zns.curvePricer, NOT_AUTHORIZED_ERR); + }); + + it("Allows setting the base length to zero", async () => { + const newLength = 0; + + await zns.curvePricer.connect(user).setBaseLength(domainHash, newLength); + const params = await zns.curvePricer.priceConfigs(domainHash); + + expect(params.baseLength).to.eq(newLength); + }); + + it("Should revert when `curveMultiplier` is already 0 and we pass `baseLength` as 0", async () => { + await zns.curvePricer.connect(user).setCurveMultiplier( + domainHash, + 0n + ); + + await expect( + zns.curvePricer.connect(user).setBaseLength( + domainHash, + 0n + ) + ).to.be.revertedWithCustomError( + zns.curvePricer, + DIVISION_BY_ZERO_ERR + ); + }); + + it("Causes any length domain to cost the base fee when set to max length of 255", async () => { + const newLength = 255; + // We have to set `maxLength` firstly, cause `baseLength` cannot be bigger than `maxLength` + await zns.curvePricer.connect(user).setMaxLength(domainHash, newLength); + await zns.curvePricer.connect(user).setBaseLength(domainHash, newLength); + const params = await zns.curvePricer.priceConfigs(domainHash); + + const shortDomain = "a"; + const longDomain = "abcdefghijklmnopqrstuvwxyz"; + + const shortPrice = await zns.curvePricer.getPrice(domainHash, shortDomain, true); + const longPrice = await zns.curvePricer.getPrice(domainHash, longDomain, true); + + expect(shortPrice).to.eq(params.maxPrice); + expect(longPrice).to.eq(params.maxPrice); + }); + + it("Causes prices to adjust correctly when length is increased", async () => { + const newLength = 8; + const paramsBefore = await zns.curvePricer.priceConfigs(domainHash); + + const expectedPriceBefore = await getCurvePrice(defaultDomain, DEFAULT_PRICE_CONFIG); + const priceBefore = await zns.curvePricer.getPrice(domainHash, defaultDomain, true); + expect(priceBefore).to.eq(expectedPriceBefore); + expect(priceBefore).to.not.eq(paramsBefore.maxPrice); + + await zns.curvePricer.connect(user).setBaseLength(domainHash, newLength); + + const paramsAfter = await zns.curvePricer.priceConfigs(domainHash); + + const newConfig = { + ...DEFAULT_PRICE_CONFIG, + baseLength: BigInt(newLength), + }; + + const expectedPriceAfter = await getCurvePrice(defaultDomain, newConfig); + const priceAfter = await zns.curvePricer.getPrice(domainHash, defaultDomain, true); + expect(priceAfter).to.eq(expectedPriceAfter); + expect(priceAfter).to.eq(paramsAfter.maxPrice); + }); + + it("Causes prices to adjust correctly when length is decreased", async () => { + const length = 8; + await zns.curvePricer.connect(user).setBaseLength(domainHash, length); + + const newConfig1 = { + ...DEFAULT_PRICE_CONFIG, + baseLength: BigInt(length), + }; + + const paramsBefore = await zns.curvePricer.priceConfigs(domainHash); + + const expectedPriceBefore = await getCurvePrice(defaultDomain, newConfig1); + const priceBefore = await zns.curvePricer.getPrice(domainHash, defaultDomain, true); + expect(priceBefore).to.eq(expectedPriceBefore); + expect(priceBefore).to.eq(paramsBefore.maxPrice); + + const newLength = 5; + await zns.curvePricer.connect(user).setBaseLength(domainHash, newLength); + + const newConfig2 = { + ...DEFAULT_PRICE_CONFIG, + baseLength: BigInt(newLength), + }; + + const paramsAfter = await zns.curvePricer.priceConfigs(domainHash); + + const expectedPriceAfter = await getCurvePrice(defaultDomain, newConfig2); + const priceAfter = await zns.curvePricer.getPrice(domainHash, defaultDomain, true); + expect(priceAfter).to.eq(expectedPriceAfter); + expect(priceAfter).to.not.eq(paramsAfter.maxPrice); + }); + + it("Returns the price = 0 whenever the baseLength is 0", async () => { + const newRootLength = 0; + await zns.curvePricer.connect(user).setBaseLength(domainHash, newRootLength); + + const price = await zns.curvePricer.getPrice(domainHash, defaultDomain, true); + + expect( + price + ).to.eq( + 0n + ); + }); + + it("Adjusts prices correctly when setting base lengths to different values", async () => { + for (let i = 0; i < 5; i++) { + const newRootLength = i * 2; + await zns.curvePricer.connect(user).setBaseLength(domainHash, newRootLength); + const newConfig = { + ...DEFAULT_PRICE_CONFIG, + baseLength: BigInt(newRootLength), + }; + + const expectedRootPrice = await getCurvePrice(defaultDomain, newConfig); + const rootPrice = await zns.curvePricer.getPrice(domainHash, defaultDomain, true); + + expect(rootPrice).to.eq(expectedRootPrice); + } + }); + + it("Should revert when `baseLength` bigger than `maxLength`", async () => { + await zns.curvePricer.connect(user).setMaxLength( + domainHash, + 10n + ); + + await expect( + zns.curvePricer.connect(user).setBaseLength( + domainHash, + 20n + ) + ).to.be.revertedWithCustomError( + zns.curvePricer, + INVALID_BASE_OR_MAX_LENGTH_ERR + ); + }); + }); + + describe("#setMaxLength", () => { + it("Allows an authorized user to set the max length", async () => { + const newLength = 5; + + await zns.curvePricer.connect(user).setMaxLength(domainHash, newLength); + const params = await zns.curvePricer.priceConfigs(domainHash); + + expect(params.maxLength).to.eq(newLength); + }); + + it("Disallows an unauthorized user to set the max length", async () => { + const newLength = 5; + + const tx = zns.curvePricer.connect(admin).setMaxLength(domainHash, newLength); + await expect(tx).to.be.revertedWithCustomError(zns.curvePricer, NOT_AUTHORIZED_ERR); + }); + + it("Doesn't allow setting the `maxLength` to zero", async () => { + // require setting `baseLength` smaller or equal `maxLength` + const newLength = 0; + + await zns.curvePricer.connect(user).setBaseLength(domainHash, 0n); + + await expect( + zns.curvePricer.connect(user).setMaxLength(domainHash, newLength) + ).to.be.revertedWithCustomError( + zns.curvePricer, + INVALID_BASE_OR_MAX_LENGTH_ERR + ).withArgs( + domainHash + ); + }); + + it("Should revert when `maxLength` smaller than `baseLength`", async () => { + await zns.curvePricer.connect(user).setBaseLength( + domainHash, + 20n + ); + + await expect( + zns.curvePricer.connect(user).setMaxLength( + domainHash, + 10n + ) + ).to.be.revertedWithCustomError( + zns.curvePricer, + INVALID_BASE_OR_MAX_LENGTH_ERR + ); + }); + }); + + describe("#setFeePercentage", () => { + it("Successfully sets the fee percentage", async () => { + const newFeePerc = BigInt(222); + await zns.curvePricer.connect(user).setFeePercentage(domainHash, newFeePerc); + const { feePercentage: feeFromSC } = await zns.curvePricer.priceConfigs(domainHash); + + expect(feeFromSC).to.eq(newFeePerc); + }); + + it("Disallows an unauthorized user to set the fee percentage", async () => { + const newFeePerc = BigInt(222); + const tx = zns.curvePricer.connect(admin) + .setFeePercentage(domainHash, newFeePerc); + await expect(tx).to.be.revertedWithCustomError(zns.curvePricer, NOT_AUTHORIZED_ERR); + }); + + it("should revert when trying to set feePercentage higher than PERCENTAGE_BASIS", async () => { + const newFeePerc = BigInt(10001); + await expect( + zns.curvePricer.connect(user).setFeePercentage(domainHash, newFeePerc) + ).to.be.revertedWithCustomError( + zns.curvePricer, + FEE_TOO_LARGE_ERR + ).withArgs(newFeePerc, 10000n); + }); + }); + + describe("#getRegistrationFee", () => { + it("Successfully gets the fee for a price", async () => { + const stake = ethers.parseEther("0.2"); + const fee = await zns.curvePricer.getFeeForPrice(domainHash, stake); + const expectedFee = stake * 222n / 10000n; + + expect(fee).to.eq(expectedFee); + }); + }); + + describe("#setAccessController", () => { + it("Successfully sets the access controller", async () => { + const currentAccessController = await zns.curvePricer.getAccessController(); + expect(currentAccessController).to.not.eq(randomAcc.address); + + const tx = await zns.curvePricer.setAccessController(randomAcc.address); + + const newAccessController = await zns.curvePricer.getAccessController(); + expect(newAccessController).to.eq(randomAcc.address); + + await expect(tx).to.emit(zns.curvePricer, "AccessControllerSet").withArgs(randomAcc.address); + }); + + it("Disallows an unauthorized user to set the access controller", async () => { + const tx = zns.curvePricer.connect(user).setAccessController(randomAcc.address); + await expect(tx).to.be.revertedWithCustomError(zns.accessController, AC_UNAUTHORIZED_ERR) + .withArgs(user.address,ADMIN_ROLE); + }); + + it("Disallows setting the access controller to the zero address", async () => { + const tx = zns.curvePricer.connect(admin).setAccessController(ethers.ZeroAddress); + await expect(tx).to.be.revertedWithCustomError( + zns.curvePricer, + ZERO_ADDRESS_ERR + ); + }); + }); + + describe("#setRegistry", () => { + it("Should successfully set the registry", async () => { + const currentRegistry = await zns.curvePricer.registry(); + expect(currentRegistry).to.not.eq(randomAcc.address); + + const tx = await zns.curvePricer.connect(admin).setRegistry(randomAcc.address); + + const newRegistry = await zns.curvePricer.registry(); + expect(newRegistry).to.eq(randomAcc.address); + + await expect(tx).to.emit(zns.curvePricer, "RegistrySet").withArgs(randomAcc.address); + }); + + it("Should NOT set the registry if called by anyone other than ADMIN_ROLE", async () => { + const tx = zns.curvePricer.connect(user).setRegistry(randomAcc.address); + await expect(tx).to.be.revertedWithCustomError(zns.accessController, AC_UNAUTHORIZED_ERR) + .withArgs(user.address,ADMIN_ROLE); + }); + }); + + describe("General validation", () => { + it("Should revert when all passed variables are 0", async () => { + await expect( + zns.curvePricer.connect(user).setPriceConfig( + domainHash, + { + maxPrice: 0n, + curveMultiplier: 0n, + maxLength: 0n, + baseLength: 0n, + precisionMultiplier: 0n, + feePercentage: 0n, + isSet: true, + } + ) + ).to.be.revertedWithCustomError( + zns.curvePricer, + // because its a first check + INVALID_PRECISION_MULTIPLIER_ERR + ).withArgs(domainHash); + }); + }); + + describe("Events", () => { + it("Emits MaxPriceSet", async () => { + const newMaxPrice = DEFAULT_PRICE_CONFIG.maxPrice + 1n; + + const tx = zns.curvePricer.connect(user).setMaxPrice(domainHash, newMaxPrice); + await expect(tx).to.emit(zns.curvePricer, "MaxPriceSet").withArgs(domainHash, newMaxPrice); + }); + + it("Emits BaseLengthSet", async () => { + const newLength = 5; + + const tx = zns.curvePricer.connect(user).setBaseLength(domainHash, newLength); + await expect(tx).to.emit(zns.curvePricer, "BaseLengthSet").withArgs(domainHash, newLength); + }); + }); + + describe("UUPS", () => { + it("Allows an authorized user to upgrade the contract", async () => { + // CurvePricer to upgrade to + const factory = new ZNSCurvePricer__factory(deployer); + const newCurvePricer = await factory.deploy(); + await newCurvePricer.waitForDeployment(); + + // Confirm the deployer is a governor, as set in `deployZNS` helper + await expect(zns.accessController.checkGovernor(deployer.address)).to.not.be.reverted; + + const tx = zns.curvePricer.connect(deployer).upgradeToAndCall( + await newCurvePricer.getAddress(), + "0x" + ); + await expect(tx).to.not.be.reverted; + }); + + it("Fails to upgrade if the caller is not authorized", async () => { + // CurvePricer to upgrade to + const factory = new ZNSCurvePricerUpgradeMock__factory(deployer); + const newCurvePricer = await factory.deploy(); + await newCurvePricer.waitForDeployment(); + + // Confirm the account is not a governor + await expect(zns.accessController.checkGovernor(randomAcc.address)).to.be.reverted; + + const tx = zns.curvePricer.connect(randomAcc).upgradeToAndCall( + await newCurvePricer.getAddress(), + "0x" + ); + + await expect(tx).to.be.revertedWithCustomError(zns.accessController, AC_UNAUTHORIZED_ERR) + .withArgs(randomAcc.address, GOVERNOR_ROLE); + }); + + it("Verifies that variable values are not changed in the upgrade process", async () => { + const factory = new ZNSCurvePricerUpgradeMock__factory(deployer); + const newCurvePricer = await factory.deploy(); + await newCurvePricer.waitForDeployment(); + + await zns.curvePricer.connect(user).setBaseLength(domainHash, "7"); + await zns.curvePricer.connect(user).setMaxPrice( + domainHash, + DEFAULT_PRICE_CONFIG.maxPrice + 15n + ); + + const contractCalls = [ + zns.curvePricer.registry(), + zns.curvePricer.getAccessController(), + zns.curvePricer.priceConfigs(domainHash), + zns.curvePricer.getPrice(domainHash, "wilder", true), + ]; + + await validateUpgrade(deployer, zns.curvePricer, newCurvePricer, factory, contractCalls); + }); + }); +}); diff --git a/test/ZNSDomainToken.test.ts b/test/ZNSDomainToken.test.ts index 46484e0c6..d4d3c0296 100644 --- a/test/ZNSDomainToken.test.ts +++ b/test/ZNSDomainToken.test.ts @@ -10,23 +10,29 @@ import { ADMIN_ROLE, REGISTRAR_ROLE, GOVERNOR_ROLE, - getAccessRevertMsg, - INVALID_TOKENID_ERC_ERR, + NONEXISTENT_TOKEN_ERC_ERR, deployZNS, validateUpgrade, ZNS_DOMAIN_TOKEN_NAME, ZNS_DOMAIN_TOKEN_SYMBOL, INITIALIZED_ERR, - DEFAULT_PERCENTAGE_BASIS, DEFAULT_ROYALTY_FRACTION, + DEFAULT_PERCENTAGE_BASIS, + DEFAULT_ROYALTY_FRACTION, + AC_UNAUTHORIZED_ERR, + ERC721_NOT_APPROVED_ERR, + ZERO_ADDRESS_ERR, + DeployZNSParams, + IZNSContractsLocal, + getProxyImplAddress, } from "./helpers"; -import { DeployZNSParams, IZNSContractsLocal } from "./helpers/types"; -import { getProxyImplAddress } from "./helpers/utils"; +import { DOMAIN_TOKEN_ROLE } from "../src/deploy/constants"; describe("ZNSDomainToken", () => { let deployer : SignerWithAddress; let caller : SignerWithAddress; let mockRegistrar : SignerWithAddress; + let mockRegistry : SignerWithAddress; let beneficiary : SignerWithAddress; let zns : IZNSContractsLocal; @@ -35,7 +41,7 @@ describe("ZNSDomainToken", () => { const randomTokenURI = "https://www.zNS.domains/1a3c2f5"; beforeEach(async () => { - [deployer, caller, mockRegistrar, beneficiary] = await hre.ethers.getSigners(); + [deployer, caller, mockRegistrar, mockRegistry, beneficiary] = await hre.ethers.getSigners(); deployParams = { deployer, governorAddresses: [deployer.address], @@ -45,6 +51,7 @@ describe("ZNSDomainToken", () => { deployParams ); + await zns.accessController.connect(deployer).grantRole(DOMAIN_TOKEN_ROLE, await zns.domainToken.getAddress()); await zns.accessController.connect(deployer).grantRole(REGISTRAR_ROLE, mockRegistrar.address); }); @@ -52,6 +59,7 @@ describe("ZNSDomainToken", () => { expect(await zns.domainToken.getAccessController()).to.equal(await zns.accessController.getAddress()); expect(await zns.domainToken.name()).to.equal(ZNS_DOMAIN_TOKEN_NAME); expect(await zns.domainToken.symbol()).to.equal(ZNS_DOMAIN_TOKEN_SYMBOL); + expect(await zns.domainToken.registry()).to.equal(await zns.registry.getAddress()); const royaltyInfo = await zns.domainToken.royaltyInfo("0", ethers.parseEther("100")); expect(royaltyInfo[0]).to.equal(zns.zeroVaultAddress); expect(royaltyInfo[1]).to.equal(ethers.parseEther("2")); @@ -63,8 +71,9 @@ describe("ZNSDomainToken", () => { ZNS_DOMAIN_TOKEN_NAME, ZNS_DOMAIN_TOKEN_SYMBOL, zns.zeroVaultAddress, - DEFAULT_ROYALTY_FRACTION - )).to.be.revertedWith(INITIALIZED_ERR); + DEFAULT_ROYALTY_FRACTION, + await zns.registry.getAddress() + )).to.be.revertedWithCustomError(zns.domainToken, INITIALIZED_ERR); }); it("Should NOT let initialize the implementation contract", async () => { @@ -78,9 +87,37 @@ describe("ZNSDomainToken", () => { ZNS_DOMAIN_TOKEN_NAME, ZNS_DOMAIN_TOKEN_SYMBOL, zns.zeroVaultAddress, - DEFAULT_ROYALTY_FRACTION + DEFAULT_ROYALTY_FRACTION, + await zns.registry.getAddress() ) - ).to.be.revertedWith(INITIALIZED_ERR); + ).to.be.revertedWithCustomError(implContract, INITIALIZED_ERR); + }); + + describe("#setRegistry", () => { + it("Should set ZNSRegistry and fire RegistrySet event", async () => { + const currentRegistry = await zns.domainToken.registry(); + const tx = await zns.domainToken.connect(deployer).setRegistry(mockRegistry.address); + const newRegistry = await zns.domainToken.registry(); + + await expect(tx).to.emit(zns.domainToken, "RegistrySet").withArgs(mockRegistry.address); + + expect(newRegistry).to.equal(mockRegistry .address); + expect(currentRegistry).to.not.equal(newRegistry); + }); + + it("Should revert if not called by ADMIN", async () => { + const tx = zns.domainToken.connect(caller).setRegistry(mockRegistry.address); + await expect(tx).to.be.revertedWithCustomError(zns.accessController, AC_UNAUTHORIZED_ERR) + .withArgs(caller.address, ADMIN_ROLE); + }); + + it("Should revert if ZNSRegistry is address zero", async () => { + const tx = zns.rootRegistrar.connect(deployer).setRegistry(ethers.ZeroAddress); + await expect(tx).to.be.revertedWithCustomError( + zns.rootRegistrar, + ZERO_ADDRESS_ERR + ); + }); }); describe("External functions", () => { @@ -130,13 +167,11 @@ describe("ZNSDomainToken", () => { it("Should revert when registering (minting) if caller does not have REGISTRAR_ROLE", async () => { const tokenId = BigInt("1"); - await expect( - zns.domainToken - .connect(caller) - .register(caller.address, tokenId, randomTokenURI) - ).to.be.revertedWith( - getAccessRevertMsg(caller.address, REGISTRAR_ROLE) - ); + await expect(zns.domainToken + .connect(caller) + .register(caller.address, tokenId, randomTokenURI)) + .to.be.revertedWithCustomError(zns.accessController, AC_UNAUTHORIZED_ERR) + .withArgs(caller.address,REGISTRAR_ROLE); }); it("Revokes a token", async () => { @@ -161,7 +196,113 @@ describe("ZNSDomainToken", () => { ); // Verify token has been burned - await expect(zns.domainToken.ownerOf(tokenId)).to.be.revertedWith(INVALID_TOKENID_ERC_ERR); + await expect(zns.domainToken.ownerOf(tokenId)).to.be.revertedWithCustomError( + zns.domainToken, + NONEXISTENT_TOKEN_ERC_ERR + ); + }); + }); + + describe("Updated Transfers", () => { + const tokenId = 1; + const domainHash = ethers.solidityPacked(["uint256"], [tokenId]); + + it("Should update owner for DomainToken and in Registry when transferred normally", async () => { + // Setup for caller as owner of both + await zns.domainToken.connect(mockRegistrar).register(caller.address, tokenId, ""); + await zns.registry.connect(mockRegistrar).createDomainRecord(domainHash, caller.address, "0x0"); + + expect(await zns.domainToken.ownerOf(tokenId)).to.equal(caller.address); + expect(await zns.registry.getDomainOwner(domainHash)).to.equal(caller.address); + + // Call to standard transfer function modifies both + await zns.domainToken.connect(caller).transferFrom(caller.address, deployer.address, tokenId); + + expect(await zns.domainToken.ownerOf(tokenId)).to.equal(deployer.address); + expect(await zns.registry.getDomainOwner(domainHash)).to.equal(deployer.address); + }); + + it("Should update owner for DomainToken and not for Registry when called with non-standard transfer", async () => { + // Setup for caller as owner of both + await zns.domainToken.connect(mockRegistrar).register(caller.address, tokenId, ""); + await zns.registry.connect(mockRegistrar).createDomainRecord(domainHash, caller.address, "0x0"); + + expect(await zns.domainToken.ownerOf(tokenId)).to.equal(caller.address); + expect(await zns.registry.getDomainOwner(domainHash)).to.equal(caller.address); + + // After calling the reg owner will be the same but the token owner is different + await zns.domainToken.connect(caller).updateTokenOwner(caller.address, deployer.address, tokenId); + + expect(await zns.domainToken.ownerOf(tokenId)).to.equal(deployer.address); + expect(await zns.registry.getDomainOwner(domainHash)).to.equal(caller.address); + }); + + it("Allows the owner of the domain record in the registry to update the owner", async () => { + // Setup for caller as owner of both + await zns.domainToken.connect(mockRegistrar).register(caller.address, tokenId, ""); + await zns.registry.connect(mockRegistrar).createDomainRecord(domainHash, caller.address, "0x0"); + + expect(await zns.domainToken.ownerOf(tokenId)).to.equal(caller.address); + expect(await zns.registry.getDomainOwner(domainHash)).to.equal(caller.address); + + // The owner of the reg record can still update independent of the token transfer method + await zns.registry.connect(caller).updateDomainOwner(domainHash, deployer.address); + + expect(await zns.registry.getDomainOwner(domainHash)).to.equal(deployer.address); + expect(await zns.domainToken.ownerOf(tokenId)).to.equal(caller.address); + }); + + it("Fails when non-owner tries to transfer through `updateTokenOwner`", async () => { + // Setup for caller as owner of both + await zns.domainToken.connect(mockRegistrar).register(caller.address, tokenId, ""); + await zns.registry.connect(mockRegistrar).createDomainRecord(domainHash, caller.address, "0x0"); + + await expect( + zns.domainToken.connect(deployer).updateTokenOwner(caller.address, deployer.address, tokenId) + ).to.be.revertedWithCustomError(zns.domainToken, ERC721_NOT_APPROVED_ERR); + + // After deployer is approved by caller, updateTokenOwner succeeds + await zns.domainToken.connect(caller).approve(deployer.address, tokenId); + await zns.domainToken.connect(deployer).transferFrom(caller.address, deployer.address, tokenId); + }); + + // it fails when non-owner uses either safeTransferFrom function + it("Fails when non-owner tries to transfer through `safeTransferFrom`", async () => { + // Setup for caller as owner of both + await zns.domainToken.connect(mockRegistrar).register(caller.address, tokenId, ""); + await zns.registry.connect(mockRegistrar).createDomainRecord(domainHash, caller.address, "0x0"); + + await expect( + zns.domainToken.connect(deployer) + ["safeTransferFrom(address,address,uint256)"] + (caller.address, deployer.address, tokenId) + ).to.be.revertedWithCustomError(zns.domainToken, ERC721_NOT_APPROVED_ERR); + + await expect( + zns.domainToken.connect(deployer) + ["safeTransferFrom(address,address,uint256,bytes)"] + (caller.address, deployer.address, tokenId, ethers.ZeroHash) + ).to.be.revertedWithCustomError(zns.domainToken, ERC721_NOT_APPROVED_ERR); + + // Approve deployer to spend on behalf of caller, then deployer safeTransferFrom passes + await zns.domainToken.connect(caller).approve(deployer.address, tokenId); + await zns.domainToken.connect(deployer) + ["safeTransferFrom(address,address,uint256)"] + (caller.address, deployer.address, tokenId); + }); + + it("Fails when non-owner tries to transfer through `transferFrom`", async () => { + // Setup for caller as owner of both + await zns.domainToken.connect(mockRegistrar).register(caller.address, tokenId, ""); + await zns.registry.connect(mockRegistrar).createDomainRecord(domainHash, caller.address, "0x0"); + + await expect( + zns.domainToken.connect(deployer).transferFrom(caller.address, deployer.address, tokenId) + ).to.be.revertedWithCustomError(zns.domainToken, ERC721_NOT_APPROVED_ERR); + + // Approve deployer to spend on behalf of caller, then deployer transferFrom passes + await zns.domainToken.connect(caller).approve(deployer.address, tokenId); + await zns.domainToken.connect(deployer).transferFrom(caller.address, deployer.address, tokenId); }); }); @@ -172,9 +313,8 @@ describe("ZNSDomainToken", () => { .connect(caller) .register(caller.address, tokenId, randomTokenURI); - await expect(registerTx).to.be.revertedWith( - getAccessRevertMsg(caller.address, REGISTRAR_ROLE) - ); + await expect(registerTx).to.be.revertedWithCustomError(zns.accessController, AC_UNAUTHORIZED_ERR) + .withArgs(caller.address,REGISTRAR_ROLE); }); it("Only authorized can revoke a token", async () => { @@ -193,9 +333,8 @@ describe("ZNSDomainToken", () => { // Revoke domain const tx = zns.domainToken.connect(caller).revoke(tokenId); - await expect(tx).to.be.revertedWith( - getAccessRevertMsg(caller.address, REGISTRAR_ROLE) - ); + await expect(tx).to.be.revertedWithCustomError(zns.accessController, AC_UNAUTHORIZED_ERR) + .withArgs(caller.address,REGISTRAR_ROLE); // Verify token has not been burned expect(await zns.domainToken.ownerOf(tokenId)).to.equal(caller.address); @@ -207,11 +346,9 @@ describe("ZNSDomainToken", () => { }); it("Should revert when setting access controller if caller does not have ADMIN_ROLE", async () => { - await expect( - zns.domainToken.connect(caller).setAccessController(caller.address) - ).to.be.revertedWith( - getAccessRevertMsg(caller.address, ADMIN_ROLE) - ); + await expect(zns.domainToken.connect(caller).setAccessController(caller.address)) + .to.be.revertedWithCustomError(zns.accessController, AC_UNAUTHORIZED_ERR) + .withArgs(caller.address,ADMIN_ROLE); }); }); @@ -293,11 +430,9 @@ describe("ZNSDomainToken", () => { }); it("#setDefaultRoyalty() should revert if called by anyone other than ADMIN_ROLE", async () => { - await expect( - zns.domainToken.connect(caller).setDefaultRoyalty(beneficiary.address, 100) - ).to.be.revertedWith( - getAccessRevertMsg(caller.address, ADMIN_ROLE) - ); + await expect(zns.domainToken.connect(caller).setDefaultRoyalty(beneficiary.address, 100)) + .to.be.revertedWithCustomError(zns.accessController, AC_UNAUTHORIZED_ERR) + .withArgs(caller.address,ADMIN_ROLE); }); it("#setTokenRoyalty() should revert if called by anyone other than ADMIN_ROLE", async () => { @@ -305,11 +440,9 @@ describe("ZNSDomainToken", () => { const tokenId = BigInt("777356"); await zns.domainToken.connect(mockRegistrar).register(deployer.address, tokenId, randomTokenURI); - await expect( - zns.domainToken.connect(caller).setTokenRoyalty(tokenId, beneficiary.address, 100) - ).to.be.revertedWith( - getAccessRevertMsg(caller.address, ADMIN_ROLE) - ); + await expect(zns.domainToken.connect(caller).setTokenRoyalty(tokenId, beneficiary.address, 100)) + .to.be.revertedWithCustomError(zns.accessController, AC_UNAUTHORIZED_ERR) + .withArgs(caller.address, ADMIN_ROLE); }); }); @@ -441,21 +574,17 @@ describe("ZNSDomainToken", () => { await zns.domainToken.connect(mockRegistrar).register(caller.address, tokenId, tokenURI); - await expect( - zns.domainToken.connect(caller).setTokenURI(tokenId, newTokenURI) - ).to.be.revertedWith( - getAccessRevertMsg(caller.address, ADMIN_ROLE) - ); + await expect(zns.domainToken.connect(caller).setTokenURI(tokenId, newTokenURI)) + .to.be.revertedWithCustomError(zns.accessController, AC_UNAUTHORIZED_ERR) + .withArgs(caller.address, ADMIN_ROLE); }); it("#setBaseURI() should revert when called by anyone other than ADMIN_ROLE", async () => { const baseURI = "https://www.zNS.domains/"; - await expect( - zns.domainToken.connect(caller).setBaseURI(baseURI) - ).to.be.revertedWith( - getAccessRevertMsg(caller.address, ADMIN_ROLE) - ); + await expect(zns.domainToken.connect(caller).setBaseURI(baseURI)) + .to.be.revertedWithCustomError(zns.accessController, AC_UNAUTHORIZED_ERR) + .withArgs(caller.address, ADMIN_ROLE); }); }); @@ -492,7 +621,10 @@ describe("ZNSDomainToken", () => { await zns.accessController.hasRole(GOVERNOR_ROLE, deployer.address) ).to.be.true; - const upgradeTx = zns.domainToken.connect(deployer).upgradeTo(await newDomainToken.getAddress()); + const upgradeTx = zns.domainToken.connect(deployer).upgradeToAndCall( + await newDomainToken.getAddress(), + "0x" + ); await expect(upgradeTx).to.not.be.reverted; }); @@ -529,15 +661,17 @@ describe("ZNSDomainToken", () => { await newDomainToken.waitForDeployment(); // Confirm the caller is not a governor - await expect(zns.accessController.checkGovernor(caller.address)).to.be.revertedWith( - getAccessRevertMsg(caller.address, GOVERNOR_ROLE) - ); + await expect(zns.accessController.checkGovernor(caller.address)) + .to.be.revertedWithCustomError(zns.accessController, AC_UNAUTHORIZED_ERR) + .withArgs(caller.address, GOVERNOR_ROLE); - const upgradeTx = zns.domainToken.connect(caller).upgradeTo(await newDomainToken.getAddress()); - - await expect(upgradeTx).to.be.revertedWith( - getAccessRevertMsg(caller.address, GOVERNOR_ROLE) + const upgradeTx = zns.domainToken.connect(caller).upgradeToAndCall( + await newDomainToken.getAddress(), + "0x" ); + + await expect(upgradeTx).to.be.revertedWithCustomError(zns.accessController, AC_UNAUTHORIZED_ERR) + .withArgs(caller.address, GOVERNOR_ROLE); }); }); }); \ No newline at end of file diff --git a/test/ZNSFixedPricer.test.ts b/test/ZNSFixedPricer.test.ts index 988224228..d79551c7f 100644 --- a/test/ZNSFixedPricer.test.ts +++ b/test/ZNSFixedPricer.test.ts @@ -2,21 +2,27 @@ import { ADMIN_ROLE, deployFixedPricer, deployZNS, - getAccessRevertMsg, GOVERNOR_ROLE, - INITIALIZED_ERR, INVALID_NAME_ERR, - NOT_AUTHORIZED_REG_WIRED_ERR, + INITIALIZED_ERR, INVALID_LABEL_ERR, + NOT_AUTHORIZED_ERR, PaymentType, DEFAULT_PERCENTAGE_BASIS, DEFAULT_PRICE_CONFIG, - validateUpgrade, AccessType, + validateUpgrade, + AccessType, + AC_UNAUTHORIZED_ERR, + FEE_TOO_LARGE_ERR, } from "./helpers"; import * as hre from "hardhat"; import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; import * as ethers from "ethers"; import { registrationWithSetup } from "./helpers/register-setup"; import { expect } from "chai"; -import { ZNSFixedPricer__factory, ZNSFixedPricer, ZNSFixedPricerUpgradeMock__factory } from "../typechain"; +import { + ZNSFixedPricer__factory, + ZNSFixedPricer, + ZNSFixedPricerUpgradeMock__factory, +} from "../typechain"; import { getProxyImplAddress } from "./helpers/utils"; import { IZNSContractsLocal } from "./helpers/types"; @@ -46,8 +52,9 @@ describe("ZNSFixedPricer", () => { zeroVaultAddress: zeroVault.address, }); - await zns.meowToken.connect(user).approve(await zns.treasury.getAddress(), ethers.MaxUint256); - await zns.meowToken.mint(user.address, ethers.parseEther("10000000000000")); + const userBalanceInitial = await zns.zToken.balanceOf(admin.address) / 2n; + await zns.zToken.connect(user).approve(await zns.treasury.getAddress(), userBalanceInitial); + await zns.zToken.connect(admin).transfer(user.address, userBalanceInitial); const fullConfig = { distrConfig: { @@ -56,7 +63,7 @@ describe("ZNSFixedPricer", () => { accessType: AccessType.OPEN, }, paymentConfig: { - token: await zns.meowToken.getAddress(), + token: await zns.zToken.getAddress(), beneficiary: user.address, }, priceConfig: { @@ -82,7 +89,7 @@ describe("ZNSFixedPricer", () => { await expect(zns.fixedPricer.initialize( await zns.accessController.getAddress(), await zns.registry.getAddress(), - )).to.be.revertedWith(INITIALIZED_ERR); + )).to.be.revertedWithCustomError(zns.fixedPricer, INITIALIZED_ERR); }); it("Should NOT let initialize the implementation contract", async () => { @@ -95,7 +102,7 @@ describe("ZNSFixedPricer", () => { deployer.address, random.address, ) - ).to.be.revertedWith(INITIALIZED_ERR); + ).to.be.revertedWithCustomError(implContract, INITIALIZED_ERR); }); it("should set config for 0x0 hash", async () => { @@ -136,9 +143,8 @@ describe("ZNSFixedPricer", () => { acAddress: await zns.accessController.getAddress(), regAddress: await zns.registry.getAddress(), }), - ).to.be.revertedWith( - getAccessRevertMsg(random.address, ADMIN_ROLE) - ); + ).to.be.revertedWithCustomError(zns.accessController, AC_UNAUTHORIZED_ERR) + .withArgs(random.address, ADMIN_ROLE); }); it("#setPrice() should work correctly and emit #PriceSet event", async () => { @@ -164,7 +170,7 @@ describe("ZNSFixedPricer", () => { it("#getPrice() should revert for invalid label when not skipping the label validation", async () => { await expect( zns.fixedPricer.getPrice(domainHash, "tEstname", false) - ).to.be.revertedWith(INVALID_NAME_ERR); + ).to.be.revertedWithCustomError(zns.fixedPricer, INVALID_LABEL_ERR); }); it("#getPriceAndFee() should return the correct price and fee", async () => { @@ -185,8 +191,9 @@ describe("ZNSFixedPricer", () => { it("#setPrice() should revert if called by anyone other than domain owner", async () => { await expect( zns.fixedPricer.connect(random).setPrice(domainHash, ethers.parseEther("1")) - ).to.be.revertedWith( - NOT_AUTHORIZED_REG_WIRED_ERR + ).to.be.revertedWithCustomError( + zns.fixedPricer, + NOT_AUTHORIZED_ERR ); }); @@ -205,16 +212,18 @@ describe("ZNSFixedPricer", () => { it("#setFeePercentage() should revert if called by anyone other than domain owner", async () => { await expect( zns.fixedPricer.connect(random).setFeePercentage(domainHash, BigInt(1)) - ).to.be.revertedWith( - NOT_AUTHORIZED_REG_WIRED_ERR + ).to.be.revertedWithCustomError( + zns.fixedPricer, + NOT_AUTHORIZED_ERR ); }); it("#setFeePercentage() should revert when trying to set feePercentage higher than PERCENTAGE_BASIS", async () => { await expect( zns.fixedPricer.connect(user).setFeePercentage(domainHash, DEFAULT_PERCENTAGE_BASIS + 1n) - ).to.be.revertedWith( - "ZNSFixedPricer: feePercentage cannot be greater than PERCENTAGE_BASIS" + ).to.be.revertedWithCustomError( + zns.fixedPricer, + FEE_TOO_LARGE_ERR ); }); @@ -244,16 +253,14 @@ describe("ZNSFixedPricer", () => { it("#setPriceConfig() should revert if called by anyone other than domain owner or operator", async () => { await expect( - zns.fixedPricer.connect(random).setPriceConfig( - domainHash, - { - price: BigInt(1), - feePercentage: BigInt(1), - isSet: true, - } - ) - ).to.be.revertedWith( - NOT_AUTHORIZED_REG_WIRED_ERR + zns.fixedPricer.connect(random).setPriceConfig(domainHash, { + price: BigInt(1), + feePercentage: BigInt(1), + isSet: true, + }) + ).to.be.revertedWithCustomError( + zns.fixedPricer, + NOT_AUTHORIZED_ERR ); }); @@ -271,17 +278,15 @@ describe("ZNSFixedPricer", () => { it("#setRegistry() should revert if called by anyone other than ADMIN_ROLE", async () => { await expect( zns.fixedPricer.connect(random).setRegistry(random.address) - ).to.be.revertedWith( - getAccessRevertMsg(random.address, ADMIN_ROLE) - ); + ).to.be.revertedWithCustomError(zns.accessController, AC_UNAUTHORIZED_ERR) + .withArgs(random.address, ADMIN_ROLE); }); it("#setAccessController() should revert if called by anyone other than ADMIN_ROLE", async () => { await expect( zns.fixedPricer.connect(random).setAccessController(random.address) - ).to.be.revertedWith( - getAccessRevertMsg(random.address, ADMIN_ROLE) - ); + ).to.be.revertedWithCustomError(zns.accessController, AC_UNAUTHORIZED_ERR) + .withArgs(random.address, ADMIN_ROLE); }); // keep this as the last test @@ -303,8 +308,9 @@ describe("ZNSFixedPricer", () => { zeroVaultAddress: zeroVault.address, }); - await zns.meowToken.connect(user).approve(await zns.treasury.getAddress(), ethers.MaxUint256); - await zns.meowToken.mint(user.address, ethers.parseEther("10000000000000")); + const userBalanceInitial = await zns.zToken.balanceOf(admin.address) / 2n; + await zns.zToken.connect(user).approve(await zns.treasury.getAddress(), userBalanceInitial); + await zns.zToken.connect(admin).transfer(user.address, userBalanceInitial); const fullConfig = { distrConfig: { @@ -313,7 +319,7 @@ describe("ZNSFixedPricer", () => { accessType: AccessType.OPEN, }, paymentConfig: { - token: await zns.meowToken.getAddress(), + token: await zns.zToken.getAddress(), beneficiary: user.address, }, priceConfig: { @@ -339,7 +345,10 @@ describe("ZNSFixedPricer", () => { // Confirm the deployer is a governor, as set in `deployZNS` helper await expect(zns.accessController.checkGovernor(deployer.address)).to.not.be.reverted; - const tx = zns.fixedPricer.connect(deployer).upgradeTo(await newFixedPricer.getAddress()); + const tx = zns.fixedPricer.connect(deployer).upgradeToAndCall( + await newFixedPricer.getAddress(), + "0x" + ); await expect(tx).to.not.be.reverted; await expect( @@ -347,7 +356,7 @@ describe("ZNSFixedPricer", () => { await zns.accessController.getAddress(), await zns.registry.getAddress(), ) - ).to.be.revertedWith(INITIALIZED_ERR); + ).to.be.revertedWithCustomError(zns.fixedPricer, INITIALIZED_ERR); }); it("Fails to upgrade if the caller is not authorized", async () => { @@ -359,11 +368,13 @@ describe("ZNSFixedPricer", () => { // Confirm the account is not a governor await expect(zns.accessController.checkGovernor(random.address)).to.be.reverted; - const tx = zns.fixedPricer.connect(random).upgradeTo(await newFixedPricer.getAddress()); - - await expect(tx).to.be.revertedWith( - getAccessRevertMsg(random.address, GOVERNOR_ROLE) + const tx = zns.fixedPricer.connect(random).upgradeToAndCall( + await newFixedPricer.getAddress(), + "0x" ); + + await expect(tx).to.be.revertedWithCustomError(zns.accessController, AC_UNAUTHORIZED_ERR) + .withArgs(random.address, GOVERNOR_ROLE); }); it("Verifies that variable values are not changed in the upgrade process", async () => { diff --git a/test/ZNSRegistry.test.ts b/test/ZNSRegistry.test.ts index a0980b603..801ba8c32 100644 --- a/test/ZNSRegistry.test.ts +++ b/test/ZNSRegistry.test.ts @@ -11,16 +11,12 @@ import { GOVERNOR_ROLE, REGISTRAR_ROLE, INITIALIZED_ERR, - getAccessRevertMsg, validateUpgrade, - NOT_AUTHORIZED_REG_ERR, DEFAULT_RESOLVER_TYPE, + AC_UNAUTHORIZED_ERR, + NOT_AUTHORIZED_ERR, + ZERO_ADDRESS_ERR, } from "./helpers"; -import { - ONLY_NAME_OWNER_REG_ERR, - ONLY_OWNER_REGISTRAR_REG_ERR, - OWNER_NOT_ZERO_REG_ERR, -} from "./helpers/errors"; import { getProxyImplAddress } from "./helpers/utils"; // eslint-disable-next-line @typescript-eslint/no-var-requires @@ -68,7 +64,8 @@ describe("ZNSRegistry", () => { zns.registry.initialize( await zns.accessController.getAddress() ) - ).to.be.revertedWith( + ).to.be.revertedWithCustomError( + zns.registry, INITIALIZED_ERR ); }); @@ -82,7 +79,7 @@ describe("ZNSRegistry", () => { implContract.initialize( deployer.address, ) - ).to.be.revertedWith(INITIALIZED_ERR); + ).to.be.revertedWithCustomError(implContract, INITIALIZED_ERR); }); // eslint-disable-next-line max-len @@ -121,9 +118,8 @@ describe("ZNSRegistry", () => { it("Should revert when setting access controller without ADMIN_ROLE", async () => { await expect( zns.registry.connect(randomUser).setAccessController(deployer.address) - ).to.be.revertedWith( - getAccessRevertMsg(randomUser.address, ADMIN_ROLE) - ); + ).to.be.revertedWithCustomError(zns.accessController, AC_UNAUTHORIZED_ERR) + .withArgs(randomUser.address, ADMIN_ROLE); }); describe("Audit fix with approved address resolvers", () => { @@ -233,12 +229,12 @@ describe("ZNSRegistry", () => { await zns.registry.connect(deployer).setOwnersOperator(operator.address, false); const tx = zns.registry.connect(operator).updateDomainResolver(wilderDomainHash, operator.address); - await expect(tx).to.be.revertedWith("ZNSRegistry: Not authorized"); + await expect(tx).to.be.revertedWithCustomError(zns.registry, NOT_AUTHORIZED_ERR); }); it("Does not permit an operator that's never been allowed to modify a record", async () => { const tx = zns.registry.connect(operator).updateDomainResolver(wilderDomainHash, operator.address); - await expect(tx).to.be.revertedWith("ZNSRegistry: Not authorized"); + await expect(tx).to.be.revertedWithCustomError(zns.registry, NOT_AUTHORIZED_ERR); }); it("#isOperatorFor() should return true for an operator", async () => { @@ -315,9 +311,8 @@ describe("ZNSRegistry", () => { DEFAULT_RESOLVER_TYPE ); - await expect(tx).to.be.revertedWith( - `AccessControl: account ${deployer.address.toLowerCase()} is missing role ${REGISTRAR_ROLE}` - ); + await expect(tx).to.be.revertedWithCustomError(zns.accessController, AC_UNAUTHORIZED_ERR) + .withArgs(deployer.address, REGISTRAR_ROLE); }); }); @@ -328,7 +323,7 @@ describe("ZNSRegistry", () => { const tx = zns.registry.updateDomainRecord(domainHash, deployer.address, mockResolver.address); // Because nobody owns a non-existing record, the error is caught by the `onlyOwnerOrOperator` first - await expect(tx).to.be.revertedWith(ONLY_NAME_OWNER_REG_ERR); + await expect(tx).to.be.revertedWithCustomError(zns.registry, NOT_AUTHORIZED_ERR); }); it("Can update a domain record if the domain exists", async () => { @@ -352,7 +347,7 @@ describe("ZNSRegistry", () => { const tx = zns.registry.updateDomainOwner(domainHash, deployer.address); // Because nobody owns a non-existing record, the error is caught by the `onlyOwnerOrOperator` first - await expect(tx).to.be.revertedWith(ONLY_OWNER_REGISTRAR_REG_ERR); + await expect(tx).to.be.revertedWithCustomError(zns.registry, NOT_AUTHORIZED_ERR); }); it("Can update a domain owner if the domain exists", async () => { @@ -371,7 +366,7 @@ describe("ZNSRegistry", () => { const tx = zns.registry.updateDomainResolver(domainHash, mockResolver.address); // Because nobody owns a non-existing record, the error is caught by the `onlyOwnerOrOperator` first - await expect(tx).to.be.revertedWith(NOT_AUTHORIZED_REG_ERR); + await expect(tx).to.be.revertedWithCustomError(zns.registry, NOT_AUTHORIZED_ERR); }); it("Can update a domain resolver if the domain exists", async () => { @@ -394,7 +389,7 @@ describe("ZNSRegistry", () => { await zns.registry.connect(mockRegistrar).createDomainRecord(domainHash, deployer.address, DEFAULT_RESOLVER_TYPE); const tx = zns.registry.updateDomainRecord(domainHash, ethers.ZeroAddress, mockResolver.address); - await expect(tx).to.be.revertedWith(OWNER_NOT_ZERO_REG_ERR); + await expect(tx).to.be.revertedWithCustomError(zns.registry, ZERO_ADDRESS_ERR); }); it("Can update a domain record if the resolver is zero address", async () => { @@ -414,7 +409,7 @@ describe("ZNSRegistry", () => { ethers.ZeroAddress ); - await expect(tx).to.be.revertedWith(OWNER_NOT_ZERO_REG_ERR); + await expect(tx).to.be.revertedWithCustomError(zns.registry, ZERO_ADDRESS_ERR); }); it("Can update a domain resolver if resolver is zero address", async () => { @@ -438,7 +433,7 @@ describe("ZNSRegistry", () => { operator.address, mockResolver.address ); - await expect(tx).to.be.revertedWith(ONLY_NAME_OWNER_REG_ERR); + await expect(tx).to.be.revertedWithCustomError(zns.registry, NOT_AUTHORIZED_ERR); }); it("cannot update a domain's record if not an owner or operator", async () => { @@ -451,7 +446,7 @@ describe("ZNSRegistry", () => { deployer.address ); - await expect(tx).to.be.revertedWith(ONLY_NAME_OWNER_REG_ERR); + await expect(tx).to.be.revertedWithCustomError(zns.registry, NOT_AUTHORIZED_ERR); }); it("cannot update an domain's owner if not an owner or operator", async () => { @@ -460,9 +455,7 @@ describe("ZNSRegistry", () => { await zns.registry.connect(mockRegistrar).createDomainRecord(domainHash, deployer.address, DEFAULT_RESOLVER_TYPE); const tx = zns.registry.connect(randomUser).updateDomainOwner(domainHash, mockResolver.address); - await expect(tx).to.be.revertedWith( - ONLY_OWNER_REGISTRAR_REG_ERR - ); + await expect(tx).to.be.revertedWithCustomError(zns.registry, NOT_AUTHORIZED_ERR); }); it("cannot update a domain's resolver if not an owner or operator", async () => { @@ -471,7 +464,7 @@ describe("ZNSRegistry", () => { await zns.registry.connect(mockRegistrar).createDomainRecord(domainHash, deployer.address, DEFAULT_RESOLVER_TYPE); const tx = zns.registry.connect(randomUser).updateDomainResolver(domainHash, deployer.address); - await expect(tx).to.be.revertedWith(NOT_AUTHORIZED_REG_ERR); + await expect(tx).to.be.revertedWithCustomError(zns.registry, NOT_AUTHORIZED_ERR); }); it("Can delete record with REGISTRAR_ROLE", async () => { @@ -491,9 +484,8 @@ describe("ZNSRegistry", () => { await zns.registry.connect(mockRegistrar).createDomainRecord(domainHash, deployer.address, DEFAULT_RESOLVER_TYPE); const tx = zns.registry.connect(randomUser).deleteRecord(domainHash); - await expect(tx).to.be.revertedWith( - getAccessRevertMsg(randomUser.address, REGISTRAR_ROLE) - ); + await expect(tx).to.be.revertedWithCustomError(zns.accessController, AC_UNAUTHORIZED_ERR) + .withArgs(randomUser.address,REGISTRAR_ROLE); }); }); @@ -595,7 +587,10 @@ describe("ZNSRegistry", () => { await registry.waitForDeployment(); // To control the signer we call manually here instead of through hardhat - const upgradeTx = zns.registry.connect(deployer).upgradeTo(await registry.getAddress()); + const upgradeTx = zns.registry.connect(deployer).upgradeToAndCall( + await registry.getAddress(), + "0x" + ); await expect(upgradeTx).to.be.not.be.reverted; }); @@ -605,8 +600,13 @@ describe("ZNSRegistry", () => { await registry.waitForDeployment(); // To control the signer we call manually here instead of through hardhat - const upgradeTx = zns.registry.connect(randomUser).upgradeTo(await registry.getAddress()); - await expect(upgradeTx).to.be.revertedWith(getAccessRevertMsg(randomUser.address, GOVERNOR_ROLE)); + const upgradeTx = zns.registry.connect(randomUser).upgradeToAndCall( + await registry.getAddress(), + "0x" + ); + + await expect(upgradeTx).to.be.revertedWithCustomError(zns.accessController, AC_UNAUTHORIZED_ERR) + .withArgs(randomUser.address, GOVERNOR_ROLE); }); it("Verifies that variable values are not changed in the upgrade process", async () => { diff --git a/test/ZNSRootRegistrar.test.ts b/test/ZNSRootRegistrar.test.ts index 241fd9e3b..07821c3dc 100644 --- a/test/ZNSRootRegistrar.test.ts +++ b/test/ZNSRootRegistrar.test.ts @@ -10,24 +10,20 @@ import { AccessType, OwnerOf, PaymentType, - getAccessRevertMsg, hashDomainLabel, DEFAULT_TOKEN_URI, distrConfigEmpty, INVALID_LENGTH_ERR, INITIALIZED_ERR, - INVALID_TOKENID_ERC_ERR, + NONEXISTENT_TOKEN_ERC_ERR, REGISTRAR_ROLE, DEFAULT_PRECISION_MULTIPLIER, DEFAULT_PRICE_CONFIG, DEFAULT_PROTOCOL_FEE_PERCENT, - NOT_AUTHORIZED_REG_ERR, - NOT_BOTH_OWNER_RAR_ERR, - NOT_TOKEN_OWNER_RAR_ERR, - ONLY_NAME_OWNER_REG_ERR, - ONLY_OWNER_REGISTRAR_REG_ERR, - INVALID_NAME_ERR, - paymentConfigEmpty, + NOT_OWNER_OF_ERR, + NOT_AUTHORIZED_ERR, + INVALID_LABEL_ERR, + paymentConfigEmpty, AC_UNAUTHORIZED_ERR, INSUFFICIENT_BALANCE_ERC_ERR, ZERO_ADDRESS_ERR, DOMAIN_EXISTS_ERR, } from "./helpers"; import { IDistributionConfig } from "./helpers/types"; import * as ethers from "ethers"; @@ -35,7 +31,7 @@ import { defaultRootRegistration } from "./helpers/register-setup"; import { checkBalance } from "./helpers/balances"; import { getPriceObject, getStakingOrProtocolFee } from "./helpers/pricing"; import { getDomainHashFromEvent } from "./helpers/events"; -import { ADMIN_ROLE, GOVERNOR_ROLE } from "../src/deploy/constants"; +import { ADMIN_ROLE, DOMAIN_TOKEN_ROLE, GOVERNOR_ROLE } from "../src/deploy/constants"; import { IERC20, ZNSRootRegistrar, @@ -48,6 +44,7 @@ import { getProxyImplAddress } from "./helpers/utils"; import { upgrades } from "hardhat"; import { getConfig } from "../src/deploy/campaign/environments"; import { IZNSContracts } from "../src/deploy/campaign/types"; +import { ZeroHash } from "ethers"; require("@nomicfoundation/hardhat-chai-matchers"); @@ -87,17 +84,19 @@ describe("ZNSRootRegistrar", () => { zns = campaign.state.contracts; + // await zns.accessController.connect(deployer).grantRole(DOMAIN_TOKEN_ROLE, await zns.domainToken.getAddress()); + mongoAdapter = campaign.dbAdapter; - await zns.meowToken.connect(deployer).approve( + await zns.zToken.connect(deployer).approve( await zns.treasury.getAddress(), ethers.MaxUint256 ); - userBalanceInitial = ethers.parseEther("1000000000000000000"); - // Give funds to user - await zns.meowToken.connect(user).approve(await zns.treasury.getAddress(), ethers.MaxUint256); - await zns.meowToken.mint(user.address, userBalanceInitial); + // Give funds to user. leave half of the amount in the deployer wallet + userBalanceInitial = await zns.zToken.balanceOf(deployer.address) / 2n; + await zns.zToken.connect(user).approve(await zns.treasury.getAddress(), userBalanceInitial); + await zns.zToken.connect(deployer).transfer(user.address, userBalanceInitial); }); afterEach(async () => { @@ -118,14 +117,14 @@ describe("ZNSRootRegistrar", () => { tokenURI, distrConfig, { - token: await zns.meowToken.getAddress(), + token: await zns.zToken.getAddress(), beneficiary: user.address, } ); const domainHash = hashDomainLabel(defaultDomain); const config = await zns.treasury.paymentConfigs(domainHash); - expect(config.token).to.eq(await zns.meowToken.getAddress()); + expect(config.token).to.eq(await zns.zToken.getAddress()); expect(config.beneficiary).to.eq(user.address); }); @@ -222,7 +221,7 @@ describe("ZNSRootRegistrar", () => { operator.address, operator.address, ) - ).to.be.revertedWith(INITIALIZED_ERR); + ).to.be.revertedWithCustomError(implContract, INITIALIZED_ERR); }); it("Allows transfer of 0x0 domain ownership after deployment", async () => { @@ -261,7 +260,7 @@ describe("ZNSRootRegistrar", () => { baseLength: BigInt("6"), maxLength: BigInt("35"), maxPrice: ethers.parseEther("150"), - minPrice: ethers.parseEther("10"), + curveMultiplier: BigInt(1000), precisionMultiplier: DEFAULT_PRECISION_MULTIPLIER, feePercentage: DEFAULT_PROTOCOL_FEE_PERCENT, isSet: true, @@ -275,7 +274,7 @@ describe("ZNSRootRegistrar", () => { await expect(pricerTx).to.emit(zns.curvePricer, "PriceConfigSet").withArgs( ethers.ZeroHash, newPricerConfig.maxPrice, - newPricerConfig.minPrice, + newPricerConfig.curveMultiplier, newPricerConfig.maxLength, newPricerConfig.baseLength, newPricerConfig.precisionMultiplier, @@ -284,11 +283,11 @@ describe("ZNSRootRegistrar", () => { }); it("Confirms a user has funds and allowance for the Registrar", async () => { - const balance = await zns.meowToken.balanceOf(user.address); + const balance = await zns.zToken.balanceOf(user.address); expect(balance).to.eq(userBalanceInitial); - const allowance = await zns.meowToken.allowance(user.address, await zns.treasury.getAddress()); - expect(allowance).to.eq(ethers.MaxUint256); + const allowance = await zns.zToken.allowance(user.address, await zns.treasury.getAddress()); + expect(allowance).to.eq(userBalanceInitial); }); it("Should revert when initialize() without ADMIN_ROLE", async () => { @@ -311,7 +310,8 @@ describe("ZNSRootRegistrar", () => { } ); - await expect(tx).to.be.revertedWith(getAccessRevertMsg(user.address, ADMIN_ROLE)); + await expect(tx).to.be.revertedWithCustomError(zns.accessController, AC_UNAUTHORIZED_ERR) + .withArgs(user.address, ADMIN_ROLE); }); it("Should NOT initialize twice", async () => { @@ -323,7 +323,10 @@ describe("ZNSRootRegistrar", () => { randomUser.address, ); - await expect(tx).to.be.revertedWith("Initializable: contract is already initialized"); + await expect(tx).to.be.revertedWithCustomError( + zns.rootRegistrar, + INITIALIZED_ERR + ); }); describe("General functionality", () => { @@ -331,22 +334,19 @@ describe("ZNSRootRegistrar", () => { const isRegistrar = await zns.accessController.hasRole(REGISTRAR_ROLE, randomUser.address); expect(isRegistrar).to.be.false; - await expect( - zns.rootRegistrar.connect(randomUser).coreRegister({ - parentHash: ethers.ZeroHash, - domainHash: ethers.ZeroHash, - label: "randomname", - registrant: ethers.ZeroAddress, - price: "0", - stakeFee: "0", - domainAddress: ethers.ZeroAddress, - tokenURI: "", - isStakePayment: false, - paymentConfig: paymentConfigEmpty, - }) - ).to.be.revertedWith( - getAccessRevertMsg(randomUser.address, REGISTRAR_ROLE) - ); + await expect(zns.rootRegistrar.connect(randomUser).coreRegister({ + parentHash: ethers.ZeroHash, + domainHash: ethers.ZeroHash, + label: "randomname", + registrant: ethers.ZeroAddress, + price: "0", + stakeFee: "0", + domainAddress: ethers.ZeroAddress, + tokenURI: "", + isStakePayment: false, + paymentConfig: paymentConfigEmpty, + })).to.be.revertedWithCustomError(zns.accessController, AC_UNAUTHORIZED_ERR) + .withArgs(randomUser.address,REGISTRAR_ROLE); }); it("#isOwnerOf() returns correct bools", async () => { @@ -376,7 +376,7 @@ describe("ZNSRootRegistrar", () => { expect(isOwnerOfBothRandom).to.be.false; // transfer token - await zns.domainToken.connect(user).transferFrom(user.address, randomUser.address, tokenId); + await zns.domainToken.connect(user).updateTokenOwner(user.address, randomUser.address, tokenId); const isOwnerOfTokenUser = await zns.rootRegistrar.isOwnerOf( domainHash, user.address, @@ -410,15 +410,19 @@ describe("ZNSRootRegistrar", () => { ).to.be.reverted; }); + it("#isOwnerOf() should revert if wrong enum value is passed", async () => { + await expect( + zns.rootRegistrar.isOwnerOf(ethers.ZeroHash, user.address, 3) + ).to.be.reverted; + }); + it("#setSubRegistrar() should revert if called by address without ADMIN_ROLE", async () => { const isAdmin = await zns.accessController.hasRole(ADMIN_ROLE, randomUser.address); expect(isAdmin).to.be.false; - await expect( - zns.rootRegistrar.connect(randomUser).setSubRegistrar(randomUser.address) - ).to.be.revertedWith( - getAccessRevertMsg(randomUser.address, ADMIN_ROLE) - ); + await expect(zns.rootRegistrar.connect(randomUser).setSubRegistrar(randomUser.address)) + .to.be.revertedWithCustomError(zns.accessController, AC_UNAUTHORIZED_ERR) + .withArgs(randomUser.address, ADMIN_ROLE); }); it("#setSubRegistrar() should set the correct address", async () => { @@ -432,8 +436,9 @@ describe("ZNSRootRegistrar", () => { it("#setSubRegistrar() should NOT set the address to zero address", async () => { await expect( zns.rootRegistrar.connect(admin).setSubRegistrar(ethers.ZeroAddress) - ).to.be.revertedWith( - "ZNSRootRegistrar: subRegistrar_ is 0x0 address" + ).to.be.revertedWithCustomError( + zns.rootRegistrar, + ZERO_ADDRESS_ERR ); }); }); @@ -448,7 +453,7 @@ describe("ZNSRootRegistrar", () => { zns, domainName: emptyName, }) - ).to.be.revertedWith(INVALID_LENGTH_ERR); + ).to.be.revertedWithCustomError(zns.curvePricer, INVALID_LENGTH_ERR); }); it("Can register a TLD with characters [a-z0-9-]", async () => { @@ -538,7 +543,7 @@ describe("ZNSRootRegistrar", () => { zns, domainName: nameA, }) - ).to.be.revertedWith(INVALID_NAME_ERR); + ).to.be.revertedWithCustomError(zns.curvePricer, INVALID_LABEL_ERR); await expect( defaultRootRegistration({ @@ -546,7 +551,7 @@ describe("ZNSRootRegistrar", () => { zns, domainName: nameB, }) - ).to.be.revertedWith(INVALID_NAME_ERR); + ).to.be.revertedWithCustomError(zns.curvePricer, INVALID_LABEL_ERR); await expect( defaultRootRegistration({ @@ -554,7 +559,7 @@ describe("ZNSRootRegistrar", () => { zns, domainName: nameC, }) - ).to.be.revertedWith(INVALID_NAME_ERR); + ).to.be.revertedWithCustomError(zns.curvePricer, INVALID_LABEL_ERR); await expect( defaultRootRegistration({ @@ -562,7 +567,7 @@ describe("ZNSRootRegistrar", () => { zns, domainName: nameD, }) - ).to.be.revertedWith(INVALID_NAME_ERR); + ).to.be.revertedWithCustomError(zns.curvePricer, INVALID_LABEL_ERR); }); // eslint-disable-next-line max-len @@ -634,8 +639,8 @@ describe("ZNSRootRegistrar", () => { }); it("Stakes and saves the correct amount and token, takes the correct fee and sends fee to Zero Vault", async () => { - const balanceBeforeUser = await zns.meowToken.balanceOf(user.address); - const balanceBeforeVault = await zns.meowToken.balanceOf(zeroVault.address); + const balanceBeforeUser = await zns.zToken.balanceOf(user.address); + const balanceBeforeVault = await zns.zToken.balanceOf(zeroVault.address); // Deploy "wilder" with default configuration await defaultRootRegistration({ @@ -655,14 +660,14 @@ describe("ZNSRootRegistrar", () => { } = getPriceObject(defaultDomain, DEFAULT_PRICE_CONFIG); await checkBalance({ - token: zns.meowToken as IERC20, + token: zns.zToken as IERC20, balanceBefore: balanceBeforeUser, userAddress: user.address, target: totalPrice, }); await checkBalance({ - token: zns.meowToken as IERC20, + token: zns.zToken as IERC20, balanceBefore: balanceBeforeVault, userAddress: zeroVault.address, target: stakeFee, @@ -672,7 +677,7 @@ describe("ZNSRootRegistrar", () => { const { amount: staked, token } = await zns.treasury.stakedForDomain(domainHash); expect(staked).to.eq(expectedPrice); - expect(token).to.eq(await zns.meowToken.getAddress()); + expect(token).to.eq(await zns.zToken.getAddress()); }); it("Sets the correct data in Registry", async () => { @@ -700,15 +705,21 @@ describe("ZNSRootRegistrar", () => { }); it("Fails when the user does not have enough funds", async () => { - const balance = await zns.meowToken.balanceOf(user.address); - await zns.meowToken.connect(user).transfer(randomUser.address, balance); + const balance = await zns.zToken.balanceOf(user.address); + await zns.zToken.connect(user).transfer(randomUser.address, balance); const tx = defaultRootRegistration({ user, zns, domainName: defaultDomain, }); - await expect(tx).to.be.revertedWith("ERC20: transfer amount exceeds balance"); + const { price, stakeFee } = await zns.curvePricer.getPriceAndFee(ZeroHash, defaultDomain, true); + + await expect(tx).to.be.revertedWithCustomError( + zns.zToken, + INSUFFICIENT_BALANCE_ERC_ERR + ) + .withArgs(user.address, 0n, price + stakeFee); }); it("Disallows creation of a duplicate domain", async () => { @@ -723,7 +734,7 @@ describe("ZNSRootRegistrar", () => { domainName: defaultDomain, }); - await expect(failTx).to.be.revertedWith("ZNSRootRegistrar: Domain already exists"); + await expect(failTx).to.be.revertedWithCustomError(zns.rootRegistrar, DOMAIN_EXISTS_ERR); }); it("Successfully registers a domain without resolver content", async () => { @@ -794,10 +805,9 @@ describe("ZNSRootRegistrar", () => { it("Should NOT charge any tokens if price and/or stake fee is 0", async () => { // set config on CurvePricer for the price to be 0 await zns.curvePricer.connect(deployer).setMaxPrice(ethers.ZeroHash, "0"); - await zns.curvePricer.connect(deployer).setMinPrice(ethers.ZeroHash, "0"); - const userBalanceBefore = await zns.meowToken.balanceOf(user.address); - const vaultBalanceBefore = await zns.meowToken.balanceOf(zeroVault.address); + const userBalanceBefore = await zns.zToken.balanceOf(user.address); + const vaultBalanceBefore = await zns.zToken.balanceOf(zeroVault.address); // register a domain await zns.rootRegistrar.connect(user).registerRootDomain( @@ -811,8 +821,8 @@ describe("ZNSRootRegistrar", () => { } ); - const userBalanceAfter = await zns.meowToken.balanceOf(user.address); - const vaultBalanceAfter = await zns.meowToken.balanceOf(zeroVault.address); + const userBalanceAfter = await zns.zToken.balanceOf(user.address); + const vaultBalanceAfter = await zns.zToken.balanceOf(zeroVault.address); expect(userBalanceBefore).to.eq(userBalanceAfter); expect(vaultBalanceBefore).to.eq(vaultBalanceAfter); @@ -823,10 +833,10 @@ describe("ZNSRootRegistrar", () => { expect(exists).to.be.true; // make sure no transfers happened - const transferEventFilter = zns.meowToken.filters.Transfer( + const transferEventFilter = zns.zToken.filters.Transfer( user.address, ); - const events = await zns.meowToken.queryFilter(transferEventFilter); + const events = await zns.zToken.queryFilter(transferEventFilter); expect(events.length).to.eq(0); }); }); @@ -843,9 +853,9 @@ describe("ZNSRootRegistrar", () => { const { amount: staked, token } = await zns.treasury.stakedForDomain(domainHash); // Transfer the domain token - await zns.domainToken.connect(deployer).transferFrom(deployer.address, user.address, tokenId); + await zns.domainToken.connect(deployer).updateTokenOwner(deployer.address, user.address, tokenId); - // Verify owner in registry + // Verify owner in Registry is unchanged after using `updateTokenOwner` const originalOwner = await zns.registry.connect(deployer).getDomainOwner(domainHash); expect(originalOwner).to.equal(deployer.address); @@ -863,7 +873,7 @@ describe("ZNSRootRegistrar", () => { // Verify same amount is staked const { amount: stakedAfterReclaim, token: tokenAfterReclaim } = await zns.treasury.stakedForDomain(domainHash); expect(staked).to.equal(stakedAfterReclaim); - expect(tokenAfterReclaim).to.equal(await zns.meowToken.getAddress()); + expect(tokenAfterReclaim).to.equal(await zns.zToken.getAddress()); expect(token).to.equal(tokenAfterReclaim); }); @@ -893,9 +903,10 @@ describe("ZNSRootRegistrar", () => { }); // Reclaim the Domain const tx = zns.rootRegistrar.connect(user).reclaimDomain(domainHash); - - // Verify Domain is not reclaimed - await expect(tx).to.be.revertedWith(NOT_TOKEN_OWNER_RAR_ERR); + await expect(tx).to.be.revertedWithCustomError( + zns.rootRegistrar, + NOT_OWNER_OF_ERR + ).withArgs(1n, user.address, domainHash); // Verify domain is not owned in registrar const registryOwner = await zns.registry.connect(user).getDomainOwner(domainHash); @@ -908,7 +919,10 @@ describe("ZNSRootRegistrar", () => { const tx = zns.rootRegistrar.connect(user).reclaimDomain(domainHash); // Verify Domain is not reclaimed - await expect(tx).to.be.revertedWith(INVALID_TOKENID_ERC_ERR); + await expect(tx).to.be.revertedWithCustomError( + zns.domainToken, + NONEXISTENT_TOKEN_ERC_ERR + ).withArgs(BigInt(domainHash)); }); it("Domain Token can be reclaimed, transferred, and then reclaimed again", async () => { @@ -947,13 +961,13 @@ describe("ZNSRootRegistrar", () => { // Verify same amount is staked const { amount: stakedAfterReclaim, token: tokenAfterReclaim } = await zns.treasury.stakedForDomain(domainHash); expect(staked).to.equal(stakedAfterReclaim); - expect(tokenAfterReclaim).to.equal(await zns.meowToken.getAddress()); + expect(tokenAfterReclaim).to.equal(await zns.zToken.getAddress()); expect(token).to.equal(tokenAfterReclaim); }); it("Can revoke and unstake after reclaiming", async () => { // Verify Balance - const balance = await zns.meowToken.balanceOf(user.address); + const balance = await zns.zToken.balanceOf(user.address); expect(balance).to.eq(userBalanceInitial); // Register Top level @@ -970,7 +984,7 @@ describe("ZNSRootRegistrar", () => { } = getPriceObject(defaultDomain, DEFAULT_PRICE_CONFIG); const { amount: staked, token } = await zns.treasury.stakedForDomain(domainHash); expect(staked).to.eq(expectedStaked); - expect(token).to.eq(await zns.meowToken.getAddress()); + expect(token).to.eq(await zns.zToken.getAddress()); // Transfer the domain token await zns.domainToken.connect(deployer).transferFrom(deployer.address, user.address, tokenId); @@ -990,7 +1004,7 @@ describe("ZNSRootRegistrar", () => { // Verify final balances const computedFinalBalance = balance + staked - protocolFee; - const finalBalance = await zns.meowToken.balanceOf(user.address); + const finalBalance = await zns.zToken.balanceOf(user.address); expect(computedFinalBalance).to.equal(finalBalance); }); }); @@ -1016,12 +1030,12 @@ describe("ZNSRootRegistrar", () => { const price = await zns.curvePricer.getPrice(ethers.ZeroHash, defaultDomain, false); const protocolFee = await zns.curvePricer.getFeeForPrice(ethers.ZeroHash, price); - const balanceBefore = await zns.meowToken.balanceOf(user.address); + const balanceBefore = await zns.zToken.balanceOf(user.address); // is revoke meant to be free if owner of parent? register subdomain is await zns.rootRegistrar.connect(user).revokeDomain(domainHash); - const balanceAfter = await zns.meowToken.balanceOf(user.address); + const balanceAfter = await zns.zToken.balanceOf(user.address); expect(balanceAfter).to.eq(balanceBefore + price - protocolFee); }); @@ -1074,9 +1088,10 @@ describe("ZNSRootRegistrar", () => { // Verify token has been burned const ownerOfTx = zns.domainToken.connect(user).ownerOf(tokenId); - await expect(ownerOfTx).to.be.revertedWith( - INVALID_TOKENID_ERC_ERR - ); + await expect(ownerOfTx).to.be.revertedWithCustomError( + zns.domainToken, + NONEXISTENT_TOKEN_ERC_ERR + ).withArgs(BigInt(domainHash)); // Verify Domain Record Deleted const exists = await zns.registry.exists(domainHash); @@ -1099,12 +1114,15 @@ describe("ZNSRootRegistrar", () => { // Verify transaction is reverted const tx = zns.rootRegistrar.connect(user).revokeDomain(fakeHash); - await expect(tx).to.be.revertedWith(NOT_BOTH_OWNER_RAR_ERR); + await expect(tx).to.be.revertedWithCustomError( + zns.rootRegistrar, + NOT_OWNER_OF_ERR + ); }); it("Revoking domain unstakes", async () => { // Verify Balance - const balance = await zns.meowToken.balanceOf(user.address); + const balance = await zns.zToken.balanceOf(user.address); expect(balance).to.eq(userBalanceInitial); // Register Top level @@ -1121,10 +1139,10 @@ describe("ZNSRootRegistrar", () => { } = getPriceObject(defaultDomain, DEFAULT_PRICE_CONFIG); const { amount: staked, token } = await zns.treasury.stakedForDomain(domainHash); expect(staked).to.eq(expectedStaked); - expect(token).to.eq(await zns.meowToken.getAddress()); + expect(token).to.eq(await zns.zToken.getAddress()); // Get balance after staking - const balanceAfterStaking = await zns.meowToken.balanceOf(user.address); + const balanceAfterStaking = await zns.zToken.balanceOf(user.address); // Revoke the domain await zns.rootRegistrar.connect(user).revokeDomain(domainHash); @@ -1141,7 +1159,7 @@ describe("ZNSRootRegistrar", () => { const computedBalanceAfterStaking = balanceAfterStaking + staked; const balanceMinusFee = balance - expectedStakeFee; expect(computedBalanceAfterStaking).to.equal(balanceMinusFee); - const finalBalance = await zns.meowToken.balanceOf(user.address); + const finalBalance = await zns.zToken.balanceOf(user.address); expect(computedBalanceAfterStaking - protocolFee).to.equal(finalBalance); }); @@ -1157,7 +1175,10 @@ describe("ZNSRootRegistrar", () => { // Try to revoke domain const tx = zns.rootRegistrar.connect(user).revokeDomain(parentDomainHash); - await expect(tx).to.be.revertedWith(NOT_BOTH_OWNER_RAR_ERR); + await expect(tx).to.be.revertedWithCustomError( + zns.rootRegistrar, + NOT_OWNER_OF_ERR + ).withArgs(2n, user.address, parentDomainHash); }); it("No one can revoke if Token and Name have different owners", async () => { @@ -1167,19 +1188,22 @@ describe("ZNSRootRegistrar", () => { zns, user: deployer, }); - const owner = await zns.registry.connect(user).getDomainOwner(parentDomainHash); + const owner = await zns.registry.getDomainOwner(parentDomainHash); expect(owner).to.not.equal(user.address); const tokenId = BigInt(parentDomainHash); - await zns.domainToken.transferFrom(deployer.address, user.address, tokenId); + await zns.domainToken.connect(deployer).updateTokenOwner(deployer.address, user.address, tokenId); // Try to revoke domain as a new owner of the token const tx = zns.rootRegistrar.connect(user).revokeDomain(parentDomainHash); - await expect(tx).to.be.revertedWith(NOT_BOTH_OWNER_RAR_ERR); + await expect(tx).to.be.revertedWithCustomError( + zns.rootRegistrar, + NOT_OWNER_OF_ERR + ); const tx2 = zns.rootRegistrar.connect(deployer).revokeDomain(parentDomainHash); - await expect(tx2).to.be.revertedWith(NOT_BOTH_OWNER_RAR_ERR); + await expect(tx2).to.be.revertedWithCustomError(zns.rootRegistrar, NOT_OWNER_OF_ERR); }); it("After domain has been revoked, an old operator can NOT access Registry", async () => { @@ -1203,8 +1227,9 @@ describe("ZNSRootRegistrar", () => { domainHash, operator.address ); - await expect(tx2).to.be.revertedWith( - ONLY_OWNER_REGISTRAR_REG_ERR + await expect(tx2).to.be.revertedWithCustomError( + zns.registry, + NOT_AUTHORIZED_ERR ); const tx3 = zns.registry @@ -1214,9 +1239,7 @@ describe("ZNSRootRegistrar", () => { user.address, operator.address ); - await expect(tx3).to.be.revertedWith( - ONLY_NAME_OWNER_REG_ERR - ); + await expect(tx3).to.be.revertedWithCustomError(zns.registry, NOT_AUTHORIZED_ERR); const tx4 = zns.registry .connect(operator) @@ -1224,9 +1247,7 @@ describe("ZNSRootRegistrar", () => { domainHash, zeroVault.address ); - await expect(tx4).to.be.revertedWith( - NOT_AUTHORIZED_REG_ERR - ); + await expect(tx4).to.be.revertedWithCustomError(zns.registry, NOT_AUTHORIZED_ERR); }); }); @@ -1245,14 +1266,16 @@ describe("ZNSRootRegistrar", () => { it("Should revert if not called by ADMIN", async () => { const tx = zns.rootRegistrar.connect(user).setAccessController(randomUser.address); - await expect(tx).to.be.revertedWith( - getAccessRevertMsg(user.address, ADMIN_ROLE) - ); + await expect(tx).to.be.revertedWithCustomError(zns.accessController, AC_UNAUTHORIZED_ERR) + .withArgs(user.address,ADMIN_ROLE); }); it("Should revert if new AccessController is address zero", async () => { const tx = zns.rootRegistrar.connect(deployer).setAccessController(ethers.ZeroAddress); - await expect(tx).to.be.revertedWith("AC: _accessController is 0x0 address"); + await expect(tx).to.be.revertedWithCustomError( + zns.rootRegistrar, + ZERO_ADDRESS_ERR + ); }); }); @@ -1270,14 +1293,16 @@ describe("ZNSRootRegistrar", () => { it("Should revert if not called by ADMIN", async () => { const tx = zns.rootRegistrar.connect(user).setRegistry(randomUser.address); - await expect(tx).to.be.revertedWith( - getAccessRevertMsg(user.address, ADMIN_ROLE) - ); + await expect(tx).to.be.revertedWithCustomError(zns.accessController, AC_UNAUTHORIZED_ERR) + .withArgs(user.address,ADMIN_ROLE); }); it("Should revert if ZNSRegistry is address zero", async () => { const tx = zns.rootRegistrar.connect(deployer).setRegistry(ethers.ZeroAddress); - await expect(tx).to.be.revertedWith("ARegistryWired: _registry can not be 0x0 address"); + await expect(tx).to.be.revertedWithCustomError( + zns.rootRegistrar, + ZERO_ADDRESS_ERR + ); }); }); @@ -1295,14 +1320,16 @@ describe("ZNSRootRegistrar", () => { it("Should revert if not called by ADMIN", async () => { const tx = zns.rootRegistrar.connect(user).setTreasury(randomUser.address); - await expect(tx).to.be.revertedWith( - getAccessRevertMsg(user.address, ADMIN_ROLE) - ); + await expect(tx).to.be.revertedWithCustomError(zns.accessController, AC_UNAUTHORIZED_ERR) + .withArgs(user.address,ADMIN_ROLE); }); it("Should revert if Treasury is address zero", async () => { const tx = zns.rootRegistrar.connect(deployer).setTreasury(ethers.ZeroAddress); - await expect(tx).to.be.revertedWith("ZNSRootRegistrar: treasury_ is 0x0 address"); + await expect(tx).to.be.revertedWithCustomError( + zns.rootRegistrar, + ZERO_ADDRESS_ERR + ); }); }); @@ -1320,14 +1347,37 @@ describe("ZNSRootRegistrar", () => { it("Should revert if not called by ADMIN", async () => { const tx = zns.rootRegistrar.connect(user).setDomainToken(randomUser.address); - await expect(tx).to.be.revertedWith( - getAccessRevertMsg(user.address, ADMIN_ROLE) - ); + await expect(tx).to.be.revertedWithCustomError(zns.accessController, AC_UNAUTHORIZED_ERR) + .withArgs(user.address,ADMIN_ROLE); }); it("Should revert if DomainToken is address zero", async () => { const tx = zns.rootRegistrar.connect(deployer).setDomainToken(ethers.ZeroAddress); - await expect(tx).to.be.revertedWith("ZNSRootRegistrar: domainToken_ is 0x0 address"); + await expect(tx).to.be.revertedWithCustomError( + zns.rootRegistrar, + ZERO_ADDRESS_ERR + ); + }); + }); + + describe("#setRootPricer", () => { + it("#setRootPricer() should set the rootPricer correctly", async () => { + const newPricer = zns.fixedPricer.target; + await zns.rootRegistrar.connect(admin).setRootPricer(newPricer); + + expect(await zns.rootRegistrar.rootPricer()).to.eq(newPricer); + + // set back + await zns.rootRegistrar.connect(admin).setRootPricer(zns.curvePricer.target); + }); + + it("#setRootPricer() should NOT let set 0x0 address as the new pricer", async () => { + await expect( + zns.rootRegistrar.connect(admin).setRootPricer(ethers.ZeroAddress) + ).to.be.revertedWithCustomError( + zns.subRegistrar, + ZERO_ADDRESS_ERR + ); }); }); }); @@ -1341,7 +1391,10 @@ describe("ZNSRootRegistrar", () => { const registrar = await registrarFactory.deploy(); await registrar.waitForDeployment(); - const upgradeTx = zns.rootRegistrar.connect(deployer).upgradeTo(await registrar.getAddress()); + const upgradeTx = zns.rootRegistrar.connect(deployer).upgradeToAndCall( + await registrar.getAddress(), + "0x" + ); await expect(upgradeTx).to.not.be.reverted; }); @@ -1350,11 +1403,13 @@ describe("ZNSRootRegistrar", () => { const registrar = await registrarFactory.deploy(); await registrar.waitForDeployment(); - const tx = zns.rootRegistrar.connect(randomUser).upgradeTo(await registrar.getAddress()); - - await expect(tx).to.be.revertedWith( - getAccessRevertMsg(randomUser.address, GOVERNOR_ROLE) + const tx = zns.rootRegistrar.connect(randomUser).upgradeToAndCall( + await registrar.getAddress(), + "0x" ); + + await expect(tx).to.be.revertedWithCustomError(zns.accessController, AC_UNAUTHORIZED_ERR) + .withArgs(randomUser.address, GOVERNOR_ROLE); }); it("Verifies that variable values are not changed in the upgrade process", async () => { @@ -1368,8 +1423,8 @@ describe("ZNSRootRegistrar", () => { const domainName = "world"; const domainHash = hashDomainLabel(domainName); - await zns.meowToken.connect(randomUser).approve(await zns.treasury.getAddress(), ethers.MaxUint256); - await zns.meowToken.mint(randomUser.address, DEFAULT_PRICE_CONFIG.maxPrice); + await zns.zToken.connect(randomUser).approve(await zns.treasury.getAddress(), ethers.MaxUint256); + await zns.zToken.connect(deployer).transfer(randomUser.address, DEFAULT_PRICE_CONFIG.maxPrice); await zns.rootRegistrar.connect(randomUser).registerRootDomain( domainName, diff --git a/test/ZNSStringResolver.test.ts b/test/ZNSStringResolver.test.ts new file mode 100644 index 000000000..5fafa4a66 --- /dev/null +++ b/test/ZNSStringResolver.test.ts @@ -0,0 +1,445 @@ +import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; +import * as hre from "hardhat"; +import { + AC_UNAUTHORIZED_ERR, + distrConfigEmpty, + GOVERNOR_ROLE, + hashDomainLabel, + INITIALIZED_ERR, NOT_AUTHORIZED_ERR, + paymentConfigEmpty, + validateUpgrade, +} from "./helpers"; +import { IZNSCampaignConfig, IZNSContracts } from "../src/deploy/campaign/types"; +import { runZnsCampaign } from "../src/deploy/zns-campaign"; +import { expect } from "chai"; +import * as ethers from "ethers"; +import { registrationWithSetup } from "./helpers/register-setup"; +import { + ERC165__factory, + ZNSAccessController, ZNSDomainToken, ZNSRegistry, ZNSRootRegistrar, + ZNSStringResolver, + ZTokenMock, + ZNSStringResolverUpgradeMock__factory, + ZNSTreasury, +} from "../typechain"; +import { DeployCampaign, MongoDBAdapter } from "@zero-tech/zdc"; +import { HardhatRuntimeEnvironment } from "hardhat/types"; +import { getConfig } from "../src/deploy/campaign/environments"; +import { IZNSContractsLocal } from "./helpers/types"; + + +describe("ZNSStringResolver", () => { + describe("Single state tests", () => { + let zeroVault : SignerWithAddress; + let user : SignerWithAddress; + let deployAdmin : SignerWithAddress; + let deployer : SignerWithAddress; + let admin : SignerWithAddress; + + const env = "dev"; + + let stringResolver : ZNSStringResolver; + let registry : ZNSRegistry; + let campaign : DeployCampaign< + HardhatRuntimeEnvironment, + SignerWithAddress, + IZNSCampaignConfig, + IZNSContracts + >; + let rootRegistrar : ZNSRootRegistrar; + let accessController : ZNSAccessController; + + let userBalance : bigint; + + const uri = "https://example.com/817c64af"; + const domainName = "domain"; + const domainNameHash = hashDomainLabel(domainName); + + let mongoAdapter : MongoDBAdapter; + + before(async () => { + [ + deployer, + zeroVault, + user, + deployAdmin, + admin, + ] = await hre.ethers.getSigners(); + + const campaignConfig = await getConfig({ + deployer, + governors: [deployAdmin.address], + admins: [admin.address], + zeroVaultAddress: zeroVault.address, + env, + }); + + campaign = await runZnsCampaign({ + config: campaignConfig, + }); + + let zToken : ZTokenMock; + let treasury : ZNSTreasury; + + ({ + accessController, + stringResolver, + registry, + zToken, + treasury, + rootRegistrar, + dbAdapter: mongoAdapter, + } = campaign); + + userBalance = ethers.parseEther("1000000"); + await zToken.connect(admin).transfer(user.address, userBalance); + await zToken.connect(user).approve(await treasury.getAddress(), ethers.MaxUint256); + }); + + after(async () => { + await mongoAdapter.dropDB(); + }); + + it("Should not let initialize the contract twice", async () => { + await expect( + stringResolver.initialize( + await campaign.state.contracts.accessController.getAddress(), + await registry.getAddress(), + ) + ).to.be.revertedWithCustomError( + stringResolver, + INITIALIZED_ERR + ); + }); + + it("Should correctly attach the string to the domain", async () => { + + const newString = "hippopotamus"; + + await rootRegistrar.connect(user).registerRootDomain( + domainName, + ethers.ZeroAddress, + uri, + distrConfigEmpty, + paymentConfigEmpty, + ); + await stringResolver.connect(user).setString(domainNameHash, newString); + + expect( + await stringResolver.resolveDomainString(domainNameHash) + ).to.eq( + newString + ); + }); + + it("Should setRegistry() using ADMIN_ROLE and emit an event", async () => { + await expect( + stringResolver.connect(admin).setRegistry(admin.address) + ) + .to.emit(stringResolver, "RegistrySet") + .withArgs(admin.address); + + expect(await stringResolver.registry()).to.equal(admin.address); + + // reset regestry address on stringResolver + await stringResolver.connect(admin).setRegistry(registry.target); + }); + + it("Should revert when setRegistry() without ADMIN_ROLE", async () => { + await expect( + stringResolver.connect(user).setRegistry(user.address) + ).to.be.revertedWithCustomError( + accessController, + AC_UNAUTHORIZED_ERR + ); + + // reset regestry address on stringResolver + await stringResolver.connect(admin).setRegistry(registry.target); + }); + + it("Should revert when setAccessController() without ADMIN_ROLE " + + "(It cannot rewrite AC address after an incorrect address has been submitted to it)", async () => { + await expect( + stringResolver.connect(user).setAccessController(user.address) + ).to.be.revertedWithCustomError( + accessController, + AC_UNAUTHORIZED_ERR + ); + }); + + it("Should setAccessController() correctly with ADMIN_ROLE " + + "(It cannot rewrite AC address after an incorrect address has been submitted to it)", async () => { + + await expect( + stringResolver.connect(admin).setAccessController(admin.address) + ).to.emit( + stringResolver, "AccessControllerSet" + ).withArgs(admin.address); + + expect( + await stringResolver.getAccessController() + ).to.equal(admin.address); + }); + }); + + describe("New campaign for each test", () => { + + let deployer : SignerWithAddress; + let zeroVault : SignerWithAddress; + let operator : SignerWithAddress; + let user : SignerWithAddress; + let deployAdmin : SignerWithAddress; + let admin : SignerWithAddress; + + const env = "dev"; + + let stringResolver : ZNSStringResolver; + let registry : ZNSRegistry; + let campaign : DeployCampaign< + HardhatRuntimeEnvironment, + SignerWithAddress, + IZNSCampaignConfig, + IZNSContracts + >; + let accessController : ZNSAccessController; + let domainToken : ZNSDomainToken; + let operatorBalance : bigint; + let userBalance : bigint; + let deployerBalance : bigint; + + let zns : IZNSContractsLocal; + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + let mongoAdapter : MongoDBAdapter; + + beforeEach(async () => { + + [ + deployer, + zeroVault, + user, + deployAdmin, + admin, + operator, + ] = await hre.ethers.getSigners(); + + const campaignConfig = await getConfig({ + deployer: deployer as unknown as SignerWithAddress, + governors: [deployAdmin.address], + admins: [admin.address], + zeroVaultAddress: zeroVault.address, + env, + }); + + campaign = await runZnsCampaign({ + config: campaignConfig, + }); + + let zToken : ZTokenMock; + let treasury : ZNSTreasury; + + zns = campaign.state.contracts as unknown as IZNSContractsLocal; + + // eslint-disable-next-line max-len + ({ stringResolver, registry, zToken, treasury, accessController, domainToken, dbAdapter: mongoAdapter } = campaign); + + operatorBalance = ethers.parseEther("100000000"); + await zToken.connect(admin).transfer(operator.address, operatorBalance); + await zToken.connect(operator).approve(await treasury.getAddress(), ethers.MaxUint256); + + userBalance = ethers.parseEther("100000000"); + await zToken.connect(admin).transfer(user.address, userBalance); + await zToken.connect(user).approve(await treasury.getAddress(), ethers.MaxUint256); + + deployerBalance = ethers.parseEther("10000000"); + await zToken.connect(admin).transfer(deployer.address, deployerBalance); + await zToken.connect(deployer).approve(await treasury.getAddress(), ethers.MaxUint256); + }); + + it("Should not allow non-owner address to setString (similar domain and string)", async () => { + + const curStringDomain = "shouldbrake"; + + await registrationWithSetup({ + zns, + user: operator, + domainLabel: curStringDomain, + domainContent: ethers.ZeroAddress, + }); + + await expect( + stringResolver.connect(user).setString(hashDomainLabel(curStringDomain), curStringDomain) + ).to.be.revertedWithCustomError( + stringResolver, + NOT_AUTHORIZED_ERR + ); + }); + + it("Should allow OWNER to setString and emit event (similar domain and string)", async () => { + + const curString = "wolf"; + const hash = hashDomainLabel(curString); + + await registrationWithSetup({ + zns, + user, + domainLabel: curString, + domainContent: ethers.ZeroAddress, + }); + + await expect( + stringResolver.connect(user).setString(hash, curString) + ).to.emit( + stringResolver, + "StringSet" + ).withArgs( + hash, + curString + ); + + expect( + await stringResolver.resolveDomainString(hash) + ).to.equal(curString); + }); + + it("Should allow OPERATOR to setString and emit event (different domain and string)", async () => { + + const curDomain = "wild"; + const curString = "wildlife"; + const hash = hashDomainLabel(curDomain); + + await registrationWithSetup({ + zns, + user: deployer, + domainLabel: curDomain, + domainContent: ethers.ZeroAddress, + }); + + await registry.connect(deployer).setOwnersOperator(operator, true); + + await expect( + stringResolver.connect(operator).setString(hash, curString) + ).to.emit( + stringResolver, + "StringSet" + ).withArgs( + hash, + curString + ); + + expect( + await stringResolver.resolveDomainString(hash) + ).to.equal(curString); + }); + + it("Should setAccessController() correctly with ADMIN_ROLE", async () => { + await expect( + stringResolver.connect(admin).setAccessController(admin.address) + ).to.emit( + stringResolver, "AccessControllerSet" + ).withArgs(admin.address); + + expect( + await stringResolver.getAccessController() + ).to.equal(admin.address); + }); + + it("Should revert when setAccessController() without ADMIN_ROLE", async () => { + await expect( + stringResolver.connect(user).setAccessController(user.address) + ).to.be.revertedWithCustomError( + accessController, + AC_UNAUTHORIZED_ERR + ); + }); + + it("Should support the IZNSAddressResolver interface ID", async () => { + const interfaceId = await stringResolver.getInterfaceId(); + const supported = await stringResolver.supportsInterface(interfaceId); + expect(supported).to.be.true; + }); + + it("Should support the ERC-165 interface ID", async () => { + expect( + await stringResolver.supportsInterface( + ERC165__factory.createInterface() + .getFunction("supportsInterface").selector + ) + ).to.be.true; + }); + + it("Should not support other interface IDs", async () => { + expect( + await stringResolver.supportsInterface("0xffffffff") + ).to.be.false; + }); + + + describe("UUPS", () => { + + it("Allows an authorized user to upgrade the StringResolver", async () => { + // deployer deployed, deployAdmin wanna edit + const factory = new ZNSStringResolverUpgradeMock__factory(deployer); + const newStringResolver = await factory.deploy(); + await newStringResolver.waitForDeployment(); + + // Confirm the deployer is a governor + expect( + await accessController.hasRole(GOVERNOR_ROLE, deployAdmin.address) + ).to.be.true; + + const upgradeTx = domainToken.connect(deployAdmin).upgradeToAndCall(await newStringResolver.getAddress(), "0x"); + + await expect(upgradeTx).to.not.be.reverted; + }); + + it("Fails to upgrade if the caller is not authorized", async () => { + const factory = new ZNSStringResolverUpgradeMock__factory(deployer); + + // DomainToken to upgrade to + const newStringResolver = await factory.deploy(); + await newStringResolver.waitForDeployment(); + + // Confirm the operator is not a governor + await expect( + accessController.checkGovernor(operator.address) + ).to.be.revertedWithCustomError( + accessController, + AC_UNAUTHORIZED_ERR + ); + + const upgradeTx = domainToken.connect(operator).upgradeToAndCall(await newStringResolver.getAddress(), "0x"); + + await expect(upgradeTx).to.be.revertedWithCustomError( + accessController, + AC_UNAUTHORIZED_ERR + ); + }); + + // TODO: Falls on the role. I think, cannot give a REGISTRAR_ROLE to mock "deployAdmin". + it("Verifies that variable values are not changed in the upgrade process", async () => { + const curString = "variableschange"; + + await registrationWithSetup({ + zns, + user: deployer, + domainLabel: curString, + domainContent: ethers.ZeroAddress, + }); + + const factory = new ZNSStringResolverUpgradeMock__factory(deployer); + const newStringResolver = await factory.deploy(); + await newStringResolver.waitForDeployment(); + + await stringResolver.connect(deployer).setString(hashDomainLabel(curString), curString); + + const contractCalls = [ + stringResolver.registry(), + stringResolver.resolveDomainString(hashDomainLabel(curString)), + ]; + + await validateUpgrade(deployAdmin, stringResolver, newStringResolver, factory, contractCalls); + }); + }); + }); +}); diff --git a/test/ZNSSubRegistrar.test.ts b/test/ZNSSubRegistrar.test.ts index 89d13d795..115ebcd44 100644 --- a/test/ZNSSubRegistrar.test.ts +++ b/test/ZNSSubRegistrar.test.ts @@ -8,18 +8,24 @@ import { distrConfigEmpty, DISTRIBUTION_LOCKED_NOT_EXIST_ERR, fullDistrConfigEmpty, - getAccessRevertMsg, getPriceObject, getStakingOrProtocolFee, GOVERNOR_ROLE, INITIALIZED_ERR, - INVALID_NAME_ERR, - INVALID_TOKENID_ERC_ERR, NO_BENEFICIARY_ERR, - ONLY_NAME_OWNER_REG_ERR, paymentConfigEmpty, + INVALID_LABEL_ERR, + NONEXISTENT_TOKEN_ERC_ERR, + NO_BENEFICIARY_ERR, + NOT_AUTHORIZED_ERR, + paymentConfigEmpty, PaymentType, - DECAULT_PRECISION, + DEFAULT_PRECISION, DEFAULT_PRICE_CONFIG, validateUpgrade, + AC_UNAUTHORIZED_ERR, + INSUFFICIENT_BALANCE_ERC_ERR, + INSUFFICIENT_ALLOWANCE_ERC_ERR, + NOT_OWNER_OF_ERR, + ZERO_ADDRESS_ERR, PARENT_CONFIG_NOT_SET_ERR, DOMAIN_EXISTS_ERR, SENDER_NOT_APPROVED_ERR, } from "./helpers"; import * as hre from "hardhat"; import * as ethers from "ethers"; @@ -82,14 +88,20 @@ describe("ZNSSubRegistrar", () => { zeroVaultAddress: zeroVault.address, }); // Give funds to users + const users = [ + rootOwner, + lvl2SubOwner, + ]; + const totalAdminBalance = await zns.zToken.balanceOf(admin.address); + const userBalanceInitial = totalAdminBalance / BigInt(users.length); + await Promise.all( - [ - rootOwner, - lvl2SubOwner, - ].map(async ({ address }) => - zns.meowToken.mint(address, ethers.parseEther("100000000000"))) + users.map(async ({ address }) => + zns.zToken.connect(admin).transfer(address, userBalanceInitial) + ) ); - await zns.meowToken.connect(rootOwner).approve(await zns.treasury.getAddress(), ethers.MaxUint256); + + await zns.zToken.connect(rootOwner).approve(await zns.treasury.getAddress(), ethers.MaxUint256); rootPriceConfig = { price: ethers.parseEther("1375.612"), @@ -108,7 +120,7 @@ describe("ZNSSubRegistrar", () => { paymentType: PaymentType.DIRECT, }, paymentConfig: { - token: await zns.meowToken.getAddress(), + token: await zns.zToken.getAddress(), beneficiary: rootOwner.address, }, priceConfig: rootPriceConfig, @@ -119,7 +131,7 @@ describe("ZNSSubRegistrar", () => { it("Sets the payment config when given", async () => { const subdomain = "world-subdomain"; - await zns.meowToken.connect(lvl2SubOwner).approve(await zns.treasury.getAddress(), ethers.MaxUint256); + await zns.zToken.connect(lvl2SubOwner).approve(await zns.treasury.getAddress(), ethers.MaxUint256); await zns.subRegistrar.connect(lvl2SubOwner).registerSubdomain( rootHash, @@ -128,14 +140,14 @@ describe("ZNSSubRegistrar", () => { subTokenURI, distrConfigEmpty, { - token: await zns.meowToken.getAddress(), + token: await zns.zToken.getAddress(), beneficiary: lvl2SubOwner.address, }, ); const subHash = await zns.subRegistrar.hashWithParent(rootHash, subdomain); const config = await zns.treasury.paymentConfigs(subHash); - expect(config.token).to.eq(await zns.meowToken.getAddress()); + expect(config.token).to.eq(await zns.zToken.getAddress()); expect(config.beneficiary).to.eq(lvl2SubOwner.address); }); @@ -173,7 +185,7 @@ describe("ZNSSubRegistrar", () => { paymentType: PaymentType.DIRECT, }, paymentConfig: { - token: await zns.meowToken.getAddress(), + token: await zns.zToken.getAddress(), beneficiary: rootOwner.address, }, priceConfig: { @@ -191,12 +203,12 @@ describe("ZNSSubRegistrar", () => { subTokenURI, distrConfigEmpty, { - token: await zns.meowToken.getAddress(), + token: await zns.zToken.getAddress(), beneficiary: rootOwner.address, - }, - ) - ).to.be.revertedWith( - "ZNSFixedPricer: parent's price config has not been set properly through IZNSPricer.setPriceConfig()" + }) + ).to.be.revertedWithCustomError( + zns.curvePricer, + PARENT_CONFIG_NOT_SET_ERR ); }); @@ -215,7 +227,7 @@ describe("ZNSSubRegistrar", () => { paymentType: PaymentType.DIRECT, }, paymentConfig: { - token: await zns.meowToken.getAddress(), + token: await zns.zToken.getAddress(), beneficiary: rootOwner.address, }, priceConfig: DEFAULT_PRICE_CONFIG, @@ -229,10 +241,11 @@ describe("ZNSSubRegistrar", () => { lvl2SubOwner.address, subTokenURI, distrConfigEmpty, - paymentConfigEmpty, + paymentConfigEmpty ) - ).to.be.revertedWith( - "ZNSCurvePricer: parent's price config has not been set properly through IZNSPricer.setPriceConfig()" + ).to.be.revertedWithCustomError( + zns.curvePricer, + PARENT_CONFIG_NOT_SET_ERR ); }); @@ -250,7 +263,7 @@ describe("ZNSSubRegistrar", () => { paymentType: PaymentType.DIRECT, }, paymentConfig: { - token: await zns.meowToken.getAddress(), + token: await zns.zToken.getAddress(), beneficiary: lvl2SubOwner.address, }, priceConfig: { @@ -269,7 +282,7 @@ describe("ZNSSubRegistrar", () => { const alphaNumeric = "0x0dwidler0x0"; // Add allowance - await zns.meowToken.connect(lvl2SubOwner).approve(await zns.treasury.getAddress(), ethers.MaxUint256); + await zns.zToken.connect(lvl2SubOwner).approve(await zns.treasury.getAddress(), ethers.MaxUint256); // While "to.not.be.reverted" isn't really a full "test" // we don't emit a custom event here, only in the `rootRegistrar.coreRegister` @@ -293,53 +306,57 @@ describe("ZNSSubRegistrar", () => { const nameC = "!%$#^*?!#👍3^29"; const nameD = "wo.rld"; - await expect(defaultSubdomainRegistration( - { - user: lvl2SubOwner, - zns, - parentHash: rootHash, - subdomainLabel: nameA, - domainContent: lvl2SubOwner.address, - tokenURI: subTokenURI, - distrConfig: distrConfigEmpty, - } - )).to.be.revertedWith(INVALID_NAME_ERR); + await expect( + defaultSubdomainRegistration( + { + user: lvl2SubOwner, + zns, + parentHash: rootHash, + subdomainLabel: nameA, + domainContent: lvl2SubOwner.address, + tokenURI: subTokenURI, + distrConfig: distrConfigEmpty, + } + )).to.be.revertedWithCustomError(zns.curvePricer, INVALID_LABEL_ERR); - await expect(defaultSubdomainRegistration( - { - user: lvl2SubOwner, - zns, - parentHash: rootHash, - subdomainLabel: nameB, - domainContent: lvl2SubOwner.address, - tokenURI: subTokenURI, - distrConfig: distrConfigEmpty, - } - )).to.be.revertedWith(INVALID_NAME_ERR); + await expect( + defaultSubdomainRegistration( + { + user: lvl2SubOwner, + zns, + parentHash: rootHash, + subdomainLabel: nameB, + domainContent: lvl2SubOwner.address, + tokenURI: subTokenURI, + distrConfig: distrConfigEmpty, + } + )).to.be.revertedWithCustomError(zns.curvePricer, INVALID_LABEL_ERR); - await expect(defaultSubdomainRegistration( - { - user: lvl2SubOwner, - zns, - parentHash: rootHash, - subdomainLabel: nameC, - domainContent: lvl2SubOwner.address, - tokenURI: subTokenURI, - distrConfig: distrConfigEmpty, - } - )).to.be.revertedWith(INVALID_NAME_ERR); + await expect( + defaultSubdomainRegistration( + { + user: lvl2SubOwner, + zns, + parentHash: rootHash, + subdomainLabel: nameC, + domainContent: lvl2SubOwner.address, + tokenURI: subTokenURI, + distrConfig: distrConfigEmpty, + } + )).to.be.revertedWithCustomError(zns.curvePricer, INVALID_LABEL_ERR); - await expect(defaultSubdomainRegistration( - { - user: lvl2SubOwner, - zns, - parentHash: rootHash, - subdomainLabel: nameD, - domainContent: lvl2SubOwner.address, - tokenURI: subTokenURI, - distrConfig: distrConfigEmpty, - } - )).to.be.revertedWith(INVALID_NAME_ERR); + await expect( + defaultSubdomainRegistration( + { + user: lvl2SubOwner, + zns, + parentHash: rootHash, + subdomainLabel: nameD, + domainContent: lvl2SubOwner.address, + tokenURI: subTokenURI, + distrConfig: distrConfigEmpty, + } + )).to.be.revertedWithCustomError(zns.curvePricer, INVALID_LABEL_ERR); }); it("should revert when trying to register a subdomain under a non-existent parent", async () => { @@ -351,9 +368,10 @@ describe("ZNSSubRegistrar", () => { lvl2SubOwner.address, subTokenURI, distrConfigEmpty, - paymentConfigEmpty, + paymentConfigEmpty ) - ).to.be.revertedWith( + ).to.be.revertedWithCustomError( + zns.subRegistrar, DISTRIBUTION_LOCKED_NOT_EXIST_ERR ); @@ -366,9 +384,10 @@ describe("ZNSSubRegistrar", () => { lvl2SubOwner.address, subTokenURI, distrConfigEmpty, - paymentConfigEmpty, + paymentConfigEmpty ) - ).to.be.revertedWith( + ).to.be.revertedWithCustomError( + zns.subRegistrar, DISTRIBUTION_LOCKED_NOT_EXIST_ERR ); }); @@ -387,7 +406,7 @@ describe("ZNSSubRegistrar", () => { paymentType: PaymentType.DIRECT, }, paymentConfig: { - token: await zns.meowToken.getAddress(), + token: await zns.zToken.getAddress(), beneficiary: lvl2SubOwner.address, }, priceConfig: { @@ -408,7 +427,7 @@ describe("ZNSSubRegistrar", () => { }); // ! this value can change based on the block gas limit ! - it("should register subdomain with a label length of 100000 chars", async () => { + it("should register subdomain with a label length of 100000 chars [ @skip-on-coverage ]", async () => { const subHash = await registrationWithSetup({ zns, user: lvl2SubOwner, @@ -431,12 +450,12 @@ describe("ZNSSubRegistrar", () => { it("should revert when user has insufficient funds", async () => { const label = "subinsufficientfunds"; const { expectedPrice } = getPriceObject(label, rootPriceConfig); - const userBalanceBefore = await zns.meowToken.balanceOf(lvl2SubOwner.address); + const userBalanceBefore = await zns.zToken.balanceOf(lvl2SubOwner.address); const userBalanceAfter = userBalanceBefore - expectedPrice; - await zns.meowToken.connect(lvl2SubOwner).transfer(deployer.address, userBalanceAfter); + await zns.zToken.connect(lvl2SubOwner).transfer(deployer.address, userBalanceAfter); // add allowance - await zns.meowToken.connect(lvl2SubOwner).approve(await zns.treasury.getAddress(), ethers.MaxUint256); + await zns.zToken.connect(lvl2SubOwner).approve(await zns.treasury.getAddress(), ethers.MaxUint256); await expect( zns.subRegistrar.connect(lvl2SubOwner).registerSubdomain( @@ -447,12 +466,13 @@ describe("ZNSSubRegistrar", () => { distrConfigEmpty, paymentConfigEmpty, ) - ).to.be.revertedWith( - "ERC20: transfer amount exceeds balance" + ).to.be.revertedWithCustomError( + zns.zToken, + INSUFFICIENT_BALANCE_ERC_ERR ); // transfer back for other tests - await zns.meowToken.connect(deployer).transfer(lvl2SubOwner.address, userBalanceAfter); + await zns.zToken.connect(deployer).transfer(lvl2SubOwner.address, userBalanceAfter); }); it("should revert when user has insufficient allowance", async () => { @@ -460,7 +480,7 @@ describe("ZNSSubRegistrar", () => { const { expectedPrice } = getPriceObject(label, rootPriceConfig); // add allowance - await zns.meowToken.connect(lvl2SubOwner).approve(await zns.treasury.getAddress(), expectedPrice - 1n); + await zns.zToken.connect(lvl2SubOwner).approve(await zns.treasury.getAddress(), expectedPrice - 1n); await expect( zns.subRegistrar.connect(lvl2SubOwner).registerSubdomain( @@ -471,8 +491,9 @@ describe("ZNSSubRegistrar", () => { distrConfigEmpty, paymentConfigEmpty, ) - ).to.be.revertedWith( - "ERC20: insufficient allowance" + ).to.be.revertedWithCustomError( + zns.zToken, + INSUFFICIENT_ALLOWANCE_ERC_ERR ); }); @@ -494,7 +515,7 @@ describe("ZNSSubRegistrar", () => { }); // set the token address - await zns.treasury.connect(rootOwner).setPaymentToken(parentHash1, await zns.meowToken.getAddress()); + await zns.treasury.connect(rootOwner).setPaymentToken(parentHash1, await zns.zToken.getAddress()); // register a new parent with stake payment and no payment config const parentHash2 = await registrationWithSetup({ @@ -513,7 +534,7 @@ describe("ZNSSubRegistrar", () => { }); // set the token address - await zns.treasury.connect(rootOwner).setPaymentToken(parentHash2, await zns.meowToken.getAddress()); + await zns.treasury.connect(rootOwner).setPaymentToken(parentHash2, await zns.zToken.getAddress()); // register subdomains under new parents await expect( @@ -523,7 +544,7 @@ describe("ZNSSubRegistrar", () => { parentHash: parentHash1, domainLabel: "sub1", }) - ).to.be.revertedWith(NO_BENEFICIARY_ERR); + ).to.be.revertedWithCustomError(zns.treasury, NO_BENEFICIARY_ERR); await expect( registrationWithSetup({ @@ -532,7 +553,7 @@ describe("ZNSSubRegistrar", () => { parentHash: parentHash2, domainLabel: "sub2", }) - ).to.be.revertedWith(NO_BENEFICIARY_ERR); + ).to.be.revertedWithCustomError(zns.treasury, NO_BENEFICIARY_ERR); // change stakeFee to 0 await zns.curvePricer.connect(rootOwner).setFeePercentage( @@ -585,21 +606,29 @@ describe("ZNSSubRegistrar", () => { }); // Give funds to users + const users = [ + rootOwner, + lvl2SubOwner, + lvl3SubOwner, + lvl4SubOwner, + lvl5SubOwner, + lvl6SubOwner, + branchLvl1Owner, + branchLvl2Owner, + multiOwner, + ]; + + const totalAdminBalance = await zns.zToken.balanceOf(admin.address); + const userBalanceInitial = totalAdminBalance / BigInt(users.length); + await zns.zToken.connect(admin).approve(await zns.treasury.getAddress(), totalAdminBalance); + await Promise.all( - [ - rootOwner, - lvl2SubOwner, - lvl3SubOwner, - lvl4SubOwner, - lvl5SubOwner, - lvl6SubOwner, - branchLvl1Owner, - branchLvl2Owner, - multiOwner, - ].map(async ({ address }) => - zns.meowToken.mint(address, ethers.parseEther("1000000"))) - ); - await zns.meowToken.connect(rootOwner).approve(await zns.treasury.getAddress(), ethers.MaxUint256); + users.map(async ({ address }) => + zns.zToken.connect(admin).transfer(address, userBalanceInitial) + ) + ); + + await zns.zToken.connect(rootOwner).approve(await zns.treasury.getAddress(), ethers.MaxUint256); domainConfigs = [ { @@ -612,7 +641,7 @@ describe("ZNSSubRegistrar", () => { accessType: AccessType.OPEN, }, paymentConfig: { - token: await zns.meowToken.getAddress(), + token: await zns.zToken.getAddress(), beneficiary: rootOwner.address, }, priceConfig: { price: fixedPrice, feePercentage: BigInt(0) }, @@ -628,7 +657,7 @@ describe("ZNSSubRegistrar", () => { accessType: AccessType.OPEN, }, paymentConfig: { - token: await zns.meowToken.getAddress(), + token: await zns.zToken.getAddress(), beneficiary: lvl2SubOwner.address, }, priceConfig: DEFAULT_PRICE_CONFIG, @@ -644,7 +673,7 @@ describe("ZNSSubRegistrar", () => { accessType: AccessType.OPEN, }, paymentConfig: { - token: await zns.meowToken.getAddress(), + token: await zns.zToken.getAddress(), beneficiary: lvl3SubOwner.address, }, priceConfig: DEFAULT_PRICE_CONFIG, @@ -660,7 +689,7 @@ describe("ZNSSubRegistrar", () => { accessType: AccessType.OPEN, }, paymentConfig: { - token: await zns.meowToken.getAddress(), + token: await zns.zToken.getAddress(), beneficiary: lvl4SubOwner.address, }, priceConfig: DEFAULT_PRICE_CONFIG, @@ -677,7 +706,7 @@ describe("ZNSSubRegistrar", () => { accessType: AccessType.OPEN, }, paymentConfig: { - token: await zns.meowToken.getAddress(), + token: await zns.zToken.getAddress(), beneficiary: lvl5SubOwner.address, }, priceConfig: { price: fixedPrice, feePercentage: fixedFeePercentage }, @@ -694,7 +723,7 @@ describe("ZNSSubRegistrar", () => { accessType: AccessType.OPEN, }, paymentConfig: { - token: await zns.meowToken.getAddress(), + token: await zns.zToken.getAddress(), beneficiary: lvl6SubOwner.address, }, priceConfig: DEFAULT_PRICE_CONFIG, @@ -730,7 +759,7 @@ describe("ZNSSubRegistrar", () => { paymentType: PaymentType.DIRECT, }, paymentConfig: { - token: await zns.meowToken.getAddress(), + token: await zns.zToken.getAddress(), beneficiary: multiOwner.address, }, priceConfig: { price: fixedPrice, feePercentage: BigInt(0) }, @@ -747,7 +776,7 @@ describe("ZNSSubRegistrar", () => { paymentType: PaymentType.STAKE, }, paymentConfig: { - token: await zns.meowToken.getAddress(), + token: await zns.zToken.getAddress(), beneficiary: zeroVault.address, }, priceConfig: DEFAULT_PRICE_CONFIG, @@ -764,7 +793,7 @@ describe("ZNSSubRegistrar", () => { paymentType: PaymentType.DIRECT, }, paymentConfig: { - token: await zns.meowToken.getAddress(), + token: await zns.zToken.getAddress(), beneficiary: multiOwner.address, }, priceConfig: DEFAULT_PRICE_CONFIG, @@ -781,7 +810,7 @@ describe("ZNSSubRegistrar", () => { paymentType: PaymentType.STAKE, }, paymentConfig: { - token: await zns.meowToken.getAddress(), + token: await zns.zToken.getAddress(), beneficiary: zeroVault.address, }, priceConfig: { price: fixedPrice, feePercentage: BigInt(0) }, @@ -798,7 +827,7 @@ describe("ZNSSubRegistrar", () => { paymentType: PaymentType.DIRECT, }, paymentConfig: { - token: await zns.meowToken.getAddress(), + token: await zns.zToken.getAddress(), beneficiary: multiOwner.address, }, priceConfig: DEFAULT_PRICE_CONFIG, @@ -815,7 +844,7 @@ describe("ZNSSubRegistrar", () => { paymentType: PaymentType.STAKE, }, paymentConfig: { - token: await zns.meowToken.getAddress(), + token: await zns.zToken.getAddress(), beneficiary: zeroVault.address, }, priceConfig: DEFAULT_PRICE_CONFIG, @@ -832,7 +861,7 @@ describe("ZNSSubRegistrar", () => { paymentType: PaymentType.DIRECT, }, paymentConfig: { - token: await zns.meowToken.getAddress(), + token: await zns.zToken.getAddress(), beneficiary: multiOwner.address, }, priceConfig: { price: fixedPrice, feePercentage: fixedFeePercentage }, @@ -841,7 +870,7 @@ describe("ZNSSubRegistrar", () => { ]; // prep - await zns.meowToken.connect(multiOwner).approve(await zns.treasury.getAddress(), ethers.MaxUint256); + await zns.zToken.connect(multiOwner).approve(await zns.treasury.getAddress(), ethers.MaxUint256); // register const domainHashes = await configs.reduce( @@ -911,13 +940,13 @@ describe("ZNSSubRegistrar", () => { [true, true] ); - const userBalBefore = await zns.meowToken.balanceOf(lvl6SubOwner.address); + const userBalBefore = await zns.zToken.balanceOf(lvl6SubOwner.address); await zns.rootRegistrar.connect(lvl6SubOwner).revokeDomain( domainHash, ); - const userBalAfter = await zns.meowToken.balanceOf(lvl6SubOwner.address); + const userBalAfter = await zns.zToken.balanceOf(lvl6SubOwner.address); expect(userBalAfter - userBalBefore).to.eq(0); @@ -937,9 +966,10 @@ describe("ZNSSubRegistrar", () => { lvl6SubOwner.address, DEFAULT_TOKEN_URI, distrConfigEmpty, - paymentConfigEmpty, + paymentConfigEmpty ) - ).to.be.revertedWith( + ).to.be.revertedWithCustomError( + zns.subRegistrar, DISTRIBUTION_LOCKED_NOT_EXIST_ERR ); @@ -950,32 +980,36 @@ describe("ZNSSubRegistrar", () => { const tokenId = BigInt(domainHash).toString(); await expect( zns.domainToken.ownerOf(tokenId) - ).to.be.revertedWith( - INVALID_TOKENID_ERC_ERR - ); + ).to.be.revertedWithCustomError( + zns.domainToken, + NONEXISTENT_TOKEN_ERC_ERR + ).withArgs(tokenId); await expect( zns.registry.connect(lvl6SubOwner).updateDomainRecord(domainHash, rootOwner.address, lvl6SubOwner.address) - ).to.be.revertedWith(ONLY_NAME_OWNER_REG_ERR); + ).to.be.revertedWithCustomError( + zns.registry, + NOT_AUTHORIZED_ERR + ); }); it("should revoke lvl 5 domain with refund", async () => { const domainHash = regResults[4].domainHash; - const userBalanceBefore = await zns.meowToken.balanceOf(lvl5SubOwner.address); - const parentBalBefore = await zns.meowToken.balanceOf(lvl4SubOwner.address); - const paymentContractBalBefore = await zns.meowToken.balanceOf(await zns.treasury.getAddress()); + const userBalanceBefore = await zns.zToken.balanceOf(lvl5SubOwner.address); + const parentBalBefore = await zns.zToken.balanceOf(lvl4SubOwner.address); + const paymentContractBalBefore = await zns.zToken.balanceOf(await zns.treasury.getAddress()); const stake = await zns.treasury.stakedForDomain(domainHash); const protocolFee = getStakingOrProtocolFee(stake.amount); - await zns.meowToken.connect(lvl5SubOwner).approve(await zns.treasury.getAddress(), protocolFee); + await zns.zToken.connect(lvl5SubOwner).approve(await zns.treasury.getAddress(), protocolFee); await zns.rootRegistrar.connect(lvl5SubOwner).revokeDomain(domainHash); - const userBalAfter = await zns.meowToken.balanceOf(lvl5SubOwner.address); - const parentBalAfter = await zns.meowToken.balanceOf(lvl4SubOwner.address); - const paymentContractBalAfter = await zns.meowToken.balanceOf(await zns.treasury.getAddress()); + const userBalAfter = await zns.zToken.balanceOf(lvl5SubOwner.address); + const parentBalAfter = await zns.zToken.balanceOf(lvl4SubOwner.address); + const paymentContractBalAfter = await zns.zToken.balanceOf(await zns.treasury.getAddress()); const { expectedPrice } = getPriceObject(domainConfigs[4].domainLabel); @@ -1007,9 +1041,10 @@ describe("ZNSSubRegistrar", () => { lvl6SubOwner.address, DEFAULT_TOKEN_URI, distrConfigEmpty, - paymentConfigEmpty, + paymentConfigEmpty ) - ).to.be.revertedWith( + ).to.be.revertedWithCustomError( + zns.subRegistrar, DISTRIBUTION_LOCKED_NOT_EXIST_ERR ); @@ -1020,13 +1055,17 @@ describe("ZNSSubRegistrar", () => { const tokenId = BigInt(domainHash).toString(); await expect( zns.domainToken.ownerOf(tokenId) - ).to.be.revertedWith( - INVALID_TOKENID_ERC_ERR - ); + ).to.be.revertedWithCustomError( + zns.domainToken, + NONEXISTENT_TOKEN_ERC_ERR + ).withArgs(tokenId); await expect( - zns.registry.connect(lvl5SubOwner).updateDomainRecord(domainHash, rootOwner.address, lvl6SubOwner.address) - ).to.be.revertedWith(ONLY_NAME_OWNER_REG_ERR); + zns.registry.connect(lvl5SubOwner).updateDomainRecord(domainHash,rootOwner.address,lvl6SubOwner.address) + ).to.be.revertedWithCustomError( + zns.registry, + NOT_AUTHORIZED_ERR + ); }); it("should register a new 2 lvl path at lvl 3 of the existing path", async () => { @@ -1042,7 +1081,7 @@ describe("ZNSSubRegistrar", () => { accessType: AccessType.OPEN, }, paymentConfig: { - token: await zns.meowToken.getAddress(), + token: await zns.zToken.getAddress(), beneficiary: branchLvl1Owner.address, }, priceConfig: { price: fixedPrice, feePercentage: fixedFeePercentage }, @@ -1058,7 +1097,7 @@ describe("ZNSSubRegistrar", () => { accessType: AccessType.OPEN, }, paymentConfig: { - token: await zns.meowToken.getAddress(), + token: await zns.zToken.getAddress(), beneficiary: branchLvl2Owner.address, }, priceConfig: DEFAULT_PRICE_CONFIG, @@ -1088,7 +1127,7 @@ describe("ZNSSubRegistrar", () => { const stake = await zns.treasury.stakedForDomain(lvl2Hash); const protocolFee = getStakingOrProtocolFee(stake.amount); - await zns.meowToken.connect(lvl2SubOwner).approve(await zns.treasury.getAddress(), protocolFee); + await zns.zToken.connect(lvl2SubOwner).approve(await zns.treasury.getAddress(), protocolFee); // revoke parent await zns.rootRegistrar.connect(lvl2SubOwner).revokeDomain( @@ -1123,10 +1162,6 @@ describe("ZNSSubRegistrar", () => { if ("maxPrice" in domainConfigs[1].fullConfig.priceConfig!) { expect(priceConfig.maxPrice).to.eq(domainConfigs[1].fullConfig.priceConfig.maxPrice); } - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - if ("minPrice" in domainConfigs[1].fullConfig.priceConfig!) { - expect(priceConfig.minPrice).to.eq(domainConfigs[1].fullConfig.priceConfig.minPrice); - } // make sure the child's stake is still there const { amount: childStakedAmt } = await zns.treasury.stakedForDomain(lvl3Hash); @@ -1134,19 +1169,19 @@ describe("ZNSSubRegistrar", () => { expect(childStakedAmt).to.eq(expectedPrice); - const userBalBefore = await zns.meowToken.balanceOf(lvl3SubOwner.address); + const userBalBefore = await zns.zToken.balanceOf(lvl3SubOwner.address); const subStake = await zns.treasury.stakedForDomain(lvl3Hash); const subProtocolFee = getStakingOrProtocolFee(subStake.amount); - await zns.meowToken.connect(lvl3SubOwner).approve(await zns.treasury.getAddress(), subProtocolFee); + await zns.zToken.connect(lvl3SubOwner).approve(await zns.treasury.getAddress(), subProtocolFee); // revoke child await zns.rootRegistrar.connect(lvl3SubOwner).revokeDomain( lvl3Hash, ); - const userBalAfter = await zns.meowToken.balanceOf(lvl3SubOwner.address); + const userBalAfter = await zns.zToken.balanceOf(lvl3SubOwner.address); expect(userBalAfter - userBalBefore).to.eq(expectedPrice - subProtocolFee); @@ -1163,13 +1198,17 @@ describe("ZNSSubRegistrar", () => { const tokenId = BigInt(lvl3Hash).toString(); await expect( zns.domainToken.ownerOf(tokenId) - ).to.be.revertedWith( - INVALID_TOKENID_ERC_ERR - ); + ).to.be.revertedWithCustomError( + zns.domainToken, + NONEXISTENT_TOKEN_ERC_ERR + ).withArgs(tokenId); await expect( zns.registry.connect(lvl3SubOwner).updateDomainRecord(lvl3Hash, rootOwner.address, lvl4SubOwner.address) - ).to.be.revertedWith(ONLY_NAME_OWNER_REG_ERR); + ).to.be.revertedWithCustomError( + zns.registry, + NOT_AUTHORIZED_ERR + ); }); it("should let anyone register a previously revoked domain", async () => { @@ -1207,7 +1246,7 @@ describe("ZNSSubRegistrar", () => { accessType: AccessType.OPEN, }, paymentConfig: { - token: await zns.meowToken.getAddress(), + token: await zns.zToken.getAddress(), beneficiary: branchLvl1Owner.address, }, priceConfig: { price: fixedPrice, feePercentage: fixedFeePercentage }, @@ -1245,9 +1284,12 @@ describe("ZNSSubRegistrar", () => { branchLvl1Owner.address, DEFAULT_TOKEN_URI, distrConfigEmpty, - paymentConfigEmpty, + paymentConfigEmpty ) - ).to.be.revertedWith(DISTRIBUTION_LOCKED_NOT_EXIST_ERR); + ).to.be.revertedWithCustomError( + zns.subRegistrar, + DISTRIBUTION_LOCKED_NOT_EXIST_ERR + ); // register root back for other tests await registrationWithSetup({ @@ -1277,9 +1319,12 @@ describe("ZNSSubRegistrar", () => { branchLvl2Owner.address, DEFAULT_TOKEN_URI, distrConfigEmpty, - paymentConfigEmpty, + paymentConfigEmpty ) - ).to.be.revertedWith(DISTRIBUTION_LOCKED_NOT_EXIST_ERR); + ).to.be.revertedWithCustomError( + zns.subRegistrar, + DISTRIBUTION_LOCKED_NOT_EXIST_ERR + ); }); // eslint-disable-next-line max-len @@ -1312,7 +1357,7 @@ describe("ZNSSubRegistrar", () => { accessType: AccessType.MINTLIST, }, paymentConfig: { - token: await zns.meowToken.getAddress(), + token: await zns.zToken.getAddress(), beneficiary: branchLvl1Owner.address, }, priceConfig: { price: fixedPrice, feePercentage: BigInt(0) }, @@ -1331,7 +1376,7 @@ describe("ZNSSubRegistrar", () => { const parentOwnerFromReg = await zns.registry.getDomainOwner(newHash); expect(parentOwnerFromReg).to.eq(branchLvl1Owner.address); - const childBalBefore = await zns.meowToken.balanceOf(branchLvl2Owner.address); + const childBalBefore = await zns.zToken.balanceOf(branchLvl2Owner.address); // try register a new child under the new parent const newChildHash = await registrationWithSetup({ @@ -1342,7 +1387,7 @@ describe("ZNSSubRegistrar", () => { fullConfig: fullDistrConfigEmpty, }); - const childBalAfter = await zns.meowToken.balanceOf(branchLvl2Owner.address); + const childBalAfter = await zns.zToken.balanceOf(branchLvl2Owner.address); // check that the new child has been registered const childOwnerFromReg = await zns.registry.getDomainOwner(newChildHash); @@ -1414,20 +1459,27 @@ describe("ZNSSubRegistrar", () => { )); // Give funds to users + const users = [ + rootOwner, + lvl2SubOwner, + lvl3SubOwner, + lvl4SubOwner, + lvl5SubOwner, + lvl6SubOwner, + branchLvl1Owner, + branchLvl2Owner, + ]; + const totalAdminBalance = await zns.zToken.balanceOf(admin.address); + const userBalanceInitial = totalAdminBalance / BigInt(users.length); + await zns.zToken.connect(admin).approve(await zns.treasury.getAddress(), totalAdminBalance); + await Promise.all( - [ - rootOwner, - lvl2SubOwner, - lvl3SubOwner, - lvl4SubOwner, - lvl5SubOwner, - lvl6SubOwner, - branchLvl1Owner, - branchLvl2Owner, - ].map(async ({ address }) => - zns.meowToken.mint(address, ethers.parseEther("1000000"))) - ); - await zns.meowToken.connect(rootOwner).approve(await zns.treasury.getAddress(), ethers.MaxUint256); + users.map(async ({ address }) => + zns.zToken.connect(admin).transfer(address, userBalanceInitial) + ) + ); + + await zns.zToken.connect(rootOwner).approve(await zns.treasury.getAddress(), ethers.MaxUint256); // register root domain rootHash = await registrationWithSetup({ @@ -1441,7 +1493,7 @@ describe("ZNSSubRegistrar", () => { paymentType: PaymentType.DIRECT, }, paymentConfig: { - token: await zns.meowToken.getAddress(), + token: await zns.zToken.getAddress(), beneficiary: rootOwner.address, }, priceConfig: { @@ -1549,11 +1601,11 @@ describe("ZNSSubRegistrar", () => { domainLabel: "subdomain", }); - const balanceBefore = await zns.meowToken.balanceOf(rootOwner.address); + const balanceBefore = await zns.zToken.balanceOf(rootOwner.address); await zns.rootRegistrar.connect(rootOwner).revokeDomain(subdomainHash); - const balanceAfter = await zns.meowToken.balanceOf(rootOwner.address); + const balanceAfter = await zns.zToken.balanceOf(rootOwner.address); expect(balanceBefore).to.eq(balanceAfter); }); @@ -1714,11 +1766,11 @@ describe("ZNSSubRegistrar", () => { it("CurvePricer - StakePayment - stake fee - 13 decimals", async () => { const priceConfig = { maxPrice: ethers.parseUnits("30000.93", decimalValues.thirteen), - minPrice: ethers.parseUnits("2000.11", decimalValues.thirteen), + curveMultiplier: BigInt(1000), maxLength: BigInt(50), baseLength: BigInt(4), precisionMultiplier: BigInt(10) ** ( - decimalValues.thirteen - DECAULT_PRECISION + decimalValues.thirteen - DEFAULT_PRECISION ), feePercentage: BigInt(185), isSet: true, @@ -1803,7 +1855,7 @@ describe("ZNSSubRegistrar", () => { it("CurvePricer - StakePayment - no fee - 2 decimals", async () => { const priceConfig = { maxPrice: ethers.parseUnits("234.46", decimalValues.two), - minPrice: ethers.parseUnits("3.37", decimalValues.two), + curveMultiplier: BigInt(1000), maxLength: BigInt(20), baseLength: BigInt(2), precisionMultiplier: BigInt(1), @@ -1901,7 +1953,7 @@ describe("ZNSSubRegistrar", () => { }, paymentConfig: { // zero has 18 decimals - token: await zns.meowToken.getAddress(), + token: await zns.zToken.getAddress(), beneficiary: lvl2SubOwner.address, }, priceConfig, @@ -1910,10 +1962,10 @@ describe("ZNSSubRegistrar", () => { const label = "asdirectnofeechild"; - const contractBalBefore = await zns.meowToken.balanceOf(await zns.treasury.getAddress()); - const parentBalBefore = await zns.meowToken.balanceOf(lvl2SubOwner.address); - const childBalBefore = await zns.meowToken.balanceOf(lvl3SubOwner.address); - const zeroVaultBalanceBefore = await zns.meowToken.balanceOf(zeroVault.address); + const contractBalBefore = await zns.zToken.balanceOf(await zns.treasury.getAddress()); + const parentBalBefore = await zns.zToken.balanceOf(lvl2SubOwner.address); + const childBalBefore = await zns.zToken.balanceOf(lvl3SubOwner.address); + const zeroVaultBalanceBefore = await zns.zToken.balanceOf(zeroVault.address); const childHash = await registrationWithSetup({ zns, @@ -1922,10 +1974,10 @@ describe("ZNSSubRegistrar", () => { domainLabel: label, }); - const parentBalAfter = await zns.meowToken.balanceOf(lvl2SubOwner.address); - const childBalAfter = await zns.meowToken.balanceOf(lvl3SubOwner.address); - const contractBalAfter = await zns.meowToken.balanceOf(await zns.treasury.getAddress()); - const zeroVaultBalanceAfter = await zns.meowToken.balanceOf(zeroVault.address); + const parentBalAfter = await zns.zToken.balanceOf(lvl2SubOwner.address); + const childBalAfter = await zns.zToken.balanceOf(lvl3SubOwner.address); + const contractBalAfter = await zns.zToken.balanceOf(await zns.treasury.getAddress()); + const zeroVaultBalanceAfter = await zns.zToken.balanceOf(zeroVault.address); const { expectedPrice } = getPriceObject(label, priceConfig); const protocolFee = getStakingOrProtocolFee(expectedPrice); @@ -1941,10 +1993,10 @@ describe("ZNSSubRegistrar", () => { ); // should NOT offer refund ! - const parentBalAfterRevoke = await zns.meowToken.balanceOf(lvl2SubOwner.address); - const childBalAfterRevoke = await zns.meowToken.balanceOf(lvl3SubOwner.address); - const contractBalAfterRevoke = await zns.meowToken.balanceOf(await zns.treasury.getAddress()); - const zeroVaultBalanceAfterRevoke = await zns.meowToken.balanceOf(zeroVault.address); + const parentBalAfterRevoke = await zns.zToken.balanceOf(lvl2SubOwner.address); + const childBalAfterRevoke = await zns.zToken.balanceOf(lvl3SubOwner.address); + const contractBalAfterRevoke = await zns.zToken.balanceOf(await zns.treasury.getAddress()); + const zeroVaultBalanceAfterRevoke = await zns.zToken.balanceOf(zeroVault.address); expect(parentBalAfterRevoke - parentBalAfter).to.eq(0); expect(childBalAfterRevoke - childBalAfter).to.eq(0); @@ -1970,17 +2022,17 @@ describe("ZNSSubRegistrar", () => { paymentType: PaymentType.DIRECT, }, paymentConfig: { - token: await zns.meowToken.getAddress(), + token: await zns.zToken.getAddress(), beneficiary: lvl2SubOwner.address, }, priceConfig, }, }); - const contractBalBefore = await zns.meowToken.balanceOf(await zns.treasury.getAddress()); - const parentBalBefore = await zns.meowToken.balanceOf(lvl2SubOwner.address); - const childBalBefore = await zns.meowToken.balanceOf(lvl3SubOwner.address); - const zeroVaultBalanceBefore = await zns.meowToken.balanceOf(zeroVault.address); + const contractBalBefore = await zns.zToken.balanceOf(await zns.treasury.getAddress()); + const parentBalBefore = await zns.zToken.balanceOf(lvl2SubOwner.address); + const childBalBefore = await zns.zToken.balanceOf(lvl3SubOwner.address); + const zeroVaultBalanceBefore = await zns.zToken.balanceOf(zeroVault.address); const label = "zeropricechild"; const childHash = await registrationWithSetup({ @@ -1990,10 +2042,10 @@ describe("ZNSSubRegistrar", () => { domainLabel: label, }); - const parentBalAfter = await zns.meowToken.balanceOf(lvl2SubOwner.address); - const childBalAfter = await zns.meowToken.balanceOf(lvl3SubOwner.address); - const contractBalAfter = await zns.meowToken.balanceOf(await zns.treasury.getAddress()); - const zeroVaultBalanceAfter = await zns.meowToken.balanceOf(zeroVault.address); + const parentBalAfter = await zns.zToken.balanceOf(lvl2SubOwner.address); + const childBalAfter = await zns.zToken.balanceOf(lvl3SubOwner.address); + const contractBalAfter = await zns.zToken.balanceOf(await zns.treasury.getAddress()); + const zeroVaultBalanceAfter = await zns.zToken.balanceOf(zeroVault.address); expect(parentBalAfter - parentBalBefore).to.eq(0); expect(childBalBefore - childBalAfter).to.eq(0); @@ -2002,17 +2054,17 @@ describe("ZNSSubRegistrar", () => { // validate transfer events are not happenning const latestBlock = await time.latestBlock(); - const transferFilterToParent = zns.meowToken.filters.Transfer(lvl3SubOwner.address, lvl2SubOwner.address); - const transferFilterToTreasury = zns.meowToken.filters.Transfer( + const transferFilterToParent = zns.zToken.filters.Transfer(lvl3SubOwner.address, lvl2SubOwner.address); + const transferFilterToTreasury = zns.zToken.filters.Transfer( lvl3SubOwner.address, await zns.treasury.getAddress() ); - const transfersToParent = await zns.meowToken.queryFilter( + const transfersToParent = await zns.zToken.queryFilter( transferFilterToParent, latestBlock - 3, latestBlock ); - const transfersToTreasury = await zns.meowToken.queryFilter( + const transfersToTreasury = await zns.zToken.queryFilter( transferFilterToTreasury, latestBlock - 3, latestBlock @@ -2026,10 +2078,10 @@ describe("ZNSSubRegistrar", () => { ); // should NOT offer refund ! - const parentBalAfterRevoke = await zns.meowToken.balanceOf(lvl2SubOwner.address); - const childBalAfterRevoke = await zns.meowToken.balanceOf(lvl3SubOwner.address); - const contractBalAfterRevoke = await zns.meowToken.balanceOf(await zns.treasury.getAddress()); - const zeroVaultBalanceAfterRevoke = await zns.meowToken.balanceOf(zeroVault.address); + const parentBalAfterRevoke = await zns.zToken.balanceOf(lvl2SubOwner.address); + const childBalAfterRevoke = await zns.zToken.balanceOf(lvl3SubOwner.address); + const contractBalAfterRevoke = await zns.zToken.balanceOf(await zns.treasury.getAddress()); + const zeroVaultBalanceAfterRevoke = await zns.zToken.balanceOf(zeroVault.address); expect(parentBalAfterRevoke - parentBalAfter).to.eq(0); expect(childBalAfterRevoke - childBalAfter).to.eq(0); @@ -2041,7 +2093,6 @@ describe("ZNSSubRegistrar", () => { const priceConfig = { ...DEFAULT_PRICE_CONFIG, maxPrice: BigInt(0), - minPrice: BigInt(0), }; const subdomainParentHash = await registrationWithSetup({ @@ -2056,17 +2107,17 @@ describe("ZNSSubRegistrar", () => { paymentType: PaymentType.DIRECT, }, paymentConfig: { - token: await zns.meowToken.getAddress(), + token: await zns.zToken.getAddress(), beneficiary: lvl2SubOwner.address, }, priceConfig, }, }); - const contractBalBefore = await zns.meowToken.balanceOf(await zns.treasury.getAddress()); - const parentBalBefore = await zns.meowToken.balanceOf(lvl2SubOwner.address); - const childBalBefore = await zns.meowToken.balanceOf(lvl3SubOwner.address); - const zeroVaultBalanceBefore = await zns.meowToken.balanceOf(zeroVault.address); + const contractBalBefore = await zns.zToken.balanceOf(await zns.treasury.getAddress()); + const parentBalBefore = await zns.zToken.balanceOf(lvl2SubOwner.address); + const childBalBefore = await zns.zToken.balanceOf(lvl3SubOwner.address); + const zeroVaultBalanceBefore = await zns.zToken.balanceOf(zeroVault.address); const label = "zeropricechildad"; const childHash = await registrationWithSetup({ @@ -2076,10 +2127,10 @@ describe("ZNSSubRegistrar", () => { domainLabel: label, }); - const parentBalAfter = await zns.meowToken.balanceOf(lvl2SubOwner.address); - const childBalAfter = await zns.meowToken.balanceOf(lvl3SubOwner.address); - const contractBalAfter = await zns.meowToken.balanceOf(await zns.treasury.getAddress()); - const zeroVaultBalanceAfter = await zns.meowToken.balanceOf(zeroVault.address); + const parentBalAfter = await zns.zToken.balanceOf(lvl2SubOwner.address); + const childBalAfter = await zns.zToken.balanceOf(lvl3SubOwner.address); + const contractBalAfter = await zns.zToken.balanceOf(await zns.treasury.getAddress()); + const zeroVaultBalanceAfter = await zns.zToken.balanceOf(zeroVault.address); expect(parentBalAfter - parentBalBefore).to.eq(0); expect(childBalBefore - childBalAfter).to.eq(0); @@ -2088,20 +2139,20 @@ describe("ZNSSubRegistrar", () => { // validate transfer events are not happenning const latestBlock = await time.latestBlock(); - const transferFilterToParent = zns.meowToken.filters.Transfer( + const transferFilterToParent = zns.zToken.filters.Transfer( lvl3SubOwner.address, lvl2SubOwner.address ); - const transferFilterToTreasury = zns.meowToken.filters.Transfer( + const transferFilterToTreasury = zns.zToken.filters.Transfer( lvl3SubOwner.address, await zns.treasury.getAddress() ); - const transfersToParent = await zns.meowToken.queryFilter( + const transfersToParent = await zns.zToken.queryFilter( transferFilterToParent, latestBlock - 3, latestBlock ); - const transfersToTreasury = await zns.meowToken.queryFilter( + const transfersToTreasury = await zns.zToken.queryFilter( transferFilterToTreasury, latestBlock - 3, latestBlock @@ -2115,10 +2166,10 @@ describe("ZNSSubRegistrar", () => { ); // should NOT offer refund ! - const parentBalAfterRevoke = await zns.meowToken.balanceOf(lvl2SubOwner.address); - const childBalAfterRevoke = await zns.meowToken.balanceOf(lvl3SubOwner.address); - const contractBalAfterRevoke = await zns.meowToken.balanceOf(await zns.treasury.getAddress()); - const zeroVaultBalanceAfterRevoke = await zns.meowToken.balanceOf(zeroVault.address); + const parentBalAfterRevoke = await zns.zToken.balanceOf(lvl2SubOwner.address); + const childBalAfterRevoke = await zns.zToken.balanceOf(lvl3SubOwner.address); + const contractBalAfterRevoke = await zns.zToken.balanceOf(await zns.treasury.getAddress()); + const zeroVaultBalanceAfterRevoke = await zns.zToken.balanceOf(zeroVault.address); expect(parentBalAfterRevoke - parentBalAfter).to.eq(0); expect(childBalAfterRevoke - childBalAfter).to.eq(0); @@ -2130,7 +2181,6 @@ describe("ZNSSubRegistrar", () => { const priceConfig = { ...DEFAULT_PRICE_CONFIG, maxPrice: BigInt(0), - minPrice: BigInt(0), }; const subdomainParentHash = await registrationWithSetup({ @@ -2145,17 +2195,17 @@ describe("ZNSSubRegistrar", () => { paymentType: PaymentType.STAKE, }, paymentConfig: { - token: await zns.meowToken.getAddress(), + token: await zns.zToken.getAddress(), beneficiary: lvl2SubOwner.address, }, priceConfig, }, }); - const contractBalBefore = await zns.meowToken.balanceOf(await zns.treasury.getAddress()); - const parentBalBefore = await zns.meowToken.balanceOf(lvl2SubOwner.address); - const childBalBefore = await zns.meowToken.balanceOf(lvl3SubOwner.address); - const zeroVaultBalanceBefore = await zns.meowToken.balanceOf(zeroVault.address); + const contractBalBefore = await zns.zToken.balanceOf(await zns.treasury.getAddress()); + const parentBalBefore = await zns.zToken.balanceOf(lvl2SubOwner.address); + const childBalBefore = await zns.zToken.balanceOf(lvl3SubOwner.address); + const zeroVaultBalanceBefore = await zns.zToken.balanceOf(zeroVault.address); const label = "zeropricechildas"; const childHash = await registrationWithSetup({ @@ -2165,10 +2215,10 @@ describe("ZNSSubRegistrar", () => { domainLabel: label, }); - const parentBalAfter = await zns.meowToken.balanceOf(lvl2SubOwner.address); - const childBalAfter = await zns.meowToken.balanceOf(lvl3SubOwner.address); - const contractBalAfter = await zns.meowToken.balanceOf(await zns.treasury.getAddress()); - const zeroVaultBalanceAfter = await zns.meowToken.balanceOf(zeroVault.address); + const parentBalAfter = await zns.zToken.balanceOf(lvl2SubOwner.address); + const childBalAfter = await zns.zToken.balanceOf(lvl3SubOwner.address); + const contractBalAfter = await zns.zToken.balanceOf(await zns.treasury.getAddress()); + const zeroVaultBalanceAfter = await zns.zToken.balanceOf(zeroVault.address); expect(parentBalAfter - parentBalBefore).to.eq(0); expect(childBalBefore - childBalAfter).to.eq(0); @@ -2177,17 +2227,17 @@ describe("ZNSSubRegistrar", () => { // validate transfer events are not happenning const latestBlock = await time.latestBlock(); - const transferFilterToParent = zns.meowToken.filters.Transfer(lvl3SubOwner.address, lvl2SubOwner.address); - const transferFilterToTreasury = zns.meowToken.filters.Transfer( + const transferFilterToParent = zns.zToken.filters.Transfer(lvl3SubOwner.address, lvl2SubOwner.address); + const transferFilterToTreasury = zns.zToken.filters.Transfer( lvl3SubOwner.address, await zns.treasury.getAddress() ); - const transfersToParent = await zns.meowToken.queryFilter( + const transfersToParent = await zns.zToken.queryFilter( transferFilterToParent, latestBlock - 3, latestBlock ); - const transfersToTreasury = await zns.meowToken.queryFilter( + const transfersToTreasury = await zns.zToken.queryFilter( transferFilterToTreasury, latestBlock - 3, latestBlock @@ -2201,10 +2251,10 @@ describe("ZNSSubRegistrar", () => { ); // should NOT offer refund ! - const parentBalAfterRevoke = await zns.meowToken.balanceOf(lvl2SubOwner.address); - const childBalAfterRevoke = await zns.meowToken.balanceOf(lvl3SubOwner.address); - const contractBalAfterRevoke = await zns.meowToken.balanceOf(await zns.treasury.getAddress()); - const zeroVaultBalanceAfterRevoke = await zns.meowToken.balanceOf(zeroVault.address); + const parentBalAfterRevoke = await zns.zToken.balanceOf(lvl2SubOwner.address); + const childBalAfterRevoke = await zns.zToken.balanceOf(lvl3SubOwner.address); + const contractBalAfterRevoke = await zns.zToken.balanceOf(await zns.treasury.getAddress()); + const zeroVaultBalanceAfterRevoke = await zns.zToken.balanceOf(zeroVault.address); expect(parentBalAfterRevoke - parentBalAfter).to.eq(0); expect(childBalAfterRevoke - childBalAfter).to.eq(0); @@ -2232,17 +2282,17 @@ describe("ZNSSubRegistrar", () => { paymentType: PaymentType.STAKE, }, paymentConfig: { - token: await zns.meowToken.getAddress(), + token: await zns.zToken.getAddress(), beneficiary: lvl2SubOwner.address, }, priceConfig, }, }); - const contractBalBefore = await zns.meowToken.balanceOf(await zns.treasury.getAddress()); - const parentBalBefore = await zns.meowToken.balanceOf(lvl2SubOwner.address); - const childBalBefore = await zns.meowToken.balanceOf(lvl3SubOwner.address); - const zeroVaultBalanceBefore = await zns.meowToken.balanceOf(zeroVault.address); + const contractBalBefore = await zns.zToken.balanceOf(await zns.treasury.getAddress()); + const parentBalBefore = await zns.zToken.balanceOf(lvl2SubOwner.address); + const childBalBefore = await zns.zToken.balanceOf(lvl3SubOwner.address); + const zeroVaultBalanceBefore = await zns.zToken.balanceOf(zeroVault.address); const label = "zeropricechildfs"; const childHash = await registrationWithSetup({ @@ -2252,10 +2302,10 @@ describe("ZNSSubRegistrar", () => { domainLabel: label, }); - const parentBalAfter = await zns.meowToken.balanceOf(lvl2SubOwner.address); - const childBalAfter = await zns.meowToken.balanceOf(lvl3SubOwner.address); - const contractBalAfter = await zns.meowToken.balanceOf(await zns.treasury.getAddress()); - const zeroVaultBalanceAfter = await zns.meowToken.balanceOf(zeroVault.address); + const parentBalAfter = await zns.zToken.balanceOf(lvl2SubOwner.address); + const childBalAfter = await zns.zToken.balanceOf(lvl3SubOwner.address); + const contractBalAfter = await zns.zToken.balanceOf(await zns.treasury.getAddress()); + const zeroVaultBalanceAfter = await zns.zToken.balanceOf(zeroVault.address); expect(parentBalAfter - parentBalBefore).to.eq(0); expect(childBalBefore - childBalAfter).to.eq(0); @@ -2264,17 +2314,17 @@ describe("ZNSSubRegistrar", () => { // validate transfer events are not happenning const latestBlock = await time.latestBlock(); - const transferFilterToParent = zns.meowToken.filters.Transfer(lvl3SubOwner.address, lvl2SubOwner.address); - const transferFilterToTreasury = zns.meowToken.filters.Transfer( + const transferFilterToParent = zns.zToken.filters.Transfer(lvl3SubOwner.address, lvl2SubOwner.address); + const transferFilterToTreasury = zns.zToken.filters.Transfer( lvl3SubOwner.address, await zns.treasury.getAddress() ); - const transfersToParent = await zns.meowToken.queryFilter( + const transfersToParent = await zns.zToken.queryFilter( transferFilterToParent, latestBlock - 3, latestBlock ); - const transfersToTreasury = await zns.meowToken.queryFilter( + const transfersToTreasury = await zns.zToken.queryFilter( transferFilterToTreasury, latestBlock - 3, latestBlock @@ -2288,10 +2338,10 @@ describe("ZNSSubRegistrar", () => { ); // should NOT offer refund ! - const parentBalAfterRevoke = await zns.meowToken.balanceOf(lvl2SubOwner.address); - const childBalAfterRevoke = await zns.meowToken.balanceOf(lvl3SubOwner.address); - const contractBalAfterRevoke = await zns.meowToken.balanceOf(await zns.treasury.getAddress()); - const zeroVaultBalanceAfterRevoke = await zns.meowToken.balanceOf(zeroVault.address); + const parentBalAfterRevoke = await zns.zToken.balanceOf(lvl2SubOwner.address); + const childBalAfterRevoke = await zns.zToken.balanceOf(lvl3SubOwner.address); + const contractBalAfterRevoke = await zns.zToken.balanceOf(await zns.treasury.getAddress()); + const zeroVaultBalanceAfterRevoke = await zns.zToken.balanceOf(zeroVault.address); expect(parentBalAfterRevoke - parentBalAfter).to.eq(0); expect(childBalAfterRevoke - childBalAfter).to.eq(0); @@ -2303,7 +2353,7 @@ describe("ZNSSubRegistrar", () => { // we will use token with 5 decimals, but set prices in 18 decimals const priceConfigIncorrect = { maxPrice: ethers.parseUnits("234.46", decimalValues.eighteen), - minPrice: ethers.parseUnits("3.37", decimalValues.eighteen), + curveMultiplier: BigInt(1000), maxLength: BigInt(20), baseLength: BigInt(2), precisionMultiplier: BigInt(1), @@ -2337,7 +2387,6 @@ describe("ZNSSubRegistrar", () => { const priceConfigCorrect = { ...priceConfigIncorrect, maxPrice: ethers.parseUnits("234.46", decimalValues.five), - minPrice: ethers.parseUnits("3.37", decimalValues.five), }; // calc prices off-chain @@ -2403,7 +2452,10 @@ describe("ZNSSubRegistrar", () => { distrConfigEmpty, paymentConfigEmpty, ) - ).to.be.revertedWith("ERC20: insufficient allowance"); + ).to.be.revertedWithCustomError( + zns.zToken, + INSUFFICIENT_ALLOWANCE_ERC_ERR + ); // let's try to buy with the incorrect price const userBalanceBefore = await token5.balanceOf(lvl3SubOwner.address); @@ -2456,18 +2508,25 @@ describe("ZNSSubRegistrar", () => { fixedPrice = ethers.parseEther("397"); fixedFeePercentage = BigInt(200); + const users = [ + rootOwner, + lvl2SubOwner, + lvl3SubOwner, + lvl4SubOwner, + lvl5SubOwner, + lvl6SubOwner, + ]; + const totalAdminBalance = await zns.zToken.balanceOf(admin.address); + const userBalanceInitial = totalAdminBalance / BigInt(users.length); + await zns.zToken.connect(admin).approve(await zns.treasury.getAddress(), totalAdminBalance); + await Promise.all( - [ - rootOwner, - lvl2SubOwner, - lvl3SubOwner, - lvl4SubOwner, - lvl5SubOwner, - lvl6SubOwner, - ].map(async ({ address }) => - zns.meowToken.mint(address, ethers.parseEther("1000000"))) - ); - await zns.meowToken.connect(rootOwner).approve(await zns.treasury.getAddress(), ethers.MaxUint256); + users.map(async ({ address }) => + zns.zToken.connect(admin).transfer(address, userBalanceInitial) + ) + ); + + await zns.zToken.connect(rootOwner).approve(await zns.treasury.getAddress(), ethers.MaxUint256); // register root domain and 1 subdomain domainConfigs = [ @@ -2481,7 +2540,7 @@ describe("ZNSSubRegistrar", () => { accessType: AccessType.OPEN, }, paymentConfig: { - token: await zns.meowToken.getAddress(), + token: await zns.zToken.getAddress(), beneficiary: rootOwner.address, }, priceConfig: { price: fixedPrice, feePercentage: fixedFeePercentage }, @@ -2497,7 +2556,7 @@ describe("ZNSSubRegistrar", () => { accessType: AccessType.OPEN, }, paymentConfig: { - token: await zns.meowToken.getAddress(), + token: await zns.zToken.getAddress(), beneficiary: lvl2SubOwner.address, }, priceConfig: { price: fixedPrice, feePercentage: fixedFeePercentage }, @@ -2517,7 +2576,7 @@ describe("ZNSSubRegistrar", () => { AccessType.LOCKED, ); - const balBefore = await zns.meowToken.balanceOf(lvl2SubOwner.address); + const balBefore = await zns.zToken.balanceOf(lvl2SubOwner.address); const hash = await registrationWithSetup({ zns, @@ -2528,8 +2587,8 @@ describe("ZNSSubRegistrar", () => { const latestBlock = await time.latestBlock(); // look for an event where user pays himself - const filter = zns.meowToken.filters.Transfer(lvl2SubOwner.address, lvl2SubOwner.address); - const events = await zns.meowToken.queryFilter( + const filter = zns.zToken.filters.Transfer(lvl2SubOwner.address, lvl2SubOwner.address); + const events = await zns.zToken.queryFilter( filter, latestBlock - 50, latestBlock @@ -2537,7 +2596,7 @@ describe("ZNSSubRegistrar", () => { // this means NO transfers have been executed, which is what we need expect(events.length).to.eq(0); - const balAfter = await zns.meowToken.balanceOf(lvl2SubOwner.address); + const balAfter = await zns.zToken.balanceOf(lvl2SubOwner.address); // the diff is 0 because user should not pay himself expect(balAfter - balBefore).to.eq(0); @@ -2582,9 +2641,10 @@ describe("ZNSSubRegistrar", () => { ethers.ZeroAddress, DEFAULT_TOKEN_URI, distrConfigEmpty, - paymentConfigEmpty, + paymentConfigEmpty ) - ).to.be.revertedWith( + ).to.be.revertedWithCustomError( + zns.subRegistrar, DISTRIBUTION_LOCKED_NOT_EXIST_ERR ); }); @@ -2602,7 +2662,7 @@ describe("ZNSSubRegistrar", () => { const protocolFee = getStakingOrProtocolFee(expectedPrice); // approve direct payment - await zns.meowToken.connect(lvl5SubOwner).approve( + await zns.zToken.connect(lvl5SubOwner).approve( await zns.treasury.getAddress(), expectedPrice + protocolFee ); @@ -2635,7 +2695,7 @@ describe("ZNSSubRegistrar", () => { // eslint-disable-next-line max-len it("should ONLY allow mintlisted addresses and NOT allow other ones to register a domain when parent's accessType is MINTLIST", async () => { // approve direct payment - await zns.meowToken.connect(lvl3SubOwner).approve(await zns.treasury.getAddress(), fixedPrice); + await zns.zToken.connect(lvl3SubOwner).approve(await zns.treasury.getAddress(), fixedPrice); // register parent with mintlisted access const parentHash = await registrationWithSetup({ zns, @@ -2649,7 +2709,7 @@ describe("ZNSSubRegistrar", () => { accessType: AccessType.MINTLIST, }, paymentConfig: { - token: await zns.meowToken.getAddress(), + token: await zns.zToken.getAddress(), beneficiary: lvl3SubOwner.address, }, priceConfig: { price: fixedPrice, feePercentage: fixedFeePercentage }, @@ -2689,10 +2749,11 @@ describe("ZNSSubRegistrar", () => { ethers.ZeroAddress, DEFAULT_TOKEN_URI, distrConfigEmpty, - paymentConfigEmpty, + paymentConfigEmpty ) - ).to.be.revertedWith( - "ZNSSubRegistrar: Sender is not approved for purchase" + ).to.be.revertedWithCustomError( + zns.subRegistrar, + SENDER_NOT_APPROVED_ERR ); // remove user from mintlist @@ -2710,10 +2771,11 @@ describe("ZNSSubRegistrar", () => { ethers.ZeroAddress, DEFAULT_TOKEN_URI, distrConfigEmpty, - paymentConfigEmpty, + paymentConfigEmpty ) - ).to.be.revertedWith( - "ZNSSubRegistrar: Sender is not approved for purchase" + ).to.be.revertedWithCustomError( + zns.subRegistrar, + SENDER_NOT_APPROVED_ERR ); }); @@ -2743,13 +2805,10 @@ describe("ZNSSubRegistrar", () => { // try with non-authorized await expect( - zns.subRegistrar.connect(lvl5SubOwner).updateMintlistForDomain( - domainHash, - [lvl5SubOwner.address], - [true], - ) - ).to.be.revertedWith( - "ZNSSubRegistrar: Not authorized" + zns.subRegistrar.connect(lvl5SubOwner).updateMintlistForDomain(domainHash, [lvl5SubOwner.address], [true]) + ).to.be.revertedWithCustomError( + zns.subRegistrar, + NOT_AUTHORIZED_ERR ); }); @@ -2806,9 +2865,10 @@ describe("ZNSSubRegistrar", () => { ethers.ZeroAddress, DEFAULT_TOKEN_URI, distrConfigEmpty, - paymentConfigEmpty, + paymentConfigEmpty ) - ).to.be.revertedWith( + ).to.be.revertedWithCustomError( + zns.subRegistrar, DISTRIBUTION_LOCKED_NOT_EXIST_ERR ); @@ -2840,7 +2900,7 @@ describe("ZNSSubRegistrar", () => { : expectedPrice; const protocolFee = getStakingOrProtocolFee(paymentToParent); - await zns.meowToken.connect(lvl5SubOwner).approve( + await zns.zToken.connect(lvl5SubOwner).approve( await zns.treasury.getAddress(), paymentToParent + protocolFee ); @@ -2888,9 +2948,10 @@ describe("ZNSSubRegistrar", () => { ethers.ZeroAddress, DEFAULT_TOKEN_URI, distrConfigEmpty, - paymentConfigEmpty, + paymentConfigEmpty ) - ).to.be.revertedWith( + ).to.be.revertedWithCustomError( + zns.subRegistrar, DISTRIBUTION_LOCKED_NOT_EXIST_ERR ); }); @@ -2928,18 +2989,24 @@ describe("ZNSSubRegistrar", () => { fixedPrice = ethers.parseEther("397"); fixedFeePercentage = BigInt(200); + const users = [ + rootOwner, + lvl2SubOwner, + lvl3SubOwner, + lvl4SubOwner, + lvl5SubOwner, + lvl6SubOwner, + ]; + const totalAdminBalance = await zns.zToken.balanceOf(admin.address); + const userBalanceInitial = totalAdminBalance / BigInt(users.length); + await Promise.all( - [ - rootOwner, - lvl2SubOwner, - lvl3SubOwner, - lvl4SubOwner, - lvl5SubOwner, - lvl6SubOwner, - ].map(async ({ address }) => - zns.meowToken.mint(address, ethers.parseEther("1000000"))) - ); - await zns.meowToken.connect(rootOwner).approve(await zns.treasury.getAddress(), ethers.MaxUint256); + users.map(async ({ address }) => + zns.zToken.connect(admin).transfer(address, userBalanceInitial) + ) + ); + + await zns.zToken.connect(rootOwner).approve(await zns.treasury.getAddress(), ethers.MaxUint256); // register root domain and 1 subdomain domainConfigs = [ @@ -2953,7 +3020,7 @@ describe("ZNSSubRegistrar", () => { accessType: AccessType.OPEN, }, paymentConfig: { - token: await zns.meowToken.getAddress(), + token: await zns.zToken.getAddress(), beneficiary: rootOwner.address, }, priceConfig: { price: fixedPrice, feePercentage: fixedFeePercentage }, @@ -2970,7 +3037,7 @@ describe("ZNSSubRegistrar", () => { accessType: AccessType.OPEN, }, paymentConfig: { - token: await zns.meowToken.getAddress(), + token: await zns.zToken.getAddress(), beneficiary: lvl2SubOwner.address, }, priceConfig: { price: fixedPrice, feePercentage: fixedFeePercentage }, @@ -2987,7 +3054,7 @@ describe("ZNSSubRegistrar", () => { accessType: AccessType.OPEN, }, paymentConfig: { - token: await zns.meowToken.getAddress(), + token: await zns.zToken.getAddress(), beneficiary: lvl3SubOwner.address, }, priceConfig: DEFAULT_PRICE_CONFIG, @@ -3009,10 +3076,11 @@ describe("ZNSSubRegistrar", () => { lvl2SubOwner.address, DEFAULT_TOKEN_URI, domainConfigs[1].fullConfig.distrConfig, - paymentConfigEmpty, + paymentConfigEmpty ) - ).to.be.revertedWith( - "ZNSSubRegistrar: Subdomain already exists" + ).to.be.revertedWithCustomError( + zns.subRegistrar, + DOMAIN_EXISTS_ERR ); }); @@ -3025,12 +3093,11 @@ describe("ZNSSubRegistrar", () => { // fail await expect( - zns.rootRegistrar.connect(lvl3SubOwner).revokeDomain( - regResults[1].domainHash, - ) - ).to.be.revertedWith( - "ZNSRootRegistrar: Not the owner of both Name and Token" - ); + zns.rootRegistrar.connect(lvl3SubOwner).revokeDomain(regResults[1].domainHash) + ).to.be.revertedWithCustomError( + zns.rootRegistrar, + NOT_OWNER_OF_ERR + ).withArgs(2n, lvl3SubOwner.address, regResults[1].domainHash); // change owner back await zns.registry.connect(rootOwner).updateDomainOwner( @@ -3039,7 +3106,7 @@ describe("ZNSSubRegistrar", () => { ); // tranfer token - await zns.domainToken.connect(lvl2SubOwner).transferFrom( + await zns.domainToken.connect(lvl2SubOwner).updateTokenOwner( lvl2SubOwner.address, lvl3SubOwner.address, regResults[1].domainHash @@ -3050,9 +3117,10 @@ describe("ZNSSubRegistrar", () => { zns.rootRegistrar.connect(lvl2SubOwner).revokeDomain( regResults[1].domainHash, ) - ).to.be.revertedWith( - "ZNSRootRegistrar: Not the owner of both Name and Token" - ); + ).to.be.revertedWithCustomError( + zns.rootRegistrar, + NOT_OWNER_OF_ERR + ).withArgs(2n, lvl2SubOwner.address, regResults[1].domainHash); // give token back await zns.domainToken.connect(lvl3SubOwner).transferFrom( @@ -3146,6 +3214,7 @@ describe("ZNSSubRegistrar", () => { it("should NOT allow to set distribution config for a non-authorized account", async () => { const domainHash = regResults[1].domainHash; + const newConfig = { pricerContract: await zns.curvePricer.getAddress(), paymentType: PaymentType.STAKE, @@ -3153,12 +3222,10 @@ describe("ZNSSubRegistrar", () => { }; await expect( - zns.subRegistrar.connect(lvl3SubOwner).setDistributionConfigForDomain( - domainHash, - newConfig, - ) - ).to.be.revertedWith( - "ZNSSubRegistrar: Not authorized" + zns.subRegistrar.connect(lvl3SubOwner).setDistributionConfigForDomain(domainHash, newConfig) + ).to.be.revertedWithCustomError( + zns.subRegistrar, + NOT_AUTHORIZED_ERR ); }); @@ -3172,12 +3239,10 @@ describe("ZNSSubRegistrar", () => { }; await expect( - zns.subRegistrar.connect(lvl3SubOwner).setDistributionConfigForDomain( - domainHash, - newConfig, - ) - ).to.be.revertedWith( - "ZNSSubRegistrar: pricerContract can not be 0x0 address" + zns.subRegistrar.connect(lvl3SubOwner).setDistributionConfigForDomain(domainHash, newConfig) + ).to.be.revertedWithCustomError( + zns.subRegistrar, + ZERO_ADDRESS_ERR ); }); }); @@ -3210,10 +3275,11 @@ describe("ZNSSubRegistrar", () => { await expect( zns.subRegistrar.connect(lvl2SubOwner).setPricerContractForDomain( domainHash, - await zns.curvePricer.getAddress(), + await zns.curvePricer.getAddress() ) - ).to.be.revertedWith( - "ZNSSubRegistrar: Not authorized" + ).to.be.revertedWithCustomError( + zns.subRegistrar, + NOT_AUTHORIZED_ERR ); }); @@ -3221,12 +3287,10 @@ describe("ZNSSubRegistrar", () => { const domainHash = regResults[2].domainHash; await expect( - zns.subRegistrar.connect(lvl3SubOwner).setPricerContractForDomain( - domainHash, - ethers.ZeroAddress, - ) - ).to.be.revertedWith( - "ZNSSubRegistrar: pricerContract can not be 0x0 address" + zns.subRegistrar.connect(lvl3SubOwner).setPricerContractForDomain(domainHash, ethers.ZeroAddress) + ).to.be.revertedWithCustomError( + zns.subRegistrar, + ZERO_ADDRESS_ERR ); }); }); @@ -3257,12 +3321,10 @@ describe("ZNSSubRegistrar", () => { const domainHash = regResults[2].domainHash; await expect( - zns.subRegistrar.connect(lvl2SubOwner).setPaymentTypeForDomain( - domainHash, - PaymentType.STAKE, - ) - ).to.be.revertedWith( - "ZNSSubRegistrar: Not authorized" + zns.subRegistrar.connect(lvl2SubOwner).setPaymentTypeForDomain(domainHash, PaymentType.STAKE) + ).to.be.revertedWithCustomError( + zns.subRegistrar, + NOT_AUTHORIZED_ERR ); }); @@ -3293,7 +3355,7 @@ describe("ZNSSubRegistrar", () => { const { amount: stakedBefore } = await zns.treasury.stakedForDomain(regResults[1].domainHash); - await zns.domainToken.connect(lvl2SubOwner).transferFrom( + await zns.domainToken.connect(lvl2SubOwner).updateTokenOwner( lvl2SubOwner.address, lvl3SubOwner.address, tokenId @@ -3320,18 +3382,18 @@ describe("ZNSSubRegistrar", () => { const { amount: stakedAfter } = await zns.treasury.stakedForDomain(regResults[1].domainHash); expect(stakedAfter).to.eq(stakedBefore); - const userBalbefore = await zns.meowToken.balanceOf(lvl3SubOwner.address); + const userBalbefore = await zns.zToken.balanceOf(lvl3SubOwner.address); const protocolFee = getStakingOrProtocolFee(stakedAfter); - await zns.meowToken.connect(lvl3SubOwner).approve(await zns.treasury.getAddress(), protocolFee); + await zns.zToken.connect(lvl3SubOwner).approve(await zns.treasury.getAddress(), protocolFee); // try revoking await zns.rootRegistrar.connect(lvl3SubOwner).revokeDomain( regResults[1].domainHash, ); // verify that refund has been acquired by the new owner - const userBalAfter = await zns.meowToken.balanceOf(lvl3SubOwner.address); + const userBalAfter = await zns.zToken.balanceOf(lvl3SubOwner.address); expect(userBalAfter - userBalbefore).to.eq(fixedPrice - protocolFee); }); }); @@ -3362,7 +3424,7 @@ describe("ZNSSubRegistrar", () => { deployer.address, deployer.address, ) - ).to.be.revertedWith(INITIALIZED_ERR); + ).to.be.revertedWithCustomError(implContract, INITIALIZED_ERR); }); it("#setRootRegistrar() should set the new root registrar correctly and emit #RootRegistrarSet event", async () => { @@ -3374,18 +3436,17 @@ describe("ZNSSubRegistrar", () => { }); it("#setRootRegistrar() should NOT be callable by anyone other than ADMIN_ROLE", async () => { - await expect( - zns.subRegistrar.connect(random).setRootRegistrar(random.address), - ).to.be.revertedWith( - getAccessRevertMsg(random.address, ADMIN_ROLE), - ); + await expect(zns.subRegistrar.connect(random).setRootRegistrar(random.address)) + .to.be.revertedWithCustomError(zns.accessController, AC_UNAUTHORIZED_ERR) + .withArgs(random.address, ADMIN_ROLE); }); it("#setRootRegistrar should NOT set registrar as 0x0 address", async () => { await expect( - zns.subRegistrar.connect(admin).setRootRegistrar(ethers.ZeroAddress), - ).to.be.revertedWith( - "ZNSSubRegistrar: _registrar can not be 0x0 address", + zns.subRegistrar.connect(admin).setRootRegistrar(ethers.ZeroAddress) + ).to.be.revertedWithCustomError( + zns.subRegistrar, + ZERO_ADDRESS_ERR ); }); @@ -3398,19 +3459,15 @@ describe("ZNSSubRegistrar", () => { }); it("#setRegistry() should not be callable by anyone other than ADMIN_ROLE", async () => { - await expect( - zns.subRegistrar.connect(random).setRegistry(random.address), - ).to.be.revertedWith( - getAccessRevertMsg(random.address, ADMIN_ROLE), - ); + await expect(zns.subRegistrar.connect(random).setRegistry(random.address)) + .to.be.revertedWithCustomError(zns.accessController, AC_UNAUTHORIZED_ERR) + .withArgs(random.address, ADMIN_ROLE); }); it("#setAccessController() should not be callable by anyone other than ADMIN_ROLE", async () => { - await expect( - zns.subRegistrar.connect(random).setAccessController(random.address), - ).to.be.revertedWith( - getAccessRevertMsg(random.address, ADMIN_ROLE), - ); + await expect(zns.subRegistrar.connect(random).setAccessController(random.address)) + .to.be.revertedWithCustomError(zns.accessController, AC_UNAUTHORIZED_ERR) + .withArgs(random.address, ADMIN_ROLE); }); it("#getAccessController() should return the correct access controller", async () => { @@ -3452,14 +3509,20 @@ describe("ZNSSubRegistrar", () => { }); // Give funds to users + const users = [ + rootOwner, + lvl2SubOwner, + ]; + const totalAdminBalance = await zns.zToken.balanceOf(admin.address); + const userBalanceInitial = totalAdminBalance / BigInt(users.length); + await Promise.all( - [ - rootOwner, - lvl2SubOwner, - ].map(async ({ address }) => - zns.meowToken.mint(address, ethers.parseEther("1000000"))) + users.map(async ({ address }) => + zns.zToken.connect(admin).transfer(address, userBalanceInitial) + ) ); - await zns.meowToken.connect(rootOwner).approve(await zns.treasury.getAddress(), ethers.MaxUint256); + + await zns.zToken.connect(rootOwner).approve(await zns.treasury.getAddress(), ethers.MaxUint256); fixedPrice = ethers.parseEther("397.13"); // register root domain @@ -3474,7 +3537,7 @@ describe("ZNSSubRegistrar", () => { paymentType: PaymentType.DIRECT, }, paymentConfig: { - token: await zns.meowToken.getAddress(), + token: await zns.zToken.getAddress(), beneficiary: rootOwner.address, }, priceConfig: { @@ -3494,7 +3557,10 @@ describe("ZNSSubRegistrar", () => { // Confirm the deployer is a governor, as set in `deployZNS` helper await expect(zns.accessController.checkGovernor(deployer.address)).to.not.be.reverted; - const tx = zns.subRegistrar.connect(deployer).upgradeTo(await newRegistrar.getAddress()); + const tx = zns.subRegistrar.connect(deployer).upgradeToAndCall( + await newRegistrar.getAddress(), + "0x" + ); await expect(tx).to.not.be.reverted; await expect( @@ -3503,7 +3569,7 @@ describe("ZNSSubRegistrar", () => { await zns.registry.getAddress(), await zns.rootRegistrar.getAddress(), ) - ).to.be.revertedWith(INITIALIZED_ERR); + ).to.be.revertedWithCustomError(zns.subRegistrar, INITIALIZED_ERR); }); it("Fails to upgrade if the caller is not authorized", async () => { @@ -3515,11 +3581,13 @@ describe("ZNSSubRegistrar", () => { // Confirm the account is not a governor await expect(zns.accessController.checkGovernor(lvl2SubOwner.address)).to.be.reverted; - const tx = zns.subRegistrar.connect(lvl2SubOwner).upgradeTo(await newRegistrar.getAddress()); - - await expect(tx).to.be.revertedWith( - getAccessRevertMsg(lvl2SubOwner.address, GOVERNOR_ROLE) + const tx = zns.subRegistrar.connect(lvl2SubOwner).upgradeToAndCall( + await newRegistrar.getAddress(), + "0x" ); + + await expect(tx).to.be.revertedWithCustomError(zns.accessController, AC_UNAUTHORIZED_ERR) + .withArgs(lvl2SubOwner.address, GOVERNOR_ROLE); }); it("Verifies that variable values are not changed in the upgrade process", async () => { @@ -3532,9 +3600,6 @@ describe("ZNSSubRegistrar", () => { const domainLabel = "world"; - await zns.meowToken.connect(lvl2SubOwner).approve(await zns.treasury.getAddress(), ethers.MaxUint256); - await zns.meowToken.mint(lvl2SubOwner.address, ethers.parseEther("1000000")); - const domainHash = await registrationWithSetup({ zns, user: lvl2SubOwner, @@ -3551,7 +3616,7 @@ describe("ZNSSubRegistrar", () => { feePercentage: BigInt(0), }, paymentConfig: { - token: await zns.meowToken.getAddress(), + token: await zns.zToken.getAddress(), beneficiary: lvl2SubOwner.address, }, }, @@ -3579,7 +3644,10 @@ describe("ZNSSubRegistrar", () => { const newRegistrar = await factory.deploy(); await newRegistrar.waitForDeployment(); - const tx = zns.subRegistrar.connect(deployer).upgradeTo(await newRegistrar.getAddress()); + const tx = zns.subRegistrar.connect(deployer).upgradeToAndCall( + await newRegistrar.getAddress(), + "0x" + ); await expect(tx).to.not.be.reverted; // create new proxy object @@ -3591,8 +3659,7 @@ describe("ZNSSubRegistrar", () => { expect(rootConfigBefore.pricerContract).to.eq(await zns.fixedPricer.getAddress()); expect(rootConfigBefore.paymentType).to.eq(PaymentType.DIRECT); - await zns.meowToken.mint(lvl2SubOwner.address, ethers.parseEther("1000000")); - await zns.meowToken.connect(lvl2SubOwner).approve(await zns.treasury.getAddress(), ethers.parseEther("1000000")); + await zns.zToken.connect(lvl2SubOwner).approve(await zns.treasury.getAddress(), ethers.parseEther("1000000")); const subConfigToSet = { accessType: AccessType.MINTLIST, diff --git a/test/ZNSTreasury.test.ts b/test/ZNSTreasury.test.ts index f215ee5c6..b8368420e 100644 --- a/test/ZNSTreasury.test.ts +++ b/test/ZNSTreasury.test.ts @@ -7,18 +7,16 @@ import { distrConfigEmpty, getPriceObject, NO_BENEFICIARY_ERR, - NOT_AUTHORIZED_REG_WIRED_ERR, INITIALIZED_ERR, DEFAULT_PRICE_CONFIG, validateUpgrade, - NOT_AUTHORIZED_TREASURY_ERR, - getStakingOrProtocolFee, + NOT_AUTHORIZED_ERR, + getStakingOrProtocolFee, AC_UNAUTHORIZED_ERR, ZERO_ADDRESS_ERR, } from "./helpers"; import { DeployZNSParams, IZNSContractsLocal } from "./helpers/types"; import * as ethers from "ethers"; import { hashDomainLabel, hashSubdomainName } from "./helpers/hashing"; import { ADMIN_ROLE, REGISTRAR_ROLE, GOVERNOR_ROLE } from "../src/deploy/constants"; -import { getAccessRevertMsg } from "./helpers/errors"; import { ZNSTreasury, ZNSTreasury__factory, ZNSTreasuryUpgradeMock__factory } from "../typechain"; import { getProxyImplAddress } from "./helpers/utils"; @@ -63,16 +61,18 @@ describe("ZNSTreasury", () => { zns = await deployZNS(params); paymentConfig = { - token: await zns.meowToken.getAddress(), + token: await zns.zToken.getAddress(), beneficiary: user.address, }; // give REGISTRAR_ROLE to a wallet address to be calling guarded functions await zns.accessController.connect(admin).grantRole(REGISTRAR_ROLE, mockRegistrar.address); - // Give funds to user - await zns.meowToken.connect(user).approve(await zns.treasury.getAddress(), ethers.MaxUint256); - await zns.meowToken.mint(user.address, ethers.parseEther("50000")); + // Give funds to user and deployer. Divide equally to give them the same amount + const userBalanceInitial = await zns.zToken.balanceOf(admin.address) / 3n; + await zns.zToken.connect(user).approve(await zns.treasury.getAddress(), userBalanceInitial); + await zns.zToken.connect(admin).transfer(user, userBalanceInitial); + await zns.zToken.connect(admin).transfer(deployer, userBalanceInitial); // register random domain await zns.rootRegistrar.connect(user).registerRootDomain( @@ -93,7 +93,7 @@ describe("ZNSTreasury", () => { const accessController = await zns.treasury.getAccessController(); expect(registry).to.eq(await zns.registry.getAddress()); - expect(token).to.eq(await zns.meowToken.getAddress()); + expect(token).to.eq(await zns.zToken.getAddress()); expect(beneficiary).to.eq(zns.zeroVaultAddress); expect(accessController).to.eq(await zns.accessController.getAddress()); }); @@ -101,11 +101,14 @@ describe("ZNSTreasury", () => { it("should NOT initialize twice", async () => { const tx = zns.treasury.initialize( await zns.registry.getAddress(), - await zns.meowToken.getAddress(), + await zns.zToken.getAddress(), zns.zeroVaultAddress, await zns.accessController.getAddress() ); - await expect(tx).to.be.revertedWith("Initializable: contract is already initialized"); + await expect(tx).to.be.revertedWithCustomError( + zns.treasury, + INITIALIZED_ERR + ); }); it("Should NOT let initialize the implementation contract", async () => { @@ -116,11 +119,11 @@ describe("ZNSTreasury", () => { await expect( implContract.initialize( await zns.registry.getAddress(), - await zns.meowToken.getAddress(), + await zns.zToken.getAddress(), zns.zeroVaultAddress, await zns.accessController.getAddress() ) - ).to.be.revertedWith(INITIALIZED_ERR); + ).to.be.revertedWithCustomError(implContract, INITIALIZED_ERR); }); it("should NOT deploy/initialize with 0x0 addresses as args", async () => { @@ -128,7 +131,7 @@ describe("ZNSTreasury", () => { deployer, accessControllerAddress: await zns.accessController.getAddress(), registryAddress: await zns.registry.getAddress(), - zTokenMockAddress: await zns.meowToken.getAddress(), + zTokenMockAddress: await zns.zToken.getAddress(), zeroVaultAddress: zns.zeroVaultAddress, isTenderlyRun: false, }; @@ -151,8 +154,8 @@ describe("ZNSTreasury", () => { describe("#stakeForDomain()", () => { it("Stakes the correct amount", async () => { - const balanceBeforeStake = await zns.meowToken.balanceOf(user.address); - const zeroVaultBalanceBeforeStake = await zns.meowToken.balanceOf(zeroVault.address); + const balanceBeforeStake = await zns.zToken.balanceOf(user.address); + const zeroVaultBalanceBeforeStake = await zns.zToken.balanceOf(zeroVault.address); const expectedStake = await zns.curvePricer.getPrice( ethers.ZeroHash, @@ -174,30 +177,27 @@ describe("ZNSTreasury", () => { expect(stake).to.eq(expectedStake); await checkBalance({ - token: zns.meowToken, + token: zns.zToken, balanceBefore: balanceBeforeStake, userAddress: user.address, target: stake + fee, shouldDecrease: true, }); - const zeroVaultBalanceAfterStake = await zns.meowToken.balanceOf(zeroVault.address); + const zeroVaultBalanceAfterStake = await zns.zToken.balanceOf(zeroVault.address); expect(zeroVaultBalanceAfterStake).to.eq(zeroVaultBalanceBeforeStake + fee); }); it("Should revert if called from an address without REGISTRAR_ROLE", async () => { - await expect( - zns.treasury.connect(randomAcc).stakeForDomain( - ethers.ZeroHash, - domainHash, - user.address, - BigInt(0), - BigInt(0), - BigInt(0) - ) - ).to.be.revertedWith( - getAccessRevertMsg(randomAcc.address, REGISTRAR_ROLE) - ); + await expect(zns.treasury.connect(randomAcc).stakeForDomain( + ethers.ZeroHash, + domainHash, + user.address, + BigInt(0), + BigInt(0), + BigInt(0) + )).to.be.revertedWithCustomError(zns.accessController, AC_UNAUTHORIZED_ERR) + .withArgs(randomAcc.address,REGISTRAR_ROLE); }); it("Should fire StakeDeposited event with correct params", async () => { @@ -224,7 +224,7 @@ describe("ZNSTreasury", () => { ethers.ZeroHash, domainHash, user.address, - await zns.meowToken.getAddress(), + await zns.zToken.getAddress(), expectedPrice, BigInt(0), protocolFee @@ -246,33 +246,30 @@ describe("ZNSTreasury", () => { protocolFee ); - const balanceBeforeUnstake = await zns.meowToken.balanceOf(user.address); + const balanceBeforeUnstake = await zns.zToken.balanceOf(user.address); const { token, amount: stake } = await zns.treasury.stakedForDomain(domainHash); await zns.treasury.connect(mockRegistrar).unstakeForDomain(domainHash, user.address, protocolFee); await checkBalance({ - token: zns.meowToken, + token: zns.zToken, balanceBefore: balanceBeforeUnstake, userAddress: user.address, target: stake - protocolFee, shouldDecrease: false, }); - expect(token).to.eq(await zns.meowToken.getAddress()); + expect(token).to.eq(await zns.zToken.getAddress()); }); it("Should revert if called from an address without REGISTRAR_ROLE", async () => { const { amount } = await zns.treasury.stakedForDomain(domainHash); const protocolFee = getStakingOrProtocolFee(amount); - await expect( - zns.treasury.connect(user).unstakeForDomain( - domainHash, - user.address, - protocolFee - ) - ).to.be.revertedWith( - getAccessRevertMsg(user.address, REGISTRAR_ROLE) - ); + await expect(zns.treasury.connect(user).unstakeForDomain( + domainHash, + user.address, + protocolFee + )).to.be.revertedWithCustomError(zns.accessController, AC_UNAUTHORIZED_ERR) + .withArgs(user.address,REGISTRAR_ROLE); }); }); @@ -280,7 +277,7 @@ describe("ZNSTreasury", () => { it("should process payment correctly with paymentConfig set", async () => { const randomHash = hashDomainLabel("randommmmmmmm2342342"); const config = { - token: await zns.meowToken.getAddress(), + token: await zns.zToken.getAddress(), beneficiary: user.address, }; @@ -298,12 +295,12 @@ describe("ZNSTreasury", () => { const paymentAmt = ethers.parseEther("1000"); const protocolFee = ethers.parseEther("10"); // give tokens to mock registrar - await zns.meowToken.connect(user).transfer(mockRegistrar.address, paymentAmt + protocolFee); - await zns.meowToken.connect(mockRegistrar).approve(await zns.treasury.getAddress(), paymentAmt + protocolFee); + await zns.zToken.connect(user).transfer(mockRegistrar.address, paymentAmt + protocolFee); + await zns.zToken.connect(mockRegistrar).approve(await zns.treasury.getAddress(), paymentAmt + protocolFee); - const userBalanceBefore = await zns.meowToken.balanceOf(user.address); - const payerBalanceBefore = await zns.meowToken.balanceOf(mockRegistrar.address); - const zeroVaultBalanceBefore = await zns.meowToken.balanceOf(zeroVault.address); + const userBalanceBefore = await zns.zToken.balanceOf(user.address); + const payerBalanceBefore = await zns.zToken.balanceOf(mockRegistrar.address); + const zeroVaultBalanceBefore = await zns.zToken.balanceOf(zeroVault.address); await zns.treasury.connect(mockRegistrar).processDirectPayment( randomHash, @@ -313,9 +310,9 @@ describe("ZNSTreasury", () => { protocolFee ); - const userBalanceAfter = await zns.meowToken.balanceOf(user.address); - const payerBalanceAfter = await zns.meowToken.balanceOf(mockRegistrar.address); - const zeroVaultBalanceAfter = await zns.meowToken.balanceOf(zeroVault.address); + const userBalanceAfter = await zns.zToken.balanceOf(user.address); + const payerBalanceAfter = await zns.zToken.balanceOf(mockRegistrar.address); + const zeroVaultBalanceAfter = await zns.zToken.balanceOf(zeroVault.address); expect(userBalanceAfter - userBalanceBefore).to.eq(paymentAmt); expect(payerBalanceBefore - payerBalanceAfter).to.eq(paymentAmt + protocolFee); @@ -343,29 +340,29 @@ describe("ZNSTreasury", () => { paymentAmt, protocolFee ) - ).to.be.revertedWith(NO_BENEFICIARY_ERR); + ).to.be.revertedWithCustomError( + zns.treasury, + NO_BENEFICIARY_ERR + ); }); it("should revert if called by anyone other than REGISTRAR_ROLE", async () => { - await expect( - zns.treasury.connect(randomAcc).processDirectPayment( - ethers.ZeroHash, - domainHash, - mockRegistrar.address, - "0", - "0" - ) - ).to.be.revertedWith( - getAccessRevertMsg(randomAcc.address, REGISTRAR_ROLE) - ); + await expect(zns.treasury.connect(randomAcc).processDirectPayment( + ethers.ZeroHash, + domainHash, + mockRegistrar.address, + "0", + "0" + )).to.be.revertedWithCustomError(zns.accessController, AC_UNAUTHORIZED_ERR) + .withArgs(randomAcc.address,REGISTRAR_ROLE); }); it("should emit DirectPaymentProcessed event with correct params", async () => { const paymentAmt = ethers.parseEther("100"); const protocolFee = ethers.parseEther("7"); // give tokens to mock registrar - await zns.meowToken.connect(user).transfer(mockRegistrar.address, paymentAmt + protocolFee); - await zns.meowToken.connect(mockRegistrar).approve(await zns.treasury.getAddress(), paymentAmt + protocolFee); + await zns.zToken.connect(user).transfer(mockRegistrar.address, paymentAmt + protocolFee); + await zns.zToken.connect(mockRegistrar).approve(await zns.treasury.getAddress(), paymentAmt + protocolFee); await expect( zns.treasury.connect(mockRegistrar).processDirectPayment( @@ -429,12 +426,10 @@ describe("ZNSTreasury", () => { }; await expect( - zns.treasury.connect(randomAcc).setPaymentConfig( - domainHash, - configToSet, - ) - ).to.be.revertedWith( - NOT_AUTHORIZED_TREASURY_ERR + zns.treasury.connect(randomAcc).setPaymentConfig(domainHash, configToSet) + ).to.be.revertedWithCustomError( + zns.treasury, + NOT_AUTHORIZED_ERR ); }); @@ -445,26 +440,22 @@ describe("ZNSTreasury", () => { }; await expect( - zns.treasury.connect(user).setPaymentConfig( - domainHash, - zeroBeneficiaryConf - ) - ).to.be.revertedWith( - "ZNSTreasury: beneficiary passed as 0x0 address" + zns.treasury.connect(user).setPaymentConfig(domainHash, zeroBeneficiaryConf) + ).to.be.revertedWithCustomError( + zns.treasury, + ZERO_ADDRESS_ERR ); - const meowTokenConf = { + const zTokenConf = { token: ethers.ZeroAddress, beneficiary: randomAcc.address, }; await expect( - zns.treasury.connect(user).setPaymentConfig( - domainHash, - meowTokenConf - ) - ).to.be.revertedWith( - "ZNSTreasury: paymentToken passed as 0x0 address" + zns.treasury.connect(user).setPaymentConfig(domainHash, zTokenConf) + ).to.be.revertedWithCustomError( + zns.treasury, + ZERO_ADDRESS_ERR ); }); }); @@ -495,9 +486,7 @@ describe("ZNSTreasury", () => { ethers.ZeroHash, mockRegistrar.address ); - await expect(tx).to.be.revertedWith( - NOT_AUTHORIZED_REG_WIRED_ERR - ); + await expect(tx).to.be.revertedWithCustomError(zns.treasury, NOT_AUTHORIZED_ERR); }); it("Should revert when beneficiary is address 0", async () => { @@ -505,7 +494,7 @@ describe("ZNSTreasury", () => { ethers.ZeroHash, ethers.ZeroAddress ); - await expect(tx).to.be.revertedWith("ZNSTreasury: beneficiary passed as 0x0 address"); + await expect(tx).to.be.revertedWithCustomError(zns.treasury, ZERO_ADDRESS_ERR); }); }); @@ -533,14 +522,15 @@ describe("ZNSTreasury", () => { domainHash, randomAcc.address ); - await expect(tx).to.be.revertedWith( - NOT_AUTHORIZED_REG_WIRED_ERR + await expect(tx).to.be.revertedWithCustomError( + zns.treasury, + NOT_AUTHORIZED_ERR ); }); it("Should revert when paymentToken is address 0", async () => { const tx = zns.treasury.connect(user).setPaymentToken(domainHash, ethers.ZeroAddress); - await expect(tx).to.be.revertedWith("ZNSTreasury: paymentToken passed as 0x0 address"); + await expect(tx).to.be.revertedWithCustomError(zns.treasury, ZERO_ADDRESS_ERR); }); }); @@ -559,14 +549,13 @@ describe("ZNSTreasury", () => { it("Should revert when called from any address without ADMIN_ROLE", async () => { const tx = zns.treasury.connect(user).setAccessController(randomAcc.address); - await expect(tx).to.be.revertedWith( - getAccessRevertMsg(user.address, ADMIN_ROLE) - ); + await expect(tx).to.be.revertedWithCustomError(zns.accessController, AC_UNAUTHORIZED_ERR) + .withArgs(user.address,ADMIN_ROLE); }); it("Should revert when accessController is address 0", async () => { const tx = zns.treasury.setAccessController(ethers.ZeroAddress); - await expect(tx).to.be.revertedWith("AC: _accessController is 0x0 address"); + await expect(tx).to.be.revertedWithCustomError(zns.treasury, ZERO_ADDRESS_ERR); }); }); @@ -585,14 +574,13 @@ describe("ZNSTreasury", () => { it("Should revert when called from any address without ADMIN_ROLE", async () => { const tx = zns.treasury.connect(user).setRegistry(randomAcc.address); - await expect(tx).to.be.revertedWith( - getAccessRevertMsg(user.address, ADMIN_ROLE) - ); + await expect(tx).to.be.revertedWithCustomError(zns.accessController, AC_UNAUTHORIZED_ERR) + .withArgs(user.address,ADMIN_ROLE); }); it("Should revert when registry is address 0", async () => { const tx = zns.treasury.setRegistry(ethers.ZeroAddress); - await expect(tx).to.be.revertedWith("ARegistryWired: _registry can not be 0x0 address"); + await expect(tx).to.be.revertedWithCustomError(zns.treasury, ZERO_ADDRESS_ERR); }); }); @@ -607,7 +595,10 @@ describe("ZNSTreasury", () => { const treasury = await treasuryFactory.deploy(); await treasury.waitForDeployment(); - await expect(zns.treasury.connect(deployer).upgradeTo(await treasury.getAddress())).to.not.be.reverted; + await expect(zns.treasury.connect(deployer).upgradeToAndCall( + await treasury.getAddress(), + "0x" + )).to.not.be.reverted; }); it("Fails when an unauthorized user tries to upgrade the contract", async () => { @@ -619,8 +610,12 @@ describe("ZNSTreasury", () => { const treasury = await treasuryFactory.deploy(); await treasury.waitForDeployment(); - const deployTx = zns.treasury.connect(user).upgradeTo(await treasury.getAddress()); - await expect(deployTx).to.be.revertedWith(getAccessRevertMsg(user.address, GOVERNOR_ROLE)); + const deployTx = zns.treasury.connect(user).upgradeToAndCall( + await treasury.getAddress(), + "0x" + ); + await expect(deployTx).to.be.revertedWithCustomError(zns.accessController, AC_UNAUTHORIZED_ERR) + .withArgs(user.address, GOVERNOR_ROLE); }); it("Verifies that variable values are not changed in the upgrade process", async () => { @@ -635,6 +630,8 @@ describe("ZNSTreasury", () => { const newHash = hashSubdomainName(newLabel); const { expectedPrice, stakeFee } = getPriceObject(newLabel, DEFAULT_PRICE_CONFIG); + await zns.zToken.connect(deployer).approve(await zns.treasury.getAddress(), ethers.MaxInt256); + await zns.treasury.connect(mockRegistrar).stakeForDomain( ethers.ZeroHash, newHash, diff --git a/test/gas/TransactionGasCosts.test.ts b/test/gas/TransactionGasCosts.test.ts index d27dd3200..f19ad4c26 100644 --- a/test/gas/TransactionGasCosts.test.ts +++ b/test/gas/TransactionGasCosts.test.ts @@ -51,14 +51,19 @@ describe("Transaction Gas Costs Test", () => { }; // Give funds to users + const users = [ + rootOwner, + lvl2SubOwner, + ]; + const totalAdminBalance = await zns.zToken.balanceOf(admin.address); + const userBalanceInitial = totalAdminBalance / BigInt(users.length); + await Promise.all( - [ - rootOwner, - lvl2SubOwner, - ].map(async ({ address }) => - zns.meowToken.mint(address, ethers.parseEther("1000000"))) + users.map(async ({ address }) => + zns.zToken.connect(admin).transfer(address, userBalanceInitial) + ) ); - await zns.meowToken.connect(rootOwner).approve(await zns.treasury.getAddress(), ethers.MaxUint256); + await zns.zToken.connect(rootOwner).approve(await zns.treasury.getAddress(), ethers.MaxUint256); rootHashDirect = await registrationWithSetup({ zns, @@ -71,7 +76,7 @@ describe("Transaction Gas Costs Test", () => { paymentType: PaymentType.DIRECT, }, paymentConfig: { - token: await zns.meowToken.getAddress(), + token: await zns.zToken.getAddress(), beneficiary: rootOwner.address, }, priceConfig: DEFAULT_PRICE_CONFIG, @@ -83,10 +88,10 @@ describe("Transaction Gas Costs Test", () => { it("Root Domain Price", async function () { // approve - await zns.meowToken.connect(rootOwner).approve(await zns.treasury.getAddress(), ethers.MaxUint256); + await zns.zToken.connect(rootOwner).approve(await zns.treasury.getAddress(), ethers.MaxUint256); // register root domain const paymentConfig = { - token: await zns.meowToken.getAddress(), + token: await zns.zToken.getAddress(), beneficiary: rootOwner.address, }; @@ -133,10 +138,10 @@ describe("Transaction Gas Costs Test", () => { it("Subdomain Price", async function () { // approve - await zns.meowToken.connect(lvl2SubOwner).approve(await zns.treasury.getAddress(), ethers.MaxUint256); + await zns.zToken.connect(lvl2SubOwner).approve(await zns.treasury.getAddress(), ethers.MaxUint256); // register subdomain const paymentConfig = { - token: await zns.meowToken.getAddress(), + token: await zns.zToken.getAddress(), beneficiary: rootOwner.address, }; diff --git a/test/gas/gas-costs.json b/test/gas/gas-costs.json index 0e8224f11..957af37b9 100644 --- a/test/gas/gas-costs.json +++ b/test/gas/gas-costs.json @@ -1,4 +1,4 @@ -{ - "Root Domain Price": "475352", - "Subdomain Price": "469054" -} \ No newline at end of file +{ + "Root Domain Price": "470187", + "Subdomain Price": "463250" +} diff --git a/test/helpers/constants.ts b/test/helpers/constants.ts index 54886505e..3ed32dd07 100644 --- a/test/helpers/constants.ts +++ b/test/helpers/constants.ts @@ -11,8 +11,8 @@ export const DEFAULT_PROTOCOL_FEE_PERCENT = BigInt("222"); export const DEFAULT_PERCENTAGE_BASIS = BigInt("10000"); export const DEFAULT_DECIMALS = BigInt(18); -export const DECAULT_PRECISION = BigInt(2); -export const DEFAULT_PRECISION_MULTIPLIER = BigInt(10) ** (DEFAULT_DECIMALS - DECAULT_PRECISION); +export const DEFAULT_PRECISION = BigInt(2); +export const DEFAULT_PRECISION_MULTIPLIER = BigInt(10) ** (DEFAULT_DECIMALS - DEFAULT_PRECISION); // eslint-disable-next-line no-shadow export const AccessType = { @@ -36,7 +36,7 @@ export const PaymentType = { export const DEFAULT_PRICE_CONFIG : ICurvePriceConfig = { maxPrice: ethers.parseEther("25000"), - minPrice: ethers.parseEther("2000"), + curveMultiplier: BigInt("1000"), maxLength: BigInt(50), baseLength: BigInt(4), precisionMultiplier: DEFAULT_PRECISION_MULTIPLIER, @@ -46,7 +46,7 @@ export const DEFAULT_PRICE_CONFIG : ICurvePriceConfig = { export const curvePriceConfigEmpty : ICurvePriceConfig = { maxPrice: BigInt(0), - minPrice: BigInt(0), + curveMultiplier: BigInt(0), maxLength: BigInt(0), baseLength: BigInt(0), precisionMultiplier: BigInt(0), @@ -77,7 +77,7 @@ export const implSlotErc1967 = "0x360894a13ba1a3210667c828492db98dca3e2076cc3735 export const accessControllerName = "ZNSAccessController"; export const registryName = "ZNSRegistry"; export const domainTokenName = "ZNSDomainToken"; -export const meowTokenMockName = "MeowTokenMock"; +export const zTokenMockName = "ZTokenMock"; export const addressResolverName = "ZNSAddressResolver"; export const curvePricerName = "ZNSCurvePricer"; export const fixedPricerName = "ZNSFixedPricer"; @@ -85,3 +85,11 @@ export const treasuryName = "ZNSTreasury"; export const registrarName = "ZNSRootRegistrar"; export const erc1967ProxyName = "ERC1967Proxy"; export const subRegistrarName = "ZNSSubRegistrar"; + +// zToken mock deploy default params +export const Z_NAME_DEFAULT = "ZERO Token"; +export const Z_SYMBOL_DEFAULT = "Z"; +export const INITIAL_ADMIN_DELAY_DEFAULT = 5n; +export const INITIAL_SUPPLY_DEFAULT = 369000000n; +export const INFLATION_RATES_DEFAULT = [0n, 900n, 765n, 650n, 552n, 469n, 398n, 338n, 287n, 243n, 206n, 175n]; +export const FINAL_INFLATION_RATE_DEFAULT = 150n; diff --git a/test/helpers/deploy-helpers.ts b/test/helpers/deploy-helpers.ts index 01d1d7219..dd2cee8fc 100644 --- a/test/helpers/deploy-helpers.ts +++ b/test/helpers/deploy-helpers.ts @@ -16,11 +16,11 @@ export const approveBulk = async ( ) => { for (const signer of signers) { // if (hre.network.name === "hardhat") { - const hasApproval = await zns.meowToken.allowance(signer.address, await zns.treasury.getAddress()); + const hasApproval = await zns.zToken.allowance(signer.address, await zns.treasury.getAddress()); // To avoid resending the approval repeatedly we first check the allowance if (hasApproval === BigInt(0)) { - const tx = await zns.meowToken.connect(signer).approve( + const tx = await zns.zToken.connect(signer).approve( await zns.treasury.getAddress(), ethers.MaxUint256, ); @@ -30,16 +30,14 @@ export const approveBulk = async ( } }; -export const mintBulk = async ( - signers : Array, +export const transferBulk = async ( + users : Array, + admin : SignerWithAddress, amount : bigint, zns : IZNSContractsLocal | IZNSContracts, ) => { - for (const signer of signers) { - await zns.meowToken.connect(signer).mint( - signer.address, - amount - ); + for (const user of users) { + await zns.zToken.connect(admin).transfer(user.address, amount); } }; @@ -94,14 +92,14 @@ export const registerRootDomainBulk = async ( let index = 0; for(const domain of domains) { - const balanceBefore = await zns.meowToken.balanceOf(signers[index].address); + const balanceBefore = await zns.zToken.balanceOf(signers[index].address); const tx = await zns.rootRegistrar.connect(signers[index]).registerRootDomain( domain, config.zeroVaultAddress, `${tokenUri}${index}`, distConfig, { - token: await zns.meowToken.getAddress(), + token: await zns.zToken.getAddress(), beneficiary: config.zeroVaultAddress, } ); @@ -111,7 +109,7 @@ export const registerRootDomainBulk = async ( logger.info(`Registered '${domain}' for ${signers[index].address} at tx: ${tx.hash}`); } - const balanceAfter = await zns.meowToken.balanceOf(signers[index].address); + const balanceAfter = await zns.zToken.balanceOf(signers[index].address); const [price, protocolFee] = await zns.curvePricer.getPriceAndFee(ethers.ZeroHash, domain, true); expect(balanceAfter).to.be.eq(balanceBefore - price - protocolFee); @@ -140,7 +138,7 @@ export const registerSubdomainBulk = async ( let index = 0; for (const subdomain of subdomains) { - const balanceBefore = await zns.meowToken.balanceOf(signers[index].address); + const balanceBefore = await zns.zToken.balanceOf(signers[index].address); const tx = await zns.subRegistrar.connect(signers[index]).registerSubdomain( parents[index], subdomain, @@ -157,7 +155,7 @@ export const registerSubdomainBulk = async ( logger.info(`registered '${subdomain}' for ${signers[index].address} at tx: ${tx.hash}`); } - const balanceAfter = await zns.meowToken.balanceOf(signers[index].address); + const balanceAfter = await zns.zToken.balanceOf(signers[index].address); const owner = await zns.registry.getDomainOwner(parents[index]); if (signers[index].address === owner) { diff --git a/test/helpers/deploy/deploy-zns.ts b/test/helpers/deploy/deploy-zns.ts index c2006a9d5..d17643b65 100644 --- a/test/helpers/deploy/deploy-zns.ts +++ b/test/helpers/deploy/deploy-zns.ts @@ -1,5 +1,5 @@ import { - MeowTokenMock__factory, + ZTokenMock__factory, ZNSAccessController, ZNSAccessController__factory, ZNSAddressResolver, @@ -18,11 +18,11 @@ import { ZNSTreasury__factory, ZNSFixedPricer, ZNSSubRegistrar, - MeowTokenMock, + ZTokenMock, } from "../../../typechain"; import { DeployZNSParams, RegistrarConfig, IZNSContractsLocal } from "../types"; import * as hre from "hardhat"; -import { ethers, upgrades } from "hardhat"; +import { upgrades } from "hardhat"; import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; import { accessControllerName, @@ -36,16 +36,21 @@ import { registryName, subRegistrarName, treasuryName, - meowTokenMockName, + zTokenMockName, ZNS_DOMAIN_TOKEN_NAME, ZNS_DOMAIN_TOKEN_SYMBOL, DEFAULT_ROYALTY_FRACTION, DEFAULT_RESOLVER_TYPE, + INITIAL_ADMIN_DELAY_DEFAULT, + INITIAL_SUPPLY_DEFAULT, + INFLATION_RATES_DEFAULT, + FINAL_INFLATION_RATE_DEFAULT, + Z_NAME_DEFAULT, + Z_SYMBOL_DEFAULT, } from "../constants"; -import { REGISTRAR_ROLE } from "../../../src/deploy/constants"; +import { DOMAIN_TOKEN_ROLE, REGISTRAR_ROLE } from "../../../src/deploy/constants"; import { getProxyImplAddress } from "../utils"; import { ICurvePriceConfig } from "../../../src/deploy/missions/types"; -import { meowTokenName, meowTokenSymbol } from "../../../src/deploy/missions/contracts"; import { transparentProxyName } from "../../../src/deploy/missions/contracts/names"; @@ -119,20 +124,22 @@ export const deployRegistry = async ( export const deployDomainToken = async ( deployer : SignerWithAddress, - accessControllerAddress : string, + accessController : ZNSAccessController, royaltyReceiverAddress : string, royaltyFraction : bigint, - isTenderlyRun : boolean + isTenderlyRun : boolean, + registry : ZNSRegistry, ) : Promise => { const domainTokenFactory = new ZNSDomainToken__factory(deployer); const domainToken = await upgrades.deployProxy( domainTokenFactory, [ - accessControllerAddress, + await accessController.getAddress(), ZNS_DOMAIN_TOKEN_NAME, ZNS_DOMAIN_TOKEN_SYMBOL, royaltyReceiverAddress, royaltyFraction, + await registry.getAddress(), ], { kind: "uups", @@ -143,6 +150,8 @@ export const deployDomainToken = async ( const proxyAddress = await domainToken.getAddress(); + await accessController.connect(deployer).grantRole(DOMAIN_TOKEN_ROLE, proxyAddress); + if (isTenderlyRun) { await hre.tenderly.verify({ name: erc1967ProxyName, @@ -164,25 +173,27 @@ export const deployDomainToken = async ( return domainToken as unknown as ZNSDomainToken; }; -export const deployMeowToken = async ( +export const deployZToken = async ( deployer : SignerWithAddress, + governorAddresses : Array, + adminAddresses : Array, isTenderlyRun : boolean -) : Promise => { - const factory = new MeowTokenMock__factory(deployer); - - const meowToken = await hre.upgrades.deployProxy( - factory, - [ - meowTokenName, - meowTokenSymbol, - ], - { - kind: "transparent", - } - ) as unknown as MeowTokenMock; - - await meowToken.waitForDeployment(); - const proxyAddress = await meowToken.getAddress(); +) : Promise => { + const Factory = new ZTokenMock__factory(deployer); + const zToken = await Factory.deploy( + Z_NAME_DEFAULT, + Z_SYMBOL_DEFAULT, + governorAddresses[0], + INITIAL_ADMIN_DELAY_DEFAULT, + deployer.address, + adminAddresses[0], + INITIAL_SUPPLY_DEFAULT, + INFLATION_RATES_DEFAULT, + FINAL_INFLATION_RATE_DEFAULT + ) as ZTokenMock; + + await zToken.waitForDeployment(); + const proxyAddress = await zToken.getAddress(); if (isTenderlyRun) { await hre.tenderly.verify({ @@ -193,19 +204,16 @@ export const deployMeowToken = async ( const impl = await getProxyImplAddress(proxyAddress); await hre.tenderly.verify({ - name: meowTokenMockName, + name: zTokenMockName, address: impl, }); - console.log(`${meowTokenMockName} deployed at: + console.log(`${zTokenMockName} deployed at: proxy: ${proxyAddress} implementation: ${impl}`); } - // Mint 10,000 ZERO for self - await meowToken.mint(proxyAddress, ethers.parseEther("10000")); - - return meowToken as unknown as MeowTokenMock; + return zToken as unknown as ZTokenMock; }; export const deployAddressResolver = async ( @@ -549,16 +557,22 @@ export const deployZNS = async ({ const domainToken = await deployDomainToken( deployer, - await accessController.getAddress(), + accessController, zeroVaultAddress, DEFAULT_ROYALTY_FRACTION, - isTenderlyRun + isTenderlyRun, + registry ); // While we do use the real ZeroToken contract, it is only deployed as a mock here // for testing purposes that verify expected behavior of other contracts. // This should not be used in any other context than deploying to a local hardhat testnet. - const meowTokenMock = await deployMeowToken(deployer, isTenderlyRun); + const zTokenMock = await deployZToken( + deployer, + governorAddresses, + adminAddresses, + isTenderlyRun, + ); const addressResolver = await deployAddressResolver( deployer, @@ -579,7 +593,7 @@ export const deployZNS = async ({ deployer, accessControllerAddress: await accessController.getAddress(), registryAddress: await registry.getAddress(), - zTokenMockAddress: await meowTokenMock.getAddress(), + zTokenMockAddress: await zTokenMock.getAddress(), zeroVaultAddress, isTenderlyRun, }); @@ -618,7 +632,7 @@ export const deployZNS = async ({ accessController, registry, domainToken, - meowToken: meowTokenMock, + zToken: zTokenMock, addressResolver, curvePricer, treasury, @@ -628,10 +642,6 @@ export const deployZNS = async ({ zeroVaultAddress, }; - // Give 15 ZERO to the deployer and allowance to the treasury - await meowTokenMock.connect(deployer).approve(await treasury.getAddress(), ethers.MaxUint256); - await meowTokenMock.mint(await deployer.getAddress(), ethers.parseEther("5000000")); - await registry.connect(deployer).addResolverType(DEFAULT_RESOLVER_TYPE, await addressResolver.getAddress()); return znsContracts; diff --git a/test/helpers/errors.ts b/test/helpers/errors.ts index 2d6cdf0e9..ef3118101 100644 --- a/test/helpers/errors.ts +++ b/test/helpers/errors.ts @@ -5,45 +5,54 @@ export const getAccessRevertMsg = (addr : string, role : string) : string => // When adding a revert test, check if this message is already present in other tests // if it is, add a new constant here and use it in all tests +export const ERC721_NOT_OWNER_ERR = "ERC721: transfer caller is not owner nor approved"; +export const ERC721_NOT_APPROVED_ERR = "ERC721InsufficientApproval"; + +// AccessControl +export const AC_UNAUTHORIZED_ERR = "AccessControlUnauthorizedAccount"; + +// ERC20 +export const INSUFFICIENT_BALANCE_ERC_ERR = "ERC20InsufficientBalance"; +export const INSUFFICIENT_ALLOWANCE_ERC_ERR = "ERC20InsufficientAllowance"; + +// CommonErrors.sol +export const ZERO_ADDRESS_ERR = "ZeroAddressPassed"; +export const DOMAIN_EXISTS_ERR = "DomainAlreadyExists"; +export const NOT_AUTHORIZED_ERR = "NotAuthorizedForDomain"; + +// IZNSPricer.sol +export const PARENT_CONFIG_NOT_SET_ERR = "ParentPriceConfigNotSet"; +export const FEE_TOO_LARGE_ERR = "FeePercentageValueTooLarge"; + // ZNSCurvePricer.sol -export const MULTIPLIER_BELOW_MIN_ERR = "ZNSCurvePricer: Multiplier must be >= baseLength + 1"; -export const NO_ZERO_MULTIPLIER_ERR = "ZNSCurvePricer: Multiplier cannot be 0"; -export const MULTIPLIER_OUT_OF_RANGE_ORA_ERR = "ZNSCurvePricer: Multiplier out of range"; -export const CURVE_NO_ZERO_PRECISION_MULTIPLIER_ERR = "ZNSCurvePricer: precisionMultiplier cannot be 0"; -export const CURVE_PRICE_CONFIG_ERR = "ZNSCurvePricer: incorrect value set causes the price spike at maxLength."; - -// ZNSRegistry -export const ONLY_NAME_OWNER_REG_ERR = "ZNSRegistry: Not the Name Owner"; -export const ONLY_OWNER_REGISTRAR_REG_ERR = "ZNSRegistry: Only Name Owner or Registrar allowed to call"; -export const NOT_AUTHORIZED_REG_WIRED_ERR = "ARegistryWired: Not authorized. Only Owner or Operator allowed"; -export const NOT_AUTHORIZED_REG_ERR = "ZNSRegistry: Not authorized"; -export const OWNER_NOT_ZERO_REG_ERR = "ZNSRegistry: Owner cannot be zero address"; +export const INVALID_PRECISION_MULTIPLIER_ERR = "InvalidPrecisionMultiplierPassed"; +export const INVALID_PRICE_CONFIG_ERR = "InvalidConfigCausingPriceSpikes"; +export const INVALID_BASE_OR_MAX_LENGTH_ERR = "MaxLengthSmallerThanBaseLength"; +export const DIVISION_BY_ZERO_ERR = "DivisionByZero"; // ZNSRootRegistrar.sol -export const NOT_NAME_OWNER_RAR_ERR = "ZNSRootRegistrar: Not the owner of the Name"; -export const NOT_TOKEN_OWNER_RAR_ERR = "ZNSRootRegistrar: Not the owner of the Token"; -export const NOT_BOTH_OWNER_RAR_ERR = "ZNSRootRegistrar: Not the owner of both Name and Token"; +export const NOT_OWNER_OF_ERR = "NotTheOwnerOf"; // Subdomain Registrar // eslint-disable-next-line max-len -export const DISTRIBUTION_LOCKED_NOT_EXIST_ERR = "ZNSSubRegistrar: Parent domain's distribution is locked or parent does not exist"; +export const DISTRIBUTION_LOCKED_NOT_EXIST_ERR = "ParentLockedOrDoesntExist"; +export const SENDER_NOT_APPROVED_ERR = "SenderNotApprovedForPurchase"; // StringUtils -export const INVALID_NAME_ERR = "StringUtils: Invalid domain label"; -export const INVALID_LENGTH_ERR = "StringUtils: Domain label too long or nonexistent"; +export const INVALID_LABEL_ERR = "DomainLabelContainsInvalidCharacters"; +export const INVALID_LENGTH_ERR = "DomainLabelTooLongOrNonexistent"; // Treasury -export const NO_BENEFICIARY_ERR = "ZNSTreasury: parent domain has no beneficiary set"; -export const NOT_AUTHORIZED_TREASURY_ERR = "ZNSTreasury: Not authorized."; +export const NO_BENEFICIARY_ERR = "NoBeneficiarySetForParent"; // OpenZeppelin -export const INVALID_TOKENID_ERC_ERR = "ERC721: invalid token ID"; -export const INITIALIZED_ERR = "Initializable: contract is already initialized"; +export const NONEXISTENT_TOKEN_ERC_ERR = "ERC721NonexistentToken"; +export const INITIALIZED_ERR = "InvalidInitialization"; // Environment validation export const INVALID_ENV_ERR = "Invalid environment value. Must set env to one of `dev`, `test`, or `prod`"; -export const NO_MOCK_PROD_ERR = "Cannot mock MEOW token in production"; -export const STAKING_TOKEN_ERR = "Must use MEOW token in production"; +export const NO_MOCK_PROD_ERR = "Cannot mock Z token in production"; +export const STAKING_TOKEN_ERR = "Must use Z token in production"; export const INVALID_CURVE_ERR = "Must use a valid price configuration"; export const MONGO_URI_ERR = "Cannot use local mongo URI in production"; export const NO_ZERO_VAULT_ERR = "Must provide ZERO_VAULT_ADDRESS for 'prod' or 'test' environments"; diff --git a/test/helpers/flows/registration.ts b/test/helpers/flows/registration.ts index 7cef8dfa2..3c60aaf9f 100644 --- a/test/helpers/flows/registration.ts +++ b/test/helpers/flows/registration.ts @@ -36,7 +36,7 @@ export const registerDomainPath = async ({ let beneficiary; if (isRootDomain) { - paymentTokenContract = zns.meowToken; + paymentTokenContract = zns.zToken; // no beneficiary for root domain beneficiary = ethers.ZeroAddress; } else { @@ -45,8 +45,8 @@ export const registerDomainPath = async ({ const { token: paymentTokenAddress } = paymentConfig; ({ beneficiary } = paymentConfig); - if (paymentTokenAddress === await zns.meowToken.getAddress()) { - paymentTokenContract = zns.meowToken; + if (paymentTokenAddress === await zns.zToken.getAddress()) { + paymentTokenContract = zns.zToken; } else { paymentTokenContract = getTokenContract(paymentTokenAddress, config.user); } @@ -119,7 +119,7 @@ export const validatePathRegistration = async ({ const { maxPrice: curveMaxPrice, - minPrice: curveMinPrice, + curveMultiplier, maxLength: curveMaxLength, baseLength: curveBaseLength, precisionMultiplier: curvePrecisionMultiplier, @@ -136,7 +136,7 @@ export const validatePathRegistration = async ({ domainLabel, { maxPrice: curveMaxPrice, - minPrice: curveMinPrice, + curveMultiplier, maxLength: curveMaxLength, baseLength: curveBaseLength, precisionMultiplier: curvePrecisionMultiplier, @@ -160,7 +160,7 @@ export const validatePathRegistration = async ({ } else { const { maxPrice, - minPrice, + curveMultiplier, maxLength, baseLength, precisionMultiplier, @@ -174,7 +174,7 @@ export const validatePathRegistration = async ({ domainLabel, { maxPrice, - minPrice, + curveMultiplier, maxLength, baseLength, precisionMultiplier, diff --git a/test/helpers/index.ts b/test/helpers/index.ts index fb5133ca3..a488c6ab9 100644 --- a/test/helpers/index.ts +++ b/test/helpers/index.ts @@ -1,12 +1,15 @@ -export * from "./deploy/deploy-zns"; -export * from "./tokens"; -export * from "./pricing"; -export * from "./hashing"; -export * from "./constants"; -export * from "./balances"; -export * from "./errors"; -export * from "./validate-upgrade"; -export { EXECUTOR_ROLE } from "../../src/deploy/constants"; -export { REGISTRAR_ROLE } from "../../src/deploy/constants"; -export { ADMIN_ROLE } from "../../src/deploy/constants"; -export { GOVERNOR_ROLE } from "../../src/deploy/constants"; \ No newline at end of file +export * from "./deploy/deploy-zns"; +export * from "./tokens"; +export * from "./pricing"; +export * from "./hashing"; +export * from "./constants"; +export * from "./balances"; +export * from "./errors"; +export * from "./validate-upgrade"; +export * from "./types"; +export * from "./utils"; + +export { EXECUTOR_ROLE } from "../../src/deploy/constants"; +export { REGISTRAR_ROLE } from "../../src/deploy/constants"; +export { ADMIN_ROLE } from "../../src/deploy/constants"; +export { GOVERNOR_ROLE } from "../../src/deploy/constants"; diff --git a/test/helpers/pricing.ts b/test/helpers/pricing.ts index 7afae8a9b..4395af5a7 100644 --- a/test/helpers/pricing.ts +++ b/test/helpers/pricing.ts @@ -18,23 +18,26 @@ export const getCurvePrice = ( // Get price configuration for contract const { maxPrice, - minPrice, + curveMultiplier, baseLength, maxLength, precisionMultiplier, } = priceConfig; - if (baseLength === 0n) return maxPrice; + let length = BigInt(name.length); - if (BigInt(name.length) <= baseLength) { + if (length <= baseLength) { return maxPrice; } if (BigInt(name.length) > maxLength) { - return minPrice; + length = maxLength; } - const base = baseLength * maxPrice / BigInt(name.length); + const MULTIPLIER_BASIS = 1000n; + + const base = (baseLength * maxPrice * MULTIPLIER_BASIS) + / (baseLength * MULTIPLIER_BASIS + curveMultiplier * (length - baseLength)); return base / precisionMultiplier * precisionMultiplier; }; diff --git a/test/helpers/types.ts b/test/helpers/types.ts index 49b03016a..3a06f6246 100644 --- a/test/helpers/types.ts +++ b/test/helpers/types.ts @@ -1,5 +1,4 @@ import { - MeowTokenMock, ZNSAccessController, ZNSAddressResolver, ZNSAddressResolverUpgradeMock, @@ -18,13 +17,14 @@ import { ZNSRegistryUpgradeMock__factory, ZNSRootRegistrar, ZNSRootRegistrarUpgradeMock, - ZNSRootRegistrarUpgradeMock__factory, + ZNSRootRegistrarUpgradeMock__factory, ZNSStringResolverUpgradeMock, ZNSStringResolverUpgradeMock__factory, ZNSSubRegistrar, ZNSSubRegistrarUpgradeMock, ZNSSubRegistrarUpgradeMock__factory, ZNSTreasury, ZNSTreasuryUpgradeMock, ZNSTreasuryUpgradeMock__factory, + ZTokenMock, } from "../../typechain"; import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; import { ICurvePriceConfig } from "../../src/deploy/missions/types"; @@ -53,7 +53,8 @@ export type ZNSContractMockFactory = ZNSTreasuryUpgradeMock__factory | ZNSRegistryUpgradeMock__factory | ZNSAddressResolverUpgradeMock__factory | - ZNSDomainTokenUpgradeMock__factory; + ZNSDomainTokenUpgradeMock__factory | + ZNSStringResolverUpgradeMock__factory; export type ZNSContractMock = ZNSRootRegistrarUpgradeMock | @@ -63,7 +64,8 @@ export type ZNSContractMock = ZNSTreasuryUpgradeMock | ZNSRegistryUpgradeMock | ZNSAddressResolverUpgradeMock | - ZNSDomainTokenUpgradeMock; + ZNSDomainTokenUpgradeMock | + ZNSStringResolverUpgradeMock; export interface IFixedPriceConfig { price : bigint; @@ -81,7 +83,7 @@ export interface IZNSContractsLocal { accessController : ZNSAccessController; registry : ZNSRegistry; domainToken : ZNSDomainToken; - meowToken : MeowTokenMock; + zToken : ZTokenMock; addressResolver : ZNSAddressResolver; curvePricer : ZNSCurvePricer; treasury : ZNSTreasury; diff --git a/test/helpers/utils.ts b/test/helpers/utils.ts index ff18b4789..50f12059c 100644 --- a/test/helpers/utils.ts +++ b/test/helpers/utils.ts @@ -20,3 +20,15 @@ export const loggerMock = { info: () => {}, debug: () => {}, }; + +export const getRandomString = (length : number) => { + const alphabet = "abcdefghijklmnopqrstuvwxyz0123456789"; + let result = ""; + + for (let i = 0; i < length; i++) { + const randomIndex = Math.floor(Math.random() * alphabet.length); + result += alphabet.charAt(randomIndex); + } + + return result; +}; \ No newline at end of file diff --git a/test/helpers/validate-upgrade.ts b/test/helpers/validate-upgrade.ts index 58c23f6f7..d0cf9e15b 100644 --- a/test/helpers/validate-upgrade.ts +++ b/test/helpers/validate-upgrade.ts @@ -2,19 +2,23 @@ import { expect } from "chai"; import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; import { ZNSContractMock, ZNSContractMockFactory, GeneralContractGetter } from "./types"; import { ZNSContract } from "../../src/deploy/campaign/types"; -import { MeowToken, ZNSAccessController } from "../../typechain"; - +import { + ZNSAccessController, + ZToken, +} from "../../typechain"; export const validateUpgrade = async ( deployer : SignerWithAddress, - contract : Exclude, MeowToken>, + contract : Exclude, ZToken>, upgradeContract : ZNSContractMock, upgradeContractFactory : ZNSContractMockFactory, getters : Array ) => { const preVals = await Promise.all(getters); - await contract.connect(deployer).upgradeTo(await upgradeContract.getAddress()); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + await contract.connect(deployer).upgradeToAndCall(await upgradeContract.getAddress(), "0x"); // Typechain doesn't update the generated interface for the contract after upgrading // so we use the new factory to attach to the existing address instead diff --git a/yarn.lock b/yarn.lock index d4beb8bed..c2a838d75 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,15 +2,10 @@ # yarn lockfile v1 -"@aashutoshrathi/word-wrap@^1.2.3": - version "1.2.6" - resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" - integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== - -"@adraffy/ens-normalize@1.10.0": - version "1.10.0" - resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.10.0.tgz#d2a39395c587e092d77cbbc80acf956a54f38bf7" - integrity sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q== +"@adraffy/ens-normalize@1.10.1": + version "1.10.1" + resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz#63430d04bd8c5e74f8d7d049338f1cd9d4f02069" + integrity sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw== "@aws-crypto/sha256-js@1.2.2": version "1.2.2" @@ -31,12 +26,12 @@ tslib "^1.11.1" "@aws-sdk/types@^3.1.0": - version "3.496.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/types/-/types-3.496.0.tgz#cdde44a94a57cf8f97cf05e4d0bdce2f56ce4eeb" - integrity sha512-umkGadK4QuNQaMoDICMm7NKRI/mYSXiyPjcn3d53BhsuArYU/52CebGQKdt4At7SwwsiVJZw9RNBHyN5Mm0HVw== + version "3.654.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/types/-/types-3.654.0.tgz#d368dda5e8aff9e7b6575985bb425bbbaf67aa97" + integrity sha512-VWvbED3SV+10QJIcmU/PKjsKilsTV16d1I7/on4bvD/jo1qGeMXqLDBSen3ks/tuvXZF/mFc7ZW/W2DiLVtO7A== dependencies: - "@smithy/types" "^2.9.1" - tslib "^2.5.0" + "@smithy/types" "^3.4.2" + tslib "^2.6.2" "@aws-sdk/util-utf8-browser@^3.0.0": version "3.259.0" @@ -46,70 +41,35 @@ tslib "^2.3.1" "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.21.4": - version "7.23.5" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.23.5.tgz#9009b69a8c602293476ad598ff53e4562e15c244" - integrity sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA== + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.24.7.tgz#882fd9e09e8ee324e496bd040401c6f046ef4465" + integrity sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA== dependencies: - "@babel/highlight" "^7.23.4" - chalk "^2.4.2" + "@babel/highlight" "^7.24.7" + picocolors "^1.0.0" -"@babel/helper-validator-identifier@^7.22.20": - version "7.22.20" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" - integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== +"@babel/helper-validator-identifier@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz#75b889cfaf9e35c2aaf42cf0d72c8e91719251db" + integrity sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w== -"@babel/highlight@^7.23.4": - version "7.23.4" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.23.4.tgz#edaadf4d8232e1a961432db785091207ead0621b" - integrity sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A== +"@babel/highlight@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.24.7.tgz#a05ab1df134b286558aae0ed41e6c5f731bf409d" + integrity sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw== dependencies: - "@babel/helper-validator-identifier" "^7.22.20" + "@babel/helper-validator-identifier" "^7.24.7" chalk "^2.4.2" js-tokens "^4.0.0" + picocolors "^1.0.0" "@babel/runtime@^7.4.4": - version "7.23.9" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.9.tgz#47791a15e4603bb5f905bc0753801cf21d6345f7" - integrity sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw== + version "7.25.6" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.25.6.tgz#9afc3289f7184d8d7f98b099884c26317b9264d2" + integrity sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ== 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" @@ -179,14 +139,14 @@ resolved "https://registry.yarnpkg.com/@ensdomains/resolver/-/resolver-0.2.4.tgz#c10fe28bf5efbf49bff4666d909aed0265efbc89" integrity sha512-bvaTH34PMCbv6anRa9I/0zjLJgY4EuznbEMgbV77JBCQ9KNC46rzi0avuxpOfu+xDjPEtSFGqVEOr5GlUSGudA== -"@es-joy/jsdoccomment@~0.37.0": - version "0.37.1" - resolved "https://registry.yarnpkg.com/@es-joy/jsdoccomment/-/jsdoccomment-0.37.1.tgz#fa32a41ba12097452693343e09ad4d26d157aedd" - integrity sha512-5vxWJ1gEkEF0yRd0O+uK6dHJf7adrxwQSX8PuRiPfFSAbNLnY0ZJfXaZucoz14Jj2N11xn2DnlEPwWRpYpvRjg== +"@es-joy/jsdoccomment@~0.48.0": + version "0.48.0" + resolved "https://registry.yarnpkg.com/@es-joy/jsdoccomment/-/jsdoccomment-0.48.0.tgz#5d9dc1a295cf5d1ed224dffafb4800d5c7206c27" + integrity sha512-G6QUWIcC+KvSwXNsJyDTHvqUdNoAVJPPgkc3+Uk4WBKqZvoXhlvazOgm9aL0HwihJLQf0l+tOE2UFzXBqCqgDw== dependencies: - comment-parser "1.3.1" - esquery "^1.5.0" - jsdoc-type-pratt-parser "~4.0.0" + comment-parser "1.4.1" + esquery "^1.6.0" + jsdoc-type-pratt-parser "~4.1.0" "@eslint-community/eslint-utils@^4.2.0": version "4.4.0" @@ -196,9 +156,9 @@ eslint-visitor-keys "^3.3.0" "@eslint-community/regexpp@^4.4.0", "@eslint-community/regexpp@^4.6.1": - version "4.10.0" - resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.10.0.tgz#548f6de556857c8bb73bbee70c35dc82a2e74d63" - integrity sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA== + version "4.11.1" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.11.1.tgz#a547badfc719eb3e5f4b556325e542fbe9d7a18f" + integrity sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q== "@eslint/eslintrc@^2.1.4": version "2.1.4" @@ -215,10 +175,10 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@eslint/js@8.56.0": - version "8.56.0" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.56.0.tgz#ef20350fec605a7f7035a01764731b2de0f3782b" - integrity sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A== +"@eslint/js@8.57.1": + version "8.57.1" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.57.1.tgz#de633db3ec2ef6a3c89e2f19038063e8a122e2c2" + integrity sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q== "@ethereumjs/rlp@^4.0.1": version "4.0.1" @@ -273,6 +233,17 @@ "@ethersproject/logger" "^5.7.0" "@ethersproject/properties" "^5.7.0" +"@ethersproject/address@5.6.1": + version "5.6.1" + resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.6.1.tgz#ab57818d9aefee919c5721d28cd31fd95eff413d" + integrity sha512-uOgF0kS5MJv9ZvCz7x6T2EXJSzotiybApn4XlOgoTX0xdtyVIJ7pF+6cGPxiEq/dpBiTfMiw7Yc81JcwhSYA0Q== + dependencies: + "@ethersproject/bignumber" "^5.6.2" + "@ethersproject/bytes" "^5.6.1" + "@ethersproject/keccak256" "^5.6.1" + "@ethersproject/logger" "^5.6.0" + "@ethersproject/rlp" "^5.6.1" + "@ethersproject/address@5.7.0", "@ethersproject/address@^5.0.2", "@ethersproject/address@^5.7.0": version "5.7.0" resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.7.0.tgz#19b56c4d74a3b0a46bfdbb6cfcc0a153fc697f37" @@ -299,7 +270,7 @@ "@ethersproject/bytes" "^5.7.0" "@ethersproject/properties" "^5.7.0" -"@ethersproject/bignumber@5.7.0", "@ethersproject/bignumber@^5.7.0": +"@ethersproject/bignumber@5.7.0", "@ethersproject/bignumber@^5.6.2", "@ethersproject/bignumber@^5.7.0": version "5.7.0" resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.7.0.tgz#e2f03837f268ba655ffba03a57853e18a18dc9c2" integrity sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw== @@ -308,7 +279,7 @@ "@ethersproject/logger" "^5.7.0" bn.js "^5.2.1" -"@ethersproject/bytes@5.7.0", "@ethersproject/bytes@^5.7.0": +"@ethersproject/bytes@5.7.0", "@ethersproject/bytes@^5.6.1", "@ethersproject/bytes@^5.7.0": version "5.7.0" resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.7.0.tgz#a00f6ea8d7e7534d6d87f47188af1148d71f155d" integrity sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A== @@ -390,7 +361,7 @@ aes-js "3.0.0" scrypt-js "3.0.1" -"@ethersproject/keccak256@5.7.0", "@ethersproject/keccak256@^5.7.0": +"@ethersproject/keccak256@5.7.0", "@ethersproject/keccak256@^5.6.1", "@ethersproject/keccak256@^5.7.0": version "5.7.0" resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.7.0.tgz#3186350c6e1cd6aba7940384ec7d6d9db01f335a" integrity sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg== @@ -398,7 +369,7 @@ "@ethersproject/bytes" "^5.7.0" js-sha3 "0.8.0" -"@ethersproject/logger@5.7.0", "@ethersproject/logger@^5.7.0": +"@ethersproject/logger@5.7.0", "@ethersproject/logger@^5.6.0", "@ethersproject/logger@^5.7.0": version "5.7.0" resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.7.0.tgz#6ce9ae168e74fecf287be17062b590852c311892" integrity sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig== @@ -425,7 +396,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== @@ -459,7 +430,7 @@ "@ethersproject/bytes" "^5.7.0" "@ethersproject/logger" "^5.7.0" -"@ethersproject/rlp@5.7.0", "@ethersproject/rlp@^5.7.0": +"@ethersproject/rlp@5.7.0", "@ethersproject/rlp@^5.6.1", "@ethersproject/rlp@^5.7.0": version "5.7.0" resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.7.0.tgz#de39e4d5918b9d74d46de93af80b7685a9c21304" integrity sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w== @@ -577,21 +548,21 @@ "@ethersproject/strings" "^5.7.0" "@fastify/busboy@^2.0.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@fastify/busboy/-/busboy-2.1.0.tgz#0709e9f4cb252351c609c6e6d8d6779a8d25edff" - integrity sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA== + version "2.1.1" + resolved "https://registry.yarnpkg.com/@fastify/busboy/-/busboy-2.1.1.tgz#b9da6a878a371829a0502c9b6c1c143ef6663f4d" + integrity sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA== "@gar/promisify@^1.1.3": version "1.1.3" resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6" integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw== -"@humanwhocodes/config-array@^0.11.13": - version "0.11.14" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.14.tgz#d78e481a039f7566ecc9660b4ea7fe6b1fec442b" - integrity sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg== +"@humanwhocodes/config-array@^0.13.0": + version "0.13.0" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.13.0.tgz#fb907624df3256d04b9aa2df50d7aa97ec648748" + integrity sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw== dependencies: - "@humanwhocodes/object-schema" "^2.0.2" + "@humanwhocodes/object-schema" "^2.0.3" debug "^4.3.1" minimatch "^3.0.5" @@ -600,10 +571,10 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== -"@humanwhocodes/object-schema@^2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz#d9fae00a2d5cb40f92cfe64b47ad749fbc38f917" - integrity sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw== +"@humanwhocodes/object-schema@^2.0.3": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz#4a2868d75d6d6963e423bcf90b7fd1be343409d3" + integrity sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA== "@isaacs/cliui@^8.0.2": version "8.0.2" @@ -623,14 +594,14 @@ integrity sha512-SQ7Kzhh9+D+ZW9MA0zkYv3VXhIDNx+LzM6EJ+/65I3QY+enU6Itte7E5XX7EWrqLW2FN4n06GWzBnPoC3th2aQ== "@jridgewell/resolve-uri@^3.0.3": - version "3.1.1" - resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" - integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== + version "3.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" + integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== "@jridgewell/sourcemap-codec@^1.4.10": - version "1.4.15" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" - integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== + version "1.5.0" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a" + integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== "@jridgewell/trace-mapping@0.3.9": version "0.3.9" @@ -651,10 +622,10 @@ tweetnacl "^1.0.3" tweetnacl-util "^0.15.1" -"@mongodb-js/saslprep@^1.1.0": - version "1.1.4" - resolved "https://registry.yarnpkg.com/@mongodb-js/saslprep/-/saslprep-1.1.4.tgz#24ec1c4915a65f5c506bb88c081731450d91bb1c" - integrity sha512-8zJ8N1x51xo9hwPh6AWnKdLGEC5N3lDa6kms1YHmFBoRhTpJR6HG8wWk0td1MVCu9cD4YBrvjZEtd5Obw0Fbnw== +"@mongodb-js/saslprep@^1.1.5": + version "1.1.9" + resolved "https://registry.yarnpkg.com/@mongodb-js/saslprep/-/saslprep-1.1.9.tgz#e974bab8eca9faa88677d4ea4da8d09a52069004" + integrity sha512-tVkljjeEaAhCqTzajSdgbQ6gE6f3oneVwa3iXR6csiEwXXOFsiC6Uh9iAjAhXPtqa/XMDHWjjeNH/77m/Yq2dw== dependencies: sparse-bitfield "^3.0.3" @@ -665,12 +636,12 @@ dependencies: "@noble/hashes" "1.3.2" -"@noble/curves@1.3.0", "@noble/curves@~1.3.0": - version "1.3.0" - resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.3.0.tgz#01be46da4fd195822dab821e72f71bf4aeec635e" - integrity sha512-t01iSXPuN+Eqzb4eBX0S5oubSqXbK/xXa1Ne18Hj8f9pStxztHCE2gfboSp/dZRLSqfuLpRK2nDXDK+W9puocA== +"@noble/curves@1.4.2", "@noble/curves@~1.4.0": + version "1.4.2" + resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.4.2.tgz#40309198c76ed71bc6dbf7ba24e81ceb4d0d1fe9" + integrity sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw== dependencies: - "@noble/hashes" "1.3.3" + "@noble/hashes" "1.4.0" "@noble/hashes@1.2.0", "@noble/hashes@~1.2.0": version "1.2.0" @@ -682,10 +653,15 @@ resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.2.tgz#6f26dbc8fbc7205873ce3cee2f690eba0d421b39" integrity sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ== -"@noble/hashes@1.3.3", "@noble/hashes@~1.3.2": - version "1.3.3" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.3.tgz#39908da56a4adc270147bb07968bf3b16cfe1699" - integrity sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA== +"@noble/hashes@1.4.0", "@noble/hashes@~1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.4.0.tgz#45814aa329f30e4fe0ba49426f49dfccdd066426" + integrity sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg== + +"@noble/hashes@^1.4.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.5.0.tgz#abadc5ca20332db2b1b2aa3e496e9af1213570b0" + integrity sha512-1j6kQFb7QRru7eKN3ZDvRcP13rugwdxZqCjbiAVZfIJwgj2A65UmT4TgARXGlXgnRkORLTDTrO19ZErt7+QXgA== "@noble/secp256k1@1.7.1", "@noble/secp256k1@~1.7.0": version "1.7.1" @@ -713,162 +689,119 @@ "@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/edr-darwin-arm64@0.6.2": + version "0.6.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.6.2.tgz#52c3da9dcdab72c0447b41faa63264de84c9b6c3" + integrity sha512-o4A9SaPlxJ1MS6u8Ozqq7Y0ri2XO0jASw+qkytQyBYowNFNReoGqVSs7SCwenYCDiN+1il8+M0VAUq7wOovnCQ== -"@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/edr-darwin-x64@0.6.2": + version "0.6.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-darwin-x64/-/edr-darwin-x64-0.6.2.tgz#327deb548f2ae62eb456ba183970b022eb98c509" + integrity sha512-WG8BeG2eR3rFC+2/9V1hoPGW7tmNRUcuztdHUijO1h2flRsf2YWv+kEHO+EEnhGkEbgBUiwOrwlwlSMxhe2cGA== -"@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/edr-linux-arm64-gnu@0.6.2": + version "0.6.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-arm64-gnu/-/edr-linux-arm64-gnu-0.6.2.tgz#83daecf1ced46bb4c70326e9358d0c2ae69b472a" + integrity sha512-wvHaTmOwuPjRIOqBB+paI3RBdNlG8f3e1F2zWj75EdeWwefimPzzFUs05JxOYuPO0JhDQIn2tbYUgdZbBQ+mqg== -"@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/edr-linux-arm64-musl@0.6.2": + version "0.6.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-arm64-musl/-/edr-linux-arm64-musl-0.6.2.tgz#b0666da450d68364975562ec5f7c2b6ee718e36b" + integrity sha512-UrOAxnsywUcEngQM2ZxIuucci0VX29hYxX7jcpwZU50HICCjxNsxnuXYPxv+IM+6gbhBY1FYvYJGW4PJcP1Nyw== -"@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" - ethereum-cryptography "0.1.3" - mcl-wasm "^0.7.1" - rustbn.js "~0.2.0" +"@nomicfoundation/edr-linux-x64-gnu@0.6.2": + version "0.6.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-x64-gnu/-/edr-linux-x64-gnu-0.6.2.tgz#c61ae692ddf906e65078962e6d86daaa04f95d0d" + integrity sha512-gYxlPLi7fkNcmDmCwZWQa5eOfNcTDundE+TWjpyafxLAjodQuKBD4I0p4XbnuocHjoBEeNzLWdE5RShbZEXEJA== -"@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/edr-linux-x64-musl@0.6.2": + version "0.6.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-x64-musl/-/edr-linux-x64-musl-0.6.2.tgz#a2714ee7a62faf55c7994c7eaddeb32d0622801d" + integrity sha512-ev5hy9wmiHZi1GKQ1l6PJ2+UpsUh+DvK9AwiCZVEdaicuhmTfO6fdL4szgE4An8RU+Ou9DeiI1tZcq6iw++Wuw== -"@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== - dependencies: - "@nomicfoundation/ethereumjs-common" "4.0.2" - "@nomicfoundation/ethereumjs-rlp" "5.0.2" - debug "^4.3.3" - ethereum-cryptography "0.1.3" - ethers "^5.7.1" - js-sdsl "^4.1.4" +"@nomicfoundation/edr-win32-x64-msvc@0.6.2": + version "0.6.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-win32-x64-msvc/-/edr-win32-x64-msvc-0.6.2.tgz#5507884a81d57f337363b7fbf9bf4ae93ff69c0c" + integrity sha512-2ZXVVcmdmEeX0Hb3IAurHUjgU3H1GIk9h7Okosdjgl3tl+BaNHxi84Us+DblynO1LRj8nL/ATeVtSfBuW3Z1vw== -"@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== +"@nomicfoundation/edr@^0.6.1": + version "0.6.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr/-/edr-0.6.2.tgz#6911d9a0b36bc054747dcd1ae894ce447400be31" + integrity sha512-yPUegN3sTWiAkRatCmGRkuvMgD9HSSpivl2ebAqq0aU2xgC7qmIO+YQPxQ3Z46MUoi7MrTf4e6GpbT4S/8x0ew== + dependencies: + "@nomicfoundation/edr-darwin-arm64" "0.6.2" + "@nomicfoundation/edr-darwin-x64" "0.6.2" + "@nomicfoundation/edr-linux-arm64-gnu" "0.6.2" + "@nomicfoundation/edr-linux-arm64-musl" "0.6.2" + "@nomicfoundation/edr-linux-x64-gnu" "0.6.2" + "@nomicfoundation/edr-linux-x64-musl" "0.6.2" + "@nomicfoundation/edr-win32-x64-msvc" "0.6.2" + +"@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-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-util" "9.0.4" -"@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-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-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== +"@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: - "@chainsafe/ssz" "^0.10.0" - "@nomicfoundation/ethereumjs-rlp" "5.0.2" + "@nomicfoundation/ethereumjs-common" "4.0.4" + "@nomicfoundation/ethereumjs-rlp" "5.0.4" + "@nomicfoundation/ethereumjs-util" "9.0.4" 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" +"@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-rlp" "5.0.4" ethereum-cryptography "0.1.3" - mcl-wasm "^0.7.1" - rustbn.js "~0.2.0" "@nomicfoundation/hardhat-chai-matchers@^2.0.2": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-chai-matchers/-/hardhat-chai-matchers-2.0.3.tgz#f4c074d39b74bd283c99e2c2bf143e3cef51ae18" - integrity sha512-A40s7EAK4Acr8UP1Yudgi9GGD9Cca/K3LHt3DzmRIje14lBfHtg9atGQ7qK56vdPcTwKmeaGn30FzxMUfPGEMw== + version "2.0.8" + resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-chai-matchers/-/hardhat-chai-matchers-2.0.8.tgz#9c7cfc4ad0f0a5e9cf16aba8ab668c02f6e273aa" + integrity sha512-Z5PiCXH4xhNLASROlSUOADfhfpfhYO6D7Hn9xp8PddmHey0jq704cr6kfU8TRrQ4PUZbpfsZadPj+pCfZdjPIg== dependencies: "@types/chai-as-promised" "^7.1.3" chai-as-promised "^7.1.1" deep-eql "^4.0.1" ordinal "^1.0.3" -"@nomicfoundation/hardhat-ethers@^3.0.4", "@nomicfoundation/hardhat-ethers@^3.0.5": - version "3.0.5" - resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-ethers/-/hardhat-ethers-3.0.5.tgz#0422c2123dec7c42e7fb2be8e1691f1d9708db56" - integrity sha512-RNFe8OtbZK6Ila9kIlHp0+S80/0Bu/3p41HUpaRIoHLm6X3WekTd83vob3rE54Duufu1edCiBDxspBzi2rxHHw== +"@nomicfoundation/hardhat-ethers@^3.0.0", "@nomicfoundation/hardhat-ethers@^3.0.6": + version "3.0.8" + resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-ethers/-/hardhat-ethers-3.0.8.tgz#af078f566373abeb77e11cbe69fe3dd47f8bfc27" + integrity sha512-zhOZ4hdRORls31DTOqg+GmEZM0ujly8GGIuRY7t7szEk2zW/arY1qDug/py8AEktT00v5K+b6RvbVog+va51IA== dependencies: debug "^4.1.1" lodash.isequal "^4.5.0" -"@nomicfoundation/hardhat-network-helpers@^1.0.9": - version "1.0.10" - resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-network-helpers/-/hardhat-network-helpers-1.0.10.tgz#c61042ceb104fdd6c10017859fdef6529c1d6585" - integrity sha512-R35/BMBlx7tWN5V6d/8/19QCwEmIdbnA4ZrsuXgvs8i2qFx5i7h6mH5pBS4Pwi4WigLH+upl6faYusrNPuzMrQ== +"@nomicfoundation/hardhat-ignition@^0.15.5": + version "0.15.6" + resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-ignition/-/hardhat-ignition-0.15.6.tgz#7b62010e4aa37ec5afc4b1c8217b11dd21a99d93" + integrity sha512-PcMf4xlYvwHYej2jcuOd/rBNNMM5FO11vh9c+MF8+m7NxV4b6NOameL3uscoD7ghg0H2GNgnGXgQ67ryRqtdIQ== + dependencies: + "@nomicfoundation/ignition-core" "^0.15.6" + "@nomicfoundation/ignition-ui" "^0.15.6" + chalk "^4.0.0" + debug "^4.3.2" + fs-extra "^10.0.0" + json5 "^2.2.3" + prompts "^2.4.2" + +"@nomicfoundation/hardhat-network-helpers@^1.0.11": + version "1.0.12" + resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-network-helpers/-/hardhat-network-helpers-1.0.12.tgz#2c0abec0c50b75f9d0d71776e49e3b5ef746d289" + integrity sha512-xTNQNI/9xkHvjmCJnJOTyqDSl8uq1rKb2WOVmixQxFtRd7Oa3ecO8zM0cyC2YmOK+jHB9WPZ+F/ijkHg1CoORA== dependencies: ethereumjs-util "^7.1.4" @@ -877,10 +810,10 @@ resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-toolbox/-/hardhat-toolbox-4.0.0.tgz#eb1f619218dd1414fa161dfec92d3e5e53a2f407" integrity sha512-jhcWHp0aHaL0aDYj8IJl80v4SZXWMS1A2XxXa1CA6pBiFfJKuZinCkO6wb+POAt0LIfXB3gA3AgdcOccrcwBwA== -"@nomicfoundation/hardhat-verify@^2.0.0": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-verify/-/hardhat-verify-2.0.3.tgz#173557f8cfa53c8c9da23a326f54d24fe459ae68" - integrity sha512-ESbRu9by53wu6VvgwtMtm108RSmuNsVqXtzg061D+/4R7jaWh/Wl/8ve+p6SdDX7vA1Z3L02hDO1Q3BY4luLXQ== +"@nomicfoundation/hardhat-verify@^2.0.8": + version "2.0.11" + resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-verify/-/hardhat-verify-2.0.11.tgz#4ce12b592e01ee93a81933924609c233ed00d951" + integrity sha512-lGIo4dNjVQFdsiEgZp3KP6ntLiF7xJEJsbNHfSyIiFCyI0Yv0518ElsFtMC5uCuHEChiBBMrib9jWQvHHT+X3Q== dependencies: "@ethersproject/abi" "^5.1.2" "@ethersproject/address" "^5.0.2" @@ -892,76 +825,149 @@ table "^6.8.0" undici "^5.14.0" -"@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.1.tgz#4c858096b1c17fe58a474fe81b46815f93645c15" - integrity sha512-KcTodaQw8ivDZyF+D76FokN/HdpgGpfjc/gFCImdLUyqB6eSWVaZPazMbeAjmfhx3R0zm/NYVzxwAokFKgrc0w== - -"@nomicfoundation/solidity-analyzer-darwin-x64@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-darwin-x64/-/solidity-analyzer-darwin-x64-0.1.1.tgz#6e25ccdf6e2d22389c35553b64fe6f3fdaec432c" - integrity sha512-XhQG4BaJE6cIbjAVtzGOGbK3sn1BO9W29uhk9J8y8fZF1DYz0Doj8QDMfpMu+A6TjPDs61lbsmeYodIDnfveSA== - -"@nomicfoundation/solidity-analyzer-freebsd-x64@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-freebsd-x64/-/solidity-analyzer-freebsd-x64-0.1.1.tgz#0a224ea50317139caeebcdedd435c28a039d169c" - integrity sha512-GHF1VKRdHW3G8CndkwdaeLkVBi5A9u2jwtlS7SLhBc8b5U/GcoL39Q+1CSO3hYqePNP+eV5YI7Zgm0ea6kMHoA== - -"@nomicfoundation/solidity-analyzer-linux-arm64-gnu@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-arm64-gnu/-/solidity-analyzer-linux-arm64-gnu-0.1.1.tgz#dfa085d9ffab9efb2e7b383aed3f557f7687ac2b" - integrity sha512-g4Cv2fO37ZsUENQ2vwPnZc2zRenHyAxHcyBjKcjaSmmkKrFr64yvzeNO8S3GBFCo90rfochLs99wFVGT/0owpg== +"@nomicfoundation/ignition-core@^0.15.6": + version "0.15.6" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ignition-core/-/ignition-core-0.15.6.tgz#bc5fd58f6281f4b8a43f4b9a2d29a112c451048c" + integrity sha512-9eD1NJ2G4vh7IleRNmCz/3bGVoNEPYrRVPqx0uvWzG2xD226GGQcTgtK+NovyxsQOE/AcLF1xjX3/+8kNc1sSg== + dependencies: + "@ethersproject/address" "5.6.1" + "@nomicfoundation/solidity-analyzer" "^0.1.1" + cbor "^9.0.0" + debug "^4.3.2" + ethers "^6.7.0" + fs-extra "^10.0.0" + immer "10.0.2" + lodash "4.17.21" + ndjson "2.0.0" + +"@nomicfoundation/ignition-ui@^0.15.6": + version "0.15.6" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ignition-ui/-/ignition-ui-0.15.6.tgz#0f71a5f1bf38d91a875b8fd212f3eafc9a9d607b" + integrity sha512-CW14g/BVcGZtBSF1K4eZSCjyvtz1fr9yppkFKC+Z0+sm/lXFWpwcwaVN+UiugQ/9wz9HAfSk4Y0gagdAMiSs0w== + +"@nomicfoundation/slang-darwin-arm64@0.17.0": + version "0.17.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/slang-darwin-arm64/-/slang-darwin-arm64-0.17.0.tgz#8cded3c24322624e3b6618760caba8e840bd1c1d" + integrity sha512-O0q94EUtoWy9A5kOTOa9/khtxXDYnLqmuda9pQELurSiwbQEVCPQL8kb34VbOW+ifdre66JM/05Xw9JWhIZ9sA== + +"@nomicfoundation/slang-darwin-x64@0.17.0": + version "0.17.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/slang-darwin-x64/-/slang-darwin-x64-0.17.0.tgz#6ebeb33a2ced89fc6023f6cda4af96403486038a" + integrity sha512-IaDbHzvT08sBK2HyGzonWhq1uu8IxdjmTqAWHr25Oh/PYnamdi8u4qchZXXYKz/DHLoYN3vIpBXoqLQIomhD/g== + +"@nomicfoundation/slang-linux-arm64-gnu@0.17.0": + version "0.17.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/slang-linux-arm64-gnu/-/slang-linux-arm64-gnu-0.17.0.tgz#41c7e57a9b1a3aee6911f0cab22e683c149fb470" + integrity sha512-Lj4anvOsQZxs1SycG8VyT2Rl2oqIhyLSUCgGepTt3CiJ/bM+8r8bLJIgh8vKkki4BWz49YsYIgaJB2IPv8FFTw== + +"@nomicfoundation/slang-linux-arm64-musl@0.17.0": + version "0.17.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/slang-linux-arm64-musl/-/slang-linux-arm64-musl-0.17.0.tgz#9c4b51689274ae75c2c8a4cddd2e1cc0a79c191d" + integrity sha512-/xkTCa9d5SIWUBQE3BmLqDFfJRr4yUBwbl4ynPiGUpRXrD69cs6pWKkwjwz/FdBpXqVo36I+zY95qzoTj/YhOA== + +"@nomicfoundation/slang-linux-x64-gnu@0.17.0": + version "0.17.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/slang-linux-x64-gnu/-/slang-linux-x64-gnu-0.17.0.tgz#c3a3b6a7b775fc617832958d10e6664bf86d39d0" + integrity sha512-oe5IO5vntOqYvTd67deCHPIWuSuWm6aYtT2/0Kqz2/VLtGz4ClEulBSRwfnNzBVtw2nksWipE1w8BzhImI7Syg== + +"@nomicfoundation/slang-linux-x64-musl@0.17.0": + version "0.17.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/slang-linux-x64-musl/-/slang-linux-x64-musl-0.17.0.tgz#725118ff99a7217b9f1d1bd84411d9442084077d" + integrity sha512-PpYCI5K/kgLAMXaPY0V4VST5gCDprEOh7z/47tbI8kJQumI5odjsj/Cs8MpTo7/uRH6flKYbVNgUzcocWVYrAQ== + +"@nomicfoundation/slang-win32-arm64-msvc@0.17.0": + version "0.17.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/slang-win32-arm64-msvc/-/slang-win32-arm64-msvc-0.17.0.tgz#9c8bc4ccf21eaaac0cfcb6d3954ede4e2dea4c02" + integrity sha512-u/Mkf7OjokdBilP7QOJj6QYJU4/mjkbKnTX21wLyCIzeVWS7yafRPYpBycKIBj2pRRZ6ceAY5EqRpb0aiCq+0Q== + +"@nomicfoundation/slang-win32-ia32-msvc@0.17.0": + version "0.17.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/slang-win32-ia32-msvc/-/slang-win32-ia32-msvc-0.17.0.tgz#3fc5d00a3f8c1d85a5e94146af78a5526a4f3d27" + integrity sha512-XJBVQfNnZQUv0tP2JSJ573S+pmgrLWgqSZOGaMllnB/TL1gRci4Z7dYRJUF2s82GlRJE+FHSI2Ro6JISKmlXCg== + +"@nomicfoundation/slang-win32-x64-msvc@0.17.0": + version "0.17.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/slang-win32-x64-msvc/-/slang-win32-x64-msvc-0.17.0.tgz#f6a5e3250fa07cbda49151edeb80f09090e5b71a" + integrity sha512-zPGsAeiTfqfPNYHD8BfrahQmYzA78ZraoHKTGraq/1xwJwzBK4bu/NtvVA4pJjBV+B4L6DCxVhSbpn40q26JQA== + +"@nomicfoundation/slang@^0.17.0": + version "0.17.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/slang/-/slang-0.17.0.tgz#d9c25cd711ebf3490c9d0c99e9b4ca2481341a6b" + integrity sha512-1GlkGRcGpVnjFw9Z1vvDKOKo2mzparFt7qrl2pDxWp+jrVtlvej98yCMX52pVyrYE7ZeOSZFnx/DtsSgoukStQ== + dependencies: + "@nomicfoundation/slang-darwin-arm64" "0.17.0" + "@nomicfoundation/slang-darwin-x64" "0.17.0" + "@nomicfoundation/slang-linux-arm64-gnu" "0.17.0" + "@nomicfoundation/slang-linux-arm64-musl" "0.17.0" + "@nomicfoundation/slang-linux-x64-gnu" "0.17.0" + "@nomicfoundation/slang-linux-x64-musl" "0.17.0" + "@nomicfoundation/slang-win32-arm64-msvc" "0.17.0" + "@nomicfoundation/slang-win32-ia32-msvc" "0.17.0" + "@nomicfoundation/slang-win32-x64-msvc" "0.17.0" + +"@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.2": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.2.tgz#3a9c3b20d51360b20affb8f753e756d553d49557" + integrity sha512-JaqcWPDZENCvm++lFFGjrDd8mxtf+CtLd2MiXvMNTBD33dContTZ9TWETwNFwg7JTJT5Q9HEecH7FA+HTSsIUw== -"@nomicfoundation/solidity-analyzer-linux-arm64-musl@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-arm64-musl/-/solidity-analyzer-linux-arm64-musl-0.1.1.tgz#c9e06b5d513dd3ab02a7ac069c160051675889a4" - integrity sha512-WJ3CE5Oek25OGE3WwzK7oaopY8xMw9Lhb0mlYuJl/maZVo+WtP36XoQTb7bW/i8aAdHW5Z+BqrHMux23pvxG3w== +"@nomicfoundation/solidity-analyzer-darwin-x64@0.1.2": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-darwin-x64/-/solidity-analyzer-darwin-x64-0.1.2.tgz#74dcfabeb4ca373d95bd0d13692f44fcef133c28" + integrity sha512-fZNmVztrSXC03e9RONBT+CiksSeYcxI1wlzqyr0L7hsQlK1fzV+f04g2JtQ1c/Fe74ZwdV6aQBdd6Uwl1052sw== -"@nomicfoundation/solidity-analyzer-linux-x64-gnu@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-x64-gnu/-/solidity-analyzer-linux-x64-gnu-0.1.1.tgz#8d328d16839e52571f72f2998c81e46bf320f893" - integrity sha512-5WN7leSr5fkUBBjE4f3wKENUy9HQStu7HmWqbtknfXkkil+eNWiBV275IOlpXku7v3uLsXTOKpnnGHJYI2qsdA== +"@nomicfoundation/solidity-analyzer-linux-arm64-gnu@0.1.2": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-arm64-gnu/-/solidity-analyzer-linux-arm64-gnu-0.1.2.tgz#4af5849a89e5a8f511acc04f28eb5d4460ba2b6a" + integrity sha512-3d54oc+9ZVBuB6nbp8wHylk4xh0N0Gc+bk+/uJae+rUgbOBwQSfuGIbAZt1wBXs5REkSmynEGcqx6DutoK0tPA== -"@nomicfoundation/solidity-analyzer-linux-x64-musl@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-x64-musl/-/solidity-analyzer-linux-x64-musl-0.1.1.tgz#9b49d0634b5976bb5ed1604a1e1b736f390959bb" - integrity sha512-KdYMkJOq0SYPQMmErv/63CwGwMm5XHenEna9X9aB8mQmhDBrYrlAOSsIPgFCUSL0hjxE3xHP65/EPXR/InD2+w== +"@nomicfoundation/solidity-analyzer-linux-arm64-musl@0.1.2": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-arm64-musl/-/solidity-analyzer-linux-arm64-musl-0.1.2.tgz#54036808a9a327b2ff84446c130a6687ee702a8e" + integrity sha512-iDJfR2qf55vgsg7BtJa7iPiFAsYf2d0Tv/0B+vhtnI16+wfQeTbP7teookbGvAo0eJo7aLLm0xfS/GTkvHIucA== -"@nomicfoundation/solidity-analyzer-win32-arm64-msvc@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-win32-arm64-msvc/-/solidity-analyzer-win32-arm64-msvc-0.1.1.tgz#e2867af7264ebbcc3131ef837878955dd6a3676f" - integrity sha512-VFZASBfl4qiBYwW5xeY20exWhmv6ww9sWu/krWSesv3q5hA0o1JuzmPHR4LPN6SUZj5vcqci0O6JOL8BPw+APg== +"@nomicfoundation/solidity-analyzer-linux-x64-gnu@0.1.2": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-x64-gnu/-/solidity-analyzer-linux-x64-gnu-0.1.2.tgz#466cda0d6e43691986c944b909fc6dbb8cfc594e" + integrity sha512-9dlHMAt5/2cpWyuJ9fQNOUXFB/vgSFORg1jpjX1Mh9hJ/MfZXlDdHQ+DpFCs32Zk5pxRBb07yGvSHk9/fezL+g== -"@nomicfoundation/solidity-analyzer-win32-ia32-msvc@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-win32-ia32-msvc/-/solidity-analyzer-win32-ia32-msvc-0.1.1.tgz#0685f78608dd516c8cdfb4896ed451317e559585" - integrity sha512-JnFkYuyCSA70j6Si6cS1A9Gh1aHTEb8kOTBApp/c7NRTFGNMH8eaInKlyuuiIbvYFhlXW4LicqyYuWNNq9hkpQ== +"@nomicfoundation/solidity-analyzer-linux-x64-musl@0.1.2": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-x64-musl/-/solidity-analyzer-linux-x64-musl-0.1.2.tgz#2b35826987a6e94444140ac92310baa088ee7f94" + integrity sha512-GzzVeeJob3lfrSlDKQw2bRJ8rBf6mEYaWY+gW0JnTDHINA0s2gPR4km5RLIj1xeZZOYz4zRw+AEeYgLRqB2NXg== -"@nomicfoundation/solidity-analyzer-win32-x64-msvc@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-win32-x64-msvc/-/solidity-analyzer-win32-x64-msvc-0.1.1.tgz#c9a44f7108646f083b82e851486e0f6aeb785836" - integrity sha512-HrVJr6+WjIXGnw3Q9u6KQcbZCtk0caVWhCdFADySvRyUxJ8PnzlaP+MhwNE8oyT8OZ6ejHBRrrgjSqDCFXGirw== +"@nomicfoundation/solidity-analyzer-win32-x64-msvc@0.1.2": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-win32-x64-msvc/-/solidity-analyzer-win32-x64-msvc-0.1.2.tgz#e6363d13b8709ca66f330562337dbc01ce8bbbd9" + integrity sha512-Fdjli4DCcFHb4Zgsz0uEJXZ2K7VEO+w5KVv7HmT7WO10iODdU9csC2az4jrhEsRtiR9Gfd74FlG0NYlw1BMdyA== -"@nomicfoundation/solidity-analyzer@^0.1.0": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.1.tgz#f5f4d36d3f66752f59a57e7208cd856f3ddf6f2d" - integrity sha512-1LMtXj1puAxyFusBgUIy5pZk3073cNXYnXUpuNKFghHbIit/xZgbk0AokpUADbNm3gyD6bFWl3LRFh3dhVdREg== +"@nomicfoundation/solidity-analyzer@^0.1.0", "@nomicfoundation/solidity-analyzer@^0.1.1": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.2.tgz#8bcea7d300157bf3a770a851d9f5c5e2db34ac55" + integrity sha512-q4n32/FNKIhQ3zQGGw5CvPF6GTvDCpYwIf7bEY/dZTZbgfDsHyjJwURxUJf3VQuuJj+fDIFl4+KkBVbw4Ef6jA== optionalDependencies: - "@nomicfoundation/solidity-analyzer-darwin-arm64" "0.1.1" - "@nomicfoundation/solidity-analyzer-darwin-x64" "0.1.1" - "@nomicfoundation/solidity-analyzer-freebsd-x64" "0.1.1" - "@nomicfoundation/solidity-analyzer-linux-arm64-gnu" "0.1.1" - "@nomicfoundation/solidity-analyzer-linux-arm64-musl" "0.1.1" - "@nomicfoundation/solidity-analyzer-linux-x64-gnu" "0.1.1" - "@nomicfoundation/solidity-analyzer-linux-x64-musl" "0.1.1" - "@nomicfoundation/solidity-analyzer-win32-arm64-msvc" "0.1.1" - "@nomicfoundation/solidity-analyzer-win32-ia32-msvc" "0.1.1" - "@nomicfoundation/solidity-analyzer-win32-x64-msvc" "0.1.1" + "@nomicfoundation/solidity-analyzer-darwin-arm64" "0.1.2" + "@nomicfoundation/solidity-analyzer-darwin-x64" "0.1.2" + "@nomicfoundation/solidity-analyzer-linux-arm64-gnu" "0.1.2" + "@nomicfoundation/solidity-analyzer-linux-arm64-musl" "0.1.2" + "@nomicfoundation/solidity-analyzer-linux-x64-gnu" "0.1.2" + "@nomicfoundation/solidity-analyzer-linux-x64-musl" "0.1.2" + "@nomicfoundation/solidity-analyzer-win32-x64-msvc" "0.1.2" + +"@npmcli/agent@^2.0.0": + version "2.2.2" + resolved "https://registry.yarnpkg.com/@npmcli/agent/-/agent-2.2.2.tgz#967604918e62f620a648c7975461c9c9e74fc5d5" + integrity sha512-OrcNPXdpSl9UX7qPVRWbmWMCSXrcDa2M9DvrbOTj7ao1S4PlqVFYv9/yLKMkrJKZ/V5A/kDBC690or307i26Og== + dependencies: + agent-base "^7.1.0" + http-proxy-agent "^7.0.0" + https-proxy-agent "^7.0.1" + lru-cache "^10.0.1" + socks-proxy-agent "^8.0.3" "@npmcli/arborist@^6.5.0": - version "6.5.0" - resolved "https://registry.yarnpkg.com/@npmcli/arborist/-/arborist-6.5.0.tgz#ee24ecc56e4c387d78c3bce66918b386df6bd560" - integrity sha512-Ir14P+DyH4COJ9fVbmxVy+9GmyU3e/DnlBtijVN7B3Ri53Y9QmAqi1S9IifG0PTGsfa2U4zhAF8e6I/0VXfWjg== + version "6.5.1" + resolved "https://registry.yarnpkg.com/@npmcli/arborist/-/arborist-6.5.1.tgz#b378a2e162e9b868d06f8f2c7e87e828de7e63ba" + integrity sha512-cdV8pGurLK0CifZRilMJbm2CZ3H4Snk8PAqOngj5qmgFLjEllMLvScSZ3XKfd+CK8fo/hrPHO9zazy9OYdvmUg== dependencies: "@isaacs/string-locale-compare" "^1.1.0" "@npmcli/fs" "^3.1.0" @@ -971,7 +977,7 @@ "@npmcli/name-from-folder" "^2.0.0" "@npmcli/node-gyp" "^3.0.0" "@npmcli/package-json" "^4.0.0" - "@npmcli/query" "^3.0.0" + "@npmcli/query" "^3.1.0" "@npmcli/run-script" "^6.0.0" bin-links "^4.0.1" cacache "^17.0.4" @@ -998,12 +1004,12 @@ walk-up-path "^3.0.1" "@npmcli/config@^6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@npmcli/config/-/config-6.4.0.tgz#3b1ddfa0c452fd09beac2cf05ca49b76c7a36bc8" - integrity sha512-/fQjIbuNVIT/PbXvw178Tm97bxV0E0nVUFKHivMKtSI2pcs8xKdaWkHJxf9dTI0G/y5hp/KuCvgcUu5HwAtI1w== + version "6.4.1" + resolved "https://registry.yarnpkg.com/@npmcli/config/-/config-6.4.1.tgz#006409c739635db008e78bf58c92421cc147911d" + integrity sha512-uSz+elSGzjCMANWa5IlbGczLYPkNI/LeR+cHrgaTqTrTSh9RHhOFA4daD2eRUz6lMtOW+Fnsb+qv7V2Zz8ML0g== dependencies: "@npmcli/map-workspaces" "^3.0.2" - ci-info "^3.8.0" + ci-info "^4.0.0" ini "^4.1.0" nopt "^7.0.0" proc-log "^3.0.0" @@ -1012,9 +1018,9 @@ walk-up-path "^3.0.1" "@npmcli/disparity-colors@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@npmcli/disparity-colors/-/disparity-colors-3.0.0.tgz#60ea8c6eb5ba9de2d1950e15b06205b2c3ab7833" - integrity sha512-5R/z157/f20Fi0Ou4ZttL51V0xz0EdPEOauFtPCEYOLInDBRCj1/TxOJ5aGTrtShxEshN2d+hXb9ZKSi5RLBcg== + version "3.0.1" + resolved "https://registry.yarnpkg.com/@npmcli/disparity-colors/-/disparity-colors-3.0.1.tgz#042d5ef548200c81e3ee3a84c994744573fe79fd" + integrity sha512-cOypTz/9IAhaPgOktbDNPeccTU88y8I1ZURbPeC0ooziK1h6dRJs2iGz1eKP1muaeVbow8GqQ0DaxLG8Bpmblw== dependencies: ansi-styles "^4.3.0" @@ -1027,9 +1033,9 @@ semver "^7.3.5" "@npmcli/fs@^3.1.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-3.1.0.tgz#233d43a25a91d68c3a863ba0da6a3f00924a173e" - integrity sha512-7kZUAaLscfgbwBQRbvdMYaZOWyMEcPTH/tJjnyAWJ/dvvs9Ef+CERx/qJb9GExJpl1qipaDGn7KqHnFGGixd0w== + version "3.1.1" + resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-3.1.1.tgz#59cdaa5adca95d135fc00f2bb53f5771575ce726" + integrity sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg== dependencies: semver "^7.3.5" @@ -1048,17 +1054,17 @@ which "^3.0.0" "@npmcli/installed-package-contents@^2.0.1", "@npmcli/installed-package-contents@^2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@npmcli/installed-package-contents/-/installed-package-contents-2.0.2.tgz#bfd817eccd9e8df200919e73f57f9e3d9e4f9e33" - integrity sha512-xACzLPhnfD51GKvTOOuNX2/V4G4mz9/1I2MfDoye9kBM3RYe5g2YbscsaGoTlaWqkxeiapBWyseULVKpSVHtKQ== + version "2.1.0" + resolved "https://registry.yarnpkg.com/@npmcli/installed-package-contents/-/installed-package-contents-2.1.0.tgz#63048e5f6e40947a3a88dcbcb4fd9b76fdd37c17" + integrity sha512-c8UuGLeZpm69BryRykLuKRyKFZYJsZSCT4aVY5ds4omyZqJ172ApzgfKJ5eV/r3HgLdUYgFVe54KSFVjKoe27w== dependencies: npm-bundled "^3.0.0" npm-normalize-package-bin "^3.0.0" "@npmcli/map-workspaces@^3.0.2", "@npmcli/map-workspaces@^3.0.4": - version "3.0.4" - resolved "https://registry.yarnpkg.com/@npmcli/map-workspaces/-/map-workspaces-3.0.4.tgz#15ad7d854292e484f7ba04bc30187a8320dba799" - integrity sha512-Z0TbvXkRbacjFFLpVpV0e2mheCh+WzQpcqL+4xp49uNJOxOnIAPZyXtUxZ5Qn3QBTGKA11Exjd9a5411rBrhDg== + version "3.0.6" + resolved "https://registry.yarnpkg.com/@npmcli/map-workspaces/-/map-workspaces-3.0.6.tgz#27dc06c20c35ef01e45a08909cab9cb3da08cea6" + integrity sha512-tkYs0OYnzQm6iIRdfy+LcLBjcKuQCeE5YLb8KnrIlutJfheNaPvPpgoFEyEFgbjzl5PLZ3IA/BWAwRU0eHuQDA== dependencies: "@npmcli/name-from-folder" "^2.0.0" glob "^10.2.2" @@ -1113,13 +1119,18 @@ dependencies: which "^3.0.0" -"@npmcli/query@^3.0.0": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@npmcli/query/-/query-3.0.1.tgz#77d63ceb7d27ed748da3cc8b50d45fc341448ed6" - integrity sha512-0jE8iHBogf/+bFDj+ju6/UMLbJ39c8h6nSe6qile+dB7PJ0iV3gNqcb2vtt6WWCBrxv9uAjzUT/8vroluulidA== +"@npmcli/query@^3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@npmcli/query/-/query-3.1.0.tgz#bc202c59e122a06cf8acab91c795edda2cdad42c" + integrity sha512-C/iR0tk7KSKGldibYIB9x8GtO/0Bd0I2mhOaDb8ucQL/bQVTmGoeREaFj64Z5+iCBRf3dQfed0CjJL7I8iTkiQ== dependencies: postcss-selector-parser "^6.0.10" +"@npmcli/redact@^2.0.0": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@npmcli/redact/-/redact-2.0.1.tgz#95432fd566e63b35c04494621767a4312c316762" + integrity sha512-YgsR5jCQZhVmTJvjduTOIHph0L73pK8xwMVaDY0PatySqVM9AZj93jpoXYSJqfHFxFkN9dmqTw6OiqExsS3LPw== + "@npmcli/run-script@^6.0.0", "@npmcli/run-script@^6.0.2": version "6.0.2" resolved "https://registry.yarnpkg.com/@npmcli/run-script/-/run-script-6.0.2.tgz#a25452d45ee7f7fb8c16dfaf9624423c0c0eb885" @@ -1137,46 +1148,51 @@ integrity sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA== "@octokit/core@^5.0.0": - version "5.1.0" - resolved "https://registry.yarnpkg.com/@octokit/core/-/core-5.1.0.tgz#81dacf0197ed7855e6413f128bd6dd9e121e7d2f" - integrity sha512-BDa2VAMLSh3otEiaMJ/3Y36GU4qf6GI+VivQ/P41NC6GHcdxpKlqV0ikSZ5gdQsmS3ojXeRx5vasgNTinF0Q4g== + version "5.2.0" + resolved "https://registry.yarnpkg.com/@octokit/core/-/core-5.2.0.tgz#ddbeaefc6b44a39834e1bb2e58a49a117672a7ea" + integrity sha512-1LFfa/qnMQvEOAdzlQymH0ulepxbxnCYAKJZfMci/5XJyIHWgEYnDmgnKakbTh7CH2tFQ5O60oYDvns4i9RAIg== dependencies: "@octokit/auth-token" "^4.0.0" - "@octokit/graphql" "^7.0.0" - "@octokit/request" "^8.0.2" - "@octokit/request-error" "^5.0.0" - "@octokit/types" "^12.0.0" + "@octokit/graphql" "^7.1.0" + "@octokit/request" "^8.3.1" + "@octokit/request-error" "^5.1.0" + "@octokit/types" "^13.0.0" before-after-hook "^2.2.0" universal-user-agent "^6.0.0" -"@octokit/endpoint@^9.0.0": - version "9.0.4" - resolved "https://registry.yarnpkg.com/@octokit/endpoint/-/endpoint-9.0.4.tgz#8afda5ad1ffc3073d08f2b450964c610b821d1ea" - integrity sha512-DWPLtr1Kz3tv8L0UvXTDP1fNwM0S+z6EJpRcvH66orY6Eld4XBMCSYsaWp4xIm61jTWxK68BrR7ibO+vSDnZqw== +"@octokit/endpoint@^9.0.1": + version "9.0.5" + resolved "https://registry.yarnpkg.com/@octokit/endpoint/-/endpoint-9.0.5.tgz#e6c0ee684e307614c02fc6ac12274c50da465c44" + integrity sha512-ekqR4/+PCLkEBF6qgj8WqJfvDq65RH85OAgrtnVp1mSxaXF03u2xW/hUdweGS5654IlC0wkNYC18Z50tSYTAFw== dependencies: - "@octokit/types" "^12.0.0" + "@octokit/types" "^13.1.0" universal-user-agent "^6.0.0" -"@octokit/graphql@^7.0.0": - version "7.0.2" - resolved "https://registry.yarnpkg.com/@octokit/graphql/-/graphql-7.0.2.tgz#3df14b9968192f9060d94ed9e3aa9780a76e7f99" - integrity sha512-OJ2iGMtj5Tg3s6RaXH22cJcxXRi7Y3EBqbHTBRq+PQAqfaS8f/236fUrWhfSn8P4jovyzqucxme7/vWSSZBX2Q== +"@octokit/graphql@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@octokit/graphql/-/graphql-7.1.0.tgz#9bc1c5de92f026648131f04101cab949eeffe4e0" + integrity sha512-r+oZUH7aMFui1ypZnAvZmn0KSqAUgE1/tUXIWaqUCa1758ts/Jio84GZuzsvUkme98kv0WFY8//n0J1Z+vsIsQ== dependencies: - "@octokit/request" "^8.0.1" - "@octokit/types" "^12.0.0" + "@octokit/request" "^8.3.0" + "@octokit/types" "^13.0.0" universal-user-agent "^6.0.0" -"@octokit/openapi-types@^19.1.0": - version "19.1.0" - resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-19.1.0.tgz#75ec7e64743870fc73e1ab4bc6ec252ecdd624dc" - integrity sha512-6G+ywGClliGQwRsjvqVYpklIfa7oRPA0vyhPQG/1Feh+B+wU0vGH1JiJ5T25d3g1JZYBHzR2qefLi9x8Gt+cpw== +"@octokit/openapi-types@^20.0.0": + version "20.0.0" + resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-20.0.0.tgz#9ec2daa0090eeb865ee147636e0c00f73790c6e5" + integrity sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA== + +"@octokit/openapi-types@^22.2.0": + version "22.2.0" + resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-22.2.0.tgz#75aa7dcd440821d99def6a60b5f014207ae4968e" + integrity sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg== "@octokit/plugin-paginate-rest@^9.0.0": - version "9.1.5" - resolved "https://registry.yarnpkg.com/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-9.1.5.tgz#1705bcef4dcde1f4015ee58a63dc61b68648f480" - integrity sha512-WKTQXxK+bu49qzwv4qKbMMRXej1DU2gq017euWyKVudA6MldaSSQuxtz+vGbhxV4CjxpUxjZu6rM2wfc1FiWVg== + version "9.2.1" + resolved "https://registry.yarnpkg.com/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-9.2.1.tgz#2e2a2f0f52c9a4b1da1a3aa17dabe3c459b9e401" + integrity sha512-wfGhE/TAkXZRLjksFXuDZdmGnJQHvtU/joFQdweXUgzo1XwvBCD4o4+75NtFfjfLK5IwLf9vHTfSiU3sLRYpRw== dependencies: - "@octokit/types" "^12.4.0" + "@octokit/types" "^12.6.0" "@octokit/plugin-retry@^6.0.0": version "6.0.1" @@ -1188,38 +1204,45 @@ bottleneck "^2.15.3" "@octokit/plugin-throttling@^8.0.0": - version "8.1.3" - resolved "https://registry.yarnpkg.com/@octokit/plugin-throttling/-/plugin-throttling-8.1.3.tgz#7fb0e001c0cb9383c6be07740b8ec326ed990f6b" - integrity sha512-pfyqaqpc0EXh5Cn4HX9lWYsZ4gGbjnSmUILeu4u2gnuM50K/wIk9s1Pxt3lVeVwekmITgN/nJdoh43Ka+vye8A== + version "8.2.0" + resolved "https://registry.yarnpkg.com/@octokit/plugin-throttling/-/plugin-throttling-8.2.0.tgz#9ec3ea2e37b92fac63f06911d0c8141b46dc4941" + integrity sha512-nOpWtLayKFpgqmgD0y3GqXafMFuKcA4tRPZIfu7BArd2lEZeb1988nhWhwx4aZWmjDmUfdgVf7W+Tt4AmvRmMQ== dependencies: "@octokit/types" "^12.2.0" bottleneck "^2.15.3" -"@octokit/request-error@^5.0.0": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@octokit/request-error/-/request-error-5.0.1.tgz#277e3ce3b540b41525e07ba24c5ef5e868a72db9" - integrity sha512-X7pnyTMV7MgtGmiXBwmO6M5kIPrntOXdyKZLigNfQWSEQzVxR4a4vo49vJjTWX70mPndj8KhfT4Dx+2Ng3vnBQ== +"@octokit/request-error@^5.0.0", "@octokit/request-error@^5.1.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@octokit/request-error/-/request-error-5.1.0.tgz#ee4138538d08c81a60be3f320cd71063064a3b30" + integrity sha512-GETXfE05J0+7H2STzekpKObFe765O5dlAKUTLNGeH+x47z7JjXHfsHKo5z21D/o/IOZTUEI6nyWyR+bZVP/n5Q== dependencies: - "@octokit/types" "^12.0.0" + "@octokit/types" "^13.1.0" deprecation "^2.0.0" once "^1.4.0" -"@octokit/request@^8.0.1", "@octokit/request@^8.0.2": - version "8.1.6" - resolved "https://registry.yarnpkg.com/@octokit/request/-/request-8.1.6.tgz#a76a859c30421737a3918b40973c2ff369009571" - integrity sha512-YhPaGml3ncZC1NfXpP3WZ7iliL1ap6tLkAp6MvbK2fTTPytzVUyUesBBogcdMm86uRYO5rHaM1xIWxigWZ17MQ== +"@octokit/request@^8.3.0", "@octokit/request@^8.3.1": + version "8.4.0" + resolved "https://registry.yarnpkg.com/@octokit/request/-/request-8.4.0.tgz#7f4b7b1daa3d1f48c0977ad8fffa2c18adef8974" + integrity sha512-9Bb014e+m2TgBeEJGEbdplMVWwPmL1FPtggHQRkV+WVsMggPtEkLKPlcVYm/o8xKLkpJ7B+6N8WfQMtDLX2Dpw== dependencies: - "@octokit/endpoint" "^9.0.0" - "@octokit/request-error" "^5.0.0" - "@octokit/types" "^12.0.0" + "@octokit/endpoint" "^9.0.1" + "@octokit/request-error" "^5.1.0" + "@octokit/types" "^13.1.0" universal-user-agent "^6.0.0" -"@octokit/types@^12.0.0", "@octokit/types@^12.2.0", "@octokit/types@^12.4.0": - version "12.4.0" - resolved "https://registry.yarnpkg.com/@octokit/types/-/types-12.4.0.tgz#8f97b601e91ce6b9776ed8152217e77a71be7aac" - integrity sha512-FLWs/AvZllw/AGVs+nJ+ELCDZZJk+kY0zMen118xhL2zD0s1etIUHm1odgjP7epxYU1ln7SZxEUWYop5bhsdgQ== +"@octokit/types@^12.0.0", "@octokit/types@^12.2.0", "@octokit/types@^12.6.0": + version "12.6.0" + resolved "https://registry.yarnpkg.com/@octokit/types/-/types-12.6.0.tgz#8100fb9eeedfe083aae66473bd97b15b62aedcb2" + integrity sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw== dependencies: - "@octokit/openapi-types" "^19.1.0" + "@octokit/openapi-types" "^20.0.0" + +"@octokit/types@^13.0.0", "@octokit/types@^13.1.0": + version "13.5.1" + resolved "https://registry.yarnpkg.com/@octokit/types/-/types-13.5.1.tgz#5685a91f295195ddfff39723b093b0df9609ce6e" + integrity sha512-F41lGiWBKPIWPBgjSvaDXTTQptBujnozENAK3S//nj7xsFdYdirImKlBB/hTjr+Vii68SM+8jG3UJWRa6DMuDA== + dependencies: + "@octokit/openapi-types" "^22.2.0" "@openzeppelin/contracts-400@npm:@openzeppelin/contracts@4.0.0": version "4.0.0" @@ -1231,185 +1254,173 @@ resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.0.0.tgz#11edb64933c43ab3eab2a84abe5e3ccf2981c4c7" integrity sha512-T5tO/KD++m+Ph74ppPPmNuhyrvNcsMDgQWt+pGshNJMsTf9UvmhBNyyOqVAL91UeuqDI0FHAbBV1+NnMg7ffFA== -"@openzeppelin/contracts-upgradeable@4.9.3": - version "4.9.3" - resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.9.3.tgz#ff17a80fb945f5102571f8efecb5ce5915cc4811" - integrity sha512-jjaHAVRMrE4UuZNfDwjlLGDxTHWIOwTJS2ldnc278a0gevfXfPr8hxKEVBGFBE96kl2G3VHDZhUimw/+G3TG2A== - -"@openzeppelin/contracts@4.9.3": - version "4.9.3" - resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.9.3.tgz#00d7a8cf35a475b160b3f0293a6403c511099364" - integrity sha512-He3LieZ1pP2TNt5JbkPA4PNT9WC3gOTOlDcFGJW4Le4QKqwmiNJCRt44APfxMxvq7OugU/cqYuPcSBzOw38DAg== - -"@openzeppelin/defender-admin-client@^1.52.0": - version "1.54.1" - resolved "https://registry.yarnpkg.com/@openzeppelin/defender-admin-client/-/defender-admin-client-1.54.1.tgz#b877972992b95a0dc3787f2ade2f044586621357" - integrity sha512-kRpSUdTsnSqntp4FOXIm95t+6VKHc8CUY2Si71VDuxs0q7HSPZkdpRPSntcolwEzWy9L4a8NS/QMwDF5NJ4X1g== - dependencies: - "@openzeppelin/defender-base-client" "1.54.1" - axios "^1.4.0" - ethers "^5.7.2" - lodash "^4.17.19" - node-fetch "^2.6.0" +"@openzeppelin/contracts-upgradeable@^5.0.2": + version "5.0.2" + resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-5.0.2.tgz#3e5321a2ecdd0b206064356798c21225b6ec7105" + integrity sha512-0MmkHSHiW2NRFiT9/r5Lu4eJq5UJ4/tzlOgYXNAIj/ONkQTVnz22pLxDvp4C4uZ9he7ZFvGn3Driptn1/iU7tQ== -"@openzeppelin/defender-base-client@1.54.1", "@openzeppelin/defender-base-client@^1.52.0": - version "1.54.1" - resolved "https://registry.yarnpkg.com/@openzeppelin/defender-base-client/-/defender-base-client-1.54.1.tgz#ed777ae56908d5a920e1f72ac735c63694e65b30" - integrity sha512-DRGz/7KN3ZQwu28YWMOaojrC7jjPkz/uCwkC8/C8B11qwZhA5qIVvyhYHhhFOCl0J84+E3TNdvkPD2q3p2WaJw== - dependencies: - amazon-cognito-identity-js "^6.0.1" - async-retry "^1.3.3" - axios "^1.4.0" - lodash "^4.17.19" - node-fetch "^2.6.0" +"@openzeppelin/contracts@^5.0.2": + version "5.0.2" + resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-5.0.2.tgz#b1d03075e49290d06570b2fd42154d76c2a5d210" + integrity sha512-ytPc6eLGcHHnapAZ9S+5qsdomhjo6QBHTDRRBFfTxXIpsicMhVPouPgmUPebZZZGX7vt9USA+Z+0M0dSVtSUEA== -"@openzeppelin/defender-sdk-account-client@^1.8.0": - version "1.8.0" - resolved "https://registry.yarnpkg.com/@openzeppelin/defender-sdk-account-client/-/defender-sdk-account-client-1.8.0.tgz#ebefcc7f893dac1bae653efcc75b4f48abb46b1a" - integrity sha512-S/G+Cmemi3D0dBlAfQBL4/ZAVt+LtivIg+oWKGaUr3wG2usx12CURMaTTb087FlQabdpxEqiExb5xTCSeKBZ9g== +"@openzeppelin/defender-sdk-account-client@^1.14.4": + version "1.14.4" + resolved "https://registry.yarnpkg.com/@openzeppelin/defender-sdk-account-client/-/defender-sdk-account-client-1.14.4.tgz#06f822cb57910fbfe15826397ede14785285626f" + integrity sha512-SxV4oTofO/xf1IcNJ5Dcc6XdXrxmu2jNPIeOx6GhdwVmO2LDVgi/9pAwXNlW1ihZ4wkJf/BSz3JsRJCgrwkadQ== dependencies: - "@openzeppelin/defender-sdk-base-client" "^1.8.0" - axios "^1.4.0" + "@openzeppelin/defender-sdk-base-client" "^1.14.4" + axios "^1.7.2" lodash "^4.17.21" -"@openzeppelin/defender-sdk-action-client@^1.8.0": - version "1.8.0" - resolved "https://registry.yarnpkg.com/@openzeppelin/defender-sdk-action-client/-/defender-sdk-action-client-1.8.0.tgz#971562101aedd2f35dd3ec500aacf987b7708fc3" - integrity sha512-+hngMvj/5YMAJ7lDKNWOJRPO4bG3KOZhgzzJpGIFOJo4vk3qRY/ogb30uDl1+aSXGCLTrtlTlwcRCM2rLyhZBQ== +"@openzeppelin/defender-sdk-action-client@^1.14.4": + version "1.14.4" + resolved "https://registry.yarnpkg.com/@openzeppelin/defender-sdk-action-client/-/defender-sdk-action-client-1.14.4.tgz#c2c6dd17f7c13e1bf7863730ac4d06a78d272689" + integrity sha512-YoRW3ZST1YCGkBIPtzJNPR0ajK9H0cxhT+evbRX9hgiUNJTgTDJeKGX+qOKOMjKOPXikiYUc2TpmKwP1I2tP5A== dependencies: - "@openzeppelin/defender-sdk-base-client" "^1.8.0" - axios "^1.4.0" - glob "^7.1.6" + "@openzeppelin/defender-sdk-base-client" "^1.14.4" + axios "^1.7.2" + dotenv "^16.3.1" + glob "^11.0.0" jszip "^3.10.1" lodash "^4.17.21" -"@openzeppelin/defender-sdk-base-client@^1.5.0", "@openzeppelin/defender-sdk-base-client@^1.8.0": - version "1.8.0" - resolved "https://registry.yarnpkg.com/@openzeppelin/defender-sdk-base-client/-/defender-sdk-base-client-1.8.0.tgz#2209a060ce61b4dfc44c7ac0c2b1d86e18b69f7d" - integrity sha512-XIJat6BW2CTM74AwG5IL0Q/aE6RXj8x7smnVKmBql4wMvmirVW+njfwzZCLhUTiBXg9AlHxIInEF14SabfIisg== +"@openzeppelin/defender-sdk-base-client@^1.14.4": + version "1.14.4" + resolved "https://registry.yarnpkg.com/@openzeppelin/defender-sdk-base-client/-/defender-sdk-base-client-1.14.4.tgz#3ccd3beb94cba61883f769afe7e6fdbdc5daa12d" + integrity sha512-tOePVQLKpqfGQ1GMzHvSBNd2psPYd86LDNpvdl5gjD0Y2kW/zNh5qBXy29RraGtk/qc8zs9hzS5pAOh0vhGkGQ== dependencies: amazon-cognito-identity-js "^6.3.6" async-retry "^1.3.3" -"@openzeppelin/defender-sdk-deploy-client@^1.5.0", "@openzeppelin/defender-sdk-deploy-client@^1.8.0": - version "1.8.0" - resolved "https://registry.yarnpkg.com/@openzeppelin/defender-sdk-deploy-client/-/defender-sdk-deploy-client-1.8.0.tgz#1e186d2b3ff176c6a4c03e8207bad8022528975f" - integrity sha512-/tNS2EnHuA5l095wzMbIkGMDNHZLcZQ2eLUP8z+AeKaAUeR2z4qzZ1ul21kR3EJURAyoy8aULFZanLggoBWHrA== +"@openzeppelin/defender-sdk-deploy-client@^1.14.4": + version "1.14.4" + resolved "https://registry.yarnpkg.com/@openzeppelin/defender-sdk-deploy-client/-/defender-sdk-deploy-client-1.14.4.tgz#1feb94575a32ed4ddee81d03cdb060064936a528" + integrity sha512-+diSoz1zid37LMsY2RDxI+uAsYx9Eryg8Vz+yfvuyd56fXrzjQEln7BBtYQw+2zp9yvyAByOL5XSQdrQga9OBQ== dependencies: - "@ethersproject/abi" "^5.7.0" - "@openzeppelin/defender-sdk-base-client" "^1.8.0" - axios "^1.4.0" + "@openzeppelin/defender-sdk-base-client" "^1.14.4" + axios "^1.7.2" lodash "^4.17.21" -"@openzeppelin/defender-sdk-monitor-client@^1.8.0": - version "1.8.0" - resolved "https://registry.yarnpkg.com/@openzeppelin/defender-sdk-monitor-client/-/defender-sdk-monitor-client-1.8.0.tgz#55f1e91a06f739c8311ed1456c5c4abd76c32cdf" - integrity sha512-eZDWs01c7+8V/d6ct6RvNKYnuTzueYxwkuoZhG9BUoT5ALmtPQJlRZrjguuBzI7+zYwCS57y4ymro7453hOKeA== +"@openzeppelin/defender-sdk-key-value-store-client@^1.14.4": + version "1.14.4" + resolved "https://registry.yarnpkg.com/@openzeppelin/defender-sdk-key-value-store-client/-/defender-sdk-key-value-store-client-1.14.4.tgz#2e9e93e41f41fcaef4f05fbe50af61e1227dc79f" + integrity sha512-8InEiGeUpahKuWTgFWUyS5DS9HkXeHWMW+yxolGwxCy+OIGEPfxg/oMBXC2UzGn3BfIvWic/CLspFzuWIlarEQ== dependencies: - "@ethersproject/abi" "^5.7.0" - "@openzeppelin/defender-sdk-base-client" "^1.8.0" - axios "^1.4.0" + "@openzeppelin/defender-sdk-base-client" "^1.14.4" + axios "^1.7.2" + fs-extra "^11.2.0" lodash "^4.17.21" -"@openzeppelin/defender-sdk-network-client@^1.8.0": - version "1.8.0" - resolved "https://registry.yarnpkg.com/@openzeppelin/defender-sdk-network-client/-/defender-sdk-network-client-1.8.0.tgz#84ab6c28ba8162f146304363546682f24c409154" - integrity sha512-Fuefe+cSlyG8qvPlgbVCtbYlsh0WgbbgAcalNbLq1esW6XHAMzYT2AoHISY2BVADtm7rpyb5fgT6lI3PWIoIcQ== +"@openzeppelin/defender-sdk-monitor-client@^1.14.4": + version "1.14.4" + resolved "https://registry.yarnpkg.com/@openzeppelin/defender-sdk-monitor-client/-/defender-sdk-monitor-client-1.14.4.tgz#092e6cb3d18f4872b6fe81b6a1c769c7a08095a1" + integrity sha512-PSesKNicY37LiHD2EVsyZXQrHRZsPYaVhUuMdqfNoJZexPZfnhv7c2A481tt+hTwAccJguQF69NLqylpdgtpFQ== dependencies: - "@ethersproject/abi" "^5.7.0" - "@openzeppelin/defender-sdk-base-client" "^1.8.0" - axios "^1.4.0" + "@openzeppelin/defender-sdk-base-client" "^1.14.4" + axios "^1.7.2" + ethers "^6.9.0" lodash "^4.17.21" -"@openzeppelin/defender-sdk-notification-channel-client@^1.8.0": - version "1.8.0" - resolved "https://registry.yarnpkg.com/@openzeppelin/defender-sdk-notification-channel-client/-/defender-sdk-notification-channel-client-1.8.0.tgz#b9dcd6fee39eefc2090e5ba3a86d9c7b62b47512" - integrity sha512-V7YJkEdxDDg3L9tcRS/K0FciYdwNhDNCwU5zCPAYHwHii0PDhz6XjB2g/zWLxhZMzOtY246swrnXiOYfvjwirA== +"@openzeppelin/defender-sdk-network-client@^1.14.4": + version "1.14.4" + resolved "https://registry.yarnpkg.com/@openzeppelin/defender-sdk-network-client/-/defender-sdk-network-client-1.14.4.tgz#0f89c45f601e28c2f87c487b62b48d9cd4b5b956" + integrity sha512-OS0H5b0vgYacJcwkvUFJUaRuyUaXhIRl916W5xLvGia5H6i/qn3dP8MZ7oLcPwKc8jB+ucRytO4H/AHsea0aVA== dependencies: - "@ethersproject/abi" "^5.7.0" - "@openzeppelin/defender-sdk-base-client" "^1.8.0" - axios "^1.4.0" + "@openzeppelin/defender-sdk-base-client" "^1.14.4" + axios "^1.7.2" lodash "^4.17.21" -"@openzeppelin/defender-sdk-proposal-client@^1.8.0": - version "1.8.0" - resolved "https://registry.yarnpkg.com/@openzeppelin/defender-sdk-proposal-client/-/defender-sdk-proposal-client-1.8.0.tgz#1273b4ac8966fcf024ae03bb96aa2c5ba4137356" - integrity sha512-EIPE3yDK0cbnHpt5ptR20yzW/ao2Qzv5v17Hwu83VG95L5csIMmy7ndjmAie15gaB9Xkw1MKdpHmHhzmohESPg== +"@openzeppelin/defender-sdk-notification-channel-client@^1.14.4": + version "1.14.4" + resolved "https://registry.yarnpkg.com/@openzeppelin/defender-sdk-notification-channel-client/-/defender-sdk-notification-channel-client-1.14.4.tgz#5387d0f14f344a1c0dfb9aedf75f64ab22c3ded1" + integrity sha512-xCMUe4pseRA+tQMrd6PDoZ4aToDi0LPrVAlBXFDFxCZ6/TzcsVA/PgfM4Hy6R+9vF+S5gMFGuJkCpDtlcYfo5A== dependencies: - "@openzeppelin/defender-sdk-base-client" "^1.8.0" - axios "^1.4.0" + "@openzeppelin/defender-sdk-base-client" "^1.14.4" + axios "^1.7.2" + lodash "^4.17.21" + +"@openzeppelin/defender-sdk-proposal-client@^1.14.4": + version "1.14.4" + resolved "https://registry.yarnpkg.com/@openzeppelin/defender-sdk-proposal-client/-/defender-sdk-proposal-client-1.14.4.tgz#fec7080fc7712e8c7daef923883ddbbdc20e76ee" + integrity sha512-xVI5A6wJb/XfqVAEkSsINrgGkNznw0eZL7CnzX1OUnZ4irrlaD4HpG/CkFgVWLx8tRIMFlUtb3as3KMc/sO8eg== + dependencies: + "@openzeppelin/defender-sdk-base-client" "^1.14.4" + axios "^1.7.2" ethers "^6.9.0" lodash "^4.17.21" -"@openzeppelin/defender-sdk-relay-client@^1.8.0": - version "1.8.0" - resolved "https://registry.yarnpkg.com/@openzeppelin/defender-sdk-relay-client/-/defender-sdk-relay-client-1.8.0.tgz#fafcc4687cabe44bf61c5613da22bcf20d0c8c0e" - integrity sha512-l50OmHl51Hnf5RMZHCVI1PBqb9Af5/DZJKefKqEMA2QpOwnY9gopeFcOsyPWS+d1EDHTUDrKpsFzpCifWWyxeA== +"@openzeppelin/defender-sdk-relay-client@^1.14.4": + version "1.14.4" + resolved "https://registry.yarnpkg.com/@openzeppelin/defender-sdk-relay-client/-/defender-sdk-relay-client-1.14.4.tgz#2649c5e7b237626df50943aef6001fb0ec18f08d" + integrity sha512-L+vPUeeg36muOy1Oh8wqNEJ8qXXQrFytYZerPS9N/Vf7TQBZoKUkuVq69dw7+XYq/ouqbppvAvUtV9SnyDkYpQ== dependencies: - "@openzeppelin/defender-sdk-base-client" "^1.8.0" - axios "^1.4.0" + "@openzeppelin/defender-sdk-base-client" "^1.14.4" + axios "^1.7.2" lodash "^4.17.21" -"@openzeppelin/defender-sdk-relay-signer-client@^1.8.0": - version "1.8.0" - resolved "https://registry.yarnpkg.com/@openzeppelin/defender-sdk-relay-signer-client/-/defender-sdk-relay-signer-client-1.8.0.tgz#c7825428c44e0b2c3912dc5817e3c65081de09f6" - integrity sha512-nZyIKk7dQHWVbtSEsr7zQWVaiX3Ftn/D9ucOCr0+tuWDM70UXrZ8uvLX3MfRPKpc8GAkZjBbUPMLcppLu3g8VQ== +"@openzeppelin/defender-sdk-relay-signer-client@^1.14.4": + version "1.14.4" + resolved "https://registry.yarnpkg.com/@openzeppelin/defender-sdk-relay-signer-client/-/defender-sdk-relay-signer-client-1.14.4.tgz#583b7a202ac5f619b5c4f954c42c2a85c0f39a32" + integrity sha512-zjVhor/LEHYG6Gf+GEFTrwsuGZjVbzqTqQew4X622FY38P13PpcEIdXDgbokqdlX8zpECcggD2kmTTDgVWRqjA== dependencies: "@ethersproject/bignumber" "^5.7.0" "@ethersproject/bytes" "^5.7.0" - "@ethersproject/contracts" "^5.7.0" "@ethersproject/logger" "^5.7.0" "@ethersproject/networks" "^5.7.1" "@ethersproject/properties" "^5.7.0" - "@ethersproject/random" "^5.7.0" + "@ethersproject/providers" "^5.7.2" "@ethersproject/strings" "^5.7.0" - "@openzeppelin/defender-sdk-base-client" "^1.8.0" + "@openzeppelin/defender-sdk-base-client" "^1.14.4" amazon-cognito-identity-js "^6.3.6" - axios "^1.4.0" + axios "^1.7.2" + ethers "^6.9.0" lodash "^4.17.21" "@openzeppelin/defender-sdk@^1.7.0": - version "1.8.0" - resolved "https://registry.yarnpkg.com/@openzeppelin/defender-sdk/-/defender-sdk-1.8.0.tgz#e5455d9eb29a2eb29089742e1f27cd2afa406ff0" - integrity sha512-aFlOLKqJgRcXa5u3uzAhz53BHAUP6S2kyWu4q5M7/9FsyXP6norqe8p6eH67aLuuAZzPzYN+t5M2ebarSW4fag== - dependencies: - "@openzeppelin/defender-sdk-account-client" "^1.8.0" - "@openzeppelin/defender-sdk-action-client" "^1.8.0" - "@openzeppelin/defender-sdk-base-client" "^1.8.0" - "@openzeppelin/defender-sdk-deploy-client" "^1.8.0" - "@openzeppelin/defender-sdk-monitor-client" "^1.8.0" - "@openzeppelin/defender-sdk-network-client" "^1.8.0" - "@openzeppelin/defender-sdk-notification-channel-client" "^1.8.0" - "@openzeppelin/defender-sdk-proposal-client" "^1.8.0" - "@openzeppelin/defender-sdk-relay-client" "^1.8.0" - "@openzeppelin/defender-sdk-relay-signer-client" "^1.8.0" - -"@openzeppelin/hardhat-upgrades@2.5.0": - version "2.5.0" - resolved "https://registry.yarnpkg.com/@openzeppelin/hardhat-upgrades/-/hardhat-upgrades-2.5.0.tgz#29b6bdc1a998bdc1672028586510e144ec25ae7e" - integrity sha512-pRsqyRbp8LX9sTSMbL7jx4NjqjN/4PlKngmuAyRQIheYTGbRIs3FW3WyLuiCjkDlTETfmOsmzrnZxJmxDmxZIA== - dependencies: - "@openzeppelin/defender-admin-client" "^1.52.0" - "@openzeppelin/defender-base-client" "^1.52.0" - "@openzeppelin/defender-sdk-base-client" "^1.5.0" - "@openzeppelin/defender-sdk-deploy-client" "^1.5.0" - "@openzeppelin/upgrades-core" "^1.31.2" + version "1.14.4" + resolved "https://registry.yarnpkg.com/@openzeppelin/defender-sdk/-/defender-sdk-1.14.4.tgz#e7953976fef682d28e3885a905bb70397f028bb0" + integrity sha512-QFXvqeLzfFxyRq5bw+7h2pq65pztNKBUy0vtizdSeQMA6MZ5wqDyTu/8bziYdQH+BmKzMqYBgErJAmic2XCzZQ== + dependencies: + "@openzeppelin/defender-sdk-account-client" "^1.14.4" + "@openzeppelin/defender-sdk-action-client" "^1.14.4" + "@openzeppelin/defender-sdk-base-client" "^1.14.4" + "@openzeppelin/defender-sdk-deploy-client" "^1.14.4" + "@openzeppelin/defender-sdk-key-value-store-client" "^1.14.4" + "@openzeppelin/defender-sdk-monitor-client" "^1.14.4" + "@openzeppelin/defender-sdk-network-client" "^1.14.4" + "@openzeppelin/defender-sdk-notification-channel-client" "^1.14.4" + "@openzeppelin/defender-sdk-proposal-client" "^1.14.4" + "@openzeppelin/defender-sdk-relay-client" "^1.14.4" + "@openzeppelin/defender-sdk-relay-signer-client" "^1.14.4" + +"@openzeppelin/hardhat-upgrades@^3.1.1", "@openzeppelin/hardhat-upgrades@^3.3.0": + version "3.4.0" + resolved "https://registry.yarnpkg.com/@openzeppelin/hardhat-upgrades/-/hardhat-upgrades-3.4.0.tgz#a67e9510c5c6a8ebb2534458164bd168cf4cb6b1" + integrity sha512-bfPtUCmRT6kfh/Mz56tAAGS8N22Zr3rdCMG3E3g8CW61QRGsaeFHnZRetBgu1JoKocjCavEtis5/x60m+o5XUQ== + dependencies: + "@openzeppelin/defender-sdk-base-client" "^1.14.4" + "@openzeppelin/defender-sdk-deploy-client" "^1.14.4" + "@openzeppelin/defender-sdk-network-client" "^1.14.4" + "@openzeppelin/upgrades-core" "^1.38.0" chalk "^4.1.0" debug "^4.1.1" ethereumjs-util "^7.1.5" proper-lockfile "^4.1.1" - undici "^5.14.0" + undici "^6.11.1" -"@openzeppelin/upgrades-core@^1.31.2": - version "1.32.3" - resolved "https://registry.yarnpkg.com/@openzeppelin/upgrades-core/-/upgrades-core-1.32.3.tgz#7f92aeab6f6c7300c8fa4c1cde14253b2bd62341" - integrity sha512-v04RbrBOTRiIhfkTRfY4M34I2wIcuz+K1cUk/6duulsMXvRpM6/IPWeXh+1Xr1K+xedJi7gcS/pNSXfYhYNXIg== +"@openzeppelin/upgrades-core@^1.32.2", "@openzeppelin/upgrades-core@^1.38.0": + version "1.38.0" + resolved "https://registry.yarnpkg.com/@openzeppelin/upgrades-core/-/upgrades-core-1.38.0.tgz#883f3ff55a63122b329fd8b0107815411ed0fbdd" + integrity sha512-0kbc6Wd6S8/Kmhg7oqRIn+GBpAL+EccYQh+SjgVBEktpkzTDN56KHuuxYHXnpXclWaO6l7u/TRMe6LsHCHqJHw== dependencies: + "@nomicfoundation/slang" "^0.17.0" cbor "^9.0.0" chalk "^4.1.0" compare-versions "^6.0.0" debug "^4.1.1" ethereumjs-util "^7.0.3" + minimatch "^9.0.5" minimist "^1.2.7" proper-lockfile "^4.1.1" solidity-ast "^0.4.51" @@ -1419,6 +1430,11 @@ resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== +"@pkgr/core@^0.1.0": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@pkgr/core/-/core-0.1.1.tgz#1ec17e2edbec25c8306d424ecfbf13c7de1aaa31" + integrity sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA== + "@pnpm/config.env-replace@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz#ab29da53df41e8948a00f2433f085f54de8b3a4c" @@ -1432,18 +1448,23 @@ graceful-fs "4.2.10" "@pnpm/npm-conf@^2.1.0": - version "2.2.2" - resolved "https://registry.yarnpkg.com/@pnpm/npm-conf/-/npm-conf-2.2.2.tgz#0058baf1c26cbb63a828f0193795401684ac86f0" - integrity sha512-UA91GwWPhFExt3IizW6bOeY/pQ0BkuNwKjk9iQW9KqxluGCrg4VenZ0/L+2Y0+ZOtme72EVvg6v0zo3AMQRCeA== + version "2.3.1" + resolved "https://registry.yarnpkg.com/@pnpm/npm-conf/-/npm-conf-2.3.1.tgz#bb375a571a0bd63ab0a23bece33033c683e9b6b0" + integrity sha512-c83qWb22rNRuB0UaVCI0uRPNRr8Z0FWnEIvT47jiHAmOIUHbBOg5XvV7pM5x+rKn9HRpjxquDbXYSXr3fAKFcw== dependencies: "@pnpm/config.env-replace" "^1.1.0" "@pnpm/network.ca-file" "^1.0.1" config-chain "^1.1.11" -"@scure/base@~1.1.0", "@scure/base@~1.1.4": - version "1.1.5" - resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.5.tgz#1d85d17269fe97694b9c592552dd9e5e33552157" - integrity sha512-Brj9FiG2W1MRQSTB212YVPRrcbjkv48FoZi/u4l/zds/ieRrqsh7aUf6CLwkAq61oKXr/ZlTzlY66gLIj3TFTQ== +"@rtsao/scc@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@rtsao/scc/-/scc-1.1.0.tgz#927dd2fae9bc3361403ac2c7a00c32ddce9ad7e8" + integrity sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g== + +"@scure/base@~1.1.0", "@scure/base@~1.1.6": + version "1.1.9" + resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.9.tgz#e5e142fbbfe251091f9c5f1dd4c834ac04c3dbd1" + integrity sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg== "@scure/bip32@1.1.5": version "1.1.5" @@ -1454,14 +1475,14 @@ "@noble/secp256k1" "~1.7.0" "@scure/base" "~1.1.0" -"@scure/bip32@1.3.3": - version "1.3.3" - resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.3.3.tgz#a9624991dc8767087c57999a5d79488f48eae6c8" - integrity sha512-LJaN3HwRbfQK0X1xFSi0Q9amqOgzQnnDngIt+ZlsBC3Bm7/nE7K0kwshZHyaru79yIVRv/e1mQAjZyuZG6jOFQ== +"@scure/bip32@1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.4.0.tgz#4e1f1e196abedcef395b33b9674a042524e20d67" + integrity sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg== dependencies: - "@noble/curves" "~1.3.0" - "@noble/hashes" "~1.3.2" - "@scure/base" "~1.1.4" + "@noble/curves" "~1.4.0" + "@noble/hashes" "~1.4.0" + "@scure/base" "~1.1.6" "@scure/bip39@1.1.1": version "1.1.1" @@ -1471,13 +1492,13 @@ "@noble/hashes" "~1.2.0" "@scure/base" "~1.1.0" -"@scure/bip39@1.2.2": - version "1.2.2" - resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.2.2.tgz#f3426813f4ced11a47489cbcf7294aa963966527" - integrity sha512-HYf9TUXG80beW+hGAt3TRM8wU6pQoYur9iNypTROm42dorCGmLnFe3eWjz3gOq6G62H2WRh0FCzAR1PI+29zIA== +"@scure/bip39@1.3.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.3.0.tgz#0f258c16823ddd00739461ac31398b4e7d6a18c3" + integrity sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ== dependencies: - "@noble/hashes" "~1.3.2" - "@scure/base" "~1.1.4" + "@noble/hashes" "~1.4.0" + "@scure/base" "~1.1.6" "@semantic-release/commit-analyzer@^10.0.0": version "10.0.4" @@ -1675,17 +1696,17 @@ resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-5.6.0.tgz#41dd6093d34652cddb5d5bdeee04eafc33826668" integrity sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g== -"@sindresorhus/merge-streams@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@sindresorhus/merge-streams/-/merge-streams-1.0.0.tgz#9cd84cc15bc865a5ca35fcaae198eb899f7b5c90" - integrity sha512-rUV5WyJrJLoloD4NDN1V1+LDMDWOa4OTsT4yYJwQNpTU6FWxkxHpL7eu4w+DmiH8x/EAM1otkPE1+LaspIbplw== +"@sindresorhus/merge-streams@^2.1.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz#719df7fb41766bc143369eaa0dd56d8dc87c9958" + integrity sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg== -"@smithy/types@^2.9.1": - version "2.9.1" - resolved "https://registry.yarnpkg.com/@smithy/types/-/types-2.9.1.tgz#ed04d4144eed3b8bd26d20fc85aae8d6e357ebb9" - integrity sha512-vjXlKNXyprDYDuJ7UW5iobdmyDm6g8dDG+BFUncAg/3XJaN45Gy5RWWWUVgrzIK7S4R1KWgIX5LeJcfvSI24bw== +"@smithy/types@^3.4.2": + version "3.4.2" + resolved "https://registry.yarnpkg.com/@smithy/types/-/types-3.4.2.tgz#aa2d087922d57205dbad68df8a45c848699c551e" + integrity sha512-tHiFcfcVedVBHpmHUEUHOCCih8iZbIAYn9NvPsNzaPm/237I3imdDdZoOC8c87H5HBAVEa06tTgb+OcSWV9g5w== dependencies: - tslib "^2.5.0" + tslib "^2.6.2" "@solidity-parser/parser@^0.14.0": version "0.14.5" @@ -1694,13 +1715,6 @@ dependencies: antlr4ts "^0.5.0-alpha.4" -"@solidity-parser/parser@^0.16.0": - version "0.16.2" - resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.16.2.tgz#42cb1e3d88b3e8029b0c9befff00b634cd92d2fa" - integrity sha512-PI9NfoA3P8XK2VBkK5oIfRgKDsicwDZfkVq9ZTBCQYGOP1N2owgY2dyLGyU5/J/hQs8KRk55kdmvTLjy3Mu3vg== - dependencies: - antlr4ts "^0.5.0-alpha.4" - "@solidity-parser/parser@^0.18.0": version "0.18.0" resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.18.0.tgz#8e77a02a09ecce957255a2f48c9a7178ec191908" @@ -1713,21 +1727,50 @@ dependencies: defer-to-connect "^2.0.1" -"@tenderly/hardhat-tenderly@^2.0.1": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@tenderly/hardhat-tenderly/-/hardhat-tenderly-2.1.0.tgz#20036426da8f11a5d8860703ef64cdb9086cc98d" - integrity sha512-wy6WnvrT4fxqTsln5DH3MgT+lvUV7AyqHVtSyGJgQh6NX0Q59ZXKoqedB8Hi3IkYMOhbjbPFlR0Z/zr8sYGEzQ== +"@tenderly/api-client@^1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@tenderly/api-client/-/api-client-1.0.1.tgz#0238bf5cc48e9a87a8f4b4c4a13743aab8721ea8" + integrity sha512-u/982299rccyvkuGuyM93AxnGXFHpIs8ZozD+E8gXHIRxLPyz/rZW/mjrcOGW9EBJwCvimVpLKcdDTKQ+DJTlQ== dependencies: - "@ethersproject/bignumber" "^5.7.0" - "@nomicfoundation/hardhat-ethers" "^3.0.4" axios "^0.27.2" - ethers "^6.8.1" + cli-table3 "^0.6.2" + commander "^9.4.0" + dotenv "^16.4.5" + js-yaml "^4.1.0" + open "^8.4.0" + prompts "^2.4.2" + tslog "^4.4.0" + +"@tenderly/hardhat-integration@^1.0.0": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@tenderly/hardhat-integration/-/hardhat-integration-1.0.2.tgz#639519ad1d47bf11bf68d34a30355a50ed85130f" + integrity sha512-ZcmorNYGEdmNJ2SVZx90bpOcK43Ay6fOAJem+qbL3o8iRlxfcDvr72kTBq7Ed/CPyfvLWBVwcyGxQIsQWNMruQ== + dependencies: + "@tenderly/api-client" "^1.0.0" + axios "^1.6.7" + dotenv "^16.4.5" fs-extra "^10.1.0" hardhat-deploy "^0.11.43" - tenderly "^0.8.0" + npm-registry-fetch "^17.1.0" + semver "^7.6.3" ts-node "^10.9.1" tslog "^4.3.1" - typescript "^5.2.2" + typescript "^5.5.4" + +"@tenderly/hardhat-tenderly@^2.0.1": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@tenderly/hardhat-tenderly/-/hardhat-tenderly-2.4.0.tgz#c1a7e5fc4a88323169253f24a9c0d7acc61bf1b9" + integrity sha512-WbKdjJ03JK2lTjtkNorOQiN6QRqzBkCUbkPcxfYAJHEaQSfIEZrP9Ui7mFl1quP9L5mFfu8PFZtXcxzzHGIBWA== + dependencies: + "@ethersproject/bignumber" "^5.7.0" + "@nomicfoundation/hardhat-ethers" "^3.0.0" + "@nomicfoundation/hardhat-ignition" "^0.15.5" + "@nomicfoundation/hardhat-verify" "^2.0.8" + "@openzeppelin/hardhat-upgrades" "^3.3.0" + "@openzeppelin/upgrades-core" "^1.32.2" + "@tenderly/hardhat-integration" "^1.0.0" + dotenv "^16.4.5" + ethers "^6.8.1" "@tootallnate/once@2": version "2.0.0" @@ -1735,9 +1778,9 @@ integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== "@tsconfig/node10@^1.0.7": - version "1.0.9" - resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2" - integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA== + version "1.0.11" + resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.11.tgz#6ee46400685f130e278128c7b38b7e031ff5b2f2" + integrity sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw== "@tsconfig/node12@^1.0.7": version "1.0.11" @@ -1790,9 +1833,9 @@ "@types/node" "*" "@types/bn.js@^5.1.0": - version "5.1.5" - resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.5.tgz#2e0dacdcce2c0f16b905d20ff87aedbc6f7b4bf0" - integrity sha512-V46N0zwKRF5Q00AZ6hWtN0T8gGmDUaUzLWQvHFo5yThtVwK/VCenFY3wXVbOvNfajEpsTfQM4IN9k/d6gUVX3A== + version "5.1.6" + resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.6.tgz#9ba818eec0c85e4d3c679518428afdf611d03203" + integrity sha512-Xh8vSwUeMKeYYrj3cX4lGQgFSF/N03r+tv4AiLl1SucqV+uTQpxRcnM8AkXKHwYP9ZPXOYXRr2KPXpVlIvqh9w== dependencies: "@types/node" "*" @@ -1803,10 +1846,15 @@ dependencies: "@types/chai" "*" -"@types/chai@*", "@types/chai@^4.3.11": - version "4.3.11" - resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.11.tgz#e95050bf79a932cb7305dd130254ccdf9bde671c" - integrity sha512-qQR1dr2rGIHYlJulmr8Ioq3De0Le9E4MJ5AiaeAETJJpndT1uUNHsGFK3L/UIu+rbkQSdj8J/w2bCsBZc/Y5fQ== +"@types/chai@*": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@types/chai/-/chai-5.0.0.tgz#7f981e71e69c9b2d422f58f78de1c59179782133" + integrity sha512-+DwhEHAaFPPdJ2ral3kNHFQXnTfscEEFsUxzD+d7nlcLrFK23JtNjH71RGasTcHb88b4vVi4mTyfpf8u2L8bdA== + +"@types/chai@^4.3.11": + version "4.3.20" + resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.20.tgz#cb291577ed342ca92600430841a00329ba05cecc" + integrity sha512-/pC9HAB5I/xMlc5FP77qjCnI16ChlJfW0tGa0IUcFn38VJrTV6DeZ60NU5KZBtaOZqjdpwTWohz5HU1RrhiYxQ== "@types/concat-stream@^1.6.0": version "1.6.1" @@ -1866,11 +1914,11 @@ integrity sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw== "@types/node@*": - version "20.11.10" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.11.10.tgz#6c3de8974d65c362f82ee29db6b5adf4205462f9" - integrity sha512-rZEfe/hJSGYmdfX9tvcPMYeYPW2sNl50nsw4jZmRcaG0HIAb0WYEpsB05GOb53vjqpyE9GUhlDQ4jLSoB5q9kg== + version "22.7.3" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.7.3.tgz#7ddf1ddf13078692b4cfadb835852b2a718ee1ef" + integrity sha512-qXKfhXXqGTyBskvWEzJZPUxSslAiLaB6JGP1ic/XTH9ctGgzdgYguuLP1C601aRTSDNlLb0jbKqXjZ48GNraSA== dependencies: - undici-types "~5.26.4" + undici-types "~6.19.2" "@types/node@18.15.13": version "18.15.13" @@ -1883,9 +1931,9 @@ integrity sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw== "@types/node@^18.15.11": - version "18.19.10" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.19.10.tgz#4de314ab66faf6bc8ba691021a091ddcdf13a158" - integrity sha512-IZD8kAM02AW1HRDTPOlz3npFava678pr8Ie9Vp8uRhBROXAv8MXT2pCnGZZAKYdromsNQLHQcfWQ6EOatVLtqA== + version "18.19.53" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.19.53.tgz#1e2f83eeede6031f03bc4780826b8b02b42ac50d" + integrity sha512-GLxgUgHhDKO1Edw9Q0lvMbiO/IQXJwJlMaqxSGBXMpPy8uhkCs2iiPFaB2Q/gmobnFkckD3rqTBMVjXdwq+nKg== dependencies: undici-types "~5.26.4" @@ -1912,17 +1960,9 @@ integrity sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA== "@types/qs@^6.2.31", "@types/qs@^6.9.7": - version "6.9.11" - resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.11.tgz#208d8a30bc507bd82e03ada29e4732ea46a6bbda" - integrity sha512-oGk0gmhnEJK4Yyk+oI7EfXsLayXatCWPHary1MtcmbAifkobT9cM9yutG/hZKIseOU0MqbIwQ/u2nn/Gb+ltuQ== - -"@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" + version "6.9.16" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.16.tgz#52bba125a07c0482d26747d5d4947a64daf8f794" + integrity sha512-7i+zxXdPD0T4cKDuxCUXJ4wHcsJLwENa6Z3dCu8cfCK743OGy5Nu1RmAGqDPsoTDINVEcdXKRvR/zre+P2Ku1A== "@types/secp256k1@^4.0.1": version "4.0.6" @@ -1932,9 +1972,9 @@ "@types/node" "*" "@types/semver@^7.3.12": - version "7.5.6" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.6.tgz#c65b2bfce1bec346582c07724e3f8c1017a20339" - integrity sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A== + version "7.5.8" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.8.tgz#8268a8c57a3e4abd25c165ecd36237db7948a55e" + integrity sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ== "@types/triple-beam@^1.3.2": version "1.3.5" @@ -1947,9 +1987,9 @@ integrity sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA== "@types/whatwg-url@^11.0.2": - version "11.0.4" - resolved "https://registry.yarnpkg.com/@types/whatwg-url/-/whatwg-url-11.0.4.tgz#ffed0dc8d89d91f62e3f368fcbda222a487c4f63" - integrity sha512-lXCmTWSHJvf0TRSO58nm978b8HJ/EdsSsEKLd3ODHFjo+3VGAyyTp4v50nWvwtzBxSMQrVOK7tcuN0zGPLICMw== + version "11.0.5" + resolved "https://registry.yarnpkg.com/@types/whatwg-url/-/whatwg-url-11.0.5.tgz#aaa2546e60f0c99209ca13360c32c78caf2c409f" + integrity sha512-coYR071JRaHa+xoEvvYqvnIHaVqaYrLPbsufM9BF63HkwI5Lgmy2QR8Q5K/lYDYo5AK82wOvSOS0UsLTpTG7uQ== dependencies: "@types/webidl-conversions" "*" @@ -2042,10 +2082,10 @@ resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== -"@zero-tech/eslint-config-cpt@0.2.7": - version "0.2.7" - resolved "https://registry.yarnpkg.com/@zero-tech/eslint-config-cpt/-/eslint-config-cpt-0.2.7.tgz#ec1d94848737863a8c9b9e226fd586b7f8a97346" - integrity sha512-reFmMkcPBjkQgq2hD5FDWfuGIl4dWvKoIdigq3zS375QNLAqQwuY2EPK2RRLQw7Qcw8nTvPFfv4Gwu2fm8yVfQ== +"@zero-tech/eslint-config-cpt@0.2.8": + version "0.2.8" + resolved "https://registry.yarnpkg.com/@zero-tech/eslint-config-cpt/-/eslint-config-cpt-0.2.8.tgz#f4b69187e65f61d519c77755f5ae0963efeb5c9d" + integrity sha512-i5v/tl6Nv23gM8HGXJiiYh5NaL1guARDtka2cx7T6K7g41zd9NZPynHQeGHHtv3zvcFG/hP5J8uS7O3k4DpplA== dependencies: "@typescript-eslint/eslint-plugin" "^5.57.1" "@typescript-eslint/parser" "^5.57.1" @@ -2053,24 +2093,24 @@ eslint-config-airbnb "^19.0.4" eslint-config-airbnb-base "^15.0.0" eslint-plugin-import "^2.27.5" - eslint-plugin-jsdoc "^40.1.1" + eslint-plugin-jsdoc "^50.3.0" eslint-plugin-prefer-arrow "^1.2.3" typescript "^5.0.2" -"@zero-tech/zdc@0.1.3": - version "0.1.3" - resolved "https://registry.yarnpkg.com/@zero-tech/zdc/-/zdc-0.1.3.tgz#d62edf13234668b10ac33053b6002c9dc93a5922" - integrity sha512-0uZpRCq3/HrTU7I79EBcZyKbPv3ey5r9eyRLghCFEf6F1Pdn3xKZQkqwJQvsz0EZyR+p4AJz5jZE/bkdGucEig== +"@zero-tech/z-token@1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@zero-tech/z-token/-/z-token-1.0.0.tgz#ba56c7e269e399e029cca69d1d54357220a2d08f" + integrity sha512-hbUmgKZ6G4Z4dLzvI0SR5n/O6OaWpWh2utG5DHDZZd6P6G5HBdeELUKVVQxecTsPQY0GnVvevxaEoLBMcyW9Xw== + +"@zero-tech/zdc@0.1.6": + version "0.1.6" + resolved "https://registry.yarnpkg.com/@zero-tech/zdc/-/zdc-0.1.6.tgz#131d13a128c494b7b5d32c208f3afdb775bf3ba2" + integrity sha512-BemYIVUs95pk0fx/otWbtLGiCJyor0SNmNKH/46iNXoSzYdeCbPFx05GsXjAE6yhu9buwHybdDRXjSj/YcQpXg== dependencies: axios "^1.6.5" mongodb "^6.3.0" winston "^3.11.0" -"@zero-tech/ztoken@2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@zero-tech/ztoken/-/ztoken-2.0.0.tgz#42e2c2aa28ffbc64ce4340cf0464bcc22a155be5" - integrity sha512-t6eLaK3KFsMUZ8cD1OqAiLQgvfYvXSIsgvEwt6FPedT5h64s/5XbVc1MWW22DZ98HqmgcWyEUs3g1MBAG1orCQ== - JSONStream@^1.3.5: version "1.3.5" resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0" @@ -2094,38 +2134,22 @@ abbrev@^2.0.0: resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-2.0.0.tgz#cf59829b8b4f03f89dda2771cb7f3653828c89bf" integrity sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ== -abstract-level@^1.0.0, abstract-level@^1.0.2, abstract-level@^1.0.3, abstract-level@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/abstract-level/-/abstract-level-1.0.4.tgz#3ad8d684c51cc9cbc9cf9612a7100b716c414b57" - integrity sha512-eUP/6pbXBkMbXFdx4IH2fVgvB7M0JvR7/lIL33zcs0IBcwjdzSSl31TOJsaCzmKSSDF9h8QYSOJux4Nd4YJqFg== - 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" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== acorn-walk@^8.1.1: - version "8.3.2" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.2.tgz#7703af9415f1b6db9315d6895503862e231d34aa" - integrity sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A== - -acorn@^8.4.1, acorn@^8.9.0: - version "8.11.3" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.3.tgz#71e0b14e13a4ec160724b38fb7b0f233b1b81d7a" - integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg== + version "8.3.4" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.4.tgz#794dd169c3977edf4ba4ea47583587c5866236b7" + integrity sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g== + dependencies: + acorn "^8.11.0" -address@^1.0.1: - version "1.2.2" - resolved "https://registry.yarnpkg.com/address/-/address-1.2.2.tgz#2b5248dac5485a6390532c6a517fda2e3faac89e" - integrity sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA== +acorn@^8.11.0, acorn@^8.12.0, acorn@^8.4.1, acorn@^8.9.0: + version "8.12.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.12.1.tgz#71616bdccbe25e27a54439e0046e89ca76df2248" + integrity sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg== adm-zip@^0.4.16: version "0.4.16" @@ -2149,10 +2173,10 @@ agent-base@6, agent-base@^6.0.2: dependencies: debug "4" -agent-base@^7.0.2, agent-base@^7.1.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.0.tgz#536802b76bc0b34aa50195eb2442276d613e3434" - integrity sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg== +agent-base@^7.0.2, agent-base@^7.1.0, agent-base@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.1.tgz#bdbded7dfb096b751a2a087eeeb9664725b2e317" + integrity sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA== dependencies: debug "^4.3.4" @@ -2190,19 +2214,19 @@ ajv@^6.12.4, ajv@^6.12.6: uri-js "^4.2.2" ajv@^8.0.1: - version "8.12.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.12.0.tgz#d1a0527323e22f53562c567c00991577dfbe19d1" - integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== + version "8.17.1" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.17.1.tgz#37d9a5c776af6bc92d7f4f9510eba4c0a60d11a6" + integrity sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g== dependencies: - fast-deep-equal "^3.1.1" + fast-deep-equal "^3.1.3" + fast-uri "^3.0.1" json-schema-traverse "^1.0.0" require-from-string "^2.0.2" - uri-js "^4.2.2" -amazon-cognito-identity-js@^6.0.1, amazon-cognito-identity-js@^6.3.6: - version "6.3.7" - resolved "https://registry.yarnpkg.com/amazon-cognito-identity-js/-/amazon-cognito-identity-js-6.3.7.tgz#65c3d7ee4e0c0a1ffea01927248989c5bd1d1868" - integrity sha512-tSjnM7KyAeOZ7UMah+oOZ6cW4Gf64FFcc7BE2l7MTcp7ekAPrXaCbpcW2xEpH1EiDS4cPcAouHzmCuc2tr72vQ== +amazon-cognito-identity-js@^6.3.6: + version "6.3.12" + resolved "https://registry.yarnpkg.com/amazon-cognito-identity-js/-/amazon-cognito-identity-js-6.3.12.tgz#af73df033094ad4c679c19cf6122b90058021619" + integrity sha512-s7NKDZgx336cp+oDeUtB2ZzT8jWJp/v2LWuYl+LQtMEODe22RF1IJ4nRiDATp+rp1pTffCZcm44Quw4jx2bqNg== dependencies: "@aws-crypto/sha256-js" "1.2.2" buffer "4.9.2" @@ -2215,12 +2239,14 @@ amdefine@>=0.0.4: resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" integrity sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg== -ansi-colors@4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" - integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== +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: +ansi-colors@^4.1.1, ansi-colors@^4.1.3: version "4.1.3" resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b" integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== @@ -2233,11 +2259,9 @@ ansi-escapes@^4.3.0: type-fest "^0.21.3" ansi-escapes@^6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-6.2.0.tgz#8a13ce75286f417f1963487d86ba9f90dccf9947" - integrity sha512-kzRaCqXnpzWs+3z5ABPQiVke+iq0KXkHo8xiWV4RPTi5Yli0l97BEQuhXV1s7+aSU/fu1kUuxgS4MsQ0fRuygw== - dependencies: - type-fest "^3.0.0" + version "6.2.1" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-6.2.1.tgz#76c54ce9b081dad39acec4b5d53377913825fb0f" + integrity sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig== ansi-regex@^2.0.0: version "2.1.1" @@ -2255,9 +2279,9 @@ ansi-regex@^5.0.1: integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== ansi-regex@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" - integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== + version "6.1.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.1.0.tgz#95ec409c69619d6cb1b8b34f14b660ef28ebd654" + integrity sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA== ansi-styles@^3.2.1: version "3.2.1" @@ -2283,10 +2307,10 @@ ansicolors@~0.3.2: resolved "https://registry.yarnpkg.com/ansicolors/-/ansicolors-0.3.2.tgz#665597de86a9ffe3aa9bfbe6cae5c6ea426b4979" integrity sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg== -antlr4@^4.11.0: - version "4.13.1" - resolved "https://registry.yarnpkg.com/antlr4/-/antlr4-4.13.1.tgz#1e0a1830a08faeb86217cb2e6c34716004e4253d" - integrity sha512-kiXTspaRYvnIArgE97z5YVVf/cDVQABr3abFRR6mE7yesLMkgu4ujuyV/sgxafQ8wgve0DJQUJ38Z8tkgA2izA== +antlr4@^4.13.1-patch-1: + version "4.13.2" + resolved "https://registry.yarnpkg.com/antlr4/-/antlr4-4.13.2.tgz#0d084ad0e32620482a9c3a0e2470c02e72e4006d" + integrity sha512-QiVbZhyy4xAZ17UPEuG3YTOt8ZaoeOR1CvEAqrEsDBsOqINslaB147i9xqljZqoyf5S+EUlGStaj+t22LT9MOg== antlr4ts@^0.5.0-alpha.4: version "0.5.0-alpha.4" @@ -2311,6 +2335,11 @@ archy@~1.0.0: resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" integrity sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw== +are-docs-informative@^0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/are-docs-informative/-/are-docs-informative-0.0.2.tgz#387f0e93f5d45280373d387a59d34c96db321963" + integrity sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig== + are-we-there-yet@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz#679df222b278c64f2cdba1175cdc00b0d96164bd" @@ -2356,28 +2385,29 @@ array-back@^4.0.1, array-back@^4.0.2: resolved "https://registry.yarnpkg.com/array-back/-/array-back-4.0.2.tgz#8004e999a6274586beeb27342168652fdb89fa1e" integrity sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg== -array-buffer-byte-length@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz#fabe8bc193fea865f317fe7807085ee0dee5aead" - integrity sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A== +array-buffer-byte-length@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz#1e5583ec16763540a27ae52eed99ff899223568f" + integrity sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg== dependencies: - call-bind "^1.0.2" - is-array-buffer "^3.0.1" + call-bind "^1.0.5" + is-array-buffer "^3.0.4" array-ify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/array-ify/-/array-ify-1.0.0.tgz#9e528762b4a9066ad163a6962a364418e9626ece" integrity sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng== -array-includes@^3.1.7: - version "3.1.7" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.7.tgz#8cd2e01b26f7a3086cbc87271593fe921c62abda" - integrity sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ== +array-includes@^3.1.8: + version "3.1.8" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.8.tgz#5e370cbe172fdd5dd6530c1d4aadda25281ba97d" + integrity sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ== dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - get-intrinsic "^1.2.1" + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.2" + es-object-atoms "^1.0.0" + get-intrinsic "^1.2.4" is-string "^1.0.7" array-union@^2.1.0: @@ -2390,27 +2420,17 @@ array-uniq@1.0.3: resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" integrity sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q== -array.prototype.findlast@^1.2.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/array.prototype.findlast/-/array.prototype.findlast-1.2.3.tgz#4e4b375de5adf4897fed155e2d2771564865cc3b" - integrity sha512-kcBubumjciBg4JKp5KTKtI7ec7tRefPk88yjkWJwaVKYd9QfTaxcsOxoMNKd7iBr447zCfDV0z1kOF47umv42g== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - es-shim-unscopables "^1.0.0" - get-intrinsic "^1.2.1" - -array.prototype.findlastindex@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz#b37598438f97b579166940814e2c0493a4f50207" - integrity sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA== +array.prototype.findlastindex@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz#8c35a755c72908719453f87145ca011e39334d0d" + integrity sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ== dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - es-shim-unscopables "^1.0.0" - get-intrinsic "^1.2.1" + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.2" + es-errors "^1.3.0" + es-object-atoms "^1.0.0" + es-shim-unscopables "^1.0.2" array.prototype.flat@^1.3.2: version "1.3.2" @@ -2432,17 +2452,18 @@ array.prototype.flatmap@^1.3.2: es-abstract "^1.22.1" es-shim-unscopables "^1.0.0" -arraybuffer.prototype.slice@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz#98bd561953e3e74bb34938e77647179dfe6e9f12" - integrity sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw== +arraybuffer.prototype.slice@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz#097972f4255e41bc3425e37dc3f6421cf9aefde6" + integrity sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A== dependencies: - array-buffer-byte-length "^1.0.0" - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - get-intrinsic "^1.2.1" - is-array-buffer "^3.0.2" + array-buffer-byte-length "^1.0.1" + call-bind "^1.0.5" + define-properties "^1.2.1" + es-abstract "^1.22.3" + es-errors "^1.2.1" + get-intrinsic "^1.2.3" + is-array-buffer "^3.0.4" is-shared-array-buffer "^1.0.2" arrify@^1.0.1: @@ -2483,9 +2504,9 @@ async@1.x: integrity sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w== async@^3.2.3: - version "3.2.5" - resolved "https://registry.yarnpkg.com/async/-/async-3.2.5.tgz#ebd52a8fdaf7a2289a24df399f8d8485c8a46b66" - integrity sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg== + version "3.2.6" + resolved "https://registry.yarnpkg.com/async/-/async-3.2.6.tgz#1b0728e14929d51b85b449b7f06e27c1145e38ce" + integrity sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA== asynckit@^0.4.0: version "0.4.0" @@ -2497,10 +2518,12 @@ at-least-node@^1.0.0: resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== -available-typed-arrays@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" - integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== +available-typed-arrays@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz#a5cc375d6a03c2efc87a553f3e0b1522def14846" + integrity sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ== + dependencies: + possible-typed-array-names "^1.0.0" axios@^0.21.1: version "0.21.4" @@ -2517,12 +2540,12 @@ axios@^0.27.2: follow-redirects "^1.14.9" form-data "^4.0.0" -axios@^1.4.0, axios@^1.5.1, axios@^1.6.5: - version "1.6.7" - resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.7.tgz#7b48c2e27c96f9c68a2f8f31e2ab19f59b06b0a7" - integrity sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA== +axios@^1.4.0, axios@^1.5.1, axios@^1.6.5, axios@^1.6.7, axios@^1.7.2: + version "1.7.7" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.7.tgz#2f554296f9892a72ac8d8e4c5b79c14a91d0a47f" + integrity sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q== dependencies: - follow-redirects "^1.15.4" + follow-redirects "^1.15.6" form-data "^4.0.0" proxy-from-env "^1.1.0" @@ -2532,9 +2555,9 @@ balanced-match@^1.0.0: integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== base-x@^3.0.2, base-x@^3.0.8: - version "3.0.9" - resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.9.tgz#6349aaabb58526332de9f60995e548a53fe21320" - integrity sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ== + version "3.0.10" + resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.10.tgz#62de58653f8762b5d6f8d9fe30fa75f7b2585a75" + integrity sha512-7d0s06rR9rYaIWHkpfLIFICM/tkSVdoPC9qYAQRpxn9DdKNWNsKC0uk++akckyLq16Tx2WIinnZ6WRriAt6njQ== dependencies: safe-buffer "^5.0.1" @@ -2558,15 +2581,10 @@ big-integer@1.6.36: resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.36.tgz#78631076265d4ae3555c04f85e7d9d2f3a071a36" integrity sha512-t70bfa7HYEA1D9idDbmuv7YbsbVkQ+Hp+8KFSul4aE5e/i1bjCNIRYJZlA8Q8p0r9T8cF/RVvwUgRA//FydEyg== -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== - bin-links@^4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/bin-links/-/bin-links-4.0.3.tgz#9e4a3c5900830aee3d7f52178b65e01dcdde64a5" - integrity sha512-obsRaULtJurnfox/MDwgq6Yo9kzbv1CPTk/1/s7Z/61Lezc8IKkFCOXNeVLXz0456WRzBQmSsDWlai2tIhBsfA== + version "4.0.4" + resolved "https://registry.yarnpkg.com/bin-links/-/bin-links-4.0.4.tgz#c3565832b8e287c85f109a02a17027d152a58a63" + integrity sha512-cMtq4W5ZsEwcutJrVId+a/tjt8GSbS+h0oNkdl6+6rBuEv8Ot33Bevj5KPm40t309zuhVic8NjpuL42QCiJWWA== dependencies: cmd-shim "^6.0.0" npm-normalize-package-bin "^3.0.0" @@ -2574,9 +2592,9 @@ bin-links@^4.0.1: write-file-atomic "^5.0.0" binary-extensions@^2.0.0, binary-extensions@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" - integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + version "2.3.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522" + integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw== blakejs@^1.1.0: version "1.2.1" @@ -2608,6 +2626,20 @@ bottleneck@^2.15.3: resolved "https://registry.yarnpkg.com/bottleneck/-/bottleneck-2.19.5.tgz#5df0b90f59fd47656ebe63c78a98419205cadd91" integrity sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw== +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" @@ -2623,29 +2655,19 @@ brace-expansion@^2.0.1: dependencies: balanced-match "^1.0.0" -braces@^3.0.2, braces@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== +braces@^3.0.3, braces@~3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" + integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== dependencies: - fill-range "^7.0.1" + fill-range "^7.1.1" brorand@^1.1.0: version "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: +browser-stdout@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== @@ -2678,10 +2700,10 @@ bs58check@^2.1.2: create-hash "^1.1.0" safe-buffer "^5.1.2" -bson@^6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/bson/-/bson-6.2.0.tgz#4b6acafc266ba18eeee111373c2699304a9ba0a3" - integrity sha512-ID1cI+7bazPDyL9wYy9GaQ8gEEohWvcUl/Yf0dIdutJxnmInEEyCsb4awy/OiBfall7zBA179Pahi3vCdFze3Q== +bson@^6.7.0: + version "6.8.0" + resolved "https://registry.yarnpkg.com/bson/-/bson-6.8.0.tgz#5063c41ba2437c2b8ff851b50d9e36cb7aaa7525" + integrity sha512-iOJg8pr7wq2tg/zSlCCHMi3hMm5JTOxLTagf3zxhcenHsFp+c6uOs6K7W5UE7A4QIJGtqh/ZovFNMP4mOPJynQ== buffer-from@^1.0.0: version "1.1.2" @@ -2702,7 +2724,7 @@ buffer@4.9.2: ieee754 "^1.1.4" isarray "^1.0.0" -buffer@6.0.3, buffer@^6.0.3: +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== @@ -2718,13 +2740,6 @@ buffer@^5.5.0, buffer@^5.6.0: base64-js "^1.3.1" ieee754 "^1.1.13" -builtins@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/builtins/-/builtins-5.0.1.tgz#87f6db9ab0458be728564fa81d876d8d74552fa9" - integrity sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ== - dependencies: - semver "^7.0.0" - bytes@3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" @@ -2754,7 +2769,7 @@ cacache@^16.1.0: tar "^6.1.11" unique-filename "^2.0.0" -cacache@^17.0.0, cacache@^17.0.4, cacache@^17.1.3: +cacache@^17.0.0, cacache@^17.0.4, cacache@^17.1.4: version "17.1.4" resolved "https://registry.yarnpkg.com/cacache/-/cacache-17.1.4.tgz#b3ff381580b47e85c6e64f801101508e26604b35" integrity sha512-/aJwG2l3ZMJ1xNAnqbMpA40of9dj/pIH3QfiuQSqjfPJF747VR0J/bHn+/KdNnHKc6XQcWt/AfRSBft82W1d2A== @@ -2772,6 +2787,24 @@ cacache@^17.0.0, cacache@^17.0.4, cacache@^17.1.3: tar "^6.1.11" unique-filename "^3.0.0" +cacache@^18.0.0: + version "18.0.4" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-18.0.4.tgz#4601d7578dadb59c66044e157d02a3314682d6a5" + integrity sha512-B+L5iIa9mgcjLbliir2th36yEwPftrzteHYujzsx3dFP/31GCHcIeS8f5MGd80odLOjaOvSpU3EEAmRQptkxLQ== + dependencies: + "@npmcli/fs" "^3.1.0" + fs-minipass "^3.0.0" + glob "^10.2.2" + lru-cache "^10.0.1" + minipass "^7.0.3" + minipass-collect "^2.0.1" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.4" + p-map "^4.0.0" + ssri "^10.0.0" + tar "^6.1.11" + unique-filename "^3.0.0" + cacheable-lookup@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz#3476a8215d046e5a3202a9209dd13fec1f933a27" @@ -2790,14 +2823,16 @@ cacheable-request@^10.2.8: normalize-url "^8.0.0" responselike "^3.0.0" -call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.4, call-bind@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.5.tgz#6fa2b7845ce0ea49bf4d8b9ef64727a2c2e2e513" - integrity sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ== +call-bind@^1.0.2, call-bind@^1.0.5, call-bind@^1.0.6, call-bind@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9" + integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w== dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" function-bind "^1.1.2" - get-intrinsic "^1.2.1" - set-function-length "^1.1.1" + get-intrinsic "^1.2.4" + set-function-length "^1.2.1" callsites@^3.0.0: version "3.1.0" @@ -2823,7 +2858,7 @@ camelcase@^5.3.1: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== -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== @@ -2836,21 +2871,11 @@ cardinal@^2.1.1: ansicolors "~0.3.2" redeyed "~2.1.0" -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" @@ -2859,23 +2884,23 @@ cbor@^8.1.0: nofilter "^3.1.0" cbor@^9.0.0: - version "9.0.1" - resolved "https://registry.yarnpkg.com/cbor/-/cbor-9.0.1.tgz#b16e393d4948d44758cd54ac6151379d443b37ae" - integrity sha512-/TQOWyamDxvVIv+DY9cOLNuABkoyz8K/F3QE56539pGVYohx0+MEA1f4lChFTX79dBTBS7R1PF6ovH7G+VtBfQ== + version "9.0.2" + resolved "https://registry.yarnpkg.com/cbor/-/cbor-9.0.2.tgz#536b4f2d544411e70ec2b19a2453f10f83cd9fdb" + integrity sha512-JPypkxsB10s9QOWwa6zwPzqE1Md3vqpPc+cai4sAecuCsRyAtAl/pMyhPlMbT/xtPnm2dznJZYRLui57qiRhaQ== dependencies: nofilter "^3.1.0" chai-as-promised@^7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/chai-as-promised/-/chai-as-promised-7.1.1.tgz#08645d825deb8696ee61725dbf590c012eb00ca0" - integrity sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA== + version "7.1.2" + resolved "https://registry.yarnpkg.com/chai-as-promised/-/chai-as-promised-7.1.2.tgz#70cd73b74afd519754161386421fb71832c6d041" + integrity sha512-aBDHZxRzYnUYuIAIPBH2s511DjlKPzXNlXSGFC8CwmroWQLfrW0LtE1nK3MAwwNhJPa9raEjNCmRoFpG0Hurdw== dependencies: check-error "^1.0.2" chai@^4.3.10: - version "4.4.1" - resolved "https://registry.yarnpkg.com/chai/-/chai-4.4.1.tgz#3603fa6eba35425b0f2ac91a009fe924106e50d1" - integrity sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g== + version "4.5.0" + resolved "https://registry.yarnpkg.com/chai/-/chai-4.5.0.tgz#707e49923afdd9b13a8b0b47d33d732d13812fd8" + integrity sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw== dependencies: assertion-error "^1.1.0" check-error "^1.0.3" @@ -2883,7 +2908,7 @@ chai@^4.3.10: get-func-name "^2.0.2" loupe "^2.3.6" pathval "^1.1.1" - type-detect "^4.0.8" + type-detect "^4.1.0" chalk@^2.3.2, chalk@^2.4.2: version "2.4.2" @@ -2919,10 +2944,10 @@ check-error@^1.0.2, check-error@^1.0.3: dependencies: get-func-name "^2.0.2" -chokidar@3.5.3, chokidar@^3.4.0, chokidar@^3.5.2: - version "3.5.3" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" - integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== +chokidar@^3.5.2, chokidar@^3.5.3: + version "3.6.0" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b" + integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw== dependencies: anymatch "~3.1.2" braces "~3.0.2" @@ -2934,6 +2959,13 @@ chokidar@3.5.3, chokidar@^3.4.0, chokidar@^3.5.2: optionalDependencies: fsevents "~2.3.2" +chokidar@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-4.0.1.tgz#4a6dff66798fb0f72a94f616abbd7e1a19f31d41" + integrity sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA== + dependencies: + readdirp "^4.0.1" + chownr@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" @@ -2944,10 +2976,10 @@ ci-info@^2.0.0: resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== -ci-info@^3.6.1, ci-info@^3.7.1, ci-info@^3.8.0: - version "3.9.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.9.0.tgz#4279a62028a7b1f262f3473fc9605f5e218c59b4" - integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ== +ci-info@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-4.0.0.tgz#65466f8b280fc019b9f50a5388115d17a63a44f2" + integrity sha512-TdHqgGf9odd8SXNuxtUBVx8Nv+qZOejE6qyqiy5NtbYYQOeFa6zmHkxlPzmaLxWWHsU6nJmB7AETdVPi+2NBUg== cidr-regex@^3.1.1: version "3.1.1" @@ -2980,17 +3012,6 @@ class-is@^1.1.0: resolved "https://registry.yarnpkg.com/class-is/-/class-is-1.1.0.tgz#9d3c0fba0440d211d843cec3dedfa48055005825" integrity sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw== -classic-level@^1.2.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/classic-level/-/classic-level-1.4.1.tgz#169ecf9f9c6200ad42a98c8576af449c1badbaee" - integrity sha512-qGx/KJl3bvtOHrGau2WklEZuXhS3zme+jf+fsu6Ej7W7IP/C49v7KNlWIsT1jZu0YnfzSIYDGcEWpCa1wKGWXQ== - 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" @@ -3003,6 +3024,11 @@ clean-stack@^5.2.0: dependencies: escape-string-regexp "5.0.0" +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-columns@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/cli-columns/-/cli-columns-4.0.0.tgz#9fe4d65975238d55218c41bd2ed296a7fa555646" @@ -3022,9 +3048,9 @@ cli-table3@^0.5.0: colors "^1.1.2" cli-table3@^0.6.2, cli-table3@^0.6.3: - version "0.6.3" - resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.6.3.tgz#61ab765aac156b52f222954ffc607a6f01dbeeb2" - integrity sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg== + version "0.6.5" + resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.6.5.tgz#013b91351762739c16a9567c21a04632e449bf2f" + integrity sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ== dependencies: string-width "^4.2.0" optionalDependencies: @@ -3063,9 +3089,9 @@ clone@^1.0.2: integrity sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg== cmd-shim@^6.0.0: - version "6.0.2" - resolved "https://registry.yarnpkg.com/cmd-shim/-/cmd-shim-6.0.2.tgz#435fd9e5c95340e61715e19f90209ed6fcd9e0a4" - integrity sha512-+FFYbB0YLaAkhkcrjkyNLYDiOsFSfRjwjY19LXk/psmMx1z00xlCv7hhQoTGXXIKi+YXHL/iiFo8NqMVQX9nOw== + version "6.0.3" + resolved "https://registry.yarnpkg.com/cmd-shim/-/cmd-shim-6.0.3.tgz#c491e9656594ba17ac83c4bd931590a9d6e26033" + integrity sha512-FMabTRlc5t5zjdenF6mS0MBeFZm0XqHqeOkcskKFb/LYCcRQ5fVgLOHVc4Lq9CqABd9zhjwPjMBCJvMCziSVtA== code-point-at@^1.0.0: version "1.1.0" @@ -3170,25 +3196,25 @@ command-line-usage@^6.1.0: table-layout "^1.0.2" typical "^5.2.0" -commander@3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/commander/-/commander-3.0.2.tgz#6837c3fb677ad9933d1cfba42dd14d5117d6b39e" - integrity sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow== - commander@^10.0.0: version "10.0.1" resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06" integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug== +commander@^8.1.0: + version "8.3.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" + integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== + commander@^9.4.0: version "9.5.0" resolved "https://registry.yarnpkg.com/commander/-/commander-9.5.0.tgz#bc08d1eb5cedf7ccb797a96199d41c7bc3e60d30" integrity sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ== -comment-parser@1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/comment-parser/-/comment-parser-1.3.1.tgz#3d7ea3adaf9345594aedee6563f422348f165c1b" - integrity sha512-B52sN2VNghyq5ofvUsqZjmk6YkihBX5vMSChmSK9v4ShjKf3Vk5Xcmgpw4o+iIgtrnM/u5FiMpz9VKb8lpBveA== +comment-parser@1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/comment-parser/-/comment-parser-1.4.1.tgz#bdafead37961ac079be11eb7ec65c4d021eaf9cc" + integrity sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg== common-ancestor-path@^1.0.1: version "1.0.1" @@ -3204,9 +3230,9 @@ compare-func@^2.0.0: dot-prop "^5.1.0" compare-versions@^6.0.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-6.1.0.tgz#3f2131e3ae93577df111dba133e6db876ffe127a" - integrity sha512-LNZQXhqUvqUTotpZ00qLSaify3b4VFD588aRr8MKFw4CMUr98ytzCW5wDH5qx/DEY5kCDXcbcRuCqL0szEf2tg== + version "6.1.1" + resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-6.1.1.tgz#7af3cc1099ba37d244b3145a9af5201b629148a9" + integrity sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg== concat-map@0.0.1: version "0.0.1" @@ -3313,11 +3339,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" @@ -3385,6 +3406,33 @@ cssesc@^3.0.0: resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== +data-view-buffer@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/data-view-buffer/-/data-view-buffer-1.0.1.tgz#8ea6326efec17a2e42620696e671d7d5a8bc66b2" + integrity sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA== + dependencies: + call-bind "^1.0.6" + es-errors "^1.3.0" + is-data-view "^1.0.1" + +data-view-byte-length@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz#90721ca95ff280677eb793749fce1011347669e2" + integrity sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ== + dependencies: + call-bind "^1.0.7" + es-errors "^1.3.0" + is-data-view "^1.0.1" + +data-view-byte-offset@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz#5e0bbfb4828ed2d1b9b400cd8a7d119bca0ff18a" + integrity sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA== + dependencies: + call-bind "^1.0.6" + es-errors "^1.3.0" + is-data-view "^1.0.1" + dateformat@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae" @@ -3395,12 +3443,12 @@ 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.0.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, 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== +debug@4, debug@^4.0.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4, debug@^4.3.5, debug@^4.3.6: + version "4.3.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.7.tgz#87945b4151a011d76d95a198d7111c865c360a52" + integrity sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ== dependencies: - ms "2.1.2" + ms "^2.1.3" debug@^3.2.7: version "3.2.7" @@ -3435,9 +3483,9 @@ decompress-response@^6.0.0: mimic-response "^3.1.0" deep-eql@^4.0.1, deep-eql@^4.1.3: - version "4.1.3" - resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-4.1.3.tgz#7c7775513092f7df98d8df9996dd085eb668cc6d" - integrity sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw== + version "4.1.4" + resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-4.1.4.tgz#d0d3912865911bb8fac5afb4e3acfa6a28dc72b7" + integrity sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg== dependencies: type-detect "^4.0.0" @@ -3463,21 +3511,21 @@ defer-to-connect@^2.0.1: resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587" integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg== -define-data-property@^1.0.1, define-data-property@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.1.tgz#c35f7cd0ab09883480d12ac5cb213715587800b3" - integrity sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ== +define-data-property@^1.0.1, define-data-property@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e" + integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A== dependencies: - get-intrinsic "^1.2.1" + es-define-property "^1.0.0" + es-errors "^1.3.0" gopd "^1.0.1" - has-property-descriptors "^1.0.0" define-lazy-prop@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== -define-properties@^1.1.3, define-properties@^1.2.0, define-properties@^1.2.1: +define-properties@^1.2.0, define-properties@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c" integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== @@ -3506,28 +3554,15 @@ deprecation@^2.0.0: resolved "https://registry.yarnpkg.com/deprecation/-/deprecation-2.3.1.tgz#6368cbdb40abf3373b525ac87e4a260c3a700919" integrity sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ== -detect-port@^1.3.0: - version "1.5.1" - resolved "https://registry.yarnpkg.com/detect-port/-/detect-port-1.5.1.tgz#451ca9b6eaf20451acb0799b8ab40dff7718727b" - integrity sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ== - dependencies: - address "^1.0.1" - debug "4" - -diff@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" - integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== - diff@^4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== -diff@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-5.1.0.tgz#bc52d298c5ea8df9194800224445ed43ffc87e40" - integrity sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw== +diff@^5.1.0, diff@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-5.2.0.tgz#26ded047cd1179b78b9537d5ef725503ce1ae531" + integrity sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A== difflib@^0.2.4: version "0.2.4" @@ -3569,6 +3604,11 @@ dotenv@16.0.3: resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.3.tgz#115aec42bac5053db3c456db30cc243a5a836a07" integrity sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ== +dotenv@^16.3.1, dotenv@^16.4.5: + version "16.4.5" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.5.tgz#cdd3b3b604cb327e286b4762e13502f717cb099f" + integrity sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg== + duplexer2@~0.1.0: version "0.1.4" resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1" @@ -3581,7 +3621,7 @@ eastasianwidth@^0.2.0: resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== -elliptic@6.5.4, elliptic@^6.5.2, elliptic@^6.5.4: +elliptic@6.5.4: version "6.5.4" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== @@ -3594,6 +3634,19 @@ elliptic@6.5.4, elliptic@^6.5.2, elliptic@^6.5.4: minimalistic-assert "^1.0.1" minimalistic-crypto-utils "^1.0.1" +elliptic@^6.5.2, elliptic@^6.5.4: + version "6.5.7" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.7.tgz#8ec4da2cb2939926a1b9a73619d768207e647c8b" + integrity sha512-ESVCtTwiA+XhY3wyh24QqRGBoP3rEdDUl3EDUUo9tft074fi19IrdpH7hLCMMP3CIj7jb3W96rn8lt/BqIlt5Q== + dependencies: + bn.js "^4.11.9" + brorand "^1.1.0" + hash.js "^1.0.0" + hmac-drbg "^1.0.1" + inherits "^2.0.4" + minimalistic-assert "^1.0.1" + minimalistic-crypto-utils "^1.0.1" + emoji-regex@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" @@ -3654,61 +3707,92 @@ error-ex@^1.2.0, error-ex@^1.3.1, error-ex@^1.3.2: dependencies: is-arrayish "^0.2.1" -es-abstract@^1.22.1: - version "1.22.3" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.22.3.tgz#48e79f5573198de6dee3589195727f4f74bc4f32" - integrity sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA== - dependencies: - array-buffer-byte-length "^1.0.0" - arraybuffer.prototype.slice "^1.0.2" - available-typed-arrays "^1.0.5" - call-bind "^1.0.5" - es-set-tostringtag "^2.0.1" +es-abstract@^1.22.1, es-abstract@^1.22.3, es-abstract@^1.23.0, es-abstract@^1.23.2: + version "1.23.3" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.23.3.tgz#8f0c5a35cd215312573c5a27c87dfd6c881a0aa0" + integrity sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A== + dependencies: + array-buffer-byte-length "^1.0.1" + arraybuffer.prototype.slice "^1.0.3" + available-typed-arrays "^1.0.7" + call-bind "^1.0.7" + data-view-buffer "^1.0.1" + data-view-byte-length "^1.0.1" + data-view-byte-offset "^1.0.0" + es-define-property "^1.0.0" + es-errors "^1.3.0" + es-object-atoms "^1.0.0" + es-set-tostringtag "^2.0.3" es-to-primitive "^1.2.1" function.prototype.name "^1.1.6" - get-intrinsic "^1.2.2" - get-symbol-description "^1.0.0" + get-intrinsic "^1.2.4" + get-symbol-description "^1.0.2" globalthis "^1.0.3" gopd "^1.0.1" - has-property-descriptors "^1.0.0" - has-proto "^1.0.1" + has-property-descriptors "^1.0.2" + has-proto "^1.0.3" has-symbols "^1.0.3" - hasown "^2.0.0" - internal-slot "^1.0.5" - is-array-buffer "^3.0.2" + hasown "^2.0.2" + internal-slot "^1.0.7" + is-array-buffer "^3.0.4" is-callable "^1.2.7" - is-negative-zero "^2.0.2" + is-data-view "^1.0.1" + is-negative-zero "^2.0.3" is-regex "^1.1.4" - is-shared-array-buffer "^1.0.2" + is-shared-array-buffer "^1.0.3" is-string "^1.0.7" - is-typed-array "^1.1.12" + is-typed-array "^1.1.13" is-weakref "^1.0.2" object-inspect "^1.13.1" object-keys "^1.1.1" - object.assign "^4.1.4" - regexp.prototype.flags "^1.5.1" - safe-array-concat "^1.0.1" - safe-regex-test "^1.0.0" - string.prototype.trim "^1.2.8" - string.prototype.trimend "^1.0.7" - string.prototype.trimstart "^1.0.7" - typed-array-buffer "^1.0.0" - typed-array-byte-length "^1.0.0" - typed-array-byte-offset "^1.0.0" - typed-array-length "^1.0.4" + object.assign "^4.1.5" + regexp.prototype.flags "^1.5.2" + safe-array-concat "^1.1.2" + safe-regex-test "^1.0.3" + string.prototype.trim "^1.2.9" + string.prototype.trimend "^1.0.8" + string.prototype.trimstart "^1.0.8" + typed-array-buffer "^1.0.2" + typed-array-byte-length "^1.0.1" + typed-array-byte-offset "^1.0.2" + typed-array-length "^1.0.6" unbox-primitive "^1.0.2" - which-typed-array "^1.1.13" + which-typed-array "^1.1.15" -es-set-tostringtag@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz#11f7cc9f63376930a5f20be4915834f4bc74f9c9" - integrity sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q== +es-define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845" + integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ== dependencies: - get-intrinsic "^1.2.2" - has-tostringtag "^1.0.0" - hasown "^2.0.0" + get-intrinsic "^1.2.4" + +es-errors@^1.2.1, es-errors@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" + integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== -es-shim-unscopables@^1.0.0: +es-module-lexer@^1.5.3: + version "1.5.4" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.5.4.tgz#a8efec3a3da991e60efa6b633a7cad6ab8d26b78" + integrity sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw== + +es-object-atoms@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/es-object-atoms/-/es-object-atoms-1.0.0.tgz#ddb55cd47ac2e240701260bc2a8e31ecb643d941" + integrity sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw== + dependencies: + es-errors "^1.3.0" + +es-set-tostringtag@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz#8bb60f0a440c2e4281962428438d58545af39777" + integrity sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ== + dependencies: + get-intrinsic "^1.2.4" + has-tostringtag "^1.0.2" + hasown "^2.0.1" + +es-shim-unscopables@^1.0.0, es-shim-unscopables@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz#1f6942e71ecc7835ed1c8a83006d8771a63a3763" integrity sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw== @@ -3725,14 +3809,9 @@ es-to-primitive@^1.2.1: is-symbol "^1.0.2" escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" - integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== - -escape-string-regexp@4.0.0, escape-string-regexp@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" - integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + version "3.2.0" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5" + integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== escape-string-regexp@5.0.0, escape-string-regexp@^5.0.0: version "5.0.0" @@ -3744,6 +3823,11 @@ escape-string-regexp@^1.0.5: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== +escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + escodegen@1.8.x: version "1.8.1" resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.8.1.tgz#5a5b53af4693110bebb0867aa3430dd3b70a1018" @@ -3784,48 +3868,53 @@ eslint-import-resolver-node@^0.3.9: is-core-module "^2.13.0" resolve "^1.22.4" -eslint-module-utils@^2.8.0: - version "2.8.0" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz#e439fee65fc33f6bba630ff621efc38ec0375c49" - integrity sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw== +eslint-module-utils@^2.9.0: + version "2.12.0" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz#fe4cfb948d61f49203d7b08871982b65b9af0b0b" + integrity sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg== dependencies: debug "^3.2.7" eslint-plugin-import@^2.27.5: - version "2.29.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz#d45b37b5ef5901d639c15270d74d46d161150643" - integrity sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw== + version "2.30.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.30.0.tgz#21ceea0fc462657195989dd780e50c92fe95f449" + integrity sha512-/mHNE9jINJfiD2EKkg1BKyPyUk4zdnT54YgbOgfjSakWT5oyX/qQLVNTkehyfpcMxZXMy1zyonZ2v7hZTX43Yw== dependencies: - array-includes "^3.1.7" - array.prototype.findlastindex "^1.2.3" + "@rtsao/scc" "^1.1.0" + array-includes "^3.1.8" + array.prototype.findlastindex "^1.2.5" array.prototype.flat "^1.3.2" array.prototype.flatmap "^1.3.2" debug "^3.2.7" doctrine "^2.1.0" eslint-import-resolver-node "^0.3.9" - eslint-module-utils "^2.8.0" - hasown "^2.0.0" - is-core-module "^2.13.1" + eslint-module-utils "^2.9.0" + hasown "^2.0.2" + is-core-module "^2.15.1" is-glob "^4.0.3" minimatch "^3.1.2" - object.fromentries "^2.0.7" - object.groupby "^1.0.1" - object.values "^1.1.7" + object.fromentries "^2.0.8" + object.groupby "^1.0.3" + object.values "^1.2.0" semver "^6.3.1" tsconfig-paths "^3.15.0" -eslint-plugin-jsdoc@^40.1.1: - version "40.3.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-40.3.0.tgz#75a91ab71c41bb797db05a32d9528ce3ab613e90" - integrity sha512-EhCqpzRkxoT2DUB4AnrU0ggBYvTh3bWrLZzQTupq6vSVE6XzNwJVKsOHa41GCoevnsWMBNmoDVjXWGqckjuG1g== +eslint-plugin-jsdoc@^50.3.0: + version "50.3.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-50.3.0.tgz#2a4d1ac7f45b2b62de42389ba8006fd00b7f08dd" + integrity sha512-P7qDB/RckdKETpBM4CtjHRQ5qXByPmFhRi86sN3E+J+tySchq+RSOGGhI2hDIefmmKFuTi/1ACjqsnDJDDDfzg== dependencies: - "@es-joy/jsdoccomment" "~0.37.0" - comment-parser "1.3.1" - debug "^4.3.4" + "@es-joy/jsdoccomment" "~0.48.0" + are-docs-informative "^0.0.2" + comment-parser "1.4.1" + debug "^4.3.6" escape-string-regexp "^4.0.0" - esquery "^1.5.0" - semver "^7.3.8" - spdx-expression-parse "^3.0.1" + espree "^10.1.0" + esquery "^1.6.0" + parse-imports "^2.1.1" + semver "^7.6.3" + spdx-expression-parse "^4.0.0" + synckit "^0.9.1" eslint-plugin-prefer-arrow@^1.2.3: version "1.2.3" @@ -3853,16 +3942,21 @@ eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4 resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== +eslint-visitor-keys@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz#e3adc021aa038a2a8e0b2f8b0ce8f66b9483b1fb" + integrity sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw== + eslint@^8.37.0: - version "8.56.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.56.0.tgz#4957ce8da409dc0809f99ab07a1b94832ab74b15" - integrity sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ== + version "8.57.1" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.57.1.tgz#7df109654aba7e3bbe5c8eae533c5e461d3c6ca9" + integrity sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA== dependencies: "@eslint-community/eslint-utils" "^4.2.0" "@eslint-community/regexpp" "^4.6.1" "@eslint/eslintrc" "^2.1.4" - "@eslint/js" "8.56.0" - "@humanwhocodes/config-array" "^0.11.13" + "@eslint/js" "8.57.1" + "@humanwhocodes/config-array" "^0.13.0" "@humanwhocodes/module-importer" "^1.0.1" "@nodelib/fs.walk" "^1.2.8" "@ungap/structured-clone" "^1.2.0" @@ -3897,6 +3991,15 @@ eslint@^8.37.0: strip-ansi "^6.0.1" text-table "^0.2.0" +espree@^10.1.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-10.1.0.tgz#8788dae611574c0f070691f522e4116c5a11fc56" + integrity sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA== + dependencies: + acorn "^8.12.0" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^4.0.0" + espree@^9.6.0, espree@^9.6.1: version "9.6.1" resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" @@ -3916,10 +4019,10 @@ esprima@^4.0.0, esprima@~4.0.0: resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== -esquery@^1.4.2, esquery@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" - integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== +esquery@^1.4.2, esquery@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.6.0.tgz#91419234f804d852a82dceec3e16cdc22cf9dae7" + integrity sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg== dependencies: estraverse "^5.1.0" @@ -3978,11 +4081,11 @@ eth-gas-reporter@^0.2.25: sync-request "^6.0.0" ethereum-bloom-filters@^1.0.6: - version "1.0.10" - resolved "https://registry.yarnpkg.com/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.10.tgz#3ca07f4aed698e75bd134584850260246a5fed8a" - integrity sha512-rxJ5OFN3RwjQxDcFP2Z5+Q9ho4eIdEmSc2ht0fCu8Se9nbXjZ7/031uXoUYJ87KHCOdVeiUuwSnoS7hmYAGVHA== + version "1.2.0" + resolved "https://registry.yarnpkg.com/ethereum-bloom-filters/-/ethereum-bloom-filters-1.2.0.tgz#8294f074c1a6cbd32c39d2cc77ce86ff14797dab" + integrity sha512-28hyiE7HVsWubqhpVLVmZXFd4ITeHi+BUu05o9isf0GUpMtzBUi+8/gFrGaGYzvGAJQmJ3JKj77Mk9G98T84rA== dependencies: - js-sha3 "^0.8.0" + "@noble/hashes" "^1.4.0" ethereum-cryptography@0.1.3, ethereum-cryptography@^0.1.3: version "0.1.3" @@ -4016,14 +4119,14 @@ ethereum-cryptography@^1.0.3: "@scure/bip39" "1.1.1" ethereum-cryptography@^2.0.0, ethereum-cryptography@^2.1.2: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-2.1.3.tgz#1352270ed3b339fe25af5ceeadcf1b9c8e30768a" - integrity sha512-BlwbIL7/P45W8FGW2r7LGuvoEZ+7PWsniMvQ4p5s2xCyw9tmaDlpfsN9HjAucbF+t/qpVHwZUisgfK24TCW8aA== + version "2.2.1" + resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-2.2.1.tgz#58f2810f8e020aecb97de8c8c76147600b0b8ccf" + integrity sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg== dependencies: - "@noble/curves" "1.3.0" - "@noble/hashes" "1.3.3" - "@scure/bip32" "1.3.3" - "@scure/bip39" "1.2.2" + "@noble/curves" "1.4.2" + "@noble/hashes" "1.4.0" + "@scure/bip32" "1.4.0" + "@scure/bip39" "1.3.0" ethereumjs-abi@^0.6.8: version "0.6.8" @@ -4057,7 +4160,7 @@ ethereumjs-util@^7.0.3, ethereumjs-util@^7.1.4, ethereumjs-util@^7.1.5: ethereum-cryptography "^0.1.3" rlp "^2.2.4" -ethers@^5.0.13, ethers@^5.7.0, ethers@^5.7.1, ethers@^5.7.2: +ethers@^5.0.13, 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== @@ -4093,18 +4196,18 @@ ethers@^5.0.13, ethers@^5.7.0, ethers@^5.7.1, ethers@^5.7.2: "@ethersproject/web" "5.7.1" "@ethersproject/wordlists" "5.7.0" -ethers@^6.8.1, ethers@^6.9.0: - version "6.10.0" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-6.10.0.tgz#20f3c63c60d59a993f8090ad423d8a3854b3b1cd" - integrity sha512-nMNwYHzs6V1FR3Y4cdfxSQmNgZsRj1RiTU25JwvnJLmyzw9z3SKxNc2XKDuiXXo/v9ds5Mp9m6HBabgYQQ26tA== +ethers@^6.7.0, ethers@^6.8.1, ethers@^6.9.0: + version "6.13.2" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-6.13.2.tgz#4b67d4b49e69b59893931a032560999e5e4419fe" + integrity sha512-9VkriTTed+/27BGuY1s0hf441kqwHJ1wtN2edksEtiRvXx+soxRX3iSXTfFqq2+YwrOqbDoTHjIhQnjJRlzKmg== dependencies: - "@adraffy/ens-normalize" "1.10.0" + "@adraffy/ens-normalize" "1.10.1" "@noble/curves" "1.2.0" "@noble/hashes" "1.3.2" "@types/node" "18.15.13" aes-js "4.0.0-beta.5" tslib "2.4.0" - ws "8.5.0" + ws "8.17.1" ethjs-unit@0.1.6: version "0.1.6" @@ -4216,15 +4319,20 @@ fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== +fast-uri@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.0.2.tgz#d78b298cf70fd3b752fd951175a3da6a7b48f024" + integrity sha512-GR6f0hD7XXyNJa25Tb9BuIdN0tdr+0BMi6/CJPH3wJO1JjNG3n/VsSw38AwRdKZABm8lGbPfakLRkYzx2V9row== + fastest-levenshtein@^1.0.16: version "1.0.16" resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz#210e61b6ff181de91ea9b3d1b84fdedd47e034e5" integrity sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg== fastq@^1.6.0: - version "1.17.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.17.0.tgz#ca5e1a90b5e68f97fc8b61330d5819b82f5fab03" - integrity sha512-zGygtijUMT7jnk3h26kUms3BkSDp4IfIKjmnqI2tvx6nuBfiF1UqOxbnLfzdv+apBy+53oaImsKtMw/xYbW+1w== + version "1.17.1" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.17.1.tgz#2a523f07a4e7b1e81a42b91b8bf2254107753b47" + integrity sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w== dependencies: reusify "^1.0.4" @@ -4255,10 +4363,10 @@ file-entry-cache@^6.0.1: dependencies: flat-cache "^3.0.4" -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== +fill-range@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" + integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== dependencies: to-regex-range "^5.0.1" @@ -4269,14 +4377,6 @@ find-replace@^3.0.0: dependencies: array-back "^3.0.1" -find-up@5.0.0, find-up@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" - integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== - dependencies: - locate-path "^6.0.0" - path-exists "^4.0.0" - find-up@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" @@ -4300,6 +4400,14 @@ find-up@^4.1.0: locate-path "^5.0.0" path-exists "^4.0.0" +find-up@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + find-up@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-6.3.0.tgz#2abab3d3280b2dc7ac10199ef324c4e002c8c790" @@ -4330,9 +4438,9 @@ flat@^5.0.2: integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== flatted@^3.2.9: - version "3.2.9" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.9.tgz#7eb4c67ca1ba34232ca9d2d93e9886e611ad7daf" - integrity sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ== + version "3.3.1" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.1.tgz#21db470729a6734d4997002f439cb308987f567a" + integrity sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw== fmix@^0.1.0: version "0.1.0" @@ -4346,10 +4454,10 @@ fn.name@1.x.x: resolved "https://registry.yarnpkg.com/fn.name/-/fn.name-1.1.0.tgz#26cad8017967aea8731bc42961d04a3d5988accc" integrity sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw== -follow-redirects@^1.12.1, follow-redirects@^1.14.0, follow-redirects@^1.14.9, follow-redirects@^1.15.4: - version "1.15.5" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.5.tgz#54d4d6d062c0fa7d9d17feb008461550e3ba8020" - integrity sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw== +follow-redirects@^1.12.1, follow-redirects@^1.14.0, follow-redirects@^1.14.9, follow-redirects@^1.15.6: + version "1.15.9" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.9.tgz#a604fa10e443bf98ca94228d9eebcc2e8a2c8ee1" + integrity sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ== for-each@^0.3.3: version "0.3.3" @@ -4359,9 +4467,9 @@ for-each@^0.3.3: is-callable "^1.1.3" foreground-child@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.1.1.tgz#1d173e776d75d2772fed08efe4a0de1ea1b12d0d" - integrity sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg== + version "3.3.0" + resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.3.0.tgz#0ac8644c06e431439f8561db8ecf29a7b5519c77" + integrity sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg== dependencies: cross-spawn "^7.0.0" signal-exit "^4.0.1" @@ -4427,7 +4535,7 @@ fs-extra@^10.0.0, fs-extra@^10.1.0: jsonfile "^6.0.1" universalify "^2.0.0" -fs-extra@^11.0.0: +fs-extra@^11.0.0, fs-extra@^11.2.0: version "11.2.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.2.0.tgz#e70e17dfad64232287d01929399e0ea7c86b0e5b" integrity sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw== @@ -4471,7 +4579,7 @@ fs-minipass@^2.0.0, fs-minipass@^2.1.0: dependencies: minipass "^3.0.0" -fs-minipass@^3.0.0, fs-minipass@^3.0.2: +fs-minipass@^3.0.0, fs-minipass@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-3.0.3.tgz#79a85981c4dc120065e96f62086bf6f9dc26cc54" integrity sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw== @@ -4508,11 +4616,6 @@ function.prototype.name@^1.1.6: es-abstract "^1.22.1" functions-have-names "^1.2.3" -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== - functions-have-names@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" @@ -4533,9 +4636,9 @@ gauge@^4.0.3: wide-align "^1.1.5" gauge@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-5.0.1.tgz#1efc801b8ff076b86ef3e9a7a280a975df572112" - integrity sha512-CmykPMJGuNan/3S4kZOpvvPYSNqSHANiWnh9XcMU2pSjtBfF0XzZ2p1bFAxTbnFxyBuPxQYHhzwaoOmUdqzvxQ== + version "5.0.2" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-5.0.2.tgz#7ab44c11181da9766333f10db8cd1e4b17fd6c46" + integrity sha512-pMaFftXPtiGIHCJHdcUUx9Rby/rFT/Kkt3fIIGCs+9PMDIljSyRiqraTlxNtBReJRDfUefpa263RQ3vnp5G/LQ== dependencies: aproba "^1.0.3 || ^2.0.0" color-support "^1.1.3" @@ -4561,11 +4664,12 @@ get-func-name@^2.0.1, get-func-name@^2.0.2: resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.2.tgz#0d7cf20cd13fda808669ffa88f4ffc7a3943fc41" integrity sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ== -get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@^1.2.1, get-intrinsic@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.2.tgz#281b7622971123e1ef4b3c90fd7539306da93f3b" - integrity sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA== +get-intrinsic@^1.1.3, get-intrinsic@^1.2.1, get-intrinsic@^1.2.3, get-intrinsic@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd" + integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ== dependencies: + es-errors "^1.3.0" function-bind "^1.1.2" has-proto "^1.0.1" has-symbols "^1.0.3" @@ -4591,13 +4695,14 @@ get-stream@^8.0.1: resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-8.0.1.tgz#def9dfd71742cd7754a7761ed43749a27d02eca2" integrity sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA== -get-symbol-description@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" - integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== +get-symbol-description@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.2.tgz#533744d5aa20aca4e079c8e5daf7fd44202821f5" + integrity sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg== dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.1" + call-bind "^1.0.5" + es-errors "^1.3.0" + get-intrinsic "^1.2.4" ghost-testrpc@^0.0.2: version "0.0.2" @@ -4608,16 +4713,16 @@ ghost-testrpc@^0.0.2: node-emoji "^1.10.0" git-log-parser@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/git-log-parser/-/git-log-parser-1.2.0.tgz#2e6a4c1b13fc00028207ba795a7ac31667b9fd4a" - integrity sha512-rnCVNfkTL8tdNryFuaY0fYiBWEBcgF748O6ZI61rslBvr2o7U65c2/6npCRqH40vuAhtgtDiqLTJjBVdrejCzA== + version "1.2.1" + resolved "https://registry.yarnpkg.com/git-log-parser/-/git-log-parser-1.2.1.tgz#44355787b37af7560dcc4ddc01cb53b5d139cc28" + integrity sha512-PI+sPDvHXNPl5WNOErAK05s3j0lgwUzMN6o8cyQrDaKfT3qd7TmNJKeXX+SknI5I0QhG5fVPAEwSY4tRGDtYoQ== dependencies: argv-formatter "~1.0.0" spawn-error-forwarder "~1.0.0" split2 "~1.0.0" stream-combiner2 "~1.1.1" through2 "~2.0.0" - traverse "~0.6.6" + traverse "0.6.8" glob-parent@^5.1.2, glob-parent@~5.1.2: version "5.1.2" @@ -4657,16 +4762,29 @@ glob@7.2.0: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^10.2.2, glob@^10.2.7: - version "10.3.10" - resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.10.tgz#0351ebb809fd187fe421ab96af83d3a70715df4b" - integrity sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g== +glob@^10.2.2, glob@^10.3.10: + version "10.4.5" + resolved "https://registry.yarnpkg.com/glob/-/glob-10.4.5.tgz#f4d9f0b90ffdbab09c9d77f5f29b4262517b0956" + integrity sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg== dependencies: foreground-child "^3.1.0" - jackspeak "^2.3.5" - minimatch "^9.0.1" - minipass "^5.0.0 || ^6.0.2 || ^7.0.0" - path-scurry "^1.10.1" + jackspeak "^3.1.2" + minimatch "^9.0.4" + minipass "^7.1.2" + package-json-from-dist "^1.0.0" + path-scurry "^1.11.1" + +glob@^11.0.0: + version "11.0.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-11.0.0.tgz#6031df0d7b65eaa1ccb9b29b5ced16cea658e77e" + integrity sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g== + dependencies: + foreground-child "^3.1.0" + jackspeak "^4.0.1" + minimatch "^10.0.0" + minipass "^7.1.2" + package-json-from-dist "^1.0.0" + path-scurry "^2.0.0" glob@^5.0.15: version "5.0.15" @@ -4679,7 +4797,7 @@ glob@^5.0.15: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.0.0, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: +glob@^7.0.0, glob@^7.1.3, glob@^7.1.4: version "7.2.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== @@ -4691,7 +4809,7 @@ glob@^7.0.0, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^8.0.1, glob@^8.0.3: +glob@^8.0.1, glob@^8.0.3, glob@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e" integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ== @@ -4726,11 +4844,12 @@ globals@^13.19.0: type-fest "^0.20.2" globalthis@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.3.tgz#5852882a52b80dc301b0660273e1ed082f0b6ccf" - integrity sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA== + version "1.0.4" + resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.4.tgz#7430ed3a975d97bfb59bcce41f5cabbafa651236" + integrity sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ== dependencies: - define-properties "^1.1.3" + define-properties "^1.2.1" + gopd "^1.0.1" globby@^10.0.1: version "10.0.2" @@ -4759,11 +4878,11 @@ globby@^11.1.0: slash "^3.0.0" globby@^14.0.0: - version "14.0.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-14.0.0.tgz#ea9c062a3614e33f516804e778590fcf055256b9" - integrity sha512-/1WM/LNHRAOH9lZta77uGbq0dAEQM+XjNesWwhlERDVenqothRbnzTrL3/LrIoEPPjeUHC3vrS6TwoyxeHs7MQ== + version "14.0.2" + resolved "https://registry.yarnpkg.com/globby/-/globby-14.0.2.tgz#06554a54ccfe9264e5a9ff8eded46aa1e306482f" + integrity sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw== dependencies: - "@sindresorhus/merge-streams" "^1.0.0" + "@sindresorhus/merge-streams" "^2.1.0" fast-glob "^3.3.2" ignore "^5.2.4" path-type "^5.0.0" @@ -4857,31 +4976,25 @@ hardhat-deploy@^0.11.43: zksync-web3 "^0.14.3" hardhat-gas-reporter@^1.0.9: - version "1.0.9" - resolved "https://registry.yarnpkg.com/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.9.tgz#9a2afb354bc3b6346aab55b1c02ca556d0e16450" - integrity sha512-INN26G3EW43adGKBNzYWOlI3+rlLnasXTwW79YNnUhXPDa+yHESgt639dJEs37gCjhkbNKcRRJnomXEuMFBXJg== + version "1.0.10" + resolved "https://registry.yarnpkg.com/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.10.tgz#ebe5bda5334b5def312747580cd923c2b09aef1b" + integrity sha512-02N4+So/fZrzJ88ci54GqwVA3Zrf0C9duuTyGt0CFRIh/CdNwbnTgkXkRfojOMLBQ+6t+lBIkgbsOtqMvNwikA== dependencies: array-uniq "1.0.3" eth-gas-reporter "^0.2.25" sha1 "^1.1.1" -hardhat@^2.19.1: - version "2.19.4" - resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.19.4.tgz#5112c30295d8be2e18e55d847373c50483ed1902" - integrity sha512-fTQJpqSt3Xo9Mn/WrdblNGAfcANM6XC3tAEi6YogB4s02DmTf93A8QsGb8uR0KR8TFcpcS8lgiW4ugAIYpnbrQ== +hardhat@^2.22.6: + version "2.22.12" + resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.22.12.tgz#a6d0be011fc009c50c454da367ad28c29f58d446" + integrity sha512-yok65M+LsOeTBHQsjg//QreGCyrsaNmeLVzhTFqlOvZ4ZE5y69N0wRxH1b2BC9dGK8S8OPUJMNiL9X0RAvbm8w== 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.6.1" + "@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" @@ -4889,8 +5002,9 @@ hardhat@^2.19.1: 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" + chokidar "^4.0.0" ci-info "^2.0.0" debug "^4.1.1" enquirer "^2.3.0" @@ -4903,6 +5017,7 @@ hardhat@^2.19.1: glob "7.2.0" immutable "^4.0.0-rc.12" io-ts "1.10.4" + json-stream-stringify "^3.1.4" keccak "^3.0.2" lodash "^4.17.11" mnemonist "^0.38.0" @@ -4911,7 +5026,7 @@ hardhat@^2.19.1: raw-body "^2.4.1" resolve "1.17.0" semver "^6.3.0" - solc "0.7.3" + solc "0.8.26" source-map-support "^0.5.13" stacktrace-parser "^0.1.10" tsort "0.0.1" @@ -4939,29 +5054,29 @@ has-flag@^4.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== -has-property-descriptors@^1.0.0, has-property-descriptors@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz#52ba30b6c5ec87fd89fa574bc1c39125c6f65340" - integrity sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg== +has-property-descriptors@^1.0.0, has-property-descriptors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854" + integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg== dependencies: - get-intrinsic "^1.2.2" + es-define-property "^1.0.0" -has-proto@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" - integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== +has-proto@^1.0.1, has-proto@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.3.tgz#b31ddfe9b0e6e9914536a6ab286426d0214f77fd" + integrity sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q== has-symbols@^1.0.2, has-symbols@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== -has-tostringtag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" - integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== +has-tostringtag@^1.0.0, has-tostringtag@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz#2cdc42d40bef2e5b4eeab7c01a73c54ce7ab5abc" + integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw== dependencies: - has-symbols "^1.0.2" + has-symbols "^1.0.3" has-unicode@^2.0.1: version "2.0.1" @@ -4985,14 +5100,14 @@ hash.js@1.1.7, hash.js@^1.0.0, hash.js@^1.0.3, hash.js@^1.1.7: inherits "^2.0.3" minimalistic-assert "^1.0.1" -hasown@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.0.tgz#f4c513d454a57b7c7e1650778de226b11700546c" - integrity sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA== +hasown@^2.0.0, hasown@^2.0.1, hasown@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" + integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== dependencies: function-bind "^1.1.2" -he@1.2.0: +he@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== @@ -5036,9 +5151,9 @@ hosted-git-info@^6.0.0, hosted-git-info@^6.1.1: lru-cache "^7.5.1" hosted-git-info@^7.0.0: - version "7.0.1" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-7.0.1.tgz#9985fcb2700467fecf7f33a4d4874e30680b5322" - integrity sha512-+K84LB1DYwMHoHSgaOY/Jfhw3ucPmSET5v98Ke/HdNSw4a0UktWzyW1mjhjpuxxTqOOsfWT/7iVshHmVZ4IpOA== + version "7.0.2" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-7.0.2.tgz#9b751acac097757667f30114607ef7b661ff4f17" + integrity sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w== dependencies: lru-cache "^10.0.1" @@ -5078,9 +5193,9 @@ http-proxy-agent@^5.0.0: debug "4" http-proxy-agent@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz#e9096c5afd071a3fce56e6252bb321583c124673" - integrity sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ== + version "7.0.2" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz#9a8b1f246866c028509486585f62b8f2c18c270e" + integrity sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig== dependencies: agent-base "^7.1.0" debug "^4.3.4" @@ -5108,10 +5223,10 @@ https-proxy-agent@^5.0.0: agent-base "6" debug "4" -https-proxy-agent@^7.0.0: - version "7.0.2" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz#e2645b846b90e96c6e6f347fb5b2e41f1590b09b" - integrity sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA== +https-proxy-agent@^7.0.0, https-proxy-agent@^7.0.1: + version "7.0.5" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz#9e8b5013873299e11fab6fd548405da2d6c602b2" + integrity sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw== dependencies: agent-base "^7.0.2" debug "4" @@ -5165,26 +5280,31 @@ ieee754@^1.1.13, ieee754@^1.1.4, ieee754@^1.2.1: integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== ignore-walk@^6.0.0: - version "6.0.4" - resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-6.0.4.tgz#89950be94b4f522225eb63a13c56badb639190e9" - integrity sha512-t7sv42WkwFkyKbivUCglsQW5YWMskWtbEf4MNKX5u/CCWHKSPzN4FtBQGsQZgCLbxOzpVlcbWVK5KB3auIOjSw== + version "6.0.5" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-6.0.5.tgz#ef8d61eab7da169078723d1f82833b36e200b0dd" + integrity sha512-VuuG0wCnjhnylG1ABXT3dAuIpTNDs/G8jlpmwXY03fXoXy/8ZK8/T+hMzt8L4WnrLCJgdybqgPagnF/f97cg3A== dependencies: minimatch "^9.0.0" ignore@^5.1.1, ignore@^5.2.0, ignore@^5.2.4: - version "5.3.0" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.0.tgz#67418ae40d34d6999c95ff56016759c718c82f78" - integrity sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg== + version "5.3.2" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.2.tgz#3cd40e729f3643fd87cb04e50bf0eb722bc596f5" + integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g== immediate@~3.0.5: version "3.0.6" resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" integrity sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ== +immer@10.0.2: + version "10.0.2" + resolved "https://registry.yarnpkg.com/immer/-/immer-10.0.2.tgz#11636c5b77acf529e059582d76faf338beb56141" + integrity sha512-Rx3CqeqQ19sxUtYV9CU911Vhy8/721wRFnJv3REVGWUmoAcIwzifTsdmJte/MV+0/XpM35LZdQMBGkRIoLPwQA== + immutable@^4.0.0-rc.12: - version "4.3.5" - resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.3.5.tgz#f8b436e66d59f99760dc577f5c99a4fd2a5cc5a0" - integrity sha512-8eabxkth9gZatlwl5TBuJnCsoTADlL6ftEr7A4qgdaTsPyreilDSnUk57SO+jfKcNtxPa22U5KK6DSeAYhpBJw== + version "4.3.7" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.3.7.tgz#c70145fc90d89fb02021e65c84eb0226e4e5a381" + integrity sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw== import-fresh@^3.2.1, import-fresh@^3.3.0: version "3.3.0" @@ -5243,9 +5363,9 @@ ini@^1.3.4, ini@^1.3.5, ini@~1.3.0: integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== ini@^4.1.0, ini@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/ini/-/ini-4.1.1.tgz#d95b3d843b1e906e56d6747d5447904ff50ce7a1" - integrity sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g== + version "4.1.3" + resolved "https://registry.yarnpkg.com/ini/-/ini-4.1.3.tgz#4c359675a6071a46985eb39b14e4a2c0ec98a795" + integrity sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg== init-package-json@^5.0.0: version "5.0.0" @@ -5260,12 +5380,12 @@ init-package-json@^5.0.0: validate-npm-package-license "^3.0.4" validate-npm-package-name "^5.0.0" -internal-slot@^1.0.5: - version "1.0.6" - resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.6.tgz#37e756098c4911c5e912b8edbf71ed3aa116f930" - integrity sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg== +internal-slot@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.7.tgz#c06dcca3ed874249881007b0a5523b172a190802" + integrity sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g== dependencies: - get-intrinsic "^1.2.2" + es-errors "^1.3.0" hasown "^2.0.0" side-channel "^1.0.4" @@ -5294,24 +5414,26 @@ io-ts@1.10.4: dependencies: fp-ts "^1.0.0" +ip-address@^9.0.5: + version "9.0.5" + resolved "https://registry.yarnpkg.com/ip-address/-/ip-address-9.0.5.tgz#117a960819b08780c3bd1f14ef3c1cc1d3f3ea5a" + integrity sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g== + dependencies: + jsbn "1.1.0" + sprintf-js "^1.1.3" + ip-regex@^4.1.0: version "4.3.0" resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-4.3.0.tgz#687275ab0f57fa76978ff8f4dddc8a23d5990db5" integrity sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q== -ip@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.0.tgz#4cf4ab182fee2314c75ede1276f8c80b479936da" - integrity sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ== - -is-array-buffer@^3.0.1, is-array-buffer@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.2.tgz#f2653ced8412081638ecb0ebbd0c41c6e0aecbbe" - integrity sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w== +is-array-buffer@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.4.tgz#7a1f92b3d61edd2bc65d24f130530ea93d7fae98" + integrity sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw== dependencies: call-bind "^1.0.2" - get-intrinsic "^1.2.0" - is-typed-array "^1.1.10" + get-intrinsic "^1.2.1" is-arrayish@^0.2.1: version "0.2.1" @@ -5345,11 +5467,6 @@ is-boolean-object@^1.1.0: call-bind "^1.0.2" has-tostringtag "^1.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-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: version "1.2.7" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" @@ -5362,12 +5479,19 @@ is-cidr@^4.0.2: dependencies: cidr-regex "^3.1.1" -is-core-module@^2.13.0, is-core-module@^2.13.1, is-core-module@^2.5.0, is-core-module@^2.8.1: - version "2.13.1" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384" - integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw== +is-core-module@^2.13.0, is-core-module@^2.15.1, is-core-module@^2.5.0, is-core-module@^2.8.1: + version "2.15.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.15.1.tgz#a7363a25bee942fefab0de13bf6aa372c82dcc37" + integrity sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ== dependencies: - hasown "^2.0.0" + hasown "^2.0.2" + +is-data-view@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-data-view/-/is-data-view-1.0.1.tgz#4b4d3a511b70f3dc26d42c03ca9ca515d847759f" + integrity sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w== + dependencies: + is-typed-array "^1.1.13" is-date-object@^1.0.1: version "1.0.5" @@ -5420,10 +5544,10 @@ is-lambda@^1.0.1: resolved "https://registry.yarnpkg.com/is-lambda/-/is-lambda-1.0.1.tgz#3d9877899e6a53efc0160504cde15f82e6f061d5" integrity sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ== -is-negative-zero@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" - integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== +is-negative-zero@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.3.tgz#ced903a027aca6381b777a5743069d7376a49747" + integrity sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw== is-number-object@^1.0.4: version "1.0.7" @@ -5465,12 +5589,12 @@ is-regex@^1.1.4: call-bind "^1.0.2" has-tostringtag "^1.0.0" -is-shared-array-buffer@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" - integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA== +is-shared-array-buffer@^1.0.2, is-shared-array-buffer@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz#1237f1cba059cdb62431d378dcc37d9680181688" + integrity sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg== dependencies: - call-bind "^1.0.2" + call-bind "^1.0.7" is-stream@^2.0.0: version "2.0.1" @@ -5503,12 +5627,12 @@ is-text-path@^2.0.0: dependencies: text-extensions "^2.0.0" -is-typed-array@^1.1.10, is-typed-array@^1.1.12, is-typed-array@^1.1.9: - version "1.1.12" - resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.12.tgz#d0bab5686ef4a76f7a73097b95470ab199c57d4a" - integrity sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg== +is-typed-array@^1.1.13: + version "1.1.13" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.13.tgz#d6c5ca56df62334959322d7d7dd1cca50debe229" + integrity sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw== dependencies: - which-typed-array "^1.1.11" + which-typed-array "^1.1.14" is-unicode-supported@^0.1.0: version "0.1.0" @@ -5573,15 +5697,22 @@ issue-parser@^6.0.0: lodash.isstring "^4.0.1" lodash.uniqby "^4.7.0" -jackspeak@^2.3.5: - version "2.3.6" - resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.3.6.tgz#647ecc472238aee4b06ac0e461acc21a8c505ca8" - integrity sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ== +jackspeak@^3.1.2: + version "3.4.3" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-3.4.3.tgz#8833a9d89ab4acde6188942bd1c53b6390ed5a8a" + integrity sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw== dependencies: "@isaacs/cliui" "^8.0.2" optionalDependencies: "@pkgjs/parseargs" "^0.11.0" +jackspeak@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-4.0.2.tgz#11f9468a3730c6ff6f56823a820d7e3be9bef015" + integrity sha512-bZsjR/iRjl1Nk1UkjGpAzLNfQtzuijhn2g+pbZb98HQ1Gk8vM9hfbxeMBP+M2/UUdwj0RqGG3mlvk2MsAqwvEw== + dependencies: + "@isaacs/cliui" "^8.0.2" + java-properties@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/java-properties/-/java-properties-1.0.2.tgz#ccd1fa73907438a5b5c38982269d0e771fe78211" @@ -5592,11 +5723,6 @@ js-cookie@^2.2.1: resolved "https://registry.yarnpkg.com/js-cookie/-/js-cookie-2.2.1.tgz#69e106dc5d5806894562902aa5baec3744e9b2b8" integrity sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ== -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" @@ -5620,17 +5746,22 @@ js-yaml@3.x: argparse "^1.0.7" esprima "^4.0.0" -js-yaml@4.1.0, js-yaml@^4.1.0: +js-yaml@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== dependencies: argparse "^2.0.1" -jsdoc-type-pratt-parser@~4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.0.0.tgz#136f0571a99c184d84ec84662c45c29ceff71114" - integrity sha512-YtOli5Cmzy3q4dP26GraSOeAhqecewG04hoO8DY56CH4KJ9Fvv5qKWUCCo3HZob7esJQHCv6/+bnTy72xZZaVQ== +jsbn@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-1.1.0.tgz#b01307cb29b618a1ed26ec79e911f803c4da0040" + integrity sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A== + +jsdoc-type-pratt-parser@~4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.1.0.tgz#ff6b4a3f339c34a6c188cbf50a16087858d22113" + integrity sha512-Hicd6JK5Njt2QB6XYFS7ok9e37O8AYk3jTcppG4YVQnYjOemymvTcmc7OWsmq/Qqj5TdRFO5/x/tIPmBeRtGHg== json-buffer@3.0.1: version "3.0.1" @@ -5647,10 +5778,10 @@ json-parse-even-better-errors@^2.3.0: resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== -json-parse-even-better-errors@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.1.tgz#02bb29fb5da90b5444581749c22cedd3597c6cb0" - integrity sha512-aatBvbL26wVUCLmbWdCpeu9iF5wOyWpagiKkInA+kfws3sWdBrTnsvN2CKcyCYyUrc7rebNBlK6+kteg7ksecg== +json-parse-even-better-errors@^3.0.0, json-parse-even-better-errors@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz#b43d35e89c0f3be6b5fbbe9dc6c82467b30c28da" + integrity sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ== json-schema-traverse@^0.4.1: version "0.4.1" @@ -5667,6 +5798,11 @@ json-stable-stringify-without-jsonify@^1.0.1: resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== +json-stream-stringify@^3.1.4: + version "3.1.4" + resolved "https://registry.yarnpkg.com/json-stream-stringify/-/json-stream-stringify-3.1.4.tgz#d5b10c4c709b27d3c3ef07a1926ffcc1b67c4c5d" + integrity sha512-oGoz05ft577LolnXFQHD2CjnXDxXVA5b8lHwfEZgRXQUZeCMo6sObQQRq+NXuHQ3oTeMZHHmmPY2rjVwyqR62A== + json-stringify-nice@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/json-stringify-nice/-/json-stringify-nice-1.1.4.tgz#2c937962b80181d3f317dd39aa323e14f5a60a67" @@ -5684,6 +5820,11 @@ json5@^1.0.2: dependencies: minimist "^1.2.0" +json5@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== + jsonfile@^2.1.0: version "2.4.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" @@ -5789,28 +5930,6 @@ lcid@^1.0.0: dependencies: invert-kv "^1.0.0" -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.1" - resolved "https://registry.yarnpkg.com/level/-/level-8.0.1.tgz#737161db1bc317193aca4e7b6f436e7e1df64379" - integrity sha512-oPBGkheysuw7DmzFQYyFe8NAia5jFLAgEnkgWnK3OXAuJr8qFT+xBQIwokAZPME2bhPFzS8hlYcL16m8UZrtwQ== - dependencies: - abstract-level "^1.0.4" - 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" @@ -5828,17 +5947,17 @@ levn@~0.3.0: type-check "~0.3.2" libnpmaccess@^7.0.2: - version "7.0.2" - resolved "https://registry.yarnpkg.com/libnpmaccess/-/libnpmaccess-7.0.2.tgz#7f056c8c933dd9c8ba771fa6493556b53c5aac52" - integrity sha512-vHBVMw1JFMTgEk15zRsJuSAg7QtGGHpUSEfnbcRL1/gTBag9iEfJbyjpDmdJmwMhvpoLoNBtdAUCdGnaP32hhw== + version "7.0.3" + resolved "https://registry.yarnpkg.com/libnpmaccess/-/libnpmaccess-7.0.3.tgz#9878b75c5cf36ddfff167dd47c1a6cf1fa21193c" + integrity sha512-It+fk/NRdRfv5giLhaVeyebGi/0S2LDSAwuZ0AGQ4x//PtCVb2Hj29wgSHe+XEL+RUkvLBkxbRV+DqLtOzuVTQ== dependencies: npm-package-arg "^10.1.0" npm-registry-fetch "^14.0.3" libnpmdiff@^5.0.20: - version "5.0.20" - resolved "https://registry.yarnpkg.com/libnpmdiff/-/libnpmdiff-5.0.20.tgz#fc1d310521ce9765f7bf7693ba6affa02a11bcc1" - integrity sha512-oG+qEc0qzg++1YqLwguQvXAyG8BrKq+23RHr4sCa5XZnf1U+hcKUp8itgaBY9sGRYyGXtsRgXWWFHBmqXIctDA== + version "5.0.21" + resolved "https://registry.yarnpkg.com/libnpmdiff/-/libnpmdiff-5.0.21.tgz#9d3036595a4cf393e1de07df98a40607a054d333" + integrity sha512-Zx+o/qnGoX46osnInyQQ5KI8jn2wIqXXiu4TJzE8GFd+o6kbyblJf+ihG81M1+yHK3AzkD1m4KK3+UTPXh/hBw== dependencies: "@npmcli/arborist" "^6.5.0" "@npmcli/disparity-colors" "^3.0.0" @@ -5851,13 +5970,13 @@ libnpmdiff@^5.0.20: tar "^6.1.13" libnpmexec@^6.0.4: - version "6.0.4" - resolved "https://registry.yarnpkg.com/libnpmexec/-/libnpmexec-6.0.4.tgz#205c7b77be5776576367c39f8d349e388025d77e" - integrity sha512-dhFp5yA9M2g8oLg/Ys9not+pNzW8B20pcz455TGqyU5VesXnEPQwK5EPVY8W24JJn7M0jMJ6/GxosywMPOTebA== + version "6.0.5" + resolved "https://registry.yarnpkg.com/libnpmexec/-/libnpmexec-6.0.5.tgz#36eb7e5a94a653478c8dd66b4a967cadf3f2540d" + integrity sha512-yN/7uJ3iYCPaKagHfrqXuCFLKn2ddcnYpEyC/tVhisHULC95uCy8AhUdNkThRXzhFqqptejO25ZfoWOGrdqnxA== dependencies: "@npmcli/arborist" "^6.5.0" "@npmcli/run-script" "^6.0.0" - ci-info "^3.7.1" + ci-info "^4.0.0" npm-package-arg "^10.1.0" npmlog "^7.0.1" pacote "^15.0.8" @@ -5868,32 +5987,32 @@ libnpmexec@^6.0.4: walk-up-path "^3.0.1" libnpmfund@^4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/libnpmfund/-/libnpmfund-4.2.1.tgz#f52bed09060e003c001cdaae8904ee97a3d6d5c6" - integrity sha512-2fbmQMk3wPMdPx1gbYLNbzghj48XAsfytKrmy+A0eFXwDxCwL0BLdgXoeLQCZPpLUMSPPXdKyL6Wm4erWezhnA== + version "4.2.2" + resolved "https://registry.yarnpkg.com/libnpmfund/-/libnpmfund-4.2.2.tgz#4e50507212e64fcb6a396e4c02369f6c0fc40369" + integrity sha512-qnkP09tpryxD/iPYasHM7+yG4ZVe0e91sBVI/R8HJ1+ajeR9poWDckwiN2LEWGvtV/T/dqB++6A1NLrA5NPryw== dependencies: "@npmcli/arborist" "^6.5.0" libnpmhook@^9.0.3: - version "9.0.3" - resolved "https://registry.yarnpkg.com/libnpmhook/-/libnpmhook-9.0.3.tgz#5dbd6a146feb7e11993d36a26f750ae2347bb1d9" - integrity sha512-wMZe58sI7KLhg0+nUWZW5KdMfjNNcOIIbkoP19BDHYoUF9El7eeUWkGNxUGzpHkPKiGoQ1z/v6CYin4deebeuw== + version "9.0.4" + resolved "https://registry.yarnpkg.com/libnpmhook/-/libnpmhook-9.0.4.tgz#43d893e19944a2e729b2b165a74f84a69443880d" + integrity sha512-bYD8nJiPnqeMtSsRc5bztqSh6/v16M0jQjLeO959HJqf9ZRWKRpVnFx971Rz5zbPGOB2BrQa6iopsh5vons5ww== dependencies: aproba "^2.0.0" npm-registry-fetch "^14.0.3" libnpmorg@^5.0.4: - version "5.0.4" - resolved "https://registry.yarnpkg.com/libnpmorg/-/libnpmorg-5.0.4.tgz#94eec2b84fbef736457eb27894c972ae6f5cac82" - integrity sha512-YqYXLMAN0Y1eJH4w3hUFN9648xfSdvJANMsdeZTOWJOW4Pqp8qapJFzQdqCfUkg+tEuQmnaFQQKXvkMZC51+Mw== + version "5.0.5" + resolved "https://registry.yarnpkg.com/libnpmorg/-/libnpmorg-5.0.5.tgz#baaba5c77bdfa6808975be9134a330f84b3fa4d4" + integrity sha512-0EbtEIFthVlmaj0hhC3LlEEXUZU3vKfJwfWL//iAqKjHreMhCD3cgdkld+UeWYDgsZzwzvXmopoY0l38I0yx9Q== dependencies: aproba "^2.0.0" npm-registry-fetch "^14.0.3" libnpmpack@^5.0.20: - version "5.0.20" - resolved "https://registry.yarnpkg.com/libnpmpack/-/libnpmpack-5.0.20.tgz#982e656e87bdfb69b458260d20c6ab243c661e5d" - integrity sha512-lPQXok0sU0V7hjb8oMD6HjYTR296aZvCJQZ1PGC7PeuKkBGuNeqSKVE2I9bwI80E4bFa9gfQ1I+rGfkNRjn6tQ== + version "5.0.21" + resolved "https://registry.yarnpkg.com/libnpmpack/-/libnpmpack-5.0.21.tgz#bcc608279840448fa8c28d8df0f326694d0b6061" + integrity sha512-mQd3pPx7Xf6i2A6QnYcCmgq34BmfVG3HJvpl422B5dLKfi9acITqcJiJ2K7adhxPKZMF5VbP2+j391cs5w+xww== dependencies: "@npmcli/arborist" "^6.5.0" "@npmcli/run-script" "^6.0.0" @@ -5901,11 +6020,11 @@ libnpmpack@^5.0.20: pacote "^15.0.8" libnpmpublish@^7.5.1: - version "7.5.1" - resolved "https://registry.yarnpkg.com/libnpmpublish/-/libnpmpublish-7.5.1.tgz#80f0b5d30210156af7a1b98b1a7bff06bd868684" - integrity sha512-z/7HYMtuRrNgcftrI9ILXezZWHYHG0RaIZFfUvcLktE75vrScE3zOO+qvAbvQodQi4YvYoOGF1ySQ8tdbDCYQQ== + version "7.5.2" + resolved "https://registry.yarnpkg.com/libnpmpublish/-/libnpmpublish-7.5.2.tgz#1b2780a4a56429d6dea332174286179b8d6f930c" + integrity sha512-azAxjEjAgBkbPHUGsGdMbTScyiLcTKdEnNYwGS+9yt+fUsNyiYn8hNH3+HeWKaXzFjvxi50MrHw1yp1gg5pumQ== dependencies: - ci-info "^3.6.1" + ci-info "^4.0.0" normalize-package-data "^5.0.0" npm-package-arg "^10.1.0" npm-registry-fetch "^14.0.3" @@ -5915,24 +6034,24 @@ libnpmpublish@^7.5.1: ssri "^10.0.1" libnpmsearch@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/libnpmsearch/-/libnpmsearch-6.0.2.tgz#b6a531a312855dd3bf84dd273b1033dd09b4cbec" - integrity sha512-p+5BF19AvnVg8mcIQhy6yWhI6jHQRVMYaIaKeITEfYAffWsqbottA/WZdMtHL76hViC6SFM1WdclM1w5eAIa1g== + version "6.0.3" + resolved "https://registry.yarnpkg.com/libnpmsearch/-/libnpmsearch-6.0.3.tgz#f6001910b4a68341c2aa3f6f9505e665ed98759e" + integrity sha512-4FLTFsygxRKd+PL32WJlFN1g6gkfx3d90PjgSgd6kl9nJ55sZQAqNyi1M7QROKB4kN8JCNCphK8fQYDMg5bCcg== dependencies: npm-registry-fetch "^14.0.3" libnpmteam@^5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/libnpmteam/-/libnpmteam-5.0.3.tgz#196657e9d87c0cc914c44fee588ad2b838074a3c" - integrity sha512-7XOGhi45s+ml6TyrhJUTyrErcoDMKGKfEtiTEco4ofU7BGGAUOalVztKMVLLJgJOOXdIAIlzCHqkTXEuSiyCiA== + version "5.0.4" + resolved "https://registry.yarnpkg.com/libnpmteam/-/libnpmteam-5.0.4.tgz#255ac22d94e4b9e911456bf97c1dc1013df03659" + integrity sha512-yN2zxNb8Urvvo7fTWRcP3E/KPtpZJXFweDWcl+H/s3zopGDI9ahpidddGVG98JhnPl3vjqtZvFGU3/sqVTfuIw== dependencies: aproba "^2.0.0" npm-registry-fetch "^14.0.3" libnpmversion@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/libnpmversion/-/libnpmversion-4.0.2.tgz#cad9cd1b287fcf9576a64edfe71491b49a65d06f" - integrity sha512-n1X70mFHv8Piy4yos+MFWUARSkTbyV5cdsHScaIkuwYvRAF/s2VtYScDzWB4Oe8uNEuGNdjiRR1E/Dh1tMvv6g== + version "4.0.3" + resolved "https://registry.yarnpkg.com/libnpmversion/-/libnpmversion-4.0.3.tgz#f4d85d3eb6bdbf7de8d9317abda92528e84b1a53" + integrity sha512-eD1O5zr0ko5pjOdz+2NyTEzP0kzKG8VIVyU+hIsz61cRmTrTxFRJhVBNOI1Q/inifkcM/UTl8EMfa0vX48zfoQ== dependencies: "@npmcli/git" "^4.0.1" "@npmcli/run-script" "^6.0.0" @@ -6072,12 +6191,12 @@ lodash.uniqby@^4.7.0: resolved "https://registry.yarnpkg.com/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz#d99c07a669e9e6d24e1362dfe266c67616af1302" integrity sha512-e/zcLx6CSbmaEgFHCA7BnoQKyCtKMxnuWrJygbwPs/AIn+IMKl66L8/s+wBUn5LRw2pZx3bUHibiV1b6aTWIww== -lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.21, lodash@^4.17.4: +lodash@4.17.21, lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.21, lodash@^4.17.4: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== -log-symbols@4.1.0: +log-symbols@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== @@ -6085,10 +6204,10 @@ log-symbols@4.1.0: chalk "^4.1.0" is-unicode-supported "^0.1.0" -logform@^2.3.2, logform@^2.4.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/logform/-/logform-2.6.0.tgz#8c82a983f05d6eaeb2d75e3decae7a768b2bf9b5" - integrity sha512-1ulHeNPp6k/LD8H91o7VYFBng5i1BDE7HoKxVbZiGFidS1Rj65qcywLxX+pVfAPoQJEjRdvKcusKwOupHCVOVQ== +logform@^2.6.0, logform@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/logform/-/logform-2.6.1.tgz#71403a7d8cae04b2b734147963236205db9b3df0" + integrity sha512-CdaO738xRapbKIMVn2m4F6KTj4j7ooJ8POVnebSgKo3KBz5axNXRAL7ZdRjIV6NOr2Uf4vjtRkxrFETOioCqSA== dependencies: "@colors/colors" "1.6.0" "@types/triple-beam" "^1.3.2" @@ -6109,17 +6228,15 @@ lowercase-keys@^3.0.0: resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-3.0.0.tgz#c5e7d442e37ead247ae9db117a9d0a467c89d4f2" integrity sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ== -lru-cache@^10.0.1, "lru-cache@^9.1.1 || ^10.0.0": - version "10.2.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.2.0.tgz#0bd445ca57363465900f4d1f9bd8db343a4d95c3" - integrity sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q== +lru-cache@^10.0.1, lru-cache@^10.2.0: + version "10.4.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119" + integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ== -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@^11.0.0: + version "11.0.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-11.0.1.tgz#3a732fbfedb82c5ba7bca6564ad3f42afcb6e147" + integrity sha512-CgeuL5uom6j/ZVrg7G/+1IXqRY8JXX4Hghfy5YE0EhoYQWvndP1kufu58cmZLNIDKnRhZrXfdS9urVWx98AipQ== lru-cache@^6.0.0: version "6.0.0" @@ -6186,6 +6303,24 @@ make-fetch-happen@^11.0.0, make-fetch-happen@^11.0.1, make-fetch-happen@^11.1.1: socks-proxy-agent "^7.0.0" ssri "^10.0.0" +make-fetch-happen@^13.0.0: + version "13.0.1" + resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-13.0.1.tgz#273ba2f78f45e1f3a6dca91cede87d9fa4821e36" + integrity sha512-cKTUFc/rbKUd/9meOvgrpJ2WrNzymt6jfRDdwg5UCnVzv9dTpEj9JS5m3wtziXVCjluIXyL8pcaukYqezIzZQA== + dependencies: + "@npmcli/agent" "^2.0.0" + cacache "^18.0.0" + http-cache-semantics "^4.1.1" + is-lambda "^1.0.1" + minipass "^7.0.2" + minipass-fetch "^3.0.0" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.4" + negotiator "^0.6.3" + proc-log "^4.2.0" + promise-retry "^2.0.1" + ssri "^10.0.0" + map-obj@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" @@ -6223,11 +6358,6 @@ match-all@^1.2.6: resolved "https://registry.yarnpkg.com/match-all/-/match-all-1.2.6.tgz#66d276ad6b49655551e63d3a6ee53e8be0566f8d" integrity sha512-0EESkXiTkWzrQQntBu2uzKvLu6vVkUGz40nGPbSZuegcfE5UuSzNjLaIu76zJWuaT/2I3Z/8M06OlUOZLGwLlQ== -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" @@ -6237,15 +6367,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" - memory-pager@^1.0.2: version "1.5.0" resolved "https://registry.yarnpkg.com/memory-pager/-/memory-pager-1.5.0.tgz#d8751655d22d384682741c972f2c3d6dfa3e66b5" @@ -6294,11 +6415,11 @@ micro-ftch@^0.3.1: integrity sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg== micromatch@^4.0.0, micromatch@^4.0.2, micromatch@^4.0.4: - version "4.0.5" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" - integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + version "4.0.8" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202" + integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA== dependencies: - braces "^3.0.2" + braces "^3.0.3" picomatch "^2.3.1" mime-db@1.52.0: @@ -6314,9 +6435,9 @@ mime-types@^2.1.12: mime-db "1.52.0" mime@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/mime/-/mime-4.0.1.tgz#ad7563d1bfe30253ad97dedfae2b1009d01b9470" - integrity sha512-5lZ5tyrIfliMXzFtkYyekWbtRXObT9OWa8IwQ5uxTBDHucNNwniRqo0yInflj+iYi5CBa6qxadGzGarDfuEOxA== + version "4.0.4" + resolved "https://registry.yarnpkg.com/mime/-/mime-4.0.4.tgz#9f851b0fc3c289d063b20a7a8055b3014b25664b" + integrity sha512-v8yqInVjhXyqP6+Kw4fV3ZzeMRqEW6FotRsKXjRS5VMTNIuXsdRoAvklpoRgSqXm6o9VNH4/C0mgedko9DdLsQ== mimic-fn@^2.1.0: version "2.1.0" @@ -6360,24 +6481,24 @@ minimalistic-crypto-utils@^1.0.1: dependencies: brace-expansion "^1.1.7" -minimatch@5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b" - integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g== +minimatch@^10.0.0: + version "10.0.1" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-10.0.1.tgz#ce0521856b453c86e25f2c4c0d03e6ff7ddc440b" + integrity sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ== dependencies: brace-expansion "^2.0.1" -minimatch@^5.0.1: +minimatch@^5.0.1, minimatch@^5.1.6: version "5.1.6" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== dependencies: brace-expansion "^2.0.1" -minimatch@^9.0.0, minimatch@^9.0.1, minimatch@^9.0.3: - version "9.0.3" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" - integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== +minimatch@^9.0.0, minimatch@^9.0.3, minimatch@^9.0.4, minimatch@^9.0.5: + version "9.0.5" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5" + integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== dependencies: brace-expansion "^2.0.1" @@ -6402,6 +6523,13 @@ minipass-collect@^1.0.2: dependencies: minipass "^3.0.0" +minipass-collect@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-2.0.1.tgz#1621bc77e12258a12c60d34e2276ec5c20680863" + integrity sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw== + dependencies: + minipass "^7.0.3" + minipass-fetch@^2.0.3: version "2.1.2" resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-2.1.2.tgz#95560b50c472d81a3bc76f20ede80eaed76d8add" @@ -6414,9 +6542,9 @@ minipass-fetch@^2.0.3: encoding "^0.1.13" minipass-fetch@^3.0.0: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-3.0.4.tgz#4d4d9b9f34053af6c6e597a64be8e66e42bf45b7" - integrity sha512-jHAqnA728uUpIaFm7NWsCnqKT6UqZz7GcI/bDpPATuwYyKwJwW0remxSCxUlKiEty+eopHGa3oc8WxgQ1FFJqg== + version "3.0.5" + resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-3.0.5.tgz#f0f97e40580affc4a35cc4a1349f05ae36cb1e4c" + integrity sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg== dependencies: minipass "^7.0.3" minipass-sized "^1.0.3" @@ -6432,9 +6560,9 @@ minipass-flush@^1.0.5: minipass "^3.0.0" minipass-json-stream@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minipass-json-stream/-/minipass-json-stream-1.0.1.tgz#7edbb92588fbfc2ff1db2fc10397acb7b6b44aa7" - integrity sha512-ODqY18UZt/I8k+b7rl2AENgbWE8IDYam+undIJONvigAz8KR5GWblsFTEfQs0WODsjbSXWlm+JHEv8Gr6Tfdbg== + version "1.0.2" + resolved "https://registry.yarnpkg.com/minipass-json-stream/-/minipass-json-stream-1.0.2.tgz#5121616c77a11c406c3ffa77509e0b77bb267ec3" + integrity sha512-myxeeTm57lYs8pH2nxPzmEEg8DGIgW+9mv6D4JZD2pa81I/OBjeU7PtICXV6c9eRGTA5JMDsuIPUZRCyBMYNhg== dependencies: jsonparse "^1.3.1" minipass "^3.0.0" @@ -6465,10 +6593,10 @@ minipass@^5.0.0: resolved "https://registry.yarnpkg.com/minipass/-/minipass-5.0.0.tgz#3e9788ffb90b694a5d0ec94479a45b5d8738133d" integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ== -"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.0.3: - version "7.0.4" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.4.tgz#dbce03740f50a4786ba994c1fb908844d27b038c" - integrity sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ== +"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.0.2, minipass@^7.0.3, minipass@^7.0.4, minipass@^7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.1.2.tgz#93a9626ce5e5e66bd4db86849e7515e92340a707" + integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw== minizlib@^2.1.1, minizlib@^2.1.2: version "2.1.2" @@ -6498,65 +6626,54 @@ mnemonist@^0.38.0: obliterator "^2.0.0" mocha@^10.0.0, mocha@^10.2.0: - version "10.2.0" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.2.0.tgz#1fd4a7c32ba5ac372e03a17eef435bd00e5c68b8" - integrity sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg== - dependencies: - ansi-colors "4.1.1" - browser-stdout "1.3.1" - chokidar "3.5.3" - debug "4.3.4" - diff "5.0.0" - escape-string-regexp "4.0.0" - find-up "5.0.0" - glob "7.2.0" - he "1.2.0" - js-yaml "4.1.0" - log-symbols "4.1.0" - minimatch "5.0.1" - ms "2.1.3" - nanoid "3.3.3" - serialize-javascript "6.0.0" - strip-json-comments "3.1.1" - supports-color "8.1.1" - workerpool "6.2.1" - yargs "16.2.0" - yargs-parser "20.2.4" - yargs-unparser "2.0.0" + version "10.7.3" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.7.3.tgz#ae32003cabbd52b59aece17846056a68eb4b0752" + integrity sha512-uQWxAu44wwiACGqjbPYmjo7Lg8sFrS3dQe7PP2FQI+woptP4vZXSMcfMyFL/e1yFEeEpV4RtyTpZROOKmxis+A== + dependencies: + ansi-colors "^4.1.3" + browser-stdout "^1.3.1" + chokidar "^3.5.3" + debug "^4.3.5" + diff "^5.2.0" + escape-string-regexp "^4.0.0" + find-up "^5.0.0" + glob "^8.1.0" + he "^1.2.0" + js-yaml "^4.1.0" + log-symbols "^4.1.0" + minimatch "^5.1.6" + ms "^2.1.3" + serialize-javascript "^6.0.2" + strip-json-comments "^3.1.1" + supports-color "^8.1.1" + workerpool "^6.5.1" + yargs "^16.2.0" + yargs-parser "^20.2.9" + yargs-unparser "^2.0.0" modify-values@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022" integrity sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw== -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== - mongodb-connection-string-url@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.0.tgz#b4f87f92fd8593f3b9365f592515a06d304a1e9c" - integrity sha512-t1Vf+m1I5hC2M5RJx/7AtxgABy1cZmIPQRMXw+gEIPn/cZNF3Oiy+l0UIypUwVB5trcWHq3crg2g3uAR9aAwsQ== + version "3.0.1" + resolved "https://registry.yarnpkg.com/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.1.tgz#c13e6ac284ae401752ebafdb8cd7f16c6723b141" + integrity sha512-XqMGwRX0Lgn05TDB4PyG2h2kKO/FfWJyCzYQbIhXUxz7ETt0I/FqHjUeqj37irJ+Dl1ZtU82uYyj14u2XsZKfg== dependencies: "@types/whatwg-url" "^11.0.2" whatwg-url "^13.0.0" mongodb@^6.1.0, mongodb@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-6.3.0.tgz#ec9993b19f7ed2ea715b903fcac6171c9d1d38ca" - integrity sha512-tt0KuGjGtLUhLoU263+xvQmPHEGTw5LbcNC73EoFRYgSHwZt5tsoJC110hDyO1kjQzpgNrpdcSza9PknWN4LrA== + version "6.9.0" + resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-6.9.0.tgz#743ebfff6b3c14b04ac6e00a55e30d4127d3016d" + integrity sha512-UMopBVx1LmEUbW/QE0Hw18u583PEDVQmUmVzzBRH0o/xtE9DBRA5ZYLOjpLIa03i8FXjzvQECJcqoMvCXftTUA== dependencies: - "@mongodb-js/saslprep" "^1.1.0" - bson "^6.2.0" + "@mongodb-js/saslprep" "^1.1.5" + bson "^6.7.0" mongodb-connection-string-url "^3.0.0" -ms@2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -ms@2.1.3, ms@^2.0.0, ms@^2.1.1, ms@^2.1.2: +ms@^2.0.0, ms@^2.1.1, ms@^2.1.2, ms@^2.1.3: version "2.1.3" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== @@ -6610,7 +6727,7 @@ murmur-128@^0.2.1: fmix "^0.1.0" imul "^1.0.0" -mute-stream@~1.0.0: +mute-stream@^1.0.0, mute-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-1.0.0.tgz#e31bd9fe62f0aed23520aa4324ea6671531e013e" integrity sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA== @@ -6620,16 +6737,6 @@ nano-base32@^1.0.1: resolved "https://registry.yarnpkg.com/nano-base32/-/nano-base32-1.0.1.tgz#ba548c879efcfb90da1c4d9e097db4a46c9255ef" integrity sha512-sxEtoTqAPdjWVGv71Q17koMFGsOMSiHsIFEvzOM7cNp8BXB4AnEwmDabm5dorusJf/v1z7QxaZYxUorU9RKaAw== -nanoid@3.3.3: - version "3.3.3" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" - integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== - -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-lite@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz#17b09581988979fddafe0201e931ba933c96cbb4" @@ -6640,6 +6747,17 @@ natural-compare@^1.4.0: resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== +ndjson@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ndjson/-/ndjson-2.0.0.tgz#320ac86f6fe53f5681897349b86ac6f43bfa3a19" + integrity sha512-nGl7LRGrzugTtaFcJMhLbpzJM6XdivmbkdlaGcrk/LXg2KL/YBC6z1g70xh0/al+oFuVFP8N8kiWRucmeEH/qQ== + dependencies: + json-stringify-safe "^5.0.1" + minimist "^1.2.5" + readable-stream "^3.6.0" + split2 "^3.0.0" + through2 "^4.0.0" + negotiator@^0.6.3: version "0.6.3" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" @@ -6667,19 +6785,19 @@ node-emoji@^1.10.0, node-emoji@^1.11.0: dependencies: lodash "^4.17.21" -node-fetch@^2.6.0, node-fetch@^2.6.1: +node-fetch@^2.6.1: version "2.7.0" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== dependencies: whatwg-url "^5.0.0" -node-gyp-build@^4.2.0, node-gyp-build@^4.3.0: - version "4.8.0" - resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.8.0.tgz#3fee9c1731df4581a3f9ead74664369ff00d26dd" - integrity sha512-u6fs2AEUljNho3EYTJNBfImO5QTo/J/1Etd+NVdCj7qWKUSN/bSLkZwhDv7I+w/MSC6qJ4cknepkAYykDdK8og== +node-gyp-build@^4.2.0: + version "4.8.2" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.8.2.tgz#4f802b71c1ab2ca16af830e6c1ea7dd1ad9496fa" + integrity sha512-IRUxE4BVsHWXkV/SFOut4qTlagw2aM8T5/vnTsmrHJvVoKueJHRc/JaFND7QDDc61kLYUJ6qlZM3sqTSyx2dTw== -node-gyp@^9.0.0, node-gyp@^9.4.0: +node-gyp@^9.0.0, node-gyp@^9.4.1: version "9.4.1" resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-9.4.1.tgz#8a1023e0d6766ecb52764cc3a734b36ff275e185" integrity sha512-OQkWKbjQKbGkMf/xqI1jjy3oCTgMKJac58G2+bjZb3fza6gW2YrCSdMQYaoTb70crvE//Gngr4f0AgVHmqHvBQ== @@ -6716,9 +6834,9 @@ nopt@^6.0.0: abbrev "^1.0.0" nopt@^7.0.0, nopt@^7.2.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-7.2.0.tgz#067378c68116f602f552876194fd11f1292503d7" - integrity sha512-CVDtwCdhYIvnAzFoJ6NJ6dX3oga9/HyciQDnG1vQDjSLMeKLJ4A93ZqYKDrgYSr1FBY5/hMYC+2VCi24pgpkGA== + version "7.2.1" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-7.2.1.tgz#1cac0eab9b8e97c9093338446eddd40b2c8ca1e7" + integrity sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w== dependencies: abbrev "^2.0.0" @@ -6753,12 +6871,11 @@ normalize-package-data@^5.0.0: validate-npm-package-license "^3.0.4" normalize-package-data@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-6.0.0.tgz#68a96b3c11edd462af7189c837b6b1064a484196" - integrity sha512-UL7ELRVxYBHBgYEtZCXjxuD5vPxnmvMGq0jp/dGPKKrN7tfsBh2IY7TlJ15WWwdjRWD3RJbnsygUurTK3xkPkg== + version "6.0.2" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-6.0.2.tgz#a7bc22167fe24025412bcff0a9651eb768b03506" + integrity sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g== dependencies: hosted-git-info "^7.0.0" - is-core-module "^2.8.1" semver "^7.3.5" validate-npm-package-license "^3.0.4" @@ -6768,9 +6885,9 @@ normalize-path@^3.0.0, normalize-path@~3.0.0: integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== normalize-url@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-8.0.0.tgz#593dbd284f743e8dcf6a5ddf8fadff149c82701a" - integrity sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw== + version "8.0.1" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-8.0.1.tgz#9b7d96af9836577c58f5883e939365fa15623a4a" + integrity sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w== npm-audit-report@^5.0.0: version "5.0.0" @@ -6778,13 +6895,13 @@ npm-audit-report@^5.0.0: integrity sha512-EkXrzat7zERmUhHaoren1YhTxFwsOu5jypE84k6632SXTHcQE1z8V51GC6GVZt8LxkC+tbBcKMUBZAgk8SUSbw== npm-bundled@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-3.0.0.tgz#7e8e2f8bb26b794265028491be60321a25a39db7" - integrity sha512-Vq0eyEQy+elFpzsKjMss9kxqb9tG3YHg4dsyWuUENuzvSUWe1TCnW/vV9FkhvBk/brEDoDiVd+M1Btosa6ImdQ== + version "3.0.1" + resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-3.0.1.tgz#cca73e15560237696254b10170d8f86dad62da25" + integrity sha512-+AvaheE/ww1JEwRHOrn4WHNzOxGtVp+adrg2AeZS/7KuxGUYFuBta98wYpfHBbJp6Tg6j1NKSEVHNcfZzJHQwQ== dependencies: npm-normalize-package-bin "^3.0.0" -npm-install-checks@^6.0.0, npm-install-checks@^6.2.0: +npm-install-checks@^6.0.0, npm-install-checks@^6.2.0, npm-install-checks@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/npm-install-checks/-/npm-install-checks-6.3.0.tgz#046552d8920e801fa9f919cad569545d60e826fe" integrity sha512-W29RiK/xtpCGqn6f3ixfRYGk+zRyr+Ew9F2E20BfXxT5/euLdA/Nm7fO7OeTGuAmTs30cpgInyJ0cYe708YTZw== @@ -6806,6 +6923,16 @@ npm-package-arg@^10.0.0, npm-package-arg@^10.1.0: semver "^7.3.5" validate-npm-package-name "^5.0.0" +npm-package-arg@^11.0.0: + version "11.0.3" + resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-11.0.3.tgz#dae0c21199a99feca39ee4bfb074df3adac87e2d" + integrity sha512-sHGJy8sOC1YraBywpzQlIKBE4pBbGbiF95U6Auspzyem956E0+FtDtsx1ZxlOJkQCZ1AFXAY/yuvtFYrOxF+Bw== + dependencies: + hosted-git-info "^7.0.0" + proc-log "^4.0.0" + semver "^7.3.5" + validate-npm-package-name "^5.0.0" + npm-packlist@^7.0.0: version "7.0.4" resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-7.0.4.tgz#033bf74110eb74daf2910dc75144411999c5ff32" @@ -6844,6 +6971,20 @@ npm-registry-fetch@^14.0.0, npm-registry-fetch@^14.0.3, npm-registry-fetch@^14.0 npm-package-arg "^10.0.0" proc-log "^3.0.0" +npm-registry-fetch@^17.1.0: + version "17.1.0" + resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-17.1.0.tgz#fb69e8e762d456f08bda2f5f169f7638fb92beb1" + integrity sha512-5+bKQRH0J1xG1uZ1zMNvxW0VEyoNWgJpY9UDuluPFLKDfJ9u2JmmjmTJV1srBGQOROfdBMiVvnH2Zvpbm+xkVA== + dependencies: + "@npmcli/redact" "^2.0.0" + jsonparse "^1.3.1" + make-fetch-happen "^13.0.0" + minipass "^7.0.2" + minipass-fetch "^3.0.0" + minizlib "^2.1.2" + npm-package-arg "^11.0.0" + proc-log "^4.0.0" + npm-run-path@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" @@ -6852,21 +6993,21 @@ npm-run-path@^4.0.1: path-key "^3.0.0" npm-run-path@^5.1.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-5.2.0.tgz#224cdd22c755560253dd71b83a1ef2f758b2e955" - integrity sha512-W4/tgAXFqFA0iL7fk0+uQ3g7wkL8xJmx3XdK0VGb4cHW//eZTtKGvFBBoRKVTpY7n6ze4NL9ly7rgXcHufqXKg== + version "5.3.0" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-5.3.0.tgz#e23353d0ebb9317f174e93417e4a4d82d0249e9f" + integrity sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ== dependencies: path-key "^4.0.0" npm-user-validate@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/npm-user-validate/-/npm-user-validate-2.0.0.tgz#7b69bbbff6f7992a1d9a8968d52fd6b6db5431b6" - integrity sha512-sSWeqAYJ2dUPStJB+AEj0DyLRltr/f6YNcvCA7phkB8/RMLMnVsQ41GMwHo/ERZLYNDsyB2wPm7pZo1mqPOl7Q== + version "2.0.1" + resolved "https://registry.yarnpkg.com/npm-user-validate/-/npm-user-validate-2.0.1.tgz#097afbf0a2351e2a8f478f1ba07960b368f2a25c" + integrity sha512-d17PKaF2h8LSGFl5j4b1gHOJt1fgH7YUcCm1kNSJvaLWWKXlBsuUvx0bBEkr0qhsVA9XP5LtRZ83hdlhm2QkgA== npm@^9.5.0: - version "9.9.2" - resolved "https://registry.yarnpkg.com/npm/-/npm-9.9.2.tgz#28133f81643bce36c1c8bcb57b51e1ee53583df7" - integrity sha512-D3tV+W0PzJOlwo8YmO6fNzaB1CrMVYd1V+2TURF6lbCbmZKqMsYgeQfPVvqiM3zbNSJPhFEnmlEXIogH2Vq7PQ== + version "9.9.3" + resolved "https://registry.yarnpkg.com/npm/-/npm-9.9.3.tgz#18272a7b966721417691fec0ca18f7fbe4a9794e" + integrity sha512-Z1l+rcQ5kYb17F3hHtO601arEpvdRYnCLtg8xo3AGtyj3IthwaraEOexI9903uANkifFbqHC8hT53KIrozWg8A== dependencies: "@isaacs/string-locale-compare" "^1.1.0" "@npmcli/arborist" "^6.5.0" @@ -6878,21 +7019,21 @@ npm@^9.5.0: "@npmcli/run-script" "^6.0.2" abbrev "^2.0.0" archy "~1.0.0" - cacache "^17.1.3" + cacache "^17.1.4" chalk "^5.3.0" - ci-info "^3.8.0" + ci-info "^4.0.0" cli-columns "^4.0.0" cli-table3 "^0.6.3" columnify "^1.6.0" fastest-levenshtein "^1.0.16" - fs-minipass "^3.0.2" - glob "^10.2.7" + fs-minipass "^3.0.3" + glob "^10.3.10" graceful-fs "^4.2.11" hosted-git-info "^6.1.1" ini "^4.1.1" init-package-json "^5.0.0" is-cidr "^4.0.2" - json-parse-even-better-errors "^3.0.0" + json-parse-even-better-errors "^3.0.1" libnpmaccess "^7.0.2" libnpmdiff "^5.0.20" libnpmexec "^6.0.4" @@ -6906,14 +7047,14 @@ npm@^9.5.0: libnpmversion "^4.0.2" make-fetch-happen "^11.1.1" minimatch "^9.0.3" - minipass "^5.0.0" + minipass "^7.0.4" minipass-pipeline "^1.2.4" ms "^2.1.2" - node-gyp "^9.4.0" + node-gyp "^9.4.1" nopt "^7.2.0" normalize-package-data "^5.0.0" npm-audit-report "^5.0.0" - npm-install-checks "^6.2.0" + npm-install-checks "^6.3.0" npm-package-arg "^10.1.0" npm-pick-manifest "^8.0.2" npm-profile "^7.0.1" @@ -6926,12 +7067,12 @@ npm@^9.5.0: proc-log "^3.0.0" qrcode-terminal "^0.12.0" read "^2.1.0" - semver "^7.5.4" + semver "^7.6.0" sigstore "^1.9.0" spdx-expression-parse "^3.0.1" - ssri "^10.0.4" + ssri "^10.0.5" supports-color "^9.4.0" - tar "^6.1.15" + tar "^6.2.0" text-table "~0.2.0" tiny-relative-date "^1.3.0" treeverse "^3.0.0" @@ -6977,17 +7118,17 @@ object-assign@^4.1.0: resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== -object-inspect@^1.13.1, object-inspect@^1.9.0: - version "1.13.1" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2" - integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ== +object-inspect@^1.13.1: + version "1.13.2" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.2.tgz#dea0088467fb991e67af4058147a24824a3043ff" + integrity sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g== object-keys@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== -object.assign@^4.1.2, object.assign@^4.1.4: +object.assign@^4.1.2, object.assign@^4.1.5: version "4.1.5" resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.5.tgz#3a833f9ab7fdb80fc9e8d2300c803d216d8fdbb0" integrity sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ== @@ -6998,41 +7139,41 @@ object.assign@^4.1.2, object.assign@^4.1.4: object-keys "^1.1.1" object.entries@^1.1.5: - version "1.1.7" - resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.7.tgz#2b47760e2a2e3a752f39dd874655c61a7f03c131" - integrity sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA== + version "1.1.8" + resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.8.tgz#bffe6f282e01f4d17807204a24f8edd823599c41" + integrity sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ== dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" + call-bind "^1.0.7" + define-properties "^1.2.1" + es-object-atoms "^1.0.0" -object.fromentries@^2.0.7: - version "2.0.7" - resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.7.tgz#71e95f441e9a0ea6baf682ecaaf37fa2a8d7e616" - integrity sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA== +object.fromentries@^2.0.8: + version "2.0.8" + resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.8.tgz#f7195d8a9b97bd95cbc1999ea939ecd1a2b00c65" + integrity sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ== dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.2" + es-object-atoms "^1.0.0" -object.groupby@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/object.groupby/-/object.groupby-1.0.1.tgz#d41d9f3c8d6c778d9cbac86b4ee9f5af103152ee" - integrity sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ== +object.groupby@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/object.groupby/-/object.groupby-1.0.3.tgz#9b125c36238129f6f7b61954a1e7176148d5002e" + integrity sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ== dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - get-intrinsic "^1.2.1" + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.2" -object.values@^1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.7.tgz#617ed13272e7e1071b43973aa1655d9291b8442a" - integrity sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng== +object.values@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.2.0.tgz#65405a9d92cee68ac2d303002e0b8470a4d9ab1b" + integrity sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ== dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" + call-bind "^1.0.7" + define-properties "^1.2.1" + es-object-atoms "^1.0.0" obliterator@^2.0.0: version "2.0.4" @@ -7089,16 +7230,16 @@ optionator@^0.8.1: word-wrap "~1.2.3" optionator@^0.9.3: - version "0.9.3" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" - integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg== + version "0.9.4" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.4.tgz#7ea1c1a5d91d764fb282139c88fe11e182a3a734" + integrity sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g== dependencies: - "@aashutoshrathi/word-wrap" "^1.2.3" deep-is "^0.1.3" fast-levenshtein "^2.0.6" levn "^0.4.1" prelude-ls "^1.2.1" type-check "^0.4.0" + word-wrap "^1.2.5" ordinal@^1.0.3: version "1.0.3" @@ -7203,9 +7344,9 @@ p-map@^4.0.0: aggregate-error "^3.0.0" p-map@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-7.0.1.tgz#1faf994e597160f7851882926bfccabc1d226f80" - integrity sha512-2wnaR0XL/FDOj+TgpDuRb2KTjLnu3Fma6b1ZUwGY7LcqenMcvP/YFpjpbPKY6WVGsbuJZRuoUz8iPrt8ORnAFw== + version "7.0.2" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-7.0.2.tgz#7c5119fada4755660f70199a66aa3fe2f85a1fe8" + integrity sha512-z4cYYMMdKHzw4O5UkWJImbZynVIo0lSGTXc7bzB1e/rrDqkgGUNysK/o4bTr+0+xKvvLoTyGqYC4Fgljy9qe1Q== p-reduce@^2.0.0: version "2.1.0" @@ -7227,6 +7368,11 @@ p-try@^2.0.0: resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== +package-json-from-dist@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz#4f1471a010827a86f94cfd9b0727e36d267de505" + integrity sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw== + package-json@^8.1.0: version "8.1.1" resolved "https://registry.yarnpkg.com/package-json/-/package-json-8.1.1.tgz#3e9948e43df40d1e8e78a85485f1070bf8f03dc8" @@ -7287,6 +7433,14 @@ parse-conflict-json@^3.0.0, parse-conflict-json@^3.0.1: just-diff "^6.0.0" just-diff-apply "^5.2.0" +parse-imports@^2.1.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/parse-imports/-/parse-imports-2.2.1.tgz#0a6e8b5316beb5c9905f50eb2bbb8c64a4805642" + integrity sha512-OL/zLggRp8mFhKL0rNORUTR4yBYujK/uU+xZL+/0Rgm2QE4nLO9v8PzEweSJEbMGKmDRjJE4R3IMJlL2di4JeQ== + dependencies: + es-module-lexer "^1.5.3" + slashes "^3.0.12" + parse-json@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" @@ -7365,14 +7519,22 @@ path-parse@^1.0.6, path-parse@^1.0.7: resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== -path-scurry@^1.10.1: - version "1.10.1" - resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.10.1.tgz#9ba6bf5aa8500fe9fd67df4f0d9483b2b0bfc698" - integrity sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ== +path-scurry@^1.11.1: + version "1.11.1" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.11.1.tgz#7960a668888594a0720b12a911d1a742ab9f11d2" + integrity sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA== dependencies: - lru-cache "^9.1.1 || ^10.0.0" + lru-cache "^10.2.0" minipass "^5.0.0 || ^6.0.2 || ^7.0.0" +path-scurry@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-2.0.0.tgz#9f052289f23ad8bf9397a2a0425e7b8615c58580" + integrity sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg== + dependencies: + lru-cache "^11.0.0" + minipass "^7.1.2" + path-type@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" @@ -7408,6 +7570,11 @@ pbkdf2@^3.0.17: safe-buffer "^5.0.1" sha.js "^2.4.8" +picocolors@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.0.tgz#5358b76a78cde483ba5cef6a9dc9671440b27d59" + integrity sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw== + picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" @@ -7453,10 +7620,15 @@ pluralize@^8.0.0: resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-8.0.0.tgz#1a6fa16a38d12a1901e0320fa017051c539ce3b1" integrity sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA== +possible-typed-array-names@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz#89bb63c6fada2c3e90adc4a647beeeb39cc7bf8f" + integrity sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q== + postcss-selector-parser@^6.0.10: - version "6.0.15" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.15.tgz#11cc2b21eebc0b99ea374ffb9887174855a01535" - integrity sha512-rEYkQOMUCEMhsKbK66tbEU9QVIxbhN18YiniAwA7XQYTVBqrBy+P2p5JcdqsHgKM2zWylp8d7J6eszocfds5Sw== + version "6.1.2" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz#27ecb41fb0e3b6ba7a1ec84fff347f734c7929de" + integrity sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg== dependencies: cssesc "^3.0.0" util-deprecate "^1.0.2" @@ -7481,6 +7653,11 @@ proc-log@^3.0.0: resolved "https://registry.yarnpkg.com/proc-log/-/proc-log-3.0.0.tgz#fb05ef83ccd64fd7b20bbe9c8c1070fc08338dd8" integrity sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A== +proc-log@^4.0.0, proc-log@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/proc-log/-/proc-log-4.2.0.tgz#b6f461e4026e75fdfe228b265e9f7a00779d7034" + integrity sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA== + process-nextick-args@~2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" @@ -7525,11 +7702,11 @@ prompts@^2.4.2: sisteransi "^1.0.5" promzard@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/promzard/-/promzard-1.0.0.tgz#3246f8e6c9895a77c0549cefb65828ac0f6c006b" - integrity sha512-KQVDEubSUHGSt5xLakaToDFrSoZhStB8dXLzk2xvwR67gJktrHFvpR63oZgHyK19WKbHFLXJqCPXdVR3aBP8Ig== + version "1.0.2" + resolved "https://registry.yarnpkg.com/promzard/-/promzard-1.0.2.tgz#2226e7c6508b1da3471008ae17066a7c3251e660" + integrity sha512-2FPputGL+mP3jJ3UZg/Dl9YOkovB7DX0oOr+ck5QbZ5MtORtds8k/BZdn+02peDLI8/YWbmzx34k5fA+fHvCVQ== dependencies: - read "^2.0.0" + read "^3.0.1" proper-lockfile@^4.1.1: version "4.1.2" @@ -7566,13 +7743,13 @@ qrcode-terminal@^0.12.0: integrity sha512-EXtzRZmC+YGmGlDFbXKxQiMZNwCLEO6BANKXG4iCtSIM0yqc/pappSx3RIKr4r0uh5JsBckOXeKrB3Iz7mdQpQ== qs@^6.4.0, qs@^6.9.4: - version "6.11.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.2.tgz#64bea51f12c1f5da1bc01496f48ffcff7c69d7d9" - integrity sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA== + version "6.13.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.13.0.tgz#6ca3bd58439f7e245655798997787b0d88a51906" + integrity sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg== dependencies: - side-channel "^1.0.4" + side-channel "^1.0.6" -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== @@ -7699,6 +7876,22 @@ read@^2.0.0, read@^2.1.0: dependencies: mute-stream "~1.0.0" +read@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/read/-/read-3.0.1.tgz#926808f0f7c83fa95f1ef33c0e2c09dbb28fd192" + integrity sha512-SLBrDU/Srs/9EoWhU5GdbAoxG1GzpQHo/6qiGItaoLJ1thmYpcNIM1qISEUvyHBzfGlWIyd6p2DNi1oV1VmAuw== + dependencies: + mute-stream "^1.0.0" + +readable-stream@3, readable-stream@^3.0.0, readable-stream@^3.4.0, readable-stream@^3.6.0, readable-stream@^3.6.2: + version "3.6.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + readable-stream@^2.0.0, readable-stream@^2.0.2, readable-stream@^2.2.2, readable-stream@~2.3.6: version "2.3.8" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" @@ -7712,14 +7905,10 @@ readable-stream@^2.0.0, readable-stream@^2.0.2, readable-stream@^2.2.2, readable string_decoder "~1.1.1" util-deprecate "~1.0.1" -readable-stream@^3.4.0, readable-stream@^3.6.0: - version "3.6.2" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" - integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" +readdirp@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-4.0.1.tgz#b2fe35f8dca63183cd3b86883ecc8f720ea96ae6" + integrity sha512-GkMg9uOTpIWWKbSsgwb5fA4EavTR+SG/PMPoAY8hkhHfEEY0/vqljY+XHqtDf2cr2IJtoNRDbrrEpZUiZCkYRw== readdirp@~3.6.0: version "3.6.0" @@ -7767,14 +7956,15 @@ regenerator-runtime@^0.14.0: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw== -regexp.prototype.flags@^1.5.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz#90ce989138db209f81492edd734183ce99f9677e" - integrity sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg== +regexp.prototype.flags@^1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz#138f644a3350f981a858c44f6bb1a61ff59be334" + integrity sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw== dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - set-function-name "^2.0.0" + call-bind "^1.0.6" + define-properties "^1.2.1" + es-errors "^1.3.0" + set-function-name "^2.0.1" registry-auth-token@^5.0.0, registry-auth-token@^5.0.1: version "5.0.2" @@ -7814,7 +8004,7 @@ require-from-string@^1.1.0: resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-1.2.1.tgz#529c9ccef27380adfec9a2f965b649bbee636418" integrity sha512-H7AkJWMobeskkttHyhTVtS0fxpFLjxhbfMa6Bk3wimP7sdPRGL3EyCg3sAQenFfAe+xQ+oAc85Nmtvq0ROM83Q== -require-from-string@^2.0.0, require-from-string@^2.0.2: +require-from-string@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== @@ -7921,13 +8111,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" @@ -7935,18 +8118,13 @@ 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== - -safe-array-concat@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.1.0.tgz#8d0cae9cb806d6d1c06e08ab13d847293ebe0692" - integrity sha512-ZdQ0Jeb9Ofti4hbt5lX3T2JcAamT9hfzYU1MNB+z/jaEbB6wfFfPIR/zEORmZqobkCCJhSjodobH6WHNmJ97dg== +safe-array-concat@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.1.2.tgz#81d77ee0c4e8b863635227c721278dd524c20edb" + integrity sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q== dependencies: - call-bind "^1.0.5" - get-intrinsic "^1.2.2" + call-bind "^1.0.7" + get-intrinsic "^1.2.4" has-symbols "^1.0.3" isarray "^2.0.5" @@ -7960,19 +8138,19 @@ safe-buffer@~5.1.0, safe-buffer@~5.1.1: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-regex-test@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.2.tgz#3ba32bdb3ea35f940ee87e5087c60ee786c3f6c5" - integrity sha512-83S9w6eFq12BBIJYvjMux6/dkirb8+4zJRA9cxNBVb7Wq5fJBW+Xze48WqR8pxua7bDuAaaAxtVVd4Idjp1dBQ== +safe-regex-test@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.3.tgz#a5b4c0f06e0ab50ea2c395c14d8371232924c377" + integrity sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw== dependencies: - call-bind "^1.0.5" - get-intrinsic "^1.2.2" + call-bind "^1.0.6" + es-errors "^1.3.0" is-regex "^1.1.4" safe-stable-stringify@^2.3.1: - version "2.4.3" - resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz#138c84b6f6edb3db5f8ef3ef7115b8f55ccbf886" - integrity sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g== + version "2.5.0" + resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz#4ca2f8e385f2831c432a719b108a3bf7af42a1dd" + integrity sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA== "safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": version "2.1.2" @@ -8069,17 +8247,15 @@ semver@^6.3.0, semver@^6.3.1: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.0.0, semver@^7.1.1, semver@^7.1.2, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8, semver@^7.5.2, semver@^7.5.3, semver@^7.5.4: - version "7.5.4" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" - integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== - dependencies: - lru-cache "^6.0.0" +semver@^7.0.0, semver@^7.1.1, semver@^7.1.2, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@^7.5.2, semver@^7.5.3, semver@^7.6.0, semver@^7.6.3: + version "7.6.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" + integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== -serialize-javascript@6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" - integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== +serialize-javascript@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.2.tgz#defa1e055c83bf6d59ea805d8da862254eb6a6c2" + integrity sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g== dependencies: randombytes "^2.1.0" @@ -8088,25 +8264,27 @@ set-blocking@^2.0.0: resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== -set-function-length@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.0.tgz#2f81dc6c16c7059bda5ab7c82c11f03a515ed8e1" - integrity sha512-4DBHDoyHlM1IRPGYcoxexgh67y4ueR53FKV1yyxwFMY7aCqcN/38M1+SwZ/qJQ8iLv7+ck385ot4CcisOAPT9w== +set-function-length@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449" + integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg== dependencies: - define-data-property "^1.1.1" + define-data-property "^1.1.4" + es-errors "^1.3.0" function-bind "^1.1.2" - get-intrinsic "^1.2.2" + get-intrinsic "^1.2.4" gopd "^1.0.1" - has-property-descriptors "^1.0.1" + has-property-descriptors "^1.0.2" -set-function-name@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/set-function-name/-/set-function-name-2.0.1.tgz#12ce38b7954310b9f61faa12701620a0c882793a" - integrity sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA== +set-function-name@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/set-function-name/-/set-function-name-2.0.2.tgz#16a705c5a0dc2f5e638ca96d8a8cd4e1c2b90985" + integrity sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ== dependencies: - define-data-property "^1.0.1" + define-data-property "^1.1.4" + es-errors "^1.3.0" functions-have-names "^1.2.3" - has-property-descriptors "^1.0.0" + has-property-descriptors "^1.0.2" setimmediate@^1.0.5: version "1.0.5" @@ -8162,14 +8340,15 @@ shelljs@^0.8.3: interpret "^1.0.0" rechoir "^0.6.2" -side-channel@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" - integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== +side-channel@^1.0.4, side-channel@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.6.tgz#abd25fb7cd24baf45466406b1096b7831c9215f2" + integrity sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA== dependencies: - call-bind "^1.0.0" - get-intrinsic "^1.0.2" - object-inspect "^1.9.0" + call-bind "^1.0.7" + es-errors "^1.3.0" + get-intrinsic "^1.2.4" + object-inspect "^1.13.1" signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: version "3.0.7" @@ -8223,6 +8402,11 @@ slash@^5.1.0: resolved "https://registry.yarnpkg.com/slash/-/slash-5.1.0.tgz#be3adddcdf09ac38eebe8dcdc7b1a57a75b095ce" integrity sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg== +slashes@^3.0.12: + version "3.0.12" + resolved "https://registry.yarnpkg.com/slashes/-/slashes-3.0.12.tgz#3d664c877ad542dc1509eaf2c50f38d483a6435a" + integrity sha512-Q9VME8WyGkc7pJf6QEkj3wE+2CnvZMI+XJhwdTPR8Z/kWQRXi7boAWLDibRPyHRTUTPx5FaU7MsyrjI3yLB4HA== + slice-ansi@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" @@ -8246,26 +8430,33 @@ socks-proxy-agent@^7.0.0: debug "^4.3.3" socks "^2.6.2" -socks@^2.6.2: - version "2.7.1" - resolved "https://registry.yarnpkg.com/socks/-/socks-2.7.1.tgz#d8e651247178fde79c0663043e07240196857d55" - integrity sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ== +socks-proxy-agent@^8.0.3: + version "8.0.4" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-8.0.4.tgz#9071dca17af95f483300316f4b063578fa0db08c" + integrity sha512-GNAq/eg8Udq2x0eNiFkr9gRg5bA7PXEWagQdeRX4cPSG+X/8V38v637gim9bjFptMk1QWsCTr0ttrJEiXbNnRw== + dependencies: + agent-base "^7.1.1" + debug "^4.3.4" + socks "^2.8.3" + +socks@^2.6.2, socks@^2.8.3: + version "2.8.3" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.8.3.tgz#1ebd0f09c52ba95a09750afe3f3f9f724a800cb5" + integrity sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw== dependencies: - ip "^2.0.0" + ip-address "^9.0.5" smart-buffer "^4.2.0" -solc@0.7.3: - version "0.7.3" - resolved "https://registry.yarnpkg.com/solc/-/solc-0.7.3.tgz#04646961bd867a744f63d2b4e3c0701ffdc7d78a" - integrity sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA== +solc@0.8.26: + version "0.8.26" + resolved "https://registry.yarnpkg.com/solc/-/solc-0.8.26.tgz#afc78078953f6ab3e727c338a2fefcd80dd5b01a" + integrity sha512-yiPQNVf5rBFHwN6SIf3TUUvVAFKcQqmSUFeq+fb6pNRCo0ZCgpYOZDi3BVoezCPIAcKrVYd/qXlBLUP9wVrZ9g== dependencies: command-exists "^1.2.8" - commander "3.0.2" + commander "^8.1.0" follow-redirects "^1.12.1" - fs-extra "^0.30.0" js-sha3 "0.8.0" memorystream "^0.3.1" - require-from-string "^2.0.0" semver "^5.5.0" tmp "0.0.33" @@ -8280,14 +8471,14 @@ solc@^0.4.20: semver "^5.3.0" yargs "^4.7.1" -solhint@^4.0.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/solhint/-/solhint-4.1.1.tgz#137c935ef028f01ba13687a1f237288d94dae1bf" - integrity sha512-7G4iF8H5hKHc0tR+/uyZesSKtfppFIMvPSW+Ku6MSL25oVRuyFeqNhOsXHfkex64wYJyXs4fe+pvhB069I19Tw== +solhint@^5.0.1: + version "5.0.3" + resolved "https://registry.yarnpkg.com/solhint/-/solhint-5.0.3.tgz#b57f6d2534fe09a60f9db1b92e834363edd1cbde" + integrity sha512-OLCH6qm/mZTCpplTXzXTJGId1zrtNuDYP5c2e6snIv/hdRVxPfBBz/bAlL91bY/Accavkayp2Zp2BaDSrLVXTQ== dependencies: - "@solidity-parser/parser" "^0.16.0" + "@solidity-parser/parser" "^0.18.0" ajv "^6.12.6" - antlr4 "^4.11.0" + antlr4 "^4.13.1-patch-1" ast-parents "^0.0.1" chalk "^4.1.2" commander "^10.0.0" @@ -8307,29 +8498,26 @@ solhint@^4.0.0: prettier "^2.8.3" solidity-ast@^0.4.38, solidity-ast@^0.4.51: - version "0.4.55" - resolved "https://registry.yarnpkg.com/solidity-ast/-/solidity-ast-0.4.55.tgz#00b685e6eefb2e8dfb67df1fe0afbe3b3bfb4b28" - integrity sha512-qeEU/r/K+V5lrAw8iswf2/yfWAnSGs3WKPHI+zAFKFjX0dIBVXEU/swQ8eJQYHf6PJWUZFO2uWV4V1wEOkeQbA== - dependencies: - array.prototype.findlast "^1.2.2" + version "0.4.59" + resolved "https://registry.yarnpkg.com/solidity-ast/-/solidity-ast-0.4.59.tgz#290a2815aef70a61092591ab3e991da080ae5931" + integrity sha512-I+CX0wrYUN9jDfYtcgWSe+OAowaXy8/1YQy7NS4ni5IBDmIYBq7ZzaP/7QqouLjzZapmQtvGLqCaYgoUWqBo5g== -solidity-coverage@^0.8.5: - version "0.8.6" - resolved "https://registry.yarnpkg.com/solidity-coverage/-/solidity-coverage-0.8.6.tgz#c7b18dc9edfeba11064726c37d96265f689c9478" - integrity sha512-vV03mA/0nNMskOdVwNarUcqk0N/aYdelxAbf6RZ5l84FcYHbqDTr2JXyeYMp4bT48qHtAQjnKrygW1FrECyWNw== +solidity-coverage@^0.8.12: + version "0.8.13" + resolved "https://registry.yarnpkg.com/solidity-coverage/-/solidity-coverage-0.8.13.tgz#8eeada2e82ae19d25568368aa782a2baad0e0ce7" + integrity sha512-RiBoI+kF94V3Rv0+iwOj3HQVSqNzA9qm/qDP1ZDXK5IX0Cvho1qiz8hAXTsAo6KOIUeP73jfscq0KlLqVxzGWA== dependencies: "@ethersproject/abi" "^5.0.9" "@solidity-parser/parser" "^0.18.0" chalk "^2.4.2" death "^1.1.0" - detect-port "^1.3.0" difflib "^0.2.4" fs-extra "^8.1.0" ghost-testrpc "^0.0.2" global-modules "^2.0.0" globby "^10.0.1" jsonschema "^1.2.4" - lodash "^4.17.15" + lodash "^4.17.21" mocha "^10.2.0" node-emoji "^1.10.0" pify "^4.0.1" @@ -8388,9 +8576,9 @@ spdx-correct@^3.0.0: spdx-license-ids "^3.0.0" spdx-exceptions@^2.1.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.4.0.tgz#c07a4ede25b16e4f78e6707bbd84b15a45c19c1b" - integrity sha512-hcjppoJ68fhxA/cjbN4T8N6uCUejN8yFw69ttpqtBeCbF3u13n7mb31NB9jKwGTTWWnt9IbRA/mf1FprYS8wfw== + version "2.5.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz#5d607d27fc806f66d7b64a766650fa890f04ed66" + integrity sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w== spdx-expression-parse@^3.0.0, spdx-expression-parse@^3.0.1: version "3.0.1" @@ -8400,10 +8588,25 @@ spdx-expression-parse@^3.0.0, spdx-expression-parse@^3.0.1: spdx-exceptions "^2.1.0" spdx-license-ids "^3.0.0" +spdx-expression-parse@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz#a23af9f3132115465dac215c099303e4ceac5794" + integrity sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + spdx-license-ids@^3.0.0: - version "3.0.16" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.16.tgz#a14f64e0954f6e25cc6587bd4f392522db0d998f" - integrity sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw== + version "3.0.20" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.20.tgz#e44ed19ed318dd1e5888f93325cee800f0f51b89" + integrity sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw== + +split2@^3.0.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/split2/-/split2-3.2.2.tgz#bf2cf2a37d838312c249c89206fd7a17dd12365f" + integrity sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg== + dependencies: + readable-stream "^3.0.0" split2@^4.0.0: version "4.2.0" @@ -8424,15 +8627,20 @@ split@^1.0.1: dependencies: through "2" +sprintf-js@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.3.tgz#4914b903a2f8b685d17fdf78a70e917e872e444a" + integrity sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA== + sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== -ssri@^10.0.0, ssri@^10.0.1, ssri@^10.0.4: - version "10.0.5" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-10.0.5.tgz#e49efcd6e36385196cb515d3a2ad6c3f0265ef8c" - integrity sha512-bSf16tAFkGeRlUNDjXu8FzaMQt6g2HZJrun7mtMbIPOddxt3GLMSz5VWUWcqTJUPfLEaDIepGxv+bYQW49596A== +ssri@^10.0.0, ssri@^10.0.1, ssri@^10.0.5: + version "10.0.6" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-10.0.6.tgz#a8aade2de60ba2bce8688e3fa349bad05c7dc1e5" + integrity sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ== dependencies: minipass "^7.0.3" @@ -8473,7 +8681,7 @@ string-format@^2.0.0: resolved "https://registry.yarnpkg.com/string-format/-/string-format-2.0.0.tgz#f2df2e7097440d3b65de31b6d40d54c96eaffb9b" integrity sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA== -"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", 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== @@ -8508,32 +8716,33 @@ string-width@^5.0.1, string-width@^5.1.2: emoji-regex "^9.2.2" strip-ansi "^7.0.1" -string.prototype.trim@^1.2.8: - version "1.2.8" - resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz#f9ac6f8af4bd55ddfa8895e6aea92a96395393bd" - integrity sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ== +string.prototype.trim@^1.2.9: + version "1.2.9" + resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz#b6fa326d72d2c78b6df02f7759c73f8f6274faa4" + integrity sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw== dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.0" + es-object-atoms "^1.0.0" -string.prototype.trimend@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz#1bb3afc5008661d73e2dc015cd4853732d6c471e" - integrity sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA== +string.prototype.trimend@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz#3651b8513719e8a9f48de7f2f77640b26652b229" + integrity sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ== dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" + call-bind "^1.0.7" + define-properties "^1.2.1" + es-object-atoms "^1.0.0" -string.prototype.trimstart@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz#d4cdb44b83a4737ffbac2d406e405d43d0184298" - integrity sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg== +string.prototype.trimstart@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz#7ee834dda8c7c17eff3118472bb35bfedaa34dde" + integrity sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg== dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" + call-bind "^1.0.7" + define-properties "^1.2.1" + es-object-atoms "^1.0.0" string_decoder@^1.1.1: version "1.3.0" @@ -8613,7 +8822,7 @@ strip-indent@^3.0.0: dependencies: min-indent "^1.0.0" -strip-json-comments@3.1.1, strip-json-comments@^3.1.1: +strip-json-comments@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== @@ -8623,13 +8832,6 @@ strip-json-comments@~2.0.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== -supports-color@8.1.1: - version "8.1.1" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" - integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== - dependencies: - has-flag "^4.0.0" - supports-color@^3.1.0: version "3.2.3" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" @@ -8651,6 +8853,13 @@ supports-color@^7.0.0, supports-color@^7.1.0: dependencies: has-flag "^4.0.0" +supports-color@^8.1.1: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + supports-color@^9.4.0: version "9.4.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-9.4.0.tgz#17bfcf686288f531db3dea3215510621ccb55954" @@ -8685,6 +8894,14 @@ sync-rpc@^1.2.1: dependencies: get-port "^3.1.0" +synckit@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.9.1.tgz#febbfbb6649979450131f64735aa3f6c14575c88" + integrity sha512-7gr8p9TQP6RAHusBOSLs46F4564ZrjV8xFmw5zCmgmhGUcw2hxsShhJ6CEiHQMgPDwAQ1fWHPM0ypc4RMAig4A== + dependencies: + "@pkgr/core" "^0.1.0" + tslib "^2.6.2" + table-layout@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/table-layout/-/table-layout-1.0.2.tgz#c4038a1853b0136d63365a734b6931cf4fad4a04" @@ -8696,9 +8913,9 @@ table-layout@^1.0.2: wordwrapjs "^4.0.0" table@^6.8.0, table@^6.8.1: - version "6.8.1" - resolved "https://registry.yarnpkg.com/table/-/table-6.8.1.tgz#ea2b71359fe03b017a5fbc296204471158080bdf" - integrity sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA== + version "6.8.2" + resolved "https://registry.yarnpkg.com/table/-/table-6.8.2.tgz#c5504ccf201213fa227248bdc8c5569716ac6c58" + integrity sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA== dependencies: ajv "^8.0.1" lodash.truncate "^4.4.2" @@ -8706,10 +8923,10 @@ table@^6.8.0, table@^6.8.1: string-width "^4.2.3" strip-ansi "^6.0.1" -tar@^6.1.11, tar@^6.1.13, tar@^6.1.15, tar@^6.1.2: - version "6.2.0" - resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.0.tgz#b14ce49a79cb1cd23bc9b016302dea5474493f73" - integrity sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ== +tar@^6.1.11, tar@^6.1.13, tar@^6.1.2, tar@^6.2.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.1.tgz#717549c541bc3c2af15751bea94b1dd068d4b03a" + integrity sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A== dependencies: chownr "^2.0.0" fs-minipass "^2.0.0" @@ -8733,19 +8950,6 @@ tempy@^3.0.0: type-fest "^2.12.2" unique-string "^3.0.0" -tenderly@^0.8.0: - version "0.8.0" - resolved "https://registry.yarnpkg.com/tenderly/-/tenderly-0.8.0.tgz#ffda1f40597b91470e728900e3bdfe6a4f152ec5" - integrity sha512-4Faw9jkwMuBOva82lAtvhTa9isc503GkWwVWSsR8ONm+i3SeFatv7hNyYPZIifQBeuU9GOVNkWHCAXon6NE/aw== - dependencies: - axios "^0.27.2" - cli-table3 "^0.6.2" - commander "^9.4.0" - js-yaml "^4.1.0" - open "^8.4.0" - prompts "^2.4.2" - tslog "^4.4.0" - testrpc@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/testrpc/-/testrpc-0.0.1.tgz#83e2195b1f5873aec7be1af8cbe6dcf39edb7aed" @@ -8783,6 +8987,13 @@ then-request@^6.0.0: promise "^8.0.0" qs "^6.4.0" +through2@^4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/through2/-/through2-4.0.2.tgz#a7ce3ac2a7a8b0b966c80e7c49f0484c3b239764" + integrity sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw== + dependencies: + readable-stream "3" + through2@~2.0.0: version "2.0.5" resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" @@ -8832,7 +9043,7 @@ tr46@~0.0.3: resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== -traverse@~0.6.6: +traverse@0.6.8: version "0.6.8" resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.6.8.tgz#5e5e0c41878b57e4b73ad2f3d1e36a715ea4ab15" integrity sha512-aXJDbk6SnumuaZSANd21XAo15ucCDE38H4fkqiGsc3MhCK+wOlZvLP9cB/TvpHT0mOyWgC4Z8EwRlzqYSUzdsA== @@ -8925,15 +9136,15 @@ tslib@^1.11.1, tslib@^1.8.1, tslib@^1.9.3: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.3.1, tslib@^2.5.0: - version "2.6.2" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" - integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== +tslib@^2.3.1, tslib@^2.6.2: + version "2.7.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.7.0.tgz#d9b40c5c40ab59e8738f297df3087bf1a2690c01" + integrity sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA== tslog@^4.3.1, tslog@^4.4.0: - version "4.9.2" - resolved "https://registry.yarnpkg.com/tslog/-/tslog-4.9.2.tgz#35de3a073784dfe3849caeaa028010c7a62b7f4a" - integrity sha512-wBM+LRJoNl34Bdu8mYEFxpvmOUedpNUwMNQB/NcuPIZKwdDde6xLHUev3bBjXQU7gdurX++X/YE7gLH8eXYsiQ== + version "4.9.3" + resolved "https://registry.yarnpkg.com/tslog/-/tslog-4.9.3.tgz#d4167d5f51748bdeab593945bc2d8f9827ea0dba" + integrity sha512-oDWuGVONxhVEBtschLf2cs/Jy8i7h1T+CpdkTNWQgdAF7DhRo2G8vMCgILKe7ojdEkLhICWgI1LYSSKaJsRgcw== tsort@0.0.1: version "0.0.1" @@ -8980,10 +9191,10 @@ type-check@~0.3.2: dependencies: prelude-ls "~1.1.2" -type-detect@^4.0.0, type-detect@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" - integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== +type-detect@^4.0.0, type-detect@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.1.0.tgz#deb2453e8f08dcae7ae98c626b13dddb0155906c" + integrity sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw== type-fest@^0.18.0: version "0.18.1" @@ -9025,15 +9236,15 @@ type-fest@^2.12.2: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.19.0.tgz#88068015bb33036a598b952e55e9311a60fd3a9b" integrity sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA== -type-fest@^3.0.0, type-fest@^3.8.0: +type-fest@^3.8.0: version "3.13.1" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-3.13.1.tgz#bb744c1f0678bea7543a2d1ec24e83e68e8c8706" integrity sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g== type-fest@^4.2.0: - version "4.10.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-4.10.1.tgz#35e6cd34d1fe331cf261d8ebb83e64788b89db4b" - integrity sha512-7ZnJYTp6uc04uYRISWtiX3DSKB/fxNQT0B5o1OUeCqiQiwF+JC9+rJiZIDrPrNCLLuTqyQmh4VdQqh/ZOkv9MQ== + version "4.26.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-4.26.1.tgz#a4a17fa314f976dd3e6d6675ef6c775c16d7955e" + integrity sha512-yOGpmOAL7CkKe/91I5O3gPICmJNLJ1G4zFYVAsRHg7M64biSnPtRj0WNQt++bRkjYOqjWXrhnUw1utzmVErAdg== typechain@^8.3.2: version "8.3.2" @@ -9051,54 +9262,59 @@ typechain@^8.3.2: ts-command-line-args "^2.2.0" ts-essentials "^7.0.1" -typed-array-buffer@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz#18de3e7ed7974b0a729d3feecb94338d1472cd60" - integrity sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw== +typed-array-buffer@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz#1867c5d83b20fcb5ccf32649e5e2fc7424474ff3" + integrity sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ== dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.2.1" - is-typed-array "^1.1.10" + call-bind "^1.0.7" + es-errors "^1.3.0" + is-typed-array "^1.1.13" -typed-array-byte-length@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz#d787a24a995711611fb2b87a4052799517b230d0" - integrity sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA== +typed-array-byte-length@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz#d92972d3cff99a3fa2e765a28fcdc0f1d89dec67" + integrity sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw== dependencies: - call-bind "^1.0.2" + call-bind "^1.0.7" for-each "^0.3.3" - has-proto "^1.0.1" - is-typed-array "^1.1.10" + gopd "^1.0.1" + has-proto "^1.0.3" + is-typed-array "^1.1.13" -typed-array-byte-offset@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz#cbbe89b51fdef9cd6aaf07ad4707340abbc4ea0b" - integrity sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg== +typed-array-byte-offset@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz#f9ec1acb9259f395093e4567eb3c28a580d02063" + integrity sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA== dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.2" + available-typed-arrays "^1.0.7" + call-bind "^1.0.7" for-each "^0.3.3" - has-proto "^1.0.1" - is-typed-array "^1.1.10" + gopd "^1.0.1" + has-proto "^1.0.3" + is-typed-array "^1.1.13" -typed-array-length@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.4.tgz#89d83785e5c4098bec72e08b319651f0eac9c1bb" - integrity sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng== +typed-array-length@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.6.tgz#57155207c76e64a3457482dfdc1c9d1d3c4c73a3" + integrity sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g== dependencies: - call-bind "^1.0.2" + call-bind "^1.0.7" for-each "^0.3.3" - is-typed-array "^1.1.9" + gopd "^1.0.1" + has-proto "^1.0.3" + is-typed-array "^1.1.13" + possible-typed-array-names "^1.0.0" typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== -typescript@^5.0.2, typescript@^5.2.2: - version "5.3.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.3.3.tgz#b3ce6ba258e72e6305ba66f5c9b452aaee3ffe37" - integrity sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw== +typescript@^5.0.2, typescript@^5.5.4: + version "5.6.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.6.2.tgz#d1de67b6bef77c41823f822df8f0b3bcff60a5a0" + integrity sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw== typical@^4.0.0: version "4.0.0" @@ -9111,9 +9327,9 @@ typical@^5.2.0: integrity sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg== uglify-js@^3.1.4: - version "3.17.4" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.17.4.tgz#61678cf5fa3f5b7eb789bb345df29afb8257c22c" - integrity sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g== + version "3.19.3" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.19.3.tgz#82315e9bbc6f2b25888858acd1fff8441035b77f" + integrity sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ== unbox-primitive@^1.0.2: version "1.0.2" @@ -9130,13 +9346,23 @@ undici-types@~5.26.4: resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== +undici-types@~6.19.2: + version "6.19.8" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02" + integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw== + undici@^5.14.0: - version "5.28.2" - resolved "https://registry.yarnpkg.com/undici/-/undici-5.28.2.tgz#fea200eac65fc7ecaff80a023d1a0543423b4c91" - integrity sha512-wh1pHJHnUeQV5Xa8/kyQhO7WFa8M34l026L5P/+2TYiakvGy5Rdc8jWZVyG7ieht/0WgJLEd3kcU5gKx+6GC8w== + version "5.28.4" + resolved "https://registry.yarnpkg.com/undici/-/undici-5.28.4.tgz#6b280408edb6a1a604a9b20340f45b422e373068" + integrity sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g== dependencies: "@fastify/busboy" "^2.0.0" +undici@^6.11.1: + version "6.19.8" + resolved "https://registry.yarnpkg.com/undici/-/undici-6.19.8.tgz#002d7c8a28f8cc3a44ff33c3d4be4d85e15d40e1" + integrity sha512-U8uCCl2x9TK3WANvmBavymRzxbfFYG+tAu+fgx3zxQy3qdagQqBLwJVrdyO1TBfUXvfKveMKJZhpvUYoOjM+4g== + unfetch@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/unfetch/-/unfetch-4.2.0.tgz#7e21b0ef7d363d8d9af0fb929a5555f6ef97a3be" @@ -9243,11 +9469,9 @@ validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.4: spdx-expression-parse "^3.0.0" validate-npm-package-name@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-5.0.0.tgz#f16afd48318e6f90a1ec101377fa0384cfc8c713" - integrity sha512-YuKoXDAhBYxY7SfOKxHBDoSyENFeW5VvIIQp2TGQuit8gpK6MnWaQelBKxso72DoxTZfZdcP3W90LqpSkgPzLQ== - dependencies: - builtins "^5.0.0" + version "5.0.1" + resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-5.0.1.tgz#a316573e9b49f3ccd90dbb6eb52b3f06c6d604e8" + integrity sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ== varint@^5.0.0: version "5.0.2" @@ -9267,9 +9491,9 @@ wcwidth@^1.0.0: defaults "^1.0.3" web3-utils@^1.0.0-beta.31, web3-utils@^1.3.6: - version "1.10.3" - resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.10.3.tgz#f1db99c82549c7d9f8348f04ffe4e0188b449714" - integrity sha512-OqcUrEE16fDBbGoQtZXWdavsPzbGIDc5v3VrRTZ0XrIpefC/viZ1ZU9bGEemazyS0catk/3rkOOxpzTfY+XsyQ== + version "1.10.4" + resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.10.4.tgz#0daee7d6841641655d8b3726baf33b08eda1cbec" + integrity sha512-tsu8FiKJLk2PzhDl9fXbGUWTkkVXYhtTA+SmEFkKft+9BgwLxfCRpU96sWv7ICC8zixBNd3JURVoiR3dUXgP8A== dependencies: "@ethereumjs/util" "^8.1.0" bn.js "^5.2.1" @@ -9322,16 +9546,16 @@ which-module@^1.0.0: resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" integrity sha512-F6+WgncZi/mJDrammbTuHe1q0R5hOXv/mBaiNA2TCNT/LTHusX0V+CJnj9XT8ki5ln2UZyyddDgHfCzyrOH7MQ== -which-typed-array@^1.1.11, which-typed-array@^1.1.13: - version "1.1.13" - resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.13.tgz#870cd5be06ddb616f504e7b039c4c24898184d36" - integrity sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow== +which-typed-array@^1.1.14, which-typed-array@^1.1.15: + version "1.1.15" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.15.tgz#264859e9b11a649b388bfaaf4f767df1f779b38d" + integrity sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA== dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.4" + available-typed-arrays "^1.0.7" + call-bind "^1.0.7" for-each "^0.3.3" gopd "^1.0.1" - has-tostringtag "^1.0.0" + has-tostringtag "^1.0.2" which@^1.1.1, which@^1.3.1: version "1.3.1" @@ -9361,38 +9585,45 @@ wide-align@^1.1.5: dependencies: string-width "^1.0.2 || 2 || 3 || 4" +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" + window-size@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.2.0.tgz#b4315bb4214a3d7058ebeee892e13fa24d98b075" integrity sha512-UD7d8HFA2+PZsbKyaOCEy8gMh1oDtHgJh1LfgjQ4zVXmYjAT/kvz3PueITKuqDiIXQe7yzpPnxX3lNc+AhQMyw== -winston-transport@^4.5.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.6.0.tgz#f1c1a665ad1b366df72199e27892721832a19e1b" - integrity sha512-wbBA9PbPAHxKiygo7ub7BYRiKxms0tpfU2ljtWzb3SjRjv5yl6Ozuy/TkXf00HTAt+Uylo3gSkNwzc4ME0wiIg== +winston-transport@^4.7.0: + version "4.7.1" + resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.7.1.tgz#52ff1bcfe452ad89991a0aaff9c3b18e7f392569" + integrity sha512-wQCXXVgfv/wUPOfb2x0ruxzwkcZfxcktz6JIMUaPLmcNhO4bZTwA/WtDWK74xV3F2dKu8YadrFv0qhwYjVEwhA== dependencies: - logform "^2.3.2" - readable-stream "^3.6.0" + logform "^2.6.1" + readable-stream "^3.6.2" triple-beam "^1.3.0" winston@^3.11.0: - version "3.11.0" - resolved "https://registry.yarnpkg.com/winston/-/winston-3.11.0.tgz#2d50b0a695a2758bb1c95279f0a88e858163ed91" - integrity sha512-L3yR6/MzZAOl0DsysUXHVjOwv8mKZ71TrA/41EIduGpOOV5LQVodqN+QdQ6BS6PJ/RdIshZhq84P/fStEZkk7g== + version "3.14.2" + resolved "https://registry.yarnpkg.com/winston/-/winston-3.14.2.tgz#94ce5fd26d374f563c969d12f0cd9c641065adab" + integrity sha512-CO8cdpBB2yqzEf8v895L+GNKYJiEq8eKlHU38af3snQBQ+sdAIUepjMSguOIJC7ICbzm0ZI+Af2If4vIJrtmOg== dependencies: "@colors/colors" "^1.6.0" "@dabh/diagnostics" "^2.0.2" async "^3.2.3" is-stream "^2.0.0" - logform "^2.4.0" + logform "^2.6.0" one-time "^1.0.0" readable-stream "^3.4.0" safe-stable-stringify "^2.3.1" stack-trace "0.0.x" triple-beam "^1.3.0" - winston-transport "^4.5.0" + winston-transport "^4.7.0" -word-wrap@~1.2.3: +word-wrap@^1.2.5, word-wrap@~1.2.3: version "1.2.5" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34" integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== @@ -9410,10 +9641,10 @@ wordwrapjs@^4.0.0: reduce-flatten "^2.0.0" typical "^5.2.0" -workerpool@6.2.1: - version "6.2.1" - resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" - integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== +workerpool@^6.5.1: + version "6.5.1" + resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.5.1.tgz#060f73b39d0caf97c6db64da004cd01b4c099544" + integrity sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA== "wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: version "7.0.0" @@ -9459,15 +9690,15 @@ ws@7.4.6: resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== -ws@8.5.0: - version "8.5.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.5.0.tgz#bfb4be96600757fe5382de12c670dab984a1ed4f" - integrity sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg== +ws@8.17.1: + version "8.17.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.17.1.tgz#9293da530bb548febc95371d90f9c878727d919b" + integrity sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ== ws@^7.4.6: - version "7.5.9" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591" - integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== + version "7.5.10" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.10.tgz#58b5c20dc281633f6c19113f39b349bd8bd558d9" + integrity sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ== xtend@~4.0.1: version "4.0.2" @@ -9484,21 +9715,11 @@ 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" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== -yargs-parser@20.2.4: - version "20.2.4" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" - integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== - yargs-parser@^2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-2.4.1.tgz#85568de3cf150ff49fa51825f03a8c880ddcc5c4" @@ -9507,7 +9728,7 @@ yargs-parser@^2.4.1: camelcase "^3.0.0" lodash.assign "^4.0.6" -yargs-parser@^20.2.2, yargs-parser@^20.2.3: +yargs-parser@^20.2.2, yargs-parser@^20.2.3, yargs-parser@^20.2.9: version "20.2.9" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== @@ -9517,7 +9738,7 @@ yargs-parser@^21.1.1: resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== -yargs-unparser@2.0.0: +yargs-unparser@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== @@ -9527,7 +9748,7 @@ yargs-unparser@2.0.0: flat "^5.0.2" is-plain-obj "^2.1.0" -yargs@16.2.0: +yargs@^16.2.0: version "16.2.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== @@ -9584,9 +9805,9 @@ yocto-queue@^0.1.0: integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== yocto-queue@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-1.0.0.tgz#7f816433fb2cbc511ec8bf7d263c3b58a1a3c251" - integrity sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g== + version "1.1.1" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-1.1.1.tgz#fef65ce3ac9f8a32ceac5a634f74e17e5b232110" + integrity sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g== zksync-web3@^0.14.3: version "0.14.4"