diff --git a/.env.sample b/.env.sample index cf4d5a693..8ea24e2a5 100644 --- a/.env.sample +++ b/.env.sample @@ -37,7 +37,7 @@ MOCK_Z_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 +# Environment variables to create an entirely custom config for CurvePricer when `env_level` above is not dev MAX_PRICE= MIN_PRICE= MAX_LENGTH= @@ -65,10 +65,19 @@ ADMIN_ADDRESSES= MONITOR_CONTRACTS="false" VERIFY_CONTRACTS="false" -DEFENDER_KEY= -DEFENDER_SECRET= -RELAYER_KEY= -RELAYER_SECRET= +# Data for Cross-Chain contract deployment +# Common data for both L1 and L2. Needs to be reset for EVERY deploy to every network !!! +SRC_CHAIN_NAME= # Has to match one of the networks in `SupportedChains` enum in `get-portal-dm.ts` +MOCK_ZKEVM_BRIDGE= # "true" | "false" to make Campaign deploy a Mocked version of the bridge for local testing +ZK_EVM_BRIDGE= # HAS to be provided if MOCK_ZKEVM_BRIDGE is set to "false", this would use actual Bridge from the chain +NETWORK_ID= # (For the Mocked Bridge) Network ID withing Polygon ZkEVM of the current chain we are deploying to +BRIDGE_TOKEN= # (For the Mocked Bridge) Address of the Bridge Token on the current chain we are deploying to +# Data for L1/Ethereum ZNS +DEST_NETWORK_ID= # Network ID withing Polygon ZkEVM of the destination chain (ZChain) where the other ZNS lies +DEST_CHAIN_NAME= # Has to match one of the networks in `SupportedChains` enum in `get-portal-dm.ts` +DEST_CHAIN_ID= # Chain ID of the destination chain (ZChain) where the other ZNS lies +# Data for L2/ZChain ZNS +SRC_ZNS_PORTAL= # Address of the ZNS Portal on the source chain (Ethereum ZNS) # Tenderly # this is your key to access Tenderly Zer0 Org diff --git a/.eslintrc b/.eslintrc index 5bfb76c6d..f8804a29e 100644 --- a/.eslintrc +++ b/.eslintrc @@ -15,4 +15,4 @@ } } ] -} \ No newline at end of file +} diff --git a/.gitignore b/.gitignore index 387691055..0976cec49 100644 --- a/.gitignore +++ b/.gitignore @@ -1,26 +1,29 @@ -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 +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 + +# Local tests and ops +test-data diff --git a/contracts/access/IZNSAccessController.sol b/contracts/access/IZNSAccessController.sol index bf687e76b..5711979e1 100644 --- a/contracts/access/IZNSAccessController.sol +++ b/contracts/access/IZNSAccessController.sol @@ -1,29 +1,33 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.26; - -import { IAccessControl } from "@openzeppelin/contracts/access/IAccessControl.sol"; - - -interface IZNSAccessController is IAccessControl { - function setRoleAdmin(bytes32 role, bytes32 adminRole) external; - - function checkGovernor(address account) external view; - - function checkAdmin(address account) external view; - - function checkExecutor(address account) external view; - - 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); -} +// SPDX-License-Identifier: MIT +pragma solidity 0.8.26; + +import { IAccessControl } from "@openzeppelin/contracts/access/IAccessControl.sol"; + + +interface IZNSAccessController is IAccessControl { + function setRoleAdmin(bytes32 role, bytes32 adminRole) external; + + function checkGovernor(address account) external view; + + function checkAdmin(address account) external view; + + function checkExecutor(address account) external view; + + function checkRegistrar(address account) external view; + + function checkPortal(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 isPortal(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 af29625c5..2d5728b6c 100644 --- a/contracts/access/ZNSAccessController.sol +++ b/contracts/access/ZNSAccessController.sol @@ -1,96 +1,107 @@ -// SPDX-License-Identifier: MIT -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"; - - -/** - * @title The main module for system-wide Access Control. - * @dev ZNS Business Logic Contract access to this module is outlined in `AAccessControlled.sol`. - * Uses a role-based access control scheme with levels: - * - GOVERNOR: The highest rank, assigns Admins, new roles and Role Admins - * - ADMIN: The main maintainer role, that gets access to all system functions (managed by Governor) - * - EXECUTOR: Can be here to future proof, if we need a new role (managed by Governor) - * - REGISTRAR: This role is here specifically for the ZNSRootRegistrar.sol contract (managed by Admin) - * - * > This contract is NOT proxied. When new implementation is needed, a new contract will be deployed - * and all modules will be updated to use the new address, since they all inherit from `AAccessControlled.sol`. - */ -contract ZNSAccessController is AccessControl, ZNSRoles, IZNSAccessController { - constructor( - address[] memory governorAddresses, - address[] memory adminAddresses - ) { - // give roles to all addresses - _grantRoleToMany(GOVERNOR_ROLE, governorAddresses); - _grantRoleToMany(ADMIN_ROLE, adminAddresses); - - // all of the governors control admins - _setRoleAdmin(ADMIN_ROLE, GOVERNOR_ROLE); - // all of the governors control governors - _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 ** - // "check...()" functions revert with a specific message - function checkGovernor(address account) external view override { - _checkRole(GOVERNOR_ROLE, account); - } - - function checkAdmin(address account) external view override { - _checkRole(ADMIN_ROLE, account); - } - - function checkExecutor(address account) external view override { - _checkRole(EXECUTOR_ROLE, account); - } - - function checkRegistrar(address account) external view override { - _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); - } - - function isRegistrar(address account) external view override returns (bool) { - 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); - } - - function isExecutor(address account) external view override returns (bool) { - return hasRole(EXECUTOR_ROLE, account); - } - - function setRoleAdmin(bytes32 role, bytes32 adminRole) external override onlyRole(GOVERNOR_ROLE) { - _setRoleAdmin(role, adminRole); - } - - function _grantRoleToMany(bytes32 role, address[] memory addresses) internal { - uint256 length = addresses.length; - for (uint256 i = 0; i < length; ++i) { - if (addresses[i] == address(0)) revert ZeroAddressPassed(); - - _grantRole(role, addresses[i]); - } - } -} +// SPDX-License-Identifier: MIT +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"; + + +/** + * @title The main module for system-wide Access Control. + * @dev ZNS Business Logic Contract access to this module is outlined in `AAccessControlled.sol`. + * Uses a role-based access control scheme with levels: + * - GOVERNOR: The highest rank, assigns Admins, new roles and Role Admins + * - ADMIN: The main maintainer role, that gets access to all system functions (managed by Governor) + * - EXECUTOR: Can be here to future proof, if we need a new role (managed by Governor) + * - REGISTRAR: This role is here specifically for the ZNSRootRegistrar.sol contract (managed by Admin) + * - PORTAL: Role for cross-chain Portal contracts that call certain functions on ZNS contracts (managed by Admin) + * + * > This contract is NOT proxied. When new implementation is needed, a new contract will be deployed + * and all modules will be updated to use the new address, since they all inherit from `AAccessControlled.sol`. + */ +contract ZNSAccessController is AccessControl, ZNSRoles, IZNSAccessController { + constructor( + address[] memory governorAddresses, + address[] memory adminAddresses + ) { + // give roles to all addresses + _grantRoleToMany(GOVERNOR_ROLE, governorAddresses); + _grantRoleToMany(ADMIN_ROLE, adminAddresses); + + // all of the governors control admins + _setRoleAdmin(ADMIN_ROLE, GOVERNOR_ROLE); + // all of the governors control governors + _setRoleAdmin(GOVERNOR_ROLE, GOVERNOR_ROLE); + // all of the admins control registrar + _setRoleAdmin(REGISTRAR_ROLE, ADMIN_ROLE); + // all of the admins control portals + _setRoleAdmin(PORTAL_ROLE, ADMIN_ROLE); + // all of the admins control domain token + _setRoleAdmin(DOMAIN_TOKEN_ROLE, ADMIN_ROLE); + } + + // ** Access Validators ** + // "check...()" functions revert with a specific message + function checkGovernor(address account) external view override { + _checkRole(GOVERNOR_ROLE, account); + } + + function checkAdmin(address account) external view override { + _checkRole(ADMIN_ROLE, account); + } + + function checkExecutor(address account) external view override { + _checkRole(EXECUTOR_ROLE, account); + } + + function checkRegistrar(address account) external view override { + _checkRole(REGISTRAR_ROLE, account); + } + + function checkDomainToken(address account) external view override { + _checkRole(DOMAIN_TOKEN_ROLE, account); + } + + function checkPortal(address account) external view override { + _checkRole(PORTAL_ROLE, account); + } + + // "is...()" functions return a boolean + function isAdmin(address account) external view override returns (bool) { + return hasRole(ADMIN_ROLE, account); + } + + function isRegistrar(address account) external view override returns (bool) { + 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); + } + + function isPortal(address account) external view override returns (bool) { + return hasRole(PORTAL_ROLE, account); + } + + function isExecutor(address account) external view override returns (bool) { + return hasRole(EXECUTOR_ROLE, account); + } + + function setRoleAdmin(bytes32 role, bytes32 adminRole) external override onlyRole(GOVERNOR_ROLE) { + _setRoleAdmin(role, adminRole); + } + + function _grantRoleToMany(bytes32 role, address[] memory addresses) internal { + uint256 length = addresses.length; + for (uint256 i = 0; i < length; ++i) { + if (addresses[i] == address(0)) revert ZeroAddressPassed(); + + _grantRole(role, addresses[i]); + } + } +} diff --git a/contracts/access/ZNSRoles.sol b/contracts/access/ZNSRoles.sol index d92522233..5b70e1869 100644 --- a/contracts/access/ZNSRoles.sol +++ b/contracts/access/ZNSRoles.sol @@ -1,35 +1,41 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.26; - - -/** - * @title Outlines the roles used in the ZNS system - * @dev > Inherited ONLY by `ZNSAccessController` - */ -abstract contract ZNSRoles { - /** - * @notice The highest rank, assigns Admins, new roles and Role Admins - */ - bytes32 public constant GOVERNOR_ROLE = keccak256("GOVERNOR_ROLE"); - - /** - * @notice The main maintainer role, that gets access to all system functions - */ - bytes32 public constant ADMIN_ROLE = keccak256("ADMIN_ROLE"); - - /** - * @notice This role is here specifically for the ZNSRootRegistrar.sol contract - */ - 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 - */ - bytes32 public constant EXECUTOR_ROLE = keccak256("EXECUTOR_ROLE"); -} +// SPDX-License-Identifier: MIT +pragma solidity 0.8.26; + + +/** + * @title Outlines the roles used in the ZNS system + * @dev > Inherited ONLY by `ZNSAccessController` + */ +abstract contract ZNSRoles { + /** + * @notice The highest rank, assigns Admins, new roles and Role Admins + */ + bytes32 public constant GOVERNOR_ROLE = keccak256("GOVERNOR_ROLE"); + + /** + * @notice The main maintainer role, that gets access to all system functions + */ + bytes32 public constant ADMIN_ROLE = keccak256("ADMIN_ROLE"); + + /** + * @notice This role is here specifically for the ZNSRootRegistrar.sol contract + */ + bytes32 public constant REGISTRAR_ROLE = keccak256("REGISTRAR_ROLE"); + + /** + * @notice Role for cross-chain contracts of Portal type that can call + * certain functions on ZNS contracts. + */ + bytes32 public constant PORTAL_ROLE = keccak256("PORTAL_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 + */ + bytes32 public constant EXECUTOR_ROLE = keccak256("EXECUTOR_ROLE"); +} diff --git a/contracts/cross-chain/IPolygonZkEVMBridgeV2Ext.sol b/contracts/cross-chain/IPolygonZkEVMBridgeV2Ext.sol new file mode 100644 index 000000000..e07afd03f --- /dev/null +++ b/contracts/cross-chain/IPolygonZkEVMBridgeV2Ext.sol @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.26; + +import { IPolygonZkEVMBridgeV2 } from "@zero-tech/zkevm-contracts/contracts/v2/interfaces/IPolygonZkEVMBridgeV2.sol"; + + +interface IPolygonZkEVMBridgeV2Ext is IPolygonZkEVMBridgeV2 { + function networkID() external view returns (uint32); +} diff --git a/contracts/cross-chain/IZNSEthereumPortal.sol b/contracts/cross-chain/IZNSEthereumPortal.sol new file mode 100644 index 000000000..bdcd8924e --- /dev/null +++ b/contracts/cross-chain/IZNSEthereumPortal.sol @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.26; + +import { IDistributionConfig } from "../types/IDistributionConfig.sol"; +import { IBridgeMessageReceiver } from "@zero-tech/zkevm-contracts/contracts/interfaces/IBridgeMessageReceiver.sol"; +import { IPolygonZkEVMBridgeV2Ext } from "./IPolygonZkEVMBridgeV2Ext.sol"; +import { IZNSRootRegistrarBranch } from "../registrar/IZNSRootRegistrarBranch.sol"; +import { IZNSSubRegistrarBranch } from "../registrar/IZNSSubRegistrarBranch.sol"; +import { IZNSRegistry } from "../registry/IZNSRegistry.sol"; +import { IZNSDomainToken } from "../token/IZNSDomainToken.sol"; + + +interface IZNSEthereumPortal is IDistributionConfig, IBridgeMessageReceiver { + event DomainClaimed( + uint32 indexed srcNetworkId, + address srcPortalAddress, + bytes32 indexed domainHash, + address indexed domainOwner + ); + event SrcZnsPortalSet(address newAddress); + + error InvalidCaller(address caller); + error InvalidOriginAddress(address originAddress); + error DomainHashDoesNotMatchBridged(bytes32 bridgedHashL1, bytes32 generatedHashL2); + + function polygonZkEVMBridge() external view returns (IPolygonZkEVMBridgeV2Ext); + + function networkId() external view returns (uint32); + + function srcZnsPortal() external view returns (address); + + function rootRegistrar() external view returns (IZNSRootRegistrarBranch); + + function subRegistrar() external view returns (IZNSSubRegistrarBranch); + + function domainToken() external view returns (IZNSDomainToken); + + function registry() external view returns (IZNSRegistry); + + function initialize( + address accessController_, + IPolygonZkEVMBridgeV2Ext zkEvmBridge_, + address srcZnsPortal_, + IZNSRegistry registry_, + IZNSDomainToken domainToken_, + IZNSRootRegistrarBranch rootRegistrar_, + IZNSSubRegistrarBranch subRegistrar_ + ) external; + + function setSrcZnsPortal(address newAddress) external; + + function onERC721Received( + address, + address, + uint256, + bytes calldata + ) external pure returns (bytes4); +} diff --git a/contracts/cross-chain/IZNSZChainPortal.sol b/contracts/cross-chain/IZNSZChainPortal.sol new file mode 100644 index 000000000..33d192851 --- /dev/null +++ b/contracts/cross-chain/IZNSZChainPortal.sol @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.26; + +import { IPolygonZkEVMBridgeV2 } from "@zero-tech/zkevm-contracts/contracts/v2/interfaces/IPolygonZkEVMBridgeV2.sol"; +import { IDistributionConfig } from "../types/IDistributionConfig.sol"; +import { IZNSRootRegistrarTrunk } from "../registrar/IZNSRootRegistrarTrunk.sol"; +import { IZNSSubRegistrarTrunk } from "../registrar/IZNSSubRegistrarTrunk.sol"; +import { IZNSRegistry } from "../registry/IZNSRegistry.sol"; +import { IZNSTreasury } from "../treasury/IZNSTreasury.sol"; +import { IZNSChainResolver } from "../resolver/IZNSChainResolver.sol"; +import { IZNSAccessController } from "../access/IZNSAccessController.sol"; + + +interface IZNSZChainPortal is IDistributionConfig { + + struct ZNSContractInput { + IZNSAccessController accessController; + IZNSRegistry registry; + IZNSChainResolver chainResolver; + IZNSTreasury treasury; + IZNSRootRegistrarTrunk rootRegistrar; + IZNSSubRegistrarTrunk subRegistrar; + } + + event DomainBridged( + uint32 indexed destNetworkId, + address destPortalAddress, + bytes32 indexed domainHash, + address indexed domainOwner + ); + event DestZnsPortalSet(address newAddress); + + error DestinationPortalNotSetInState(); + + function polygonZkEVMBridge() external view returns (IPolygonZkEVMBridgeV2); + + function destNetworkId() external view returns (uint32); + + function destChainName() external view returns (string memory); + + function destChainId() external view returns (uint256); + + function destZnsPortal() external view returns (address); + + function rootRegistrar() external view returns (IZNSRootRegistrarTrunk); + + function subRegistrar() external view returns (IZNSSubRegistrarTrunk); + + function treasury() external view returns (IZNSTreasury); + + function chainResolver() external view returns (IZNSChainResolver); + + function registry() external view returns (IZNSRegistry); + + function initialize( + uint32 destNetworkId_, + string calldata destChainName_, + uint256 destChainId_, + IPolygonZkEVMBridgeV2 zkEvmBridge_, + ZNSContractInput calldata znsContracts + ) external; + + function registerAndBridgeDomain( + bytes32 parentHash, + string calldata label, + string calldata tokenURI +// bool forceUpdateGlobalExitRoot - do we need to pass this ??? + ) external; + + function onERC721Received( + address, + address, + uint256, + bytes calldata + ) external pure returns (bytes4); + + function setDestZnsPortal(address newAddress) external; +} diff --git a/contracts/cross-chain/ZNSEthereumPortal.sol b/contracts/cross-chain/ZNSEthereumPortal.sol new file mode 100644 index 000000000..e2a74dd6c --- /dev/null +++ b/contracts/cross-chain/ZNSEthereumPortal.sol @@ -0,0 +1,143 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.26; + +import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; +import { AAccessControlled } from "../access/AAccessControlled.sol"; +import { IZNSEthereumPortal } from "./IZNSEthereumPortal.sol"; +import { IPolygonZkEVMBridgeV2Ext } from "./IPolygonZkEVMBridgeV2Ext.sol"; +import { ZeroAddressPassed } from "../utils/CommonErrors.sol"; +import { BridgedDomain } from "../types/CrossChainTypes.sol"; +import { IZNSRootRegistrarBranch } from "../registrar/IZNSRootRegistrarBranch.sol"; +import { IZNSSubRegistrarBranch } from "../registrar/IZNSSubRegistrarBranch.sol"; +import { IZNSRegistry } from "../registry/IZNSRegistry.sol"; +import { IZNSDomainToken } from "../token/IZNSDomainToken.sol"; + + +contract ZNSEthereumPortal is UUPSUpgradeable, AAccessControlled, IZNSEthereumPortal { + // *--| Cross-chain Data |--* + // TODO multi: should we keep this extended interface ??? + IPolygonZkEVMBridgeV2Ext public polygonZkEVMBridge; + // This chain + uint32 public networkId; + // figure out better names for these vars !!! + address public srcZnsPortal; + + // *--| ZNS Data for THIS chain |--* + IZNSRootRegistrarBranch public rootRegistrar; + IZNSSubRegistrarBranch public subRegistrar; + IZNSDomainToken public domainToken; + IZNSRegistry public registry; + + /// @custom:oz-upgrades-unsafe-allow constructor + constructor() { + _disableInitializers(); + } + + function initialize( + address accessController_, + IPolygonZkEVMBridgeV2Ext zkEvmBridge_, + address srcZnsPortal_, + IZNSRegistry registry_, + IZNSDomainToken domainToken_, + IZNSRootRegistrarBranch rootRegistrar_, + IZNSSubRegistrarBranch subRegistrar_ + ) external override initializer { + _setAccessController(accessController_); + + if ( + address(zkEvmBridge_) == address(0) + || srcZnsPortal_ == address(0) + || address(rootRegistrar_) == address(0) + || address(subRegistrar_) == address(0) + || address(domainToken_) == address(0) + || address(registry_) == address(0) + ) revert ZeroAddressPassed(); + + polygonZkEVMBridge = zkEvmBridge_; + networkId = polygonZkEVMBridge.networkID(); + srcZnsPortal = srcZnsPortal_; + rootRegistrar = rootRegistrar_; + subRegistrar = subRegistrar_; + domainToken = domainToken_; + registry = registry_; + } + + function onMessageReceived( + address originAddress, + // TODO multi: do we need to add this value to state and validate against it here with a revert ??? + // so it can only be called with from one network ??? + uint32 originNetwork, + bytes memory data + ) external payable override { + if (msg.sender != address(polygonZkEVMBridge)) revert InvalidCaller(msg.sender); + if (originAddress != srcZnsPortal) revert InvalidOriginAddress(originAddress); + + BridgedDomain memory proof = abi.decode(data, (BridgedDomain)); + + // Register bridged domain + bytes32 domainHash; + if (proof.parentHash == bytes32(0)) { + domainHash = rootRegistrar.registerBridgedRootDomain( + proof.label, + proof.tokenUri + ); + } else { + domainHash = subRegistrar.registerBridgedSubdomain( + proof.parentHash, + proof.label, + proof.tokenUri + ); + } + + // Validate that we bridged a proper domain + if (domainHash != proof.domainHash) + revert DomainHashDoesNotMatchBridged(proof.domainHash, domainHash); + + // TODO multi: remove registry owner change if merged after DomainToken transfer changes! + // this should be done automatically by transferring the token! + // Transfer domain ownership to the address of registrant on L1 + registry.updateDomainOwner( + proof.domainHash, + proof.domainOwner + ); + // Transfer the token + domainToken.transferFrom( + address(this), + proof.domainOwner, + uint256(proof.domainHash) + ); + + emit DomainClaimed( + originNetwork, + originAddress, + proof.domainHash, + proof.domainOwner + ); + } + + function setSrcZnsPortal(address newAddress) external override onlyAdmin { + if (newAddress == address(0)) revert ZeroAddressPassed(); + + srcZnsPortal = newAddress; + + emit SrcZnsPortalSet(newAddress); + } + + function onERC721Received( + address, + address, + uint256, + bytes calldata + ) external pure override returns (bytes4) { + return this.onERC721Received.selector; + } + + /** + * @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/cross-chain/ZNSZChainPortal.sol b/contracts/cross-chain/ZNSZChainPortal.sol new file mode 100644 index 000000000..4363616a9 --- /dev/null +++ b/contracts/cross-chain/ZNSZChainPortal.sol @@ -0,0 +1,221 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.26; + +import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; +import { IPolygonZkEVMBridgeV2 } from "@zero-tech/zkevm-contracts/contracts/v2/interfaces/IPolygonZkEVMBridgeV2.sol"; +import { AAccessControlled } from "../access/AAccessControlled.sol"; +import { IZNSZChainPortal } from "./IZNSZChainPortal.sol"; +import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import { IZNSChainResolver } from "../resolver/IZNSChainResolver.sol"; +import { IZNSPricer } from "../types/IZNSPricer.sol"; +import { IZNSRegistry } from "../registry/IZNSRegistry.sol"; +import { IZNSRootRegistrarTrunk } from "../registrar/IZNSRootRegistrarTrunk.sol"; +import { IZNSSubRegistrarTrunk } from "../registrar/IZNSSubRegistrarTrunk.sol"; +import { IZNSTreasury } from "../treasury/IZNSTreasury.sol"; +import { PaymentConfig } from "../treasury/IZNSTreasury.sol"; +import { BridgedDomain } from "../types/CrossChainTypes.sol"; +import { ZeroAddressPassed } from "../utils/CommonErrors.sol"; + + +contract ZNSZChainPortal is UUPSUpgradeable, AAccessControlled, IZNSZChainPortal { + // *--| Cross-chain Data |--* + IPolygonZkEVMBridgeV2 public polygonZkEVMBridge; + // Destination chain (L2) + uint32 public destNetworkId; + string public destChainName; + uint256 public destChainId; + address public destZnsPortal; + + // *--| ZNS Data for THIS chain |--* + IZNSRootRegistrarTrunk public rootRegistrar; + IZNSSubRegistrarTrunk public subRegistrar; + IZNSTreasury public treasury; + IZNSChainResolver public chainResolver; + IZNSRegistry public registry; + + /// @custom:oz-upgrades-unsafe-allow constructor + constructor() { + _disableInitializers(); + } + + function initialize( + uint32 destNetworkId_, + string calldata destChainName_, + uint256 destChainId_, + IPolygonZkEVMBridgeV2 zkEvmBridge_, + ZNSContractInput calldata znsContracts + ) external override initializer { + _setAccessController(address(znsContracts.accessController)); + + if ( + address(zkEvmBridge_) == address(0) + || address(znsContracts.rootRegistrar) == address(0) + || address(znsContracts.subRegistrar) == address(0) + || address(znsContracts.treasury) == address(0) + || address(znsContracts.chainResolver) == address(0) + || address(znsContracts.registry) == address(0) + ) revert ZeroAddressPassed(); + + polygonZkEVMBridge = zkEvmBridge_; + destNetworkId = destNetworkId_; + destChainName = destChainName_; + destChainId = destChainId_; + rootRegistrar = znsContracts.rootRegistrar; + subRegistrar = znsContracts.subRegistrar; + treasury = znsContracts.treasury; + chainResolver = znsContracts.chainResolver; + registry = znsContracts.registry; + } + + function registerAndBridgeDomain( + bytes32 parentHash, + string calldata label, + string calldata tokenURI +// bool forceUpdateGlobalExitRoot - do we need to pass this ??? + ) external override { + DistributionConfig memory emptyDistrConfig; + PaymentConfig memory emptyPaymentConfig; + + _processPayment(label, parentHash); + + // Register domain + bytes32 domainHash; + if (parentHash == bytes32(0)) { // 0x0 parent for root domains + domainHash = rootRegistrar.registerRootDomain( + label, + address(0), + tokenURI, + emptyDistrConfig, + emptyPaymentConfig + ); + } else { + domainHash = subRegistrar.registerSubdomain( + parentHash, + label, + address(0), + tokenURI, + emptyDistrConfig, + emptyPaymentConfig + ); + } + + // TODO multi: analyze how to make these strings better !!! + registry.updateDomainResolver(domainHash, "chain"); + // TODO multi: iron out what should go to ChainResolver data !!! + chainResolver.setChainData( + domainHash, + destChainId, + destChainName, + address(0), + "" + ); + + // Bridge domain + _bridgeDomain( + domainHash, + parentHash, + label, + tokenURI + ); + } + + function onERC721Received( + address, + address, + uint256, + bytes calldata + ) external pure override returns (bytes4) { + return this.onERC721Received.selector; + } + + function setDestZnsPortal(address newAddress) external override onlyAdmin { + if (newAddress == address(0)) revert ZeroAddressPassed(); + + destZnsPortal = newAddress; + + emit DestZnsPortalSet(newAddress); + } + + function _processPayment( + string calldata label, + bytes32 parentHash + ) internal { + // TODO multi: do we actually want to stake on BOTH sides? What other payment option can we do ???!!! + // TODO multi: if we leave this option (stake as Portal address) this needs to be optimized!!! + // take payment to this contract so it can register + + uint256 price; + uint256 stakeFee; + IZNSPricer rootPricer = rootRegistrar.rootPricer(); + if (parentHash == bytes32(0)) { // Root Domains + price = rootPricer.getPrice( + parentHash, + label, + true + ); + } else { // Subdomains + (IZNSPricer pricer, PaymentType paymentType,) = subRegistrar.distrConfigs(parentHash); + (price, stakeFee) = pricer.getPriceAndFee( + parentHash, + label, + true + ); + stakeFee = paymentType == PaymentType.STAKE ? stakeFee : 0; + } + + uint256 protocolFee = rootPricer.getFeeForPrice(bytes32(0), price + stakeFee); + uint256 totalCost = price + stakeFee + protocolFee; + + ( IERC20 paymentToken, ) = treasury.paymentConfigs(parentHash); + paymentToken.transferFrom(msg.sender, address(this), totalCost); + + paymentToken.approve(address(treasury), totalCost); + } + + function _bridgeDomain( + bytes32 domainHash, + bytes32 parentHash, + string calldata label, + string calldata tokenURI + ) internal { + // Create data proof for ZNS on L2 + // we are using msg.sender here because the current caller on L1 will be the owner of the bridged L2 domain + BridgedDomain memory proof = BridgedDomain({ + domainOwner: msg.sender, + domainHash: domainHash, + parentHash: parentHash, + label: label, + tokenUri: tokenURI + }); + + bytes memory encodedProof = abi.encode(proof); + + // TODO multi: should we leave this? We can't rely on setting this properly on time + // and can permanently lock domains !!! + if (destZnsPortal == address(0)) revert DestinationPortalNotSetInState(); + + polygonZkEVMBridge.bridgeMessage( + destNetworkId, + destZnsPortal, + // TODO multi: figure out what this is and how to better pass it !!! + true, + encodedProof + ); + + emit DomainBridged( + destNetworkId, + destZnsPortal, + domainHash, + msg.sender + ); + } + + /** + * @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/cross-chain/mock/PolygonZkEVMBridgeV2Mock.sol b/contracts/cross-chain/mock/PolygonZkEVMBridgeV2Mock.sol new file mode 100644 index 000000000..5eadbcb8d --- /dev/null +++ b/contracts/cross-chain/mock/PolygonZkEVMBridgeV2Mock.sol @@ -0,0 +1,161 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.26; + +// This is here only to bring the contract so Hardhat compiles it by default +import { IBridgeMessageReceiver } from "@zero-tech/zkevm-contracts/contracts/interfaces/IBridgeMessageReceiver.sol"; +import { ERC20Mock } from "../../token/mocks/ERC20Mock.sol"; +import { ReentrancyGuardUpgradeable } from "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol"; +// import { PolygonZkEVMBridgeV2 } from "@zero-tech/zkevm-contracts/contracts/v2/PolygonZkEVMBridgeV2.sol"; + + +// Note that this does NOT inherit the original Bridge contract! +// We are EMULATING bridge behavior here so we can run tests on the same chain +contract PolygonZkEVMBridgeV2Mock is ReentrancyGuardUpgradeable { + error NoValueInMessagesOnGasTokenNetworks(); + error DestinationNetworkInvalid(); + error MessageFailed(); + + event ClaimEvent( + uint256 globalIndex, + uint32 originNetwork, + address originAddress, + address destinationAddress, + uint256 amount + ); + event BridgeEvent( + uint8 leafType, + uint32 originNetwork, + address originAddress, + uint32 destinationNetwork, + address destinationAddress, + uint256 amount, + bytes metadata, + uint32 depositCount + ); + + + uint256 internal constant _DEPOSIT_CONTRACT_TREE_DEPTH = 32; + uint8 private constant _LEAF_TYPE_MESSAGE = 1; + + uint32 public networkID; + uint256 public depositCount; + + // TODO multi: in original contract there is TokenWrapped type here + // WETH address + ERC20Mock public WETHToken; + + /// @custom:oz-upgrades-unsafe-allow constructor + constructor() { + _disableInitializers(); + } + + function initialize( + uint32 _networkID, + address _WETHToken + ) external initializer { + networkID = _networkID; + WETHToken = ERC20Mock(_WETHToken); + } + + function bridgeMessage( + uint32 destinationNetwork, + address destinationAddress, + bool forceUpdateGlobalExitRoot, + bytes calldata metadata + ) external payable { + // If exist a gas token, only allow call this function without value + if (msg.value != 0 && address(WETHToken) != address(0)) { + revert NoValueInMessagesOnGasTokenNetworks(); + } + + _bridgeMessage( + destinationNetwork, + destinationAddress, + msg.value, + forceUpdateGlobalExitRoot, + metadata + ); + } + + function _bridgeMessage( + uint32 destinationNetwork, + address destinationAddress, + uint256 amountEther, + bool forceUpdateGlobalExitRoot, + bytes calldata metadata + ) internal { + if (destinationNetwork == networkID) { + revert DestinationNetworkInvalid(); + } + + ++depositCount; + + emit BridgeEvent( + _LEAF_TYPE_MESSAGE, + networkID, + msg.sender, + destinationNetwork, + destinationAddress, + amountEther, + metadata, + uint32(depositCount) + ); + } + + function claimMessage( + bytes32[_DEPOSIT_CONTRACT_TREE_DEPTH] calldata smtProofLocalExitRoot, + bytes32[_DEPOSIT_CONTRACT_TREE_DEPTH] calldata smtProofRollupExitRoot, + uint256 globalIndex, + bytes32 mainnetExitRoot, + bytes32 rollupExitRoot, + uint32 originNetwork, + address originAddress, + uint32 destinationNetwork, + address destinationAddress, + uint256 amount, + bytes calldata metadata + ) external { + // Destination network must be this networkID + if (destinationNetwork != networkID) { + revert DestinationNetworkInvalid(); + } + + // Execute message + bool success; + if (address(WETHToken) == address(0)) { + // Native token is ether + // Transfer ether + /* solhint-disable avoid-low-level-calls */ + (success, ) = destinationAddress.call{value: amount}( + abi.encodeCall( + IBridgeMessageReceiver.onMessageReceived, + (originAddress, originNetwork, metadata) + ) + ); + } else { + // Mint wETH tokens + WETHToken.mint(destinationAddress, amount); + + // Execute message + /* solhint-disable avoid-low-level-calls */ + (success, ) = destinationAddress.call( + abi.encodeCall( + IBridgeMessageReceiver.onMessageReceived, + (originAddress, originNetwork, metadata) + ) + ); + } + + if (!success) { + revert MessageFailed(); + } + + emit ClaimEvent( + globalIndex, + originNetwork, + originAddress, + destinationAddress, + amount + ); + } +} diff --git a/contracts/price/ZNSFixedPricer.sol b/contracts/price/ZNSFixedPricer.sol index e3be189a9..3b65de851 100644 --- a/contracts/price/ZNSFixedPricer.sol +++ b/contracts/price/ZNSFixedPricer.sol @@ -149,6 +149,7 @@ contract ZNSFixedPricer is AAccessControlled, ARegistryWired, UUPSUpgradeable, I */ function _setPrice(bytes32 domainHash, uint256 price) internal { priceConfigs[domainHash].price = price; + priceConfigs[domainHash].isSet = true; emit PriceSet(domainHash, price); } diff --git a/contracts/registrar/IZNSRootRegistrarBase.sol b/contracts/registrar/IZNSRootRegistrarBase.sol new file mode 100644 index 000000000..c3a80bf88 --- /dev/null +++ b/contracts/registrar/IZNSRootRegistrarBase.sol @@ -0,0 +1,68 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.26; + +import { IZNSDomainToken } from "../token/IZNSDomainToken.sol"; +import { IZNSSubRegistrarTrunk } from "./IZNSSubRegistrarTrunk.sol"; +import { IZNSPricer } from "../types/IZNSPricer.sol"; +import { IZNSTreasury } from "../treasury/IZNSTreasury.sol"; +import { IZNSRootRegistrarTypes } from "./IZNSRootRegistrarTypes.sol"; +import { CoreRegisterArgs } from "./IZNSRootRegistrarTypes.sol"; + + +// TODO multi: fix NatSpec here!!! +/** + * @title IZNSRootRegistrar.sol - Interface for the ZNSRootRegistrar contract resposible for registering root domains. + * @notice Below are docs for the types in this file: + * - `OwnerOf`: Enum signifying ownership of ZNS entities + * + NAME: The owner of the Name only + * + TOKEN: The owner of the Token only + * + BOTH: The owner of both the Name and the Token + * - `CoreRegisterArgs`: Struct containing all the arguments required to register a domain + * with ZNSRootRegistrar.coreRegister(): + * + `parentHash`: The hash of the parent domain (0x0 for root domains) + * + `domainHash`: The hash of the domain to be registered + * + `label`: The label of the domain to be registered + * + `registrant`: The address of the user who is registering the domain + * + `price`: The determined price for the domain to be registered based on parent rules + * + `stakeFee`: The determined stake fee for the domain to be registered (only for PaymentType.STAKE!) + * + `domainAddress`: The address to which the domain will be resolved to + * + `tokenURI`: The tokenURI for the domain to be registered + * + `isStakePayment`: A flag for whether the payment is a stake payment or not + */ +interface IZNSRootRegistrarBase is IZNSRootRegistrarTypes { + function initialize( + address accessController_, + address registry_, + address rootPricer_, + address treasury_, + address domainToken_ + ) external; + + function coreRegister( + CoreRegisterArgs memory args + ) external; + + function revokeDomain(bytes32 domainHash) external; + + function reclaimDomain(bytes32 domainHash) external; + + function isOwnerOf(bytes32 domainHash, address candidate, OwnerOf ownerOf) external view returns (bool); + + function setRegistry(address registry_) external; + + function setRootPricer(address rootPricer_) external; + + function setTreasury(address treasury_) external; + + function setDomainToken(address domainToken_) external; + + function setSubRegistrar(address subRegistrar_) external; + + function rootPricer() external view returns (IZNSPricer); + + function treasury() external view returns (IZNSTreasury); + + function domainToken() external view returns (IZNSDomainToken); + + function subRegistrar() external view returns (IZNSSubRegistrarTrunk); +} diff --git a/contracts/registrar/IZNSRootRegistrarBranch.sol b/contracts/registrar/IZNSRootRegistrarBranch.sol new file mode 100644 index 000000000..a68e51c06 --- /dev/null +++ b/contracts/registrar/IZNSRootRegistrarBranch.sol @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.26; + +import { IZNSRootRegistrarBase } from "./IZNSRootRegistrarBase.sol"; + + +interface IZNSRootRegistrarBranch is IZNSRootRegistrarBase { + function registerBridgedRootDomain( + string calldata label, + string calldata tokenURI + ) external returns (bytes32); +} diff --git a/contracts/registrar/IZNSRootRegistrarTrunk.sol b/contracts/registrar/IZNSRootRegistrarTrunk.sol new file mode 100644 index 000000000..c0e08536c --- /dev/null +++ b/contracts/registrar/IZNSRootRegistrarTrunk.sol @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.26; + +import { IZNSRootRegistrarBase } from "./IZNSRootRegistrarBase.sol"; +import { PaymentConfig } from "../treasury/IZNSTreasury.sol"; + + +interface IZNSRootRegistrarTrunk is IZNSRootRegistrarBase { + function registerRootDomain( + string calldata name, + address domainAddress, + string calldata tokenURI, + DistributionConfig calldata distributionConfig, + PaymentConfig calldata paymentConfig + ) external returns (bytes32); +} diff --git a/contracts/registrar/IZNSRootRegistrar.sol b/contracts/registrar/IZNSRootRegistrarTypes.sol similarity index 56% rename from contracts/registrar/IZNSRootRegistrar.sol rename to contracts/registrar/IZNSRootRegistrarTypes.sol index b98da35ce..e7ff4db18 100644 --- a/contracts/registrar/IZNSRootRegistrar.sol +++ b/contracts/registrar/IZNSRootRegistrarTypes.sol @@ -9,39 +9,21 @@ import { PaymentConfig } from "../treasury/IZNSTreasury.sol"; * @notice Stake fee is 0x0 for anything other than subdomain under a parent with Stake Payment * parent hash will be 0x0 for root domain */ -struct CoreRegisterArgs { - bytes32 parentHash; - bytes32 domainHash; - address registrant; - address domainAddress; - uint256 price; - uint256 stakeFee; - string label; - string tokenURI; - bool isStakePayment; - PaymentConfig paymentConfig; -} + struct CoreRegisterArgs { + bytes32 parentHash; + bytes32 domainHash; + address registrant; + address domainAddress; + uint256 price; + uint256 stakeFee; + string label; + string tokenURI; + bool isStakePayment; + PaymentConfig paymentConfig; + } -/** - * @title IZNSRootRegistrar.sol - Interface for the ZNSRootRegistrar contract resposible for registering root domains. - * @notice Below are docs for the types in this file: - * - `OwnerOf`: Enum signifying ownership of ZNS entities - * + NAME: The owner of the Name only - * + TOKEN: The owner of the Token only - * + BOTH: The owner of both the Name and the Token - * - `CoreRegisterArgs`: Struct containing all the arguments required to register a domain - * with ZNSRootRegistrar.coreRegister(): - * + `parentHash`: The hash of the parent domain (0x0 for root domains) - * + `domainHash`: The hash of the domain to be registered - * + `label`: The label of the domain to be registered - * + `registrant`: The address of the user who is registering the domain - * + `price`: The determined price for the domain to be registered based on parent rules - * + `stakeFee`: The determined stake fee for the domain to be registered (only for PaymentType.STAKE!) - * + `domainAddress`: The address to which the domain will be resolved to - * + `tokenURI`: The tokenURI for the domain to be registered - * + `isStakePayment`: A flag for whether the payment is a stake payment or not - */ -interface IZNSRootRegistrar is IDistributionConfig { + +interface IZNSRootRegistrarTypes is IDistributionConfig { error NotTheOwnerOf( OwnerOf ownerOf, address candidate, @@ -55,6 +37,7 @@ interface IZNSRootRegistrar is IDistributionConfig { 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. @@ -69,6 +52,7 @@ interface IZNSRootRegistrar is IDistributionConfig { * @param registrant The address that called `ZNSRootRegistrar.registerRootDomain()` * @param domainAddress The domain address of the domain registered */ + // TODO multi: make parentHash indexed instead of tokenId !!! event DomainRegistered( bytes32 parentHash, bytes32 indexed domainHash, @@ -124,40 +108,4 @@ interface IZNSRootRegistrar is IDistributionConfig { * @param subRegistrar The new address of the SubRegistrar contract */ event SubRegistrarSet(address subRegistrar); - - function initialize( - address accessController_, - address registry_, - address rootPricer_, - address treasury_, - address domainToken_ - ) external; - - function registerRootDomain( - string calldata name, - address domainAddress, - string calldata tokenURI, - DistributionConfig calldata distributionConfig, - PaymentConfig calldata paymentConfig - ) external returns (bytes32); - - function coreRegister( - CoreRegisterArgs memory args - ) external; - - function revokeDomain(bytes32 domainHash) external; - - function reclaimDomain(bytes32 domainHash) external; - - function isOwnerOf(bytes32 domainHash, address candidate, OwnerOf ownerOf) external view returns (bool); - - function setRegistry(address registry_) external; - - function setRootPricer(address rootPricer_) external; - - function setTreasury(address treasury_) external; - - function setDomainToken(address domainToken_) external; - - function setSubRegistrar(address subRegistrar_) external; } diff --git a/contracts/registrar/IZNSSubRegistrarBranch.sol b/contracts/registrar/IZNSSubRegistrarBranch.sol new file mode 100644 index 000000000..0081185f8 --- /dev/null +++ b/contracts/registrar/IZNSSubRegistrarBranch.sol @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.26; + +import { IZNSSubRegistrarTrunk } from "./IZNSSubRegistrarTrunk.sol"; + + +interface IZNSSubRegistrarBranch is IZNSSubRegistrarTrunk { + function registerBridgedSubdomain( + bytes32 parentHash, + string calldata label, + string calldata tokenURI + ) external returns (bytes32); +} diff --git a/contracts/registrar/IZNSSubRegistrar.sol b/contracts/registrar/IZNSSubRegistrarTrunk.sol similarity index 95% rename from contracts/registrar/IZNSSubRegistrar.sol rename to contracts/registrar/IZNSSubRegistrarTrunk.sol index ae5bc7bdd..be4f787c0 100644 --- a/contracts/registrar/IZNSSubRegistrar.sol +++ b/contracts/registrar/IZNSSubRegistrarTrunk.sol @@ -1,140 +1,140 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.26; - -import { IDistributionConfig } from "../types/IDistributionConfig.sol"; -import { PaymentConfig } from "../treasury/IZNSTreasury.sol"; -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 - ); - - /** - * @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, - PaymentType paymentType, - AccessType accessType - ); - - /** - * @notice Emitted when a `mintlist` is updated for a domain. - */ - event MintlistUpdated( - bytes32 indexed domainHash, - uint256 indexed ownerIndex, - address[] candidates, - bool[] allowed - ); - - /* - * @notice Emitted when a `mintlist` is removed for a domain by the owner or through - * `ZNSRootRegistrar.revokeDomain()`. - */ - event MintlistCleared(bytes32 indexed domainHash); - - /** - * @notice Emitted when the ZNSRootRegistrar address is set in state. - */ - event RootRegistrarSet(address registrar); - - function distrConfigs( - bytes32 domainHash - ) external view returns ( - IZNSPricer pricerContract, - PaymentType paymentType, - AccessType accessType - ); - - function isMintlistedForDomain( - bytes32 domainHash, - address candidate - ) external view returns (bool); - - function initialize( - address _accessController, - address _registry, - address _rootRegistrar - ) external; - - function registerSubdomain( - bytes32 parentHash, - string calldata label, - address domainAddress, - string calldata tokenURI, - DistributionConfig calldata configForSubdomains, - PaymentConfig calldata paymentConfig - ) external returns (bytes32); - - function hashWithParent( - bytes32 parentHash, - string calldata label - ) external pure returns (bytes32); - - function setDistributionConfigForDomain( - bytes32 parentHash, - DistributionConfig calldata config - ) external; - - function setPricerContractForDomain( - bytes32 domainHash, - IZNSPricer pricerContract - ) external; - - function setPaymentTypeForDomain( - bytes32 domainHash, - PaymentType paymentType - ) external; - - function setAccessTypeForDomain( - bytes32 domainHash, - AccessType accessType - ) external; - - function updateMintlistForDomain( - bytes32 domainHash, - address[] calldata candidates, - bool[] calldata allowed - ) external; - - function clearMintlistForDomain(bytes32 domainHash) external; - - function clearMintlistAndLock(bytes32 domainHash) external; - - function setRegistry(address registry_) external; - - function setRootRegistrar(address registrar_) external; -} +// SPDX-License-Identifier: MIT +pragma solidity 0.8.26; + +import { IDistributionConfig } from "../types/IDistributionConfig.sol"; +import { PaymentConfig } from "../treasury/IZNSTreasury.sol"; +import { IZNSPricer } from "../types/IZNSPricer.sol"; + + +/** + * @title IZNSSubRegistrar.sol - Interface for the ZNSSubRegistrar contract responsible for registering subdomains. + */ +interface IZNSSubRegistrarTrunk 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 + ); + + /** + * @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, + PaymentType paymentType, + AccessType accessType + ); + + /** + * @notice Emitted when a `mintlist` is updated for a domain. + */ + event MintlistUpdated( + bytes32 indexed domainHash, + uint256 indexed ownerIndex, + address[] candidates, + bool[] allowed + ); + + /* + * @notice Emitted when a `mintlist` is removed for a domain by the owner or through + * `ZNSRootRegistrar.revokeDomain()`. + */ + event MintlistCleared(bytes32 indexed domainHash); + + /** + * @notice Emitted when the ZNSRootRegistrar address is set in state. + */ + event RootRegistrarSet(address registrar); + + function distrConfigs( + bytes32 domainHash + ) external view returns ( + IZNSPricer pricerContract, + PaymentType paymentType, + AccessType accessType + ); + + function isMintlistedForDomain( + bytes32 domainHash, + address candidate + ) external view returns (bool); + + function initialize( + address _accessController, + address _registry, + address _rootRegistrar + ) external; + + function registerSubdomain( + bytes32 parentHash, + string calldata label, + address domainAddress, + string calldata tokenURI, + DistributionConfig calldata configForSubdomains, + PaymentConfig calldata paymentConfig + ) external returns (bytes32); + + function hashWithParent( + bytes32 parentHash, + string calldata label + ) external pure returns (bytes32); + + function setDistributionConfigForDomain( + bytes32 parentHash, + DistributionConfig calldata config + ) external; + + function setPricerContractForDomain( + bytes32 domainHash, + IZNSPricer pricerContract + ) external; + + function setPaymentTypeForDomain( + bytes32 domainHash, + PaymentType paymentType + ) external; + + function setAccessTypeForDomain( + bytes32 domainHash, + AccessType accessType + ) external; + + function updateMintlistForDomain( + bytes32 domainHash, + address[] calldata candidates, + bool[] calldata allowed + ) external; + + function clearMintlistForDomain(bytes32 domainHash) external; + + function clearMintlistAndLock(bytes32 domainHash) external; + + function setRegistry(address registry_) external; + + function setRootRegistrar(address registrar_) external; +} diff --git a/contracts/registrar/ZNSRootRegistrar.sol b/contracts/registrar/ZNSRootRegistrarBase.sol similarity index 87% rename from contracts/registrar/ZNSRootRegistrar.sol rename to contracts/registrar/ZNSRootRegistrarBase.sol index 5cb841e91..62fd04175 100644 --- a/contracts/registrar/ZNSRootRegistrar.sol +++ b/contracts/registrar/ZNSRootRegistrarBase.sol @@ -3,17 +3,19 @@ pragma solidity 0.8.26; import { AAccessControlled } from "../access/AAccessControlled.sol"; import { ARegistryWired } from "../registry/ARegistryWired.sol"; -import { IZNSRootRegistrar, CoreRegisterArgs } from "./IZNSRootRegistrar.sol"; +import { IZNSRootRegistrarBase } from "./IZNSRootRegistrarBase.sol"; +import { CoreRegisterArgs } from "./IZNSRootRegistrarTypes.sol"; import { IZNSTreasury, PaymentConfig } from "../treasury/IZNSTreasury.sol"; import { IZNSDomainToken } from "../token/IZNSDomainToken.sol"; import { IZNSAddressResolver } from "../resolver/IZNSAddressResolver.sol"; -import { IZNSSubRegistrar } from "../registrar/IZNSSubRegistrar.sol"; +import { IZNSSubRegistrarTrunk } from "../registrar/IZNSSubRegistrarTrunk.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"; +// TODO multi: fix NatSpec here to the Base contract /** * @title Main entry point for the three main flows of ZNS - Register Root Domain, Reclaim and Revoke any domain. * @notice This contract serves as the "umbrella" for many ZNS operations, it is given REGISTRAR_ROLE @@ -27,17 +29,17 @@ import { ZeroAddressPassed, DomainAlreadyExists } from "../utils/CommonErrors.so * @dev This contract is also called at the last stage of registering subdomains, since it has the common * logic required to be performed for any level domains. */ -contract ZNSRootRegistrar is +contract ZNSRootRegistrarBase is UUPSUpgradeable, AAccessControlled, ARegistryWired, - IZNSRootRegistrar { + IZNSRootRegistrarBase { using StringUtils for string; IZNSPricer public rootPricer; IZNSTreasury public treasury; IZNSDomainToken public domainToken; - IZNSSubRegistrar public subRegistrar; + IZNSSubRegistrarTrunk public subRegistrar; /// @custom:oz-upgrades-unsafe-allow constructor constructor() { @@ -70,42 +72,46 @@ contract ZNSRootRegistrar is } /** - * @notice This function is the main entry point for the Register Root Domain flow. - * Registers a new root domain such as `0://wilder`. - * Gets domain hash as a keccak256 hash of the domain label string casted to bytes32, - * checks existence of the domain in the registry and reverts if it exists. - * Calls `ZNSTreasury` to do the staking part, gets `tokenId` for the new token to be minted - * as domain hash casted to uint256, mints the token and sets the domain data in the `ZNSRegistry` - * and, possibly, `ZNSAddressResolver`. Emits a `DomainRegistered` event. - * @param name Name (label) of the domain to register - * @param domainAddress (optional) Address for the `ZNSAddressResolver` to return when requested - * @param tokenURI URI to assign to the Domain Token issued for the domain - * @param distributionConfig (optional) Distribution config for the domain to set in the same tx - * > Please note that passing distribution config will add more gas to the tx and most importantly - - * - the distributionConfig HAS to be passed FULLY filled or all zeros. It is optional as a whole, - * but all the parameters inside are required. - * @param paymentConfig (optional) Payment config for the domain to set on ZNSTreasury in the same tx - * > `paymentConfig` has to be fully filled or all zeros. It is optional as a whole, - * but all the parameters inside are required. - */ - function registerRootDomain( - string calldata name, + * @notice External function used by `ZNSSubRegistrar` for the final stage of registering subdomains. + * @param args `CoreRegisterArgs`: Struct containing all the arguments required to register a domain + * with ZNSRootRegistrar.coreRegister(): + * + `parentHash`: The hash of the parent domain (0x0 for root domains) + * + `domainHash`: The hash of the domain to be registered + * + `label`: The label of the domain to be registered + * + `registrant`: The address of the user who is registering the domain + * + `price`: The determined price for the domain to be registered based on parent rules + * + `stakeFee`: The determined stake fee for the domain to be registered (only for PaymentType.STAKE!) + * + `domainAddress`: The address to which the domain will be resolved to + * + `tokenURI`: The tokenURI for the domain to be registered + * + `isStakePayment`: A flag for whether the payment is a stake payment or not + */ + function coreRegister( + CoreRegisterArgs memory args + ) external override onlyRegistrar { + _coreRegister( + args + ); + } + + function _coreRootRegister( + string calldata label, address domainAddress, string calldata tokenURI, - DistributionConfig calldata distributionConfig, - PaymentConfig calldata paymentConfig - ) external override returns (bytes32) { + DistributionConfig memory distributionConfig, + PaymentConfig memory paymentConfig, + bool isBridgedDomain + ) internal returns (bytes32) { // Confirms string values are only [a-z0-9-] - name.validate(); + label.validate(); // Create hash for given domain name - bytes32 domainHash = keccak256(bytes(name)); + bytes32 domainHash = keccak256(bytes(label)); if (registry.exists(domainHash)) revert DomainAlreadyExists(domainHash); // Get price for the domain - uint256 domainPrice = rootPricer.getPrice(0x0, name, true); + uint256 domainPrice = !isBridgedDomain ? rootPricer.getPrice(0x0, label, true) : 0; _coreRegister( CoreRegisterArgs( @@ -115,7 +121,7 @@ contract ZNSRootRegistrar is domainAddress, domainPrice, 0, - name, + label, tokenURI, true, paymentConfig @@ -130,28 +136,6 @@ contract ZNSRootRegistrar is return domainHash; } - /** - * @notice External function used by `ZNSSubRegistrar` for the final stage of registering subdomains. - * @param args `CoreRegisterArgs`: Struct containing all the arguments required to register a domain - * with ZNSRootRegistrar.coreRegister(): - * + `parentHash`: The hash of the parent domain (0x0 for root domains) - * + `domainHash`: The hash of the domain to be registered - * + `label`: The label of the domain to be registered - * + `registrant`: The address of the user who is registering the domain - * + `price`: The determined price for the domain to be registered based on parent rules - * + `stakeFee`: The determined stake fee for the domain to be registered (only for PaymentType.STAKE!) - * + `domainAddress`: The address to which the domain will be resolved to - * + `tokenURI`: The tokenURI for the domain to be registered - * + `isStakePayment`: A flag for whether the payment is a stake payment or not - */ - function coreRegister( - CoreRegisterArgs memory args - ) external override onlyRegistrar { - _coreRegister( - args - ); - } - /** * @dev Internal function that is called by this contract to finalize the registration of a domain. * This function as also called by the external `coreRegister()` function as a part of @@ -182,7 +166,7 @@ contract ZNSRootRegistrar is registry.createDomainRecord(args.domainHash, args.registrant, "address"); IZNSAddressResolver(registry.getDomainResolver(args.domainHash)) - .setAddress(args.domainHash, args.domainAddress); + .setAddress(args.domainHash, args.domainAddress); } else { // By passing an empty string we tell the registry to not add a resolver registry.createDomainRecord(args.domainHash, args.registrant, ""); @@ -334,7 +318,7 @@ contract ZNSRootRegistrar is * Only ADMIN in `ZNSAccessController` can call this function. * @param registry_ Address of the `ZNSRegistry` contract */ - function setRegistry(address registry_) public override(ARegistryWired, IZNSRootRegistrar) onlyAdmin { + function setRegistry(address registry_) public virtual override(ARegistryWired, IZNSRootRegistrarBase) onlyAdmin { _setRegistry(registry_); } @@ -388,7 +372,7 @@ contract ZNSRootRegistrar is if (subRegistrar_ == address(0)) revert ZeroAddressPassed(); - subRegistrar = IZNSSubRegistrar(subRegistrar_); + subRegistrar = IZNSSubRegistrarTrunk(subRegistrar_); emit SubRegistrarSet(subRegistrar_); } diff --git a/contracts/registrar/ZNSRootRegistrarBranch.sol b/contracts/registrar/ZNSRootRegistrarBranch.sol new file mode 100644 index 000000000..acd531f2d --- /dev/null +++ b/contracts/registrar/ZNSRootRegistrarBranch.sol @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.26; + +import { ZNSRootRegistrarBase } from "./ZNSRootRegistrarBase.sol"; +import { IZNSRootRegistrarBranch } from "./IZNSRootRegistrarBranch.sol"; +import { IZNSRootRegistrarBase } from "./IZNSRootRegistrarBase.sol"; +import { PaymentConfig } from "../treasury/IZNSTreasury.sol"; + + +// TODO multi: fix NatSpec here ! +/** + * @title Main entry point for the three main flows of ZNS - Register Root Domain, Reclaim and Revoke any domain. + * @notice This contract serves as the "umbrella" for many ZNS operations, it is given REGISTRAR_ROLE + * to combine multiple calls/operations between different modules to achieve atomic state changes + * and proper logic for the ZNS flows. You can see functions in other modules that are only allowed + * to be called by this contract to ensure proper management of ZNS data in multiple places. + * RRR - Register, Reclaim, Revoke start here and then call other modules to complete the flow. + * ZNSRootRegistrar.sol stores most of the other contract addresses and can communicate with other modules, + * but the relationship is one-sided, where other modules do not need to know about the ZNSRootRegistrar.sol, + * they only check REGISTRAR_ROLE that can, in theory, be assigned to any other address. + * @dev This contract is also called at the last stage of registering subdomains, since it has the common + * logic required to be performed for any level domains. + */ +contract ZNSRootRegistrarBranch is + ZNSRootRegistrarBase, + IZNSRootRegistrarBranch { + + // TODO multi: add NatSpec here !!! + function registerBridgedRootDomain( + string calldata label, + string calldata tokenURI + ) external override returns (bytes32) { + accessController.checkPortal(msg.sender); + + DistributionConfig memory emptyDistrConfig; + PaymentConfig memory emptyPaymentConfig; + + return _coreRootRegister( + label, + address(0), + tokenURI, + emptyDistrConfig, + emptyPaymentConfig, + true + ); + } + + function setRegistry(address registry) + public + override( + ZNSRootRegistrarBase, + IZNSRootRegistrarBase + ) + onlyAdmin { + super.setRegistry(registry); + } +} diff --git a/contracts/registrar/ZNSRootRegistrarTrunk.sol b/contracts/registrar/ZNSRootRegistrarTrunk.sol new file mode 100644 index 000000000..2ee966c0b --- /dev/null +++ b/contracts/registrar/ZNSRootRegistrarTrunk.sol @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.26; + +import { ZNSRootRegistrarBase } from "./ZNSRootRegistrarBase.sol"; +import { IZNSRootRegistrarTrunk } from "./IZNSRootRegistrarTrunk.sol"; +import { IZNSRootRegistrarBase } from "./IZNSRootRegistrarBase.sol"; +import { PaymentConfig } from "../treasury/IZNSTreasury.sol"; + + +/** + * @title Main entry point for the three main flows of ZNS - Register Root Domain, Reclaim and Revoke any domain. + * @notice This contract serves as the "umbrella" for many ZNS operations, it is given REGISTRAR_ROLE + * to combine multiple calls/operations between different modules to achieve atomic state changes + * and proper logic for the ZNS flows. You can see functions in other modules that are only allowed + * to be called by this contract to ensure proper management of ZNS data in multiple places. + * RRR - Register, Reclaim, Revoke start here and then call other modules to complete the flow. + * ZNSRootRegistrar.sol stores most of the other contract addresses and can communicate with other modules, + * but the relationship is one-sided, where other modules do not need to know about the ZNSRootRegistrar.sol, + * they only check REGISTRAR_ROLE that can, in theory, be assigned to any other address. + * @dev This contract is also called at the last stage of registering subdomains, since it has the common + * logic required to be performed for any level domains. + */ +contract ZNSRootRegistrarTrunk is + ZNSRootRegistrarBase, + IZNSRootRegistrarTrunk { + + /** + * @notice This function is the main entry point for the Register Root Domain flow. + * Registers a new root domain such as `0://wilder`. + * Gets domain hash as a keccak256 hash of the domain label string casted to bytes32, + * checks existence of the domain in the registry and reverts if it exists. + * Calls `ZNSTreasury` to do the staking part, gets `tokenId` for the new token to be minted + * as domain hash casted to uint256, mints the token and sets the domain data in the `ZNSRegistry` + * and, possibly, `ZNSAddressResolver`. Emits a `DomainRegistered` event. + * @param label Name (label) of the domain to register + * @param domainAddress (optional) Address for the `ZNSAddressResolver` to return when requested + * @param tokenURI URI to assign to the Domain Token issued for the domain + * @param distributionConfig (optional) Distribution config for the domain to set in the same tx + * > Please note that passing distribution config will add more gas to the tx and most importantly - + * - the distributionConfig HAS to be passed FULLY filled or all zeros. It is optional as a whole, + * but all the parameters inside are required. + * @param paymentConfig (optional) Payment config for the domain to set on ZNSTreasury in the same tx + * > `paymentConfig` has to be fully filled or all zeros. It is optional as a whole, + * but all the parameters inside are required. + */ + function registerRootDomain( + string calldata label, + address domainAddress, + string calldata tokenURI, + DistributionConfig calldata distributionConfig, + PaymentConfig calldata paymentConfig + ) external override returns (bytes32) { + return _coreRootRegister( + label, + domainAddress, + tokenURI, + distributionConfig, + paymentConfig, + false + ); + } + + function setRegistry(address registry) public override( + ZNSRootRegistrarBase, + IZNSRootRegistrarBase + ) onlyAdmin { + super.setRegistry(registry); + } +} diff --git a/contracts/registrar/ZNSSubRegistrarBranch.sol b/contracts/registrar/ZNSSubRegistrarBranch.sol new file mode 100644 index 000000000..7b8154293 --- /dev/null +++ b/contracts/registrar/ZNSSubRegistrarBranch.sol @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.26; + +import { IZNSSubRegistrarBranch } from "./IZNSSubRegistrarBranch.sol"; +import { ZNSSubRegistrarTrunk } from "./ZNSSubRegistrarTrunk.sol"; +import { IZNSSubRegistrarTrunk } from "./IZNSSubRegistrarTrunk.sol"; +import { PaymentConfig } from "../treasury/IZNSTreasury.sol"; + + +contract ZNSSubRegistrarBranch is ZNSSubRegistrarTrunk, IZNSSubRegistrarBranch { + function registerBridgedSubdomain( + bytes32 parentHash, + string calldata label, + string calldata tokenURI + ) external override returns (bytes32) { + accessController.checkPortal(msg.sender); + + DistributionConfig memory emptyDistrConfig; + PaymentConfig memory emptyPaymentConfig; + + return _coreSubdomainRegister( + parentHash, + label, + address(0), + tokenURI, + emptyDistrConfig, + emptyPaymentConfig, + true + ); + } + + function setRegistry(address registry) public override( + ZNSSubRegistrarTrunk, + IZNSSubRegistrarTrunk + ) onlyAdmin { + super.setRegistry(registry); + } +} diff --git a/contracts/registrar/ZNSSubRegistrar.sol b/contracts/registrar/ZNSSubRegistrarTrunk.sol similarity index 82% rename from contracts/registrar/ZNSSubRegistrar.sol rename to contracts/registrar/ZNSSubRegistrarTrunk.sol index b1b8a65a8..71cc0a23a 100644 --- a/contracts/registrar/ZNSSubRegistrar.sol +++ b/contracts/registrar/ZNSSubRegistrarTrunk.sol @@ -2,8 +2,9 @@ pragma solidity 0.8.26; import { IZNSPricer } from "../types/IZNSPricer.sol"; -import { IZNSRootRegistrar, CoreRegisterArgs } from "./IZNSRootRegistrar.sol"; -import { IZNSSubRegistrar } from "./IZNSSubRegistrar.sol"; +import { IZNSRootRegistrarBase } from "./IZNSRootRegistrarBase.sol"; +import { CoreRegisterArgs } from "./IZNSRootRegistrarTypes.sol"; +import { IZNSSubRegistrarTrunk } from "./IZNSSubRegistrarTrunk.sol"; import { AAccessControlled } from "../access/AAccessControlled.sol"; import { ARegistryWired } from "../registry/ARegistryWired.sol"; import { StringUtils } from "../utils/StringUtils.sol"; @@ -18,13 +19,13 @@ import { DomainAlreadyExists, ZeroAddressPassed, NotAuthorizedForDomain } from " * the ZNSRootRegistrar back to finalize registration. Common logic for domains * of any level is in the `ZNSRootRegistrar.coreRegister()`. */ -contract ZNSSubRegistrar is AAccessControlled, ARegistryWired, UUPSUpgradeable, IZNSSubRegistrar { +contract ZNSSubRegistrarTrunk is AAccessControlled, ARegistryWired, UUPSUpgradeable, IZNSSubRegistrarTrunk { using StringUtils for string; /** * @notice State var for the ZNSRootRegistrar contract that finalizes registration of subdomains. */ - IZNSRootRegistrar public rootRegistrar; + IZNSRootRegistrarBase public rootRegistrar; /** * @notice Mapping of domainHash to distribution config set by the domain owner/operator. @@ -91,57 +92,48 @@ contract ZNSSubRegistrar is AAccessControlled, ARegistryWired, UUPSUpgradeable, DistributionConfig calldata distrConfig, PaymentConfig calldata paymentConfig ) external override returns (bytes32) { + return _coreSubdomainRegister( + parentHash, + label, + domainAddress, + tokenURI, + distrConfig, + paymentConfig, + false + ); + } + + function _coreSubdomainRegister( + bytes32 parentHash, + string calldata label, + address domainAddress, + string calldata tokenURI, + DistributionConfig memory distrConfig, + PaymentConfig memory paymentConfig, + bool isBridgedDomain + ) internal 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); - if (parentConfig.accessType == AccessType.LOCKED && !isOwnerOrOperator) - revert ParentLockedOrDoesntExist(parentHash); - - if (parentConfig.accessType == AccessType.MINTLIST) { - if ( - !mintlist[parentHash] - .list - [mintlist[parentHash].ownerIndex] - [msg.sender] - ) revert SenderNotApprovedForPurchase(parentHash, msg.sender); - } - CoreRegisterArgs memory coreRegisterArgs = CoreRegisterArgs({ parentHash: parentHash, - domainHash: domainHash, + domainHash: 0x0, label: label, registrant: msg.sender, price: 0, stakeFee: 0, domainAddress: domainAddress, tokenURI: tokenURI, - isStakePayment: parentConfig.paymentType == PaymentType.STAKE, + isStakePayment: false, paymentConfig: paymentConfig }); - if (!isOwnerOrOperator) { - if (coreRegisterArgs.isStakePayment) { - (coreRegisterArgs.price, coreRegisterArgs.stakeFee) = IZNSPricer(address(parentConfig.pricerContract)) - .getPriceAndFee( - parentHash, - label, - true - ); - } else { - coreRegisterArgs.price = IZNSPricer(address(parentConfig.pricerContract)) - .getPrice( - parentHash, - label, - true - ); - } + coreRegisterArgs.domainHash = hashWithParent(parentHash, label); + if (registry.exists(coreRegisterArgs.domainHash)) + revert DomainAlreadyExists(coreRegisterArgs.domainHash); + + if (!isBridgedDomain) { + _checkFillParentData(coreRegisterArgs); } rootRegistrar.coreRegister(coreRegisterArgs); @@ -152,7 +144,48 @@ contract ZNSSubRegistrar is AAccessControlled, ARegistryWired, UUPSUpgradeable, setDistributionConfigForDomain(coreRegisterArgs.domainHash, distrConfig); } - return domainHash; + return coreRegisterArgs.domainHash; + } + + function _checkFillParentData( + CoreRegisterArgs memory args + ) internal view returns (CoreRegisterArgs memory) { + DistributionConfig memory parentConfig = distrConfigs[args.parentHash]; + + bool isOwnerOrOperator = registry.isOwnerOrOperator(args.parentHash, msg.sender); + if (parentConfig.accessType == AccessType.LOCKED && !isOwnerOrOperator) + revert ParentLockedOrDoesntExist(args.parentHash); + + if (parentConfig.accessType == AccessType.MINTLIST) { + if ( + !mintlist[args.parentHash] + .list + [mintlist[args.parentHash].ownerIndex] + [msg.sender] + ) revert SenderNotApprovedForPurchase(args.parentHash, msg.sender); + } + + if (!isOwnerOrOperator) { + if (parentConfig.paymentType == PaymentType.STAKE) { + args.isStakePayment = true; + + (args.price, args.stakeFee) = IZNSPricer(address(parentConfig.pricerContract)) + .getPriceAndFee( + args.parentHash, + args.label, + true + ); + } else { + args.price = IZNSPricer(address(parentConfig.pricerContract)) + .getPrice( + args.parentHash, + args.label, + true + ); + } + } + + return args; } /** @@ -181,7 +214,7 @@ contract ZNSSubRegistrar is AAccessControlled, ARegistryWired, UUPSUpgradeable, */ function setDistributionConfigForDomain( bytes32 domainHash, - DistributionConfig calldata config + DistributionConfig memory config ) public override onlyOwnerOperatorOrRegistrar(domainHash) { if (address(config.pricerContract) == address(0)) revert ZeroAddressPassed(); @@ -319,7 +352,7 @@ contract ZNSSubRegistrar is AAccessControlled, ARegistryWired, UUPSUpgradeable, * @notice Sets the registry address in state. * @dev This function is required for all contracts inheriting `ARegistryWired`. */ - function setRegistry(address registry_) public override(ARegistryWired, IZNSSubRegistrar) onlyAdmin { + function setRegistry(address registry_) public virtual override(ARegistryWired, IZNSSubRegistrarTrunk) onlyAdmin { _setRegistry(registry_); } @@ -330,7 +363,7 @@ contract ZNSSubRegistrar is AAccessControlled, ARegistryWired, UUPSUpgradeable, */ function setRootRegistrar(address registrar_) public override onlyAdmin { if (registrar_ == address(0)) revert ZeroAddressPassed(); - rootRegistrar = IZNSRootRegistrar(registrar_); + rootRegistrar = IZNSRootRegistrarBase(registrar_); emit RootRegistrarSet(registrar_); } diff --git a/contracts/resolver/IZNSChainResolver.sol b/contracts/resolver/IZNSChainResolver.sol new file mode 100644 index 000000000..02aab879c --- /dev/null +++ b/contracts/resolver/IZNSChainResolver.sol @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.26; + + +interface IZNSChainResolver { + event ChainDataSet( + bytes32 indexed domainHash, + uint256 chainID, + string chainName, + address znsRegistryOnChain, + string auxData + ); + + struct ChainData { + uint256 chainId; + string chainName; + address znsRegistryOnChain; + string auxData; + } + + function initialize(address accessController_, address registry_) external; + + function resolveChainData( + bytes32 domainHash + ) external view returns (uint256, string memory, address, string memory); + + function resolveChainDataStruct( + bytes32 domainHash + ) external view returns (ChainData memory); + + function setChainData( + bytes32 domainHash, + uint256 chainID, + string memory chainName, + address znsRegistryOnChain, + string memory auxData + ) external; + + function supportsInterface( + bytes4 interfaceId + ) external view returns (bool); + + function getInterfaceId() external pure returns (bytes4); + + function setRegistry(address _registry) external; +} diff --git a/contracts/resolver/ZNSChainResolver.sol b/contracts/resolver/ZNSChainResolver.sol new file mode 100644 index 000000000..033140b4e --- /dev/null +++ b/contracts/resolver/ZNSChainResolver.sol @@ -0,0 +1,96 @@ +// 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 { AAccessControlled } from "../access/AAccessControlled.sol"; +import { ARegistryWired } from "../registry/ARegistryWired.sol"; +import { NotAuthorizedForDomain } from "../utils/CommonErrors.sol"; +import { IZNSChainResolver } from "./IZNSChainResolver.sol"; + + +contract ZNSChainResolver is + UUPSUpgradeable, + AAccessControlled, + ARegistryWired, + ERC165, + IZNSChainResolver { + + mapping(bytes32 domainHash => ChainData data) internal chainData; + + /// @custom:oz-upgrades-unsafe-allow constructor + constructor() { + _disableInitializers(); + } + + function initialize(address accessController_, address registry_) external override initializer { + _setAccessController(accessController_); + setRegistry(registry_); + } + + function resolveChainData( + bytes32 domainHash + ) external view override returns (uint256, string memory, address, string memory) { + ChainData memory data = chainData[domainHash]; + // TODO multi: should we add RootRegistrar that has all ZNS addresses instead of Registry here ??? + return (data.chainId, data.chainName, data.znsRegistryOnChain, data.auxData); + } + + function resolveChainDataStruct( + bytes32 domainHash + ) external view override returns (ChainData memory) { + return chainData[domainHash]; + } + + // TODO multi: make this better !!! + function setChainData( + bytes32 domainHash, + uint256 chainID, + string memory chainName, + address znsRegistryOnChain, + string memory auxData + ) external override { + if ( + !registry.isOwnerOrOperator(domainHash, msg.sender) + ) revert NotAuthorizedForDomain(msg.sender, domainHash); + + chainData[domainHash] = ChainData( + chainID, + chainName, + znsRegistryOnChain, + auxData + ); + + emit ChainDataSet( + domainHash, + chainID, + chainName, + znsRegistryOnChain, + auxData + ); + } + + function supportsInterface( + bytes4 interfaceId + ) public view virtual override(ERC165, IZNSChainResolver) returns (bool) { + return + interfaceId == getInterfaceId() || + super.supportsInterface(interfaceId); + } + + /** + * @dev Exposes IZNSAddressResolver interfaceId + */ + function getInterfaceId() public pure override returns (bytes4) { + return type(IZNSChainResolver).interfaceId; + } + + function setRegistry(address _registry) public override(ARegistryWired, IZNSChainResolver) onlyAdmin { + _setRegistry(_registry); + } + + // solhint-disable-next-line no-unused-vars + function _authorizeUpgrade(address newImplementation) internal view override { + accessController.checkGovernor(msg.sender); + } +} diff --git a/contracts/token/mocks/CustomDecimalTokenMock.sol b/contracts/token/mocks/CustomDecimalTokenMock.sol index 507a1adf0..7d8133216 100644 --- a/contracts/token/mocks/CustomDecimalTokenMock.sol +++ b/contracts/token/mocks/CustomDecimalTokenMock.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.26; // solhint-disable -import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; contract CustomDecimalTokenMock is ERC20 { uint8 private _decimals; diff --git a/contracts/token/mocks/ERC20Mock.sol b/contracts/token/mocks/ERC20Mock.sol new file mode 100644 index 000000000..456dc38c7 --- /dev/null +++ b/contracts/token/mocks/ERC20Mock.sol @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.26; + +// solhint-disable +import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; + + +contract ERC20Mock is ERC20 { + uint256 private _totalSupplyBase = 10000000000000000000000; + + constructor(address owner_, uint256 decimals_) ERC20("TokenMock", "ETM") { + _mint(owner_, totalSupply()); + } + + function totalSupply() public view override returns (uint256) { + return _totalSupplyBase * 10 ** decimals(); + } + + function mint(address to, uint256 amount) public { + _mint(to, amount); + } +} diff --git a/contracts/types/CrossChainTypes.sol b/contracts/types/CrossChainTypes.sol new file mode 100644 index 000000000..92d38e52c --- /dev/null +++ b/contracts/types/CrossChainTypes.sol @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.26; + + +struct BridgedDomain { + bytes32 domainHash; + bytes32 parentHash; + string label; + address domainOwner; + string tokenUri; +} diff --git a/contracts/upgrade-test-mocks/distribution/ZNSRootRegistrarMock.sol b/contracts/upgrade-test-mocks/distribution/ZNSRootRegistrarMock.sol index 76fd2d202..b4952b8ec 100644 --- a/contracts/upgrade-test-mocks/distribution/ZNSRootRegistrarMock.sol +++ b/contracts/upgrade-test-mocks/distribution/ZNSRootRegistrarMock.sol @@ -1,8 +1,9 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.26; -import { ZNSRootRegistrar } from "../../registrar/ZNSRootRegistrar.sol"; +import { ZNSRootRegistrarTrunk } from "../../registrar/ZNSRootRegistrarTrunk.sol"; import { UpgradeMock } from "../UpgradeMock.sol"; - /* solhint-disable */ -contract ZNSRootRegistrarUpgradeMock is ZNSRootRegistrar, UpgradeMock {} + +contract ZNSRootRegistrarUpgradeMock is ZNSRootRegistrarTrunk, UpgradeMock { +} diff --git a/contracts/upgrade-test-mocks/distribution/ZNSSubRegistrarMock.sol b/contracts/upgrade-test-mocks/distribution/ZNSSubRegistrarMock.sol index eaf21610c..4e03802c6 100644 --- a/contracts/upgrade-test-mocks/distribution/ZNSSubRegistrarMock.sol +++ b/contracts/upgrade-test-mocks/distribution/ZNSSubRegistrarMock.sol @@ -3,11 +3,12 @@ pragma solidity 0.8.26; // solhint-disable -import { ZNSSubRegistrar } from "../../registrar/ZNSSubRegistrar.sol"; -import { IZNSSubRegistrar } from "../../registrar/IZNSSubRegistrar.sol"; +// TODO multi: fix these are remove unnecessary imports +import { ZNSSubRegistrarTrunk } from "../../registrar/ZNSSubRegistrarTrunk.sol"; +import { IZNSSubRegistrarTrunk } from "../../registrar/IZNSSubRegistrarTrunk.sol"; import { UpgradeMock } from "../UpgradeMock.sol"; import { IZNSPricer } from "../../types/IZNSPricer.sol"; -import { IZNSRootRegistrar, CoreRegisterArgs } from "../../registrar/IZNSRootRegistrar.sol"; +import { IZNSRootRegistrarBase, CoreRegisterArgs } from "../../registrar/IZNSRootRegistrarBase.sol"; import { AAccessControlled } from "../../access/AAccessControlled.sol"; import { ARegistryWired } from "../../registry/ARegistryWired.sol"; import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; @@ -37,7 +38,7 @@ struct DistributionConfig { contract ZNSSubRegistrarMainState { - IZNSRootRegistrar public rootRegistrar; + IZNSRootRegistrarBase public rootRegistrar; mapping(bytes32 domainHash => DistributionConfig config) public distrConfigs; @@ -250,7 +251,7 @@ contract ZNSSubRegistrarUpgradeMock is function setRootRegistrar(address registrar_) public onlyAdmin { if (registrar_ == address(0)) revert ZeroAddressPassed(); - rootRegistrar = IZNSRootRegistrar(registrar_); + rootRegistrar = IZNSRootRegistrarBase(registrar_); } // solhint-disable-next-line diff --git a/hardhat.config.ts b/hardhat.config.ts index d82597ab5..578419caf 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -1,6 +1,5 @@ /* eslint-disable @typescript-eslint/no-var-requires, @typescript-eslint/no-unused-vars */ -require("dotenv").config(); - +import "./init-env"; import { mochaGlobalSetup, mochaGlobalTeardown } from "./test/mocha-global"; @@ -47,6 +46,9 @@ const config : HardhatUserConfig = { enabled: true, runs: 20000, }, + // Only use this when running coverage + // TODO multi: figure out if this is worth using for actual deploys to networks and tests + viaIR: process.argv.includes("coverage"), }, }, { @@ -59,26 +61,27 @@ const config : HardhatUserConfig = { }, }, ], - overrides: { - "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol": { - version: "0.8.20", - settings: { - optimizer: { - enabled: true, - runs: 20000, - }, - }, - }, - "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol": { - version: "0.8.20", - settings: { - optimizer: { - enabled: true, - runs: 20000, - }, - }, - }, - }, + // TODO multi: figure out why this breaks the compilation even though the version is correct ?? + // overrides: { + // "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol": { + // version: "0.8.20", + // settings: { + // optimizer: { + // enabled: true, + // runs: 20000, + // }, + // }, + // }, + // "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol": { + // version: "0.8.20", + // settings: { + // optimizer: { + // enabled: true, + // runs: 20000, + // }, + // }, + // }, + // }, }, paths: { sources: "./contracts", @@ -88,6 +91,7 @@ const config : HardhatUserConfig = { }, typechain: { outDir: "typechain", + // externalArtifacts: ["./node_modules/@zero-tech/zkevm-contracts/compiled-contracts/*.json"], }, mocha: { timeout: 5000000, @@ -103,14 +107,14 @@ const config : HardhatUserConfig = { sepolia: { url: `${process.env.SEPOLIA_RPC_URL}`, timeout: 10000000, - // accounts: [ // Comment out for CI, uncomment this when using Sepolia - // `${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}`, - // ], + accounts: [ // Comment out for CI, uncomment this when using Sepolia + // `${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}`, + ], // // Must have to avoid instead failing as `invalid length for result data` error // throwOnCallFailures: false, // not sure if this even works }, @@ -119,26 +123,46 @@ const config : HardhatUserConfig = { url: `${process.env.DEVNET_RPC_URL}`, chainId: 1, }, - // meowtestnet: { - // url: `${process.env.MEOWTESTNET_RPC_URL}`, - // accounts: [ - // `${process.env.DEPLOYER_PRIVATE_KEY}`, - // ], - // }, + zchaintest: { + url: `${process.env.ZCHAIN_TEST_RPC_URL}`, + chainId: 2012605151, + accounts: [ + // `${process.env.TESTNET_PRIVATE_KEY_A}`, + // `${process.env.TESTNET_PRIVATE_KEY_B}`, + // `${process.env.TESTNET_PRIVATE_KEY_C}`, + ], + }, + moonwalker: { + url: `${process.env.MOONWALKER_RPC_URL}`, + chainId: 1828369849, + accounts: [ + // `${process.env.ZTOKEN_BENEFICIARY}`, + // `${process.env.TESTNET_PRIVATE_KEY_B}`, + // `${process.env.TESTNET_PRIVATE_KEY_C}`, + ], + }, + }, + etherscan: { + apiKey: `${process.env.ETHERSCAN_API_KEY}`, + customChains: [ + { + network: "moonwalker", + chainId: 1828369849, + urls: { + apiURL: "https://moonwalker-blockscout.eu-north-2.gateway.fm/api/", + browserURL: "https://moonwalker-blockscout.eu-north-2.gateway.fm/", + }, + }, + { + network: "zchaintest", + chainId: 2012605151, + urls: { + apiURL: "https://wilderworld-dev-erigon1-blockscout.eu-north-2.gateway.fm/api/", + browserURL: "https://wilderworld-dev-erigon1-blockscout.eu-north-2.gateway.fm/", + }, + }, + ], }, - // 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, @@ -159,20 +183,6 @@ 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/init-env.ts b/init-env.ts new file mode 100644 index 000000000..672e99b6a --- /dev/null +++ b/init-env.ts @@ -0,0 +1,3 @@ +import { setDefaultEnvironment } from "./src/environment/set-env"; + +setDefaultEnvironment(); diff --git a/package.json b/package.json index e4ef41ee3..6ecd52b44 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,9 @@ "mongo:drop": "ts-node src/utils/drop-db.ts", "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" + "run-zchaintest": "hardhat run src/deploy/run-campaign.ts --network zchaintest", + "bridge-get": "ts-node src/utils/cross-chain/run-bridge-api.ts", + "mint-looper": "hardhat run test/cross-chain/mint-looper.temp.ts --network zchaintest" }, "pre-commit": [ "lint" @@ -63,9 +65,11 @@ "@types/node": "^18.15.11", "@zero-tech/eslint-config-cpt": "0.2.8", "@zero-tech/z-token": "1.0.0", + "@zero-tech/zkevm-contracts": "6.0.0-fork-9", "chai": "^4.3.10", "eslint": "^8.37.0", "ethers": "^6.9.0", + "ethers-decode-error": "^2.1.3", "hardhat": "^2.22.6", "hardhat-gas-reporter": "^1.0.9", "semantic-release": "^21.0.1", @@ -78,7 +82,7 @@ }, "dependencies": { "@zero-tech/zdc": "0.1.6", - "axios": "^1.4.0", + "axios": "1.7.4", "dotenv": "16.0.3", "mongodb": "^6.1.0", "winston": "^3.11.0" diff --git a/src/deploy/campaign/environments.ts b/src/deploy/campaign/get-config.ts similarity index 65% rename from src/deploy/campaign/environments.ts rename to src/deploy/campaign/get-config.ts index 3ca1ab452..f77bb6423 100644 --- a/src/deploy/campaign/environments.ts +++ b/src/deploy/campaign/get-config.ts @@ -1,18 +1,18 @@ 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, + IZNSCampaignConfig, + IZNSEthCrossConfig, + IZNSZChainCrossConfig, + TZNSCrossConfig, +} from "./types"; +import { 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, + INVALID_ENV_ERR, INITIAL_ADMIN_DELAY_DEFAULT, INITIAL_SUPPLY_DEFAULT, INFLATION_RATES_DEFAULT, @@ -20,10 +20,13 @@ import { Z_NAME_DEFAULT, Z_SYMBOL_DEFAULT, } from "../../../test/helpers"; -import { ethers } from "ethers"; +import { ethers, Wallet } from "ethers"; +import { TSupportedChain } from "../missions/contracts/cross-chain/portals/types"; +import { SupportedChains } from "../missions/contracts/cross-chain/portals/get-portal-dm"; +import { findMissingEnvVars } from "../../environment/validate"; import { ICurvePriceConfig, IZTokenConfig } from "../missions/types"; import process from "process"; -import { ZSepolia } from "../missions/contracts/z-token/mainnet-data"; +import { ZSepolia, ZTokenMainnet } from "../missions/contracts/zns-base/z-token/mainnet-data"; const getCustomAddresses = ( @@ -58,6 +61,65 @@ const getCustomAddresses = ( return addresses; }; +export const buildCrosschainConfig = () : TZNSCrossConfig => { + const srcChainName = process.env.SRC_CHAIN_NAME as TSupportedChain; + const mockZkEvmBridge = process.env.MOCK_ZKEVM_BRIDGE === "true"; + + let curNetworkId; + let zkEvmBridgeAddress; + if (!mockZkEvmBridge) { + requires( + !!process.env.ZK_EVM_BRIDGE, + "Must provide source zkEVM bridge address from this chain if not mocking!" + ); + zkEvmBridgeAddress = process.env.ZK_EVM_BRIDGE; + } else { + requires( + !!process.env.NETWORK_ID, + "Must provide current network ID for mocked bridge!" + ); + curNetworkId = BigInt(process.env.NETWORK_ID); + } + + const baseConfig = { + mockZkEvmBridge, + srcChainName, + zkEvmBridgeAddress, + curNetworkId, + bridgeToken: process.env.BRIDGE_TOKEN, + }; + + let crossConfig; + switch (srcChainName) { + case SupportedChains.eth: + requires(!!process.env.DEST_NETWORK_ID, "Must provide destination network ID!"); + requires(!!process.env.DEST_CHAIN_NAME, "Must provide destination chain name!"); + requires(!!process.env.DEST_CHAIN_ID, "Must provide destination chain ID!"); + + crossConfig = { + ...baseConfig, + destNetworkId: BigInt(process.env.DEST_NETWORK_ID), + destChainName: process.env.DEST_CHAIN_NAME, + destChainId: BigInt(process.env.DEST_CHAIN_ID), + } as IZNSEthCrossConfig; + + break; + case SupportedChains.z: + requires(!!process.env.SRC_ZNS_PORTAL, "Must provide source ZNSZChainPortal address!"); + + crossConfig = { + ...baseConfig, + srcZnsPortal: process.env.SRC_ZNS_PORTAL, + } as IZNSZChainCrossConfig; + + break; + default: + throw new Error(`Unsupported chain: ${srcChainName}!`); + } + + return crossConfig; +}; + // This function builds a config with default values but overrides them with any values that are set export const getConfig = async ({ deployer, @@ -67,13 +129,13 @@ export const getConfig = async ({ env, // this is ONLY used for tests! zTokenConfig, } : { - deployer : SignerWithAddress; + deployer : Wallet | SignerWithAddress; governors ?: Array; admins ?: Array; zeroVaultAddress ?: string; env ?: string; zTokenConfig ?: IZTokenConfig; -}) : Promise> => { +}) : Promise> => { // Will throw an error based on any invalid setup, given the `ENV_LEVEL` set const priceConfig = validateEnv(env); @@ -84,13 +146,11 @@ export const getConfig = async ({ deployerAddress = await deployer.getAddress(); } - let zeroVaultAddressConf; + let zeroVaultAddressConf : string; 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 @@ -120,40 +180,36 @@ export const getConfig = async ({ finalInflationRate: FINAL_INFLATION_RATE_DEFAULT, }; } else { - zConfig = zTokenConfig; + zeroVaultAddressConf = zeroVaultAddressEnv; } - } 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 royaltyFraction = BigInt(process.env.ROYALTY_FRACTION); - const config : IZNSCampaignConfig = { - env: envLevel!, + 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!, + name: process.env.DOMAIN_TOKEN_NAME, + symbol: process.env.DOMAIN_TOKEN_SYMBOL, + defaultRoyaltyReceiver: royaltyReceiver, defaultRoyaltyFraction: royaltyFraction, }, rootPriceConfig: priceConfig, zTokenConfig: zConfig, - zeroVaultAddress: zeroVaultAddressConf as string, - mockZToken: mockZTokenEnv === "true", - stakingTokenAddress: process.env.STAKING_TOKEN_ADDRESS!, + zeroVaultAddress: zeroVaultAddressConf, + mockZToken: process.env.MOCK_Z_TOKEN === "true", + stakingTokenAddress: process.env.STAKING_TOKEN_ADDRESS, postDeploy: { - tenderlyProjectSlug: process.env.TENDERLY_PROJECT_SLUG!, + tenderlyProjectSlug: process.env.TENDERLY_PROJECT_SLUG ?? "", monitorContracts: process.env.MONITOR_CONTRACTS === "true", verifyContracts: process.env.VERIFY_CONTRACTS === "true", }, + crosschain: buildCrosschainConfig(), }; return config; @@ -173,6 +229,8 @@ export const validateEnv = ( envLevel = env; } + findMissingEnvVars(); + // Validate price config first since we have to return it const priceConfig = getValidateRootPriceConfig(); @@ -191,25 +249,11 @@ export const validateEnv = ( 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); + requires(process.env.STAKING_TOKEN_ADDRESS === ZTokenMainnet.address, STAKING_TOKEN_ERR); } if (process.env.VERIFY_CONTRACTS === "true") { @@ -225,58 +269,19 @@ export const validateEnv = ( 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!" - ); - } - +export const getValidateRootPriceConfig = () => { // 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, + maxPrice: ethers.parseEther(process.env.MAX_PRICE), + curveMultiplier: BigInt(process.env.CURVE_MULTIPLIER), + maxLength: BigInt(process.env.MAX_LENGTH), + baseLength: BigInt(process.env.BASE_LENGTH), precisionMultiplier, - feePercentage, + feePercentage: BigInt(process.env.PROTOCOL_FEE_PERC), isSet: true, }; diff --git a/src/deploy/campaign/types.ts b/src/deploy/campaign/types.ts index 7bb75fd15..a856c389e 100644 --- a/src/deploy/campaign/types.ts +++ b/src/deploy/campaign/types.ts @@ -1,71 +1,106 @@ -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; -} +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, + ZNSTreasury, + ZToken, + ZTokenMock, + ZNSStringResolver, + ZNSZChainPortal, + ZNSEthereumPortal, + PolygonZkEVMBridgeV2Mock, + ZNSChainResolver, + ZNSRootRegistrarTrunk, ZNSRootRegistrarBranch, ZNSSubRegistrarTrunk, ZNSSubRegistrarBranch, +} from "../../../typechain"; +import { TSupportedChain } from "../missions/contracts/cross-chain/portals/types"; + +export type IZNSSigner = HardhatEthersSigner | DefenderRelaySigner | SignerWithAddress; + +export interface IZNSBaseCrossConfig { + mockZkEvmBridge : boolean; + zkEvmBridgeAddress ?: string; + srcChainName : TSupportedChain; + curNetworkId ?: bigint; + bridgeToken ?: string; +} + +export interface IZNSEthCrossConfig extends IZNSBaseCrossConfig { + destNetworkId : bigint; + destChainName : string; + destChainId : bigint; +} + +export interface IZNSZChainCrossConfig extends IZNSBaseCrossConfig { + srcZnsPortal : string; +} + +export type TZNSCrossConfig = IZNSEthCrossConfig | IZNSZChainCrossConfig; + +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; + crosschain : TZNSCrossConfig; + postDeploy : { + tenderlyProjectSlug : string; + monitorContracts : boolean; + verifyContracts : boolean; + }; +} + +export type ZNSContract = + ZNSAccessController | + ZNSRegistry | + ZNSDomainToken | + ZTokenMock | + ZToken | + ZNSAddressResolver | + ZNSStringResolver | + ZNSChainResolver | + ZNSCurvePricer | + ZNSTreasury | + ZNSRootRegistrarTrunk | + ZNSRootRegistrarBranch | + ZNSFixedPricer | + ZNSSubRegistrarTrunk | + ZNSSubRegistrarBranch | + ZNSZChainPortal | + ZNSEthereumPortal | + PolygonZkEVMBridgeV2Mock; + +export interface IZNSContracts extends IContractState { + accessController : ZNSAccessController; + registry : ZNSRegistry; + domainToken : ZNSDomainToken; + zToken : ZTokenMock; + addressResolver : ZNSAddressResolver; + stringResolver : ZNSStringResolver; + chainResolver : ZNSChainResolver; + curvePricer : ZNSCurvePricer; + treasury : ZNSTreasury; + rootRegistrar : ZNSRootRegistrarTrunk | ZNSRootRegistrarBranch; + fixedPricer : ZNSFixedPricer; + subRegistrar : ZNSSubRegistrarTrunk | ZNSSubRegistrarBranch; + zChainPortal : ZNSZChainPortal; + ethPortal : ZNSEthereumPortal; + zkEvmBridge : PolygonZkEVMBridgeV2Mock; +} diff --git a/src/deploy/constants.ts b/src/deploy/constants.ts index c31511520..e4965f92f 100644 --- a/src/deploy/constants.ts +++ b/src/deploy/constants.ts @@ -1,38 +1,42 @@ -import { IProxyKinds } from "@zero-tech/zdc"; -import { ethers } from "ethers"; - - -export const ProxyKinds : IProxyKinds = { - uups: "uups", - transparent: "transparent", - beacon: "beacon", -}; - -// role names -export const GOVERNOR_ROLE = ethers.solidityPackedKeccak256( - ["string"], - ["GOVERNOR_ROLE"], -); -export const ADMIN_ROLE = ethers.solidityPackedKeccak256( - ["string"], - ["ADMIN_ROLE"], -); -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"], -); - -export const ResolverTypes = { - address: "address", - // TODO: Which word to use for a string type of resolver?? - // eslint-disable-next-line id-blacklist - string: "string", -}; +import { IProxyKinds } from "@zero-tech/zdc"; +import { ethers } from "ethers"; + + +export const ProxyKinds : IProxyKinds = { + uups: "uups", + transparent: "transparent", + beacon: "beacon", +}; + +// role names +export const GOVERNOR_ROLE = ethers.solidityPackedKeccak256( + ["string"], + ["GOVERNOR_ROLE"], +); +export const ADMIN_ROLE = ethers.solidityPackedKeccak256( + ["string"], + ["ADMIN_ROLE"], +); +export const REGISTRAR_ROLE = ethers.solidityPackedKeccak256( + ["string"], + ["REGISTRAR_ROLE"], +); +export const PORTAL_ROLE = ethers.solidityPackedKeccak256( + ["string"], + ["PORTAL_ROLE"], +); +export const DOMAIN_TOKEN_ROLE = ethers.solidityPackedKeccak256( + ["string"], + ["DOMAIN_TOKEN_ROLE"], +); +export const EXECUTOR_ROLE = ethers.solidityPackedKeccak256( + ["string"], + ["EXECUTOR_ROLE"], +); + +export const ResolverTypes = { + address: "address", + // eslint-disable-next-line id-blacklist + string: "string", + chain: "chain", +}; diff --git a/src/deploy/missions/contracts/cross-chain/chain-resolver.ts b/src/deploy/missions/contracts/cross-chain/chain-resolver.ts new file mode 100644 index 000000000..15a17b5e7 --- /dev/null +++ b/src/deploy/missions/contracts/cross-chain/chain-resolver.ts @@ -0,0 +1,69 @@ +import { IZNSCampaignConfig, IZNSContracts } from "../../../campaign/types"; +import { BaseDeployMission } from "@zero-tech/zdc"; +import { HardhatRuntimeEnvironment } from "hardhat/types"; +import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; +import { ProxyKinds, ResolverTypes } from "../../../constants"; +import { znsNames } from "../names"; +import { executeWithConfirmation } from "../../../zns-campaign"; + + +export class ZNSChainResolverDM extends BaseDeployMission< +HardhatRuntimeEnvironment, +SignerWithAddress, +IZNSCampaignConfig, +IZNSContracts +> { + proxyData = { + isProxy: true, + kind: ProxyKinds.uups, + }; + + contractName = znsNames.chainResolver.contract; + instanceName = znsNames.chainResolver.instance; + + async deployArgs () { + const { + accessController, + registry, + } = this.campaign; + + return [await accessController.getAddress(), await registry.getAddress()]; + } + + async needsPostDeploy () { + const { + registry, + chainResolver, + } = this.campaign; + + const resolverInReg = await registry.getResolverType( + ResolverTypes.chain, + ); + + const needs = resolverInReg !== await chainResolver.getAddress(); + const msg = needs ? "needs" : "doesn't need"; + + this.logger.debug(`${this.contractName} ${msg} post deploy sequence`); + + return needs; + } + + async postDeploy () { + const { + registry, + chainResolver, + config: { + deployAdmin, + }, + } = this.campaign; + + await executeWithConfirmation( + registry.connect(deployAdmin).addResolverType( + ResolverTypes.chain, + await chainResolver.getAddress(), + ) + ); + + this.logger.debug(`${this.contractName} post deploy sequence completed`); + } +} diff --git a/src/deploy/missions/contracts/cross-chain/portals/eth-portal.ts b/src/deploy/missions/contracts/cross-chain/portals/eth-portal.ts new file mode 100644 index 000000000..195e74109 --- /dev/null +++ b/src/deploy/missions/contracts/cross-chain/portals/eth-portal.ts @@ -0,0 +1,88 @@ +import { BaseDeployMission, TDeployArgs } from "@zero-tech/zdc"; +import { HardhatRuntimeEnvironment } from "hardhat/types"; +import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; +import { IZNSCampaignConfig, IZNSContracts, IZNSZChainCrossConfig } from "../../../../campaign/types"; +import { PORTAL_ROLE, ProxyKinds } from "../../../../constants"; +import { znsNames } from "../../names"; +import { executeWithConfirmation } from "../../../../zns-campaign"; + + +export class ZNSEthereumPortalDM extends BaseDeployMission< +HardhatRuntimeEnvironment, +SignerWithAddress, +IZNSCampaignConfig, +IZNSContracts +> { + proxyData = { + isProxy: true, + kind: ProxyKinds.uups, + }; + + contractName = znsNames.ethPortal.contract; + instanceName = znsNames.ethPortal.instance; + + async deployArgs () : Promise { + const { + accessController, + registry, + domainToken, + rootRegistrar, + subRegistrar, + zkEvmBridge, + config: { + crosschain, + }, + } = this.campaign; + + const { + zkEvmBridgeAddress, + srcZnsPortal, + } = crosschain as IZNSZChainCrossConfig; + + // TODO multi: figure out proper handling of this for actual contract AND mock !!! + const bridgeAddress = !zkEvmBridgeAddress ? await zkEvmBridge.getAddress() : zkEvmBridgeAddress; + + return [ + await accessController.getAddress(), + bridgeAddress, + srcZnsPortal, + await registry.getAddress(), + await domainToken.getAddress(), + await rootRegistrar.getAddress(), + await subRegistrar.getAddress(), + ]; + } + + async needsPostDeploy () { + const { + accessController, + ethPortal, + } = this.campaign; + + const hasPortalRole = await accessController.isPortal(await ethPortal.getAddress()); + + const needs = !hasPortalRole; + const msg = needs ? "needs" : "doesn't need"; + + this.logger.debug(`${this.contractName} ${msg} post deploy sequence`); + + return needs; + } + + async postDeploy () { + const { + accessController, + ethPortal, + config: { deployAdmin }, + } = this.campaign; + + await executeWithConfirmation( + accessController.connect(deployAdmin).grantRole( + PORTAL_ROLE, + ethPortal.target + ) + ); + + this.logger.debug(`${this.contractName} post deploy sequence completed`); + } +} diff --git a/src/deploy/missions/contracts/cross-chain/portals/get-portal-dm.ts b/src/deploy/missions/contracts/cross-chain/portals/get-portal-dm.ts new file mode 100644 index 000000000..6272ce511 --- /dev/null +++ b/src/deploy/missions/contracts/cross-chain/portals/get-portal-dm.ts @@ -0,0 +1,21 @@ +import { ZNSZChainPortalDM } from "./zchain-portal"; +import { ZNSEthereumPortalDM } from "./eth-portal"; +import { ISupportedChains, TSupportedChain } from "./types"; + + +export const SupportedChains : ISupportedChains = { + z: "zchain", + eth: "ethereum", +}; + + +export const getPortalDM = (chainName : TSupportedChain) => { + switch (chainName) { + case SupportedChains.eth: + return ZNSZChainPortalDM; + case SupportedChains.z: + return ZNSEthereumPortalDM; + default: + throw new Error(`Unknown unsupported chain: ${chainName}!`); + } +}; diff --git a/src/deploy/missions/contracts/cross-chain/portals/types.ts b/src/deploy/missions/contracts/cross-chain/portals/types.ts new file mode 100644 index 000000000..d1aaf2e04 --- /dev/null +++ b/src/deploy/missions/contracts/cross-chain/portals/types.ts @@ -0,0 +1,6 @@ +export type TSupportedChain = "zchain" | "ethereum"; +export interface ISupportedChains { + z : TSupportedChain; + eth : TSupportedChain; +} + diff --git a/src/deploy/missions/contracts/cross-chain/portals/zchain-portal.ts b/src/deploy/missions/contracts/cross-chain/portals/zchain-portal.ts new file mode 100644 index 000000000..c63ae720a --- /dev/null +++ b/src/deploy/missions/contracts/cross-chain/portals/zchain-portal.ts @@ -0,0 +1,63 @@ +import { BaseDeployMission, TDeployArgs } from "@zero-tech/zdc"; +import { HardhatRuntimeEnvironment } from "hardhat/types"; +import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; +import { IZNSCampaignConfig, IZNSContracts, IZNSEthCrossConfig } from "../../../../campaign/types"; +import { ProxyKinds } from "../../../../constants"; +import { znsNames } from "../../names"; + + +// TODO multi: figure out how to set EthereumPortal address on this contract after that is deployed !!! +export class ZNSZChainPortalDM extends BaseDeployMission< +HardhatRuntimeEnvironment, +SignerWithAddress, +IZNSCampaignConfig, +IZNSContracts +> { + proxyData = { + isProxy: true, + kind: ProxyKinds.uups, + }; + + contractName = znsNames.zPortal.contract; + instanceName = znsNames.zPortal.instance; + + async deployArgs () : Promise { + const { + accessController, + registry, + treasury, + chainResolver, + rootRegistrar, + subRegistrar, + zkEvmBridge, + config: { + crosschain, + }, + } = this.campaign; + + const { + destNetworkId, + destChainName, + destChainId, + zkEvmBridgeAddress, + } = crosschain as IZNSEthCrossConfig; + + // TODO multi: figure out proper handling of this for actual contract AND mock !!! + const bridgeAddress = !zkEvmBridgeAddress ? await zkEvmBridge.getAddress() : zkEvmBridgeAddress; + + return [ + destNetworkId, + destChainName, + destChainId, + bridgeAddress, + { + accessController: await accessController.getAddress(), + registry: await registry.getAddress(), + chainResolver: await chainResolver.getAddress(), + treasury: await treasury.getAddress(), + rootRegistrar: await rootRegistrar.getAddress(), + subRegistrar: await subRegistrar.getAddress(), + }, + ]; + } +} diff --git a/src/deploy/missions/contracts/cross-chain/zk-evm-bridge.ts b/src/deploy/missions/contracts/cross-chain/zk-evm-bridge.ts new file mode 100644 index 000000000..21e7b427d --- /dev/null +++ b/src/deploy/missions/contracts/cross-chain/zk-evm-bridge.ts @@ -0,0 +1,130 @@ +import { BaseDeployMission, IContractArtifact, IDeployMissionArgs, 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 } from "../../../constants"; +import { znsNames } from "../names"; +import { ethers, Interface } from "ethers"; + + +export class PolygonZkEVMBridgeV2DM extends BaseDeployMission< +HardhatRuntimeEnvironment, +SignerWithAddress, +IZNSCampaignConfig, +IZNSContracts +> { + proxyData = { + isProxy: true, + kind: ProxyKinds.transparent, + }; + + contractName = znsNames.zkEvmBridge.contract; + instanceName = znsNames.zkEvmBridge.instance; + + constructor (args : IDeployMissionArgs< + HardhatRuntimeEnvironment, + SignerWithAddress, + IZNSCampaignConfig, + IZNSContracts + >) { + super(args); + + if (this.config.crosschain.mockZkEvmBridge) { + this.contractName = znsNames.zkEvmBridge.contractMock; + } + } + + async deploy () { + if (!this.config.crosschain.mockZkEvmBridge) { + const { + crosschain: { + zkEvmBridgeAddress, + }, + } = this.config; + + this.logger.info("Using PolygonZkEvmBridgeV2 deployed on chain"); + + if (!zkEvmBridgeAddress) + throw new Error("No existing ZkEvmBridge address has been passed to the campaign config!"); + + this.logger.debug(`Writing ${this.contractName} to DB...`); + + // TODO multi: + // const factory = await this.campaign.deployer.getFactory(this.contractName); + // const contract = factory.attach(zkEvmBridgeAddress); + const contract = this.getContractObject(zkEvmBridgeAddress); + + await this.saveToDB(contract); + + this.campaign.updateStateContract(this.instanceName, this.contractName, contract); + + // eslint-disable-next-line max-len + this.logger.info(`Successfully created ${this.contractName} contract from chain data at ${await contract.getAddress()}`); + } else { + await super.deploy(); + } + } + + getContractObject (address : string) { + // TODO multi: make this better when figured out how to compile the Bridge !!! + + const { abi } = this.getArtifact(); + // TODO multi: fix this ! + const contract = new ethers.Contract(address, abi as unknown as Interface, this.campaign.config.deployAdmin); + + return contract; + } + + // TODO multi: make this better !!! maybe add a new getContractObject() method to BaseDeployMission for this !!! + async needsDeploy () { + const dbContract = await this.getFromDB(); + + if (!dbContract) { + this.logger.info(`${this.dbName} not found in DB, proceeding to deploy...`); + } else { + this.logger.info(`${this.dbName} found in DB at ${dbContract.address}, no deployment needed.`); + + const contract = this.getContractObject(dbContract.address); + + // eslint-disable-next-line max-len + this.logger.debug(`Updating ${this.contractName} in state from DB data with address ${await contract.getAddress()}`); + + this.campaign.updateStateContract(this.instanceName, this.contractName, contract); + } + + return !dbContract; + } + + async verify () { + if (!this.config.crosschain.mockZkEvmBridge) { + this.logger.info("Skipping verification for PolygonZkEvmBridge since it's already verified."); + return; + } + + await super.verify(); + } + + // TODO multi: make this better !!! + getArtifact () : IContractArtifact { + return require( + `${process.cwd()}/node_modules/@zero-tech/zkevm-contracts/compiled-contracts/PolygonZkEVMBridgeV2.json` + ); + } + + async deployArgs () : Promise { + // this is ONLY for the Mock version of the Bridge ! + const { + crosschain: { + curNetworkId, + bridgeToken, + }, + } = this.config; + + const tokenAddress = !bridgeToken ? ethers.ZeroAddress : bridgeToken; + + return [ + curNetworkId as bigint, + tokenAddress, + ]; + } +} diff --git a/src/deploy/missions/contracts/index.ts b/src/deploy/missions/contracts/index.ts index ef0972558..bb1bc71c2 100644 --- a/src/deploy/missions/contracts/index.ts +++ b/src/deploy/missions/contracts/index.ts @@ -1,11 +1,16 @@ -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 "./z-token/z-token"; -export * from "./fixed-pricer"; -export * from "./sub-registrar"; +export * from "./zns-base/address-resolver"; +export * from "./zns-base/string-resolver"; +export * from "./zns-base/registry"; +export * from "./zns-base/root-registrar"; +export * from "./zns-base/domain-token"; +export * from "./zns-base/treasury"; +export * from "./zns-base/curve-pricer"; +export * from "./zns-base/access-controller"; +export * from "./zns-base/z-token/z-token"; +export * from "./zns-base/fixed-pricer"; +export * from "./zns-base/sub-registrar"; + +export * from "./cross-chain/chain-resolver"; +export * from "./cross-chain/portals/zchain-portal"; +export * from "./cross-chain/portals/eth-portal"; +export * from "./cross-chain/zk-evm-bridge"; diff --git a/src/deploy/missions/contracts/names.ts b/src/deploy/missions/contracts/names.ts index 099d4020d..8ce256d13 100644 --- a/src/deploy/missions/contracts/names.ts +++ b/src/deploy/missions/contracts/names.ts @@ -27,6 +27,10 @@ export const znsNames = { contract: "ZNSStringResolver", instance: "stringResolver", }, + chainResolver: { + contract: "ZNSChainResolver", + instance: "chainResolver", + }, curvePricer: { contract: "ZNSCurvePricer", instance: "curvePricer", @@ -40,13 +44,29 @@ export const znsNames = { instance: "treasury", }, rootRegistrar: { - contract: "ZNSRootRegistrar", + contractBase: "ZNSRootRegistrarBase", + contractTrunk: "ZNSRootRegistrarTrunk", + contractBranch: "ZNSRootRegistrarBranch", instance: "rootRegistrar", }, subRegistrar: { - contract: "ZNSSubRegistrar", + contractTrunk: "ZNSSubRegistrarTrunk", + contractBranch: "ZNSSubRegistrarBranch", instance: "subRegistrar", }, + zPortal: { + contract: "ZNSZChainPortal", + instance: "zChainPortal", + }, + ethPortal: { + contract: "ZNSEthereumPortal", + instance: "ethPortal", + }, + zkEvmBridge: { + contract: "PolygonZkEVMBridgeV2", + contractMock: "PolygonZkEVMBridgeV2Mock", + instance: "zkEvmBridge", + }, erc1967Proxy: { contract: erc1967ProxyName, instance: "erc1967Proxy", diff --git a/src/deploy/missions/contracts/z-token/mainnet-data.ts b/src/deploy/missions/contracts/z-token/mainnet-data.ts deleted file mode 100644 index bc2879a8c..000000000 --- a/src/deploy/missions/contracts/z-token/mainnet-data.ts +++ /dev/null @@ -1,4 +0,0 @@ - -export const ZSepolia = { - address: "0x7148Db73c78Ded8e4f81784A121Bbe7E163f4834", -}; diff --git a/src/deploy/missions/contracts/access-controller.ts b/src/deploy/missions/contracts/zns-base/access-controller.ts similarity index 85% rename from src/deploy/missions/contracts/access-controller.ts rename to src/deploy/missions/contracts/zns-base/access-controller.ts index 60586a16d..949974ca6 100644 --- a/src/deploy/missions/contracts/access-controller.ts +++ b/src/deploy/missions/contracts/zns-base/access-controller.ts @@ -1,10 +1,10 @@ import { BaseDeployMission, } from "@zero-tech/zdc"; -import { znsNames } from "./names"; +import { znsNames } from "../names"; import { HardhatRuntimeEnvironment } from "hardhat/types"; import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; -import { IZNSCampaignConfig, IZNSContracts } from "../../campaign/types"; +import { IZNSCampaignConfig, IZNSContracts } from "../../../campaign/types"; export class ZNSAccessControllerDM extends BaseDeployMission< diff --git a/src/deploy/missions/contracts/address-resolver.ts b/src/deploy/missions/contracts/zns-base/address-resolver.ts similarity index 68% rename from src/deploy/missions/contracts/address-resolver.ts rename to src/deploy/missions/contracts/zns-base/address-resolver.ts index be22147f6..2d580f6d5 100644 --- a/src/deploy/missions/contracts/address-resolver.ts +++ b/src/deploy/missions/contracts/zns-base/address-resolver.ts @@ -2,11 +2,12 @@ import { BaseDeployMission, TDeployArgs, } from "@zero-tech/zdc"; -import { ProxyKinds, ResolverTypes } from "../../constants"; -import { znsNames } from "./names"; +import { ProxyKinds, ResolverTypes } from "../../../constants"; +import { znsNames } from "../names"; import { HardhatRuntimeEnvironment } from "hardhat/types"; -import { IZNSCampaignConfig, IZNSContracts } from "../../campaign/types"; +import { IZNSCampaignConfig, IZNSContracts } from "../../../campaign/types"; import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; +import { executeWithConfirmation } from "../../../zns-campaign"; export class ZNSAddressResolverDM extends BaseDeployMission< @@ -56,9 +57,14 @@ IZNSContracts }, } = this.campaign; - await registry.connect(deployAdmin).addResolverType( - ResolverTypes.address, - await addressResolver.getAddress(), + // TODO multi: wrap this in a tx runner that will wait for every tx if not on "dev" + // amount of confirmations should be a var passed to the config! + // do this for all DMs here after the zDC code is changed! + await executeWithConfirmation( + registry.connect(deployAdmin).addResolverType( + ResolverTypes.address, + await addressResolver.getAddress() + ) ); this.logger.debug(`${this.contractName} post deploy sequence completed`); diff --git a/src/deploy/missions/contracts/curve-pricer.ts b/src/deploy/missions/contracts/zns-base/curve-pricer.ts similarity index 83% rename from src/deploy/missions/contracts/curve-pricer.ts rename to src/deploy/missions/contracts/zns-base/curve-pricer.ts index 8dee27dd2..c71b5270f 100644 --- a/src/deploy/missions/contracts/curve-pricer.ts +++ b/src/deploy/missions/contracts/zns-base/curve-pricer.ts @@ -2,11 +2,11 @@ import { BaseDeployMission, TDeployArgs, } from "@zero-tech/zdc"; -import { ProxyKinds } from "../../constants"; -import { znsNames } from "./names"; +import { ProxyKinds } from "../../../constants"; +import { znsNames } from "../names"; import { HardhatRuntimeEnvironment } from "hardhat/types"; import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; -import { IZNSCampaignConfig, IZNSContracts } from "../../campaign/types"; +import { IZNSCampaignConfig, IZNSContracts } from "../../../campaign/types"; export class ZNSCurvePricerDM extends BaseDeployMission< diff --git a/src/deploy/missions/contracts/domain-token.ts b/src/deploy/missions/contracts/zns-base/domain-token.ts similarity index 87% rename from src/deploy/missions/contracts/domain-token.ts rename to src/deploy/missions/contracts/zns-base/domain-token.ts index 833368ae2..34c292ee1 100644 --- a/src/deploy/missions/contracts/domain-token.ts +++ b/src/deploy/missions/contracts/zns-base/domain-token.ts @@ -1,80 +1,80 @@ -import { - BaseDeployMission, - TDeployArgs, -} from "@zero-tech/zdc"; -import { DOMAIN_TOKEN_ROLE, ProxyKinds } from "../../constants"; -import { znsNames } from "./names"; -import { HardhatRuntimeEnvironment } from "hardhat/types"; -import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; -import { IZNSCampaignConfig, IZNSContracts } from "../../campaign/types"; - - -export class ZNSDomainTokenDM extends BaseDeployMission< -HardhatRuntimeEnvironment, -SignerWithAddress, -IZNSCampaignConfig, -IZNSContracts -> { - proxyData = { - isProxy: true, - kind: ProxyKinds.uups, - }; - - contractName = znsNames.domainToken.contract; - instanceName = znsNames.domainToken.instance; - - async deployArgs () : Promise { - const { accessController, registry } = this.campaign; - const { - domainToken: { - name, - symbol, - defaultRoyaltyReceiver, - defaultRoyaltyFraction, - }, - } = this.config; - - 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`); - } -} +import { + BaseDeployMission, + TDeployArgs, +} from "@zero-tech/zdc"; +import { DOMAIN_TOKEN_ROLE, ProxyKinds } from "../../../constants"; +import { znsNames } from "../names"; +import { HardhatRuntimeEnvironment } from "hardhat/types"; +import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; +import { IZNSCampaignConfig, IZNSContracts } from "../../../campaign/types"; + + +export class ZNSDomainTokenDM extends BaseDeployMission< +HardhatRuntimeEnvironment, +SignerWithAddress, +IZNSCampaignConfig, +IZNSContracts +> { + proxyData = { + isProxy: true, + kind: ProxyKinds.uups, + }; + + contractName = znsNames.domainToken.contract; + instanceName = znsNames.domainToken.instance; + + async deployArgs () : Promise { + const { accessController, registry } = this.campaign; + const { + domainToken: { + name, + symbol, + defaultRoyaltyReceiver, + defaultRoyaltyFraction, + }, + } = this.config; + + 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/zns-base/fixed-pricer.ts similarity index 81% rename from src/deploy/missions/contracts/fixed-pricer.ts rename to src/deploy/missions/contracts/zns-base/fixed-pricer.ts index 3f6e5e263..fe43c08a3 100644 --- a/src/deploy/missions/contracts/fixed-pricer.ts +++ b/src/deploy/missions/contracts/zns-base/fixed-pricer.ts @@ -1,12 +1,12 @@ -import { ProxyKinds } from "../../constants"; +import { ProxyKinds } from "../../../constants"; import { BaseDeployMission, TDeployArgs, } from "@zero-tech/zdc"; -import { znsNames } from "./names"; +import { znsNames } from "../names"; import { HardhatRuntimeEnvironment } from "hardhat/types"; import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; -import { IZNSCampaignConfig, IZNSContracts } from "../../campaign/types"; +import { IZNSCampaignConfig, IZNSContracts } from "../../../campaign/types"; export class ZNSFixedPricerDM extends BaseDeployMission< HardhatRuntimeEnvironment, diff --git a/src/deploy/missions/contracts/registry.ts b/src/deploy/missions/contracts/zns-base/registry.ts similarity index 80% rename from src/deploy/missions/contracts/registry.ts rename to src/deploy/missions/contracts/zns-base/registry.ts index f9b99f6bd..12da13ce3 100644 --- a/src/deploy/missions/contracts/registry.ts +++ b/src/deploy/missions/contracts/zns-base/registry.ts @@ -2,11 +2,11 @@ import { BaseDeployMission, TDeployArgs, } from "@zero-tech/zdc"; -import { ProxyKinds } from "../../constants"; -import { znsNames } from "./names"; +import { ProxyKinds } from "../../../constants"; +import { znsNames } from "../names"; import { HardhatRuntimeEnvironment } from "hardhat/types"; import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; -import { IZNSCampaignConfig, IZNSContracts } from "../../campaign/types"; +import { IZNSCampaignConfig, IZNSContracts } from "../../../campaign/types"; export class ZNSRegistryDM extends BaseDeployMission< diff --git a/src/deploy/missions/contracts/root-registrar.ts b/src/deploy/missions/contracts/zns-base/root-registrar.ts similarity index 58% rename from src/deploy/missions/contracts/root-registrar.ts rename to src/deploy/missions/contracts/zns-base/root-registrar.ts index 0bfd60b59..3a26d1e75 100644 --- a/src/deploy/missions/contracts/root-registrar.ts +++ b/src/deploy/missions/contracts/zns-base/root-registrar.ts @@ -1,12 +1,14 @@ import { - BaseDeployMission, + BaseDeployMission, IDeployMissionArgs, TDeployArgs, } from "@zero-tech/zdc"; -import { ProxyKinds, REGISTRAR_ROLE } from "../../constants"; -import { znsNames } from "./names"; +import { ProxyKinds, REGISTRAR_ROLE } from "../../../constants"; +import { znsNames } from "../names"; import { HardhatRuntimeEnvironment } from "hardhat/types"; import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; -import { IZNSCampaignConfig, IZNSContracts } from "../../campaign/types"; +import { IZNSCampaignConfig, IZNSContracts } from "../../../campaign/types"; +import { SupportedChains } from "../cross-chain/portals/get-portal-dm"; +import { executeWithConfirmation } from "../../../zns-campaign"; export class ZNSRootRegistrarDM extends BaseDeployMission< @@ -20,9 +22,26 @@ IZNSContracts kind: ProxyKinds.uups, }; - contractName = znsNames.rootRegistrar.contract; + contractName = znsNames.rootRegistrar.contractBase; instanceName = znsNames.rootRegistrar.instance; + constructor (args : IDeployMissionArgs< + HardhatRuntimeEnvironment, + SignerWithAddress, + IZNSCampaignConfig, + IZNSContracts + >) { + super(args); + + if (this.config.crosschain.srcChainName === SupportedChains.eth) { + this.contractName = znsNames.rootRegistrar.contractTrunk; + } else if (this.config.crosschain.srcChainName === SupportedChains.z) { + this.contractName = znsNames.rootRegistrar.contractBranch; + } else { + throw new Error("Unsupported chain for Root Registrar deployment"); + } + } + async deployArgs () : Promise { const { accessController, @@ -69,9 +88,11 @@ IZNSContracts }, } = this.campaign; - await accessController - .connect(deployAdmin) - .grantRole(REGISTRAR_ROLE, await rootRegistrar.getAddress()); + await executeWithConfirmation( + accessController + .connect(deployAdmin) + .grantRole(REGISTRAR_ROLE, await rootRegistrar.getAddress()) + ); this.logger.debug(`${this.contractName} post deploy sequence completed`); } diff --git a/src/deploy/missions/contracts/string-resolver.ts b/src/deploy/missions/contracts/zns-base/string-resolver.ts similarity index 77% rename from src/deploy/missions/contracts/string-resolver.ts rename to src/deploy/missions/contracts/zns-base/string-resolver.ts index 305aaf5f4..142c54d68 100644 --- a/src/deploy/missions/contracts/string-resolver.ts +++ b/src/deploy/missions/contracts/zns-base/string-resolver.ts @@ -1,9 +1,10 @@ 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"; +import { IZNSCampaignConfig, IZNSContracts } from "../../../campaign/types"; +import { ProxyKinds, ResolverTypes } from "../../../constants"; +import { znsNames } from "../names"; +import { executeWithConfirmation } from "../../../zns-campaign"; export class ZNSStringResolverDM extends BaseDeployMission< @@ -56,9 +57,11 @@ IZNSContracts }, } = this.campaign; - await registry.connect(deployAdmin).addResolverType( - ResolverTypes.string, - await stringResolver.getAddress(), + await executeWithConfirmation( + 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/zns-base/sub-registrar.ts similarity index 62% rename from src/deploy/missions/contracts/sub-registrar.ts rename to src/deploy/missions/contracts/zns-base/sub-registrar.ts index b1d0b0594..a55d59d29 100644 --- a/src/deploy/missions/contracts/sub-registrar.ts +++ b/src/deploy/missions/contracts/zns-base/sub-registrar.ts @@ -1,12 +1,14 @@ import { - BaseDeployMission, + BaseDeployMission, IDeployMissionArgs, TDeployArgs, } from "@zero-tech/zdc"; -import { ProxyKinds, REGISTRAR_ROLE } from "../../constants"; -import { znsNames } from "./names"; +import { ProxyKinds, REGISTRAR_ROLE } from "../../../constants"; +import { znsNames } from "../names"; import { HardhatRuntimeEnvironment } from "hardhat/types"; import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; -import { IZNSCampaignConfig, IZNSContracts } from "../../campaign/types"; +import { IZNSCampaignConfig, IZNSContracts } from "../../../campaign/types"; +import { SupportedChains } from "../cross-chain/portals/get-portal-dm"; +import { executeWithConfirmation } from "../../../zns-campaign"; export class ZNSSubRegistrarDM extends BaseDeployMission< @@ -20,12 +22,29 @@ IZNSContracts kind: ProxyKinds.uups, }; - contractName = znsNames.subRegistrar.contract; + contractName = znsNames.subRegistrar.contractTrunk; instanceName = znsNames.subRegistrar.instance; private hasRegistrarRole : boolean | undefined; private isSetOnRoot : boolean | undefined; + constructor (args : IDeployMissionArgs< + HardhatRuntimeEnvironment, + SignerWithAddress, + IZNSCampaignConfig, + IZNSContracts + >) { + super(args); + + if (this.config.crosschain.srcChainName === SupportedChains.eth) { + this.contractName = znsNames.subRegistrar.contractTrunk; + } else if (this.config.crosschain.srcChainName === SupportedChains.z) { + this.contractName = znsNames.subRegistrar.contractBranch; + } else { + throw new Error("Unsupported chain for Root Registrar deployment"); + } + } + async deployArgs () : Promise { const { accessController, @@ -77,13 +96,17 @@ IZNSContracts } = this.campaign; if (!this.isSetOnRoot) { - await rootRegistrar.connect(deployAdmin).setSubRegistrar(await subRegistrar.getAddress()); + await executeWithConfirmation( + rootRegistrar.connect(deployAdmin).setSubRegistrar(await subRegistrar.getAddress()) + ); } if (!this.hasRegistrarRole) { - await accessController - .connect(deployAdmin) - .grantRole(REGISTRAR_ROLE, await subRegistrar.getAddress()); + await executeWithConfirmation( + accessController + .connect(deployAdmin) + .grantRole(REGISTRAR_ROLE, await subRegistrar.getAddress()) + ); } this.logger.debug(`${this.contractName} post deploy sequence completed`); diff --git a/src/deploy/missions/contracts/treasury.ts b/src/deploy/missions/contracts/zns-base/treasury.ts similarity index 84% rename from src/deploy/missions/contracts/treasury.ts rename to src/deploy/missions/contracts/zns-base/treasury.ts index 5a356ee3a..7d65e273c 100644 --- a/src/deploy/missions/contracts/treasury.ts +++ b/src/deploy/missions/contracts/zns-base/treasury.ts @@ -2,11 +2,11 @@ import { BaseDeployMission, TDeployArgs, } from "@zero-tech/zdc"; -import { ProxyKinds } from "../../constants"; -import { znsNames } from "./names"; +import { ProxyKinds } from "../../../constants"; +import { znsNames } from "../names"; import { HardhatRuntimeEnvironment } from "hardhat/types"; import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; -import { IZNSCampaignConfig, IZNSContracts } from "../../campaign/types"; +import { IZNSCampaignConfig, IZNSContracts } from "../../../campaign/types"; export class ZNSTreasuryDM extends BaseDeployMission< diff --git a/src/deploy/missions/contracts/zns-base/z-token/mainnet-data.ts b/src/deploy/missions/contracts/zns-base/z-token/mainnet-data.ts new file mode 100644 index 000000000..4783e9836 --- /dev/null +++ b/src/deploy/missions/contracts/zns-base/z-token/mainnet-data.ts @@ -0,0 +1,8 @@ + +export const ZSepolia = { + address: "0x7148Db73c78Ded8e4f81784A121Bbe7E163f4834", +}; +// TODO multi: fix this to have actual MAINNET DATA HERE! +export const ZTokenMainnet = { + address: "NOT IMPLEMENTED!", +}; diff --git a/src/deploy/missions/contracts/z-token/z-token.ts b/src/deploy/missions/contracts/zns-base/z-token/z-token.ts similarity index 91% rename from src/deploy/missions/contracts/z-token/z-token.ts rename to src/deploy/missions/contracts/zns-base/z-token/z-token.ts index adabaa128..1ae93b622 100644 --- a/src/deploy/missions/contracts/z-token/z-token.ts +++ b/src/deploy/missions/contracts/zns-base/z-token/z-token.ts @@ -1,15 +1,14 @@ -/* eslint-disable prefer-const */ import { BaseDeployMission, IDeployMissionArgs, TDeployArgs, } from "@zero-tech/zdc"; -import { znsNames } from "../names"; +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"; +import { IZNSCampaignConfig, IZNSContracts } from "../../../../campaign/types"; +import { IZTokenConfig } from "../../../types"; +import { ZToken__factory } from "../../../../../../typechain"; export class ZTokenDM extends BaseDeployMission< @@ -80,7 +79,7 @@ IZNSContracts } async deployArgs () : Promise { - let { + const { name, symbol, defaultAdmin, diff --git a/src/deploy/run-campaign.ts b/src/deploy/run-campaign.ts index c11d57554..8ff168ae2 100644 --- a/src/deploy/run-campaign.ts +++ b/src/deploy/run-campaign.ts @@ -1,4 +1,4 @@ -import { getConfig } from "./campaign/environments"; +import { getConfig } from "./campaign/get-config"; import { runZnsCampaign } from "./zns-campaign"; import * as hre from "hardhat"; import { getLogger } from "@zero-tech/zdc"; diff --git a/src/deploy/zns-campaign.ts b/src/deploy/zns-campaign.ts index 38cfb0497..c42df1a88 100644 --- a/src/deploy/zns-campaign.ts +++ b/src/deploy/zns-campaign.ts @@ -1,9 +1,10 @@ +/* eslint-disable @typescript-eslint/no-shadow, no-shadow */ import * as hre from "hardhat"; import { HardhatRuntimeEnvironment } from "hardhat/types"; import { HardhatDeployer, DeployCampaign, - getLogger, + getLogger, IHardhatDeployerArgs, TDeployArgs, TProxyKind, IContractV6, } from "@zero-tech/zdc"; import { ZTokenDM, @@ -11,19 +12,85 @@ import { ZNSAddressResolverDM, ZNSStringResolverDM, ZNSDomainTokenDM, ZNSCurvePricerDM, ZNSRootRegistrarDM, - ZNSRegistryDM, ZNSTreasuryDM, ZNSFixedPricerDM, ZNSSubRegistrarDM, + ZNSRegistryDM, ZNSTreasuryDM, ZNSFixedPricerDM, ZNSSubRegistrarDM, PolygonZkEVMBridgeV2DM, ZNSChainResolverDM, } from "./missions/contracts"; import { IZNSCampaignConfig, IZNSContracts } from "./campaign/types"; import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; import { getZnsMongoAdapter } from "./mongo"; +import { getPortalDM } from "./missions/contracts/cross-chain/portals/get-portal-dm"; +import { ContractTransactionResponse, Wallet } from "ethers"; +import { getConfirmationsNumber } from "../../test/helpers/tx"; +export const executeWithConfirmation = async ( + tx : Promise, + confNum ?: number, +) => { + confNum = confNum ?? getConfirmationsNumber(); + const txRes = await tx; + return txRes.wait(confNum); +}; + +// TODO multi: move this or change zDC code to include this !! +class HardhatDeployerWrapper extends HardhatDeployer { + constructor ({ + hre, + signer, + env, + } : IHardhatDeployerArgs) { + super({ + hre, + signer, + env, + }); + } + + async deployProxy ({ + contractName, + args, + kind, + } : { + contractName : string; + args : TDeployArgs; + kind : TProxyKind; + }) : Promise { + const contract = await super.deployProxy({ + contractName, + args, + kind, + }); + + if (this.env !== "dev") { + // TODO multi: fix this in zDC since there is a wrong type in IContractV6 for this method + const deployTx = contract.deploymentTransaction() as ContractTransactionResponse; + // TODO multi: make the amount of blocks a var passed to deployed by the config ?? + if (deployTx) await deployTx.wait(getConfirmationsNumber()); + } + + return contract; + } + + async deployContract (contractName : string, args : TDeployArgs) : Promise { + const contract = await super.deployContract(contractName, args); + + if (this.env !== "dev") { + // TODO multi: fix this in zDC since there is a wrong type in IContractV6 for this method + const deployTx = contract.deploymentTransaction() as ContractTransactionResponse; + // TODO multi: make the amount of blocks a var passed to deployed by the config ?? + // this may be needed to be higher than 2 in times of network congestion + if (deployTx) await deployTx.wait(getConfirmationsNumber()); + } + + return contract; + } +} + export const runZnsCampaign = async ({ config, dbVersion, deployer, } : { - config : IZNSCampaignConfig; + config : IZNSCampaignConfig; dbVersion ?: string; deployer ?: HardhatDeployer; }) => { @@ -32,7 +99,8 @@ export const runZnsCampaign = async ({ const logger = getLogger(); if (!deployer) { - deployer = new HardhatDeployer({ + // TODO multi: change this when finalized ! + deployer = new HardhatDeployerWrapper({ hre, signer: config.deployAdmin, env: config.env, @@ -57,8 +125,11 @@ export const runZnsCampaign = async ({ ZNSCurvePricerDM, ZNSTreasuryDM, ZNSRootRegistrarDM, - ZNSFixedPricerDM, ZNSSubRegistrarDM, + ZNSFixedPricerDM, + ZNSChainResolverDM, + PolygonZkEVMBridgeV2DM, + getPortalDM(config.crosschain.srcChainName), ], deployer, dbAdapter, @@ -70,5 +141,8 @@ export const runZnsCampaign = async ({ await dbAdapter.finalize(dbVersion); + // TODO multi: add setting L2 portal address on L1 portal here for prod !!!!!! + // find a good way to acquire this from the DB or something else possibly + return campaign; }; diff --git a/src/environment/env.ts b/src/environment/env.ts new file mode 100644 index 000000000..4826f4cab --- /dev/null +++ b/src/environment/env.ts @@ -0,0 +1,80 @@ +// TODO multi: create a proper big ENV file with all default values here +// and make it be the default for all the tests and so it's easier to fill, clear +// and override it when needed. + +// These are DEFAULT values for local testing that can be overridden by ENV vars +// set in .env file locally. +// For detailed breakdown of vars, see env.sample file. +// !!! --< DO NOT WRITE ANY MAINNET DATA HERE >-- !!! +import { IZNSEnvironment } from "./types"; + + +export const environment : IZNSEnvironment = { + ENV_LEVEL: "dev", + CONFIRMATION_N: "0", + // RPCs for actual networks + MAINNET_RPC_URL: "", + SEPOLIA_RPC_URL: "", + ZCHAIN_TEST_RPC_URL: "", + ZCHAIN_MAIN_RPC_URL: "", + // MongoDB setup + // TODO multi: should we split these into 2 for L1 and L2 ZNS contracts ?? + // how do we structure the DB here ?? + MONGO_DB_URI: `mongodb://localhost:2701${process.argv.includes("coverage") ? "7" : "8"}`, + MONGO_DB_NAME: "zns-campaign", + MONGO_DB_CLIENT_OPTS: "", + MONGO_DB_VERSION: "", + ARCHIVE_PREVIOUS_DB_VERSION: "true", + // Logger vars + LOG_LEVEL: "debug", + SILENT_LOGGER: "true", + MAKE_LOG_FILE: "false", + // 3rd Party Services: + // Etherscan + VERIFY_CONTRACTS: "false", + ETHERSCAN_API_KEY: "", + // Tenderly + MONITOR_CONTRACTS: "false", + TENDERLY_ACCOUNT_ID: "zer0-os", + TENDERLY_PROJECT_SLUG: "", + TENDERLY_ACCESS_KEY: "", + // Tenderly for testing with it's DevNet feature + TENDERLY_DEVNET_TEMPLATE: "zns-devnet", + DEVNET_RPC_URL: "", + + // Contracts Config: + // ! System Administration ! + GOVERNOR_ADDRESSES: "", + ADMIN_ADDRESSES: "", + // ZNS Payment Token (e.g. Z) + MOCK_Z_TOKEN: "true", + STAKING_TOKEN_ADDRESS: "", + // CurvePricer Config [without decimals!] + // TODO multi: check defaults for the new formula and update !!! + MAX_PRICE: "25000", + CURVE_MULTIPLIER: "1000", + MAX_LENGTH: "50", + BASE_LENGTH: "4", + PROTOCOL_FEE_PERC: "222", + DECIMALS: "18", + PRECISION: "2", + // DomainToken Config + DOMAIN_TOKEN_NAME: "ZERO ID", + DOMAIN_TOKEN_SYMBOL: "ZID", + ROYALTY_FRACTION: "200", + ROYALTY_RECEIVER: "", + // Vault for all protocol fees + ZERO_VAULT_ADDRESS: "", + // Cross-Chain Config + SRC_CHAIN_NAME: "ethereum", + MOCK_ZKEVM_BRIDGE: "true", + ZK_EVM_BRIDGE: "", + NETWORK_ID: "0", + BRIDGE_TOKEN: "0x0000000000000000000000000000000000000000", + DEST_NETWORK_ID: "1", + // TODO multi: should we use existing constants here or make constants from this file ?? + // maybe the former so we can modify this file locally without affecting default constants... + DEST_CHAIN_NAME: "zchain", + DEST_CHAIN_ID: "2012605151", + SRC_ZNS_PORTAL: "", +}; diff --git a/src/environment/globals.d.ts b/src/environment/globals.d.ts new file mode 100644 index 000000000..c9f773a71 --- /dev/null +++ b/src/environment/globals.d.ts @@ -0,0 +1,7 @@ +import { IZNSEnvironment } from "./types"; + +declare global { + namespace NodeJS { + interface ProcessEnv extends IZNSEnvironment {} + } +} diff --git a/src/environment/set-env.ts b/src/environment/set-env.ts new file mode 100644 index 000000000..453c81be8 --- /dev/null +++ b/src/environment/set-env.ts @@ -0,0 +1,12 @@ +/* eslint-disable @typescript-eslint/no-var-requires */ +import { environment } from "./env"; + +export const setDefaultEnvironment = () => { + Object.entries(environment).forEach(([key, value]) => { + // load the defaults first + process.env[key] = value; + }); + + // override from local .env file if anything is present + require("dotenv").config({ override: true }); +}; diff --git a/src/environment/types.ts b/src/environment/types.ts new file mode 100644 index 000000000..ed8523cc9 --- /dev/null +++ b/src/environment/types.ts @@ -0,0 +1,49 @@ +export interface IZNSEnvironment { + ENV_LEVEL : string; + CONFIRMATION_N ?: string; + MAINNET_RPC_URL ?: string; + SEPOLIA_RPC_URL ?: string; + ZCHAIN_TEST_RPC_URL ?: string; + ZCHAIN_MAIN_RPC_URL ?: string; + MONGO_DB_URI : string; + MONGO_DB_NAME : string; + MONGO_DB_CLIENT_OPTS ?: string; + MONGO_DB_VERSION ?: string; + ARCHIVE_PREVIOUS_DB_VERSION : string; + LOG_LEVEL : string; + SILENT_LOGGER : string; + MAKE_LOG_FILE ?: string; + VERIFY_CONTRACTS : string; + ETHERSCAN_API_KEY ?: string; + MONITOR_CONTRACTS : string; + TENDERLY_ACCOUNT_ID : string; + TENDERLY_PROJECT_SLUG ?: string; + TENDERLY_ACCESS_KEY ?: string; + TENDERLY_DEVNET_TEMPLATE ?: string; + DEVNET_RPC_URL ?: string; + GOVERNOR_ADDRESSES ?: string; + ADMIN_ADDRESSES ?: string; + MOCK_Z_TOKEN : string; + STAKING_TOKEN_ADDRESS ?: string; + MAX_PRICE : string; + CURVE_MULTIPLIER : string; + MAX_LENGTH : string; + BASE_LENGTH : string; + PROTOCOL_FEE_PERC : string; + DECIMALS : string; + PRECISION : string; + DOMAIN_TOKEN_NAME : string; + DOMAIN_TOKEN_SYMBOL : string; + ROYALTY_FRACTION : string; + ROYALTY_RECEIVER ?: string; + ZERO_VAULT_ADDRESS ?: string; + SRC_CHAIN_NAME : string; + MOCK_ZKEVM_BRIDGE : string; + ZK_EVM_BRIDGE ?: string; + NETWORK_ID : string; + BRIDGE_TOKEN : string; + DEST_NETWORK_ID : string; + DEST_CHAIN_NAME : string; + DEST_CHAIN_ID : string; + SRC_ZNS_PORTAL ?: string; +} diff --git a/src/environment/validate.ts b/src/environment/validate.ts new file mode 100644 index 000000000..4d596868f --- /dev/null +++ b/src/environment/validate.ts @@ -0,0 +1,20 @@ + +const required = [ + "MONGO_DB_URI", "MONGO_DB_NAME", "ARCHIVE_PREVIOUS_DB_VERSION", "LOG_LEVEL", "ARCHIVE_PREVIOUS_DB_VERSION", + "LOG_LEVEL", "ENV_LEVEL", "MAX_PRICE", "CURVE_MULTIPLIER", "MAX_LENGTH", "BASE_LENGTH", "PROTOCOL_FEE_PERC", + "DECIMALS", "PRECISION", "DOMAIN_TOKEN_NAME", "DOMAIN_TOKEN_SYMBOL", "ROYALTY_FRACTION", "MOCK_MEOW_TOKEN", + "SRC_CHAIN_NAME", "MOCK_ZKEVM_BRIDGE", +]; + +// TODO multi: is there a way to evaluate a type of the full ENV and run the below function +// only on non-optional parameters? +export const findMissingEnvVars = () => { + const missing = required.filter( + key => + process.env[key] === undefined || process.env[key] === "" + ); + + if (missing.length > 0) { + throw new Error(`Missing required environment variables: ${missing.join(", ")}`); + } +}; diff --git a/src/utils/cross-chain/bridge-api.ts b/src/utils/cross-chain/bridge-api.ts new file mode 100644 index 000000000..fb3a2655b --- /dev/null +++ b/src/utils/cross-chain/bridge-api.ts @@ -0,0 +1,109 @@ +/* eslint-disable @typescript-eslint/no-var-requires, camelcase, no-shadow, @typescript-eslint/no-explicit-any */ +import axios from "axios"; +import { + BridgeApiOps, + GET_BRIDGE_DEPOSIT_DATA_EP, getTempDataFilePath, + MERKLE_PROOF_EP, TBridgeApiOp, + TEMP_DATA_DIR_PATH, + ZCHAIN_TEST_BRIDGE_API_URL, +} from "./constants"; +import fs from "fs"; + + +export const baseApiGET = async ({ + apiURL, + endpoint, + params, +} : { + apiURL : string; + endpoint : string; + params ?: any; +}) => { + const axio = axios.create({ + baseURL: apiURL, + }); + + return axio.get(endpoint, { params }); +}; + +export const getBridgeDepositData = async ({ + apiURL = ZCHAIN_TEST_BRIDGE_API_URL, + endpoint = GET_BRIDGE_DEPOSIT_DATA_EP, + destAddress, + params = { limit: 100, offset: 0 }, +} : { + apiURL ?: string; + endpoint ?: string; + destAddress : string; + params ?: any; +}) : Promise> => { + const result = await baseApiGET({ + apiURL, + endpoint: `${endpoint}${destAddress}`, + params, + }); + + const { data: { deposits } } = result; + + return deposits; +}; + +export const getMerkeProof = async ({ + apiURL = ZCHAIN_TEST_BRIDGE_API_URL, + endpoint = MERKLE_PROOF_EP, + depositCnt, + netId, +} : { + apiURL ?: string; + endpoint ?: string; + depositCnt : number; + netId : number; +}) => { + const result = await baseApiGET({ + apiURL, + endpoint, + params: { deposit_cnt: depositCnt, net_id: netId }, + }); + + const { data: { proof } } = result; + + return proof; +}; + +export const getSaveBridgeApiResponse = async (args : Array) => { + let apiDataReturn : string; + const op = args[0] as TBridgeApiOp; + + switch (op) { + case BridgeApiOps.deposit: + const destAddress = args[1]; + + const deposits = await getBridgeDepositData({ destAddress }); + console.log("Deposits acquired:", JSON.stringify(deposits, null, "\t")); + apiDataReturn = JSON.stringify(deposits, null, "\t"); + break; + + case BridgeApiOps.proof: + const depositCnt = Number(args[1]); + const netId = Number(args[2]); + + let proof = await getMerkeProof({ depositCnt, netId }); + proof = JSON.stringify(proof, null, "\t"); + console.log("Proof acquired:", proof); + apiDataReturn = proof; + break; + + default: + throw new Error("Invalid operation argument!"); + } + + if (args[args.length - 1] === "save" && apiDataReturn) { + const pathToFile = getTempDataFilePath(op); + + if (!fs.existsSync(TEMP_DATA_DIR_PATH)) { + fs.mkdirSync(TEMP_DATA_DIR_PATH); + } + + fs.writeFileSync(pathToFile, apiDataReturn); + } +}; diff --git a/src/utils/cross-chain/constants.ts b/src/utils/cross-chain/constants.ts new file mode 100644 index 000000000..d029a1794 --- /dev/null +++ b/src/utils/cross-chain/constants.ts @@ -0,0 +1,21 @@ +import path from "path"; + +// ZChain Testnet URLs +export const ZCHAIN_TEST_BRIDGE_API_URL = "https://wilderworld-dev-erigon1-bridge-api.eu-north-2.gateway.fm"; +export const ZCHAIN_TEST_RPC_URL = "https://wilderworld-dev-erigon1-rpc.eu-north-2.gateway.fm/"; + +export const ZCHAIN_TEST_BRIDGE_ADDRESS = "0xbE57e0450ae99b62997f2F4731bF8D950e06D124"; + +// Bridge API endpoints +export const GET_BRIDGE_DEPOSIT_DATA_EP = "/bridges/"; +export const MERKLE_PROOF_EP = "/merkle-proof"; + +export type TBridgeApiOp = "deposit" | "proof"; +export const BridgeApiOps : { [key in TBridgeApiOp] : TBridgeApiOp; } = { + deposit: "deposit", + proof: "proof", +}; + +export const TEMP_DATA_DIR_PATH = path.join(process.cwd(), "./test-data"); +export const getTempDataFilePath = (opName : TBridgeApiOp) => + path.join(TEMP_DATA_DIR_PATH, `bridge-${opName}.json`); diff --git a/src/utils/cross-chain/run-bridge-api.ts b/src/utils/cross-chain/run-bridge-api.ts new file mode 100644 index 000000000..76e9f8e88 --- /dev/null +++ b/src/utils/cross-chain/run-bridge-api.ts @@ -0,0 +1,10 @@ +import { getSaveBridgeApiResponse } from "./bridge-api"; + +const args = process.argv.slice(2); + +getSaveBridgeApiResponse(args) + .then(() => process.exit(0)) + .catch(error => { + console.error(error); + process.exit(1); + }); diff --git a/src/utils/drop-db.ts b/src/utils/drop-db.ts index 793c82ac3..72fd80fc4 100644 --- a/src/utils/drop-db.ts +++ b/src/utils/drop-db.ts @@ -1,9 +1,6 @@ -import { getLogger } from "@zero-tech/zdc"; import { startMongo, stopMongo, getZnsMongoAdapter } from "../deploy/mongo"; -const logger = getLogger(); - export const dropDB = async () => { try { const adapter = await getZnsMongoAdapter(); @@ -18,6 +15,6 @@ export const dropDB = async () => { dropDB() .then(() => process.exit(0)) .catch(error => { - logger.debug(error); + console.log(error); process.exit(1); }); diff --git a/src/utils/git-tag/get-tag.ts b/src/utils/git-tag/get-tag.ts index d2b512229..e793a1889 100644 --- a/src/utils/git-tag/get-tag.ts +++ b/src/utils/git-tag/get-tag.ts @@ -3,13 +3,13 @@ import { tagFilePath } from "./constants"; import { getLogger } from "@zero-tech/zdc"; -const logger = getLogger(); - export const getGitTag = () => { if (!fs.existsSync(tagFilePath)) { throw Error(`No git tag found at ${tagFilePath}`); } + const logger = getLogger(); + const tag = fs.readFileSync(tagFilePath, "utf8").trim(); logger.info(`Git tag found at ${tagFilePath}: ${tag}`); diff --git a/src/utils/git-tag/save-tag.ts b/src/utils/git-tag/save-tag.ts index 0b74952ce..c5faac189 100644 --- a/src/utils/git-tag/save-tag.ts +++ b/src/utils/git-tag/save-tag.ts @@ -6,12 +6,12 @@ import { tagFilePath } from "./constants"; const execAsync = promisify(exec); -const logger = getLogger(); export const acquireLatestGitTag = async () => { const gitTag = await execAsync("git describe --tags --abbrev=0"); const tag = gitTag.stdout.trim(); + const logger = getLogger(); logger.info(`Latest git tag acquired: ${tag}`); @@ -26,6 +26,7 @@ export const acquireLatestGitTag = async () => { export const saveTag = async () => { const tag = await acquireLatestGitTag(); + const logger = getLogger(); fs.writeFileSync(tagFilePath, tag, "utf8"); logger.info(`Saved git tag-commit to ${tagFilePath}}`); diff --git a/test/DeployCampaign.integration.test.ts b/test/DeployCampaign.integration.test.ts index c7aee5c49..f3206ebd4 100644 --- a/test/DeployCampaign.integration.test.ts +++ b/test/DeployCampaign.integration.test.ts @@ -3,7 +3,7 @@ import { } from "@zero-tech/zdc"; import * as hre from "hardhat"; import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; -import { getConfig } from "../src/deploy/campaign/environments"; +import { getConfig } from "../src/deploy/campaign/get-config"; import { runZnsCampaign } from "../src/deploy/zns-campaign"; import { IDistributionConfig } from "./helpers/types"; import { expect } from "chai"; @@ -16,6 +16,7 @@ import { registerSubdomainBulk, } from "./helpers/deploy-helpers"; import { IZNSCampaignConfig, IZNSContracts } from "../src/deploy/campaign/types"; +import { Wallet } from "ethers"; describe("zNS + zDC Single Integration Test", () => { @@ -29,7 +30,7 @@ describe("zNS + zDC Single Integration Test", () => { let userE : SignerWithAddress; let userF : SignerWithAddress; - let config : IZNSCampaignConfig; + let config : IZNSCampaignConfig; let zns : IZNSContracts; // let mongoAdapter : MongoDBAdapter; diff --git a/test/DeployCampaignInt.test.ts b/test/DeployCampaignInt.test.ts index 332b16155..3b71dd059 100644 --- a/test/DeployCampaignInt.test.ts +++ b/test/DeployCampaignInt.test.ts @@ -30,27 +30,28 @@ import { Z_SYMBOL_DEFAULT, } from "./helpers"; import { - ZTokenDM, + ZTokenDM, PolygonZkEVMBridgeV2DM, ZNSAccessControllerDM, - ZNSAddressResolverDM, + ZNSAddressResolverDM, ZNSChainResolverDM, ZNSCurvePricerDM, ZNSDomainTokenDM, ZNSFixedPricerDM, ZNSRegistryDM, ZNSRootRegistrarDM, ZNSSubRegistrarDM, ZNSTreasuryDM, } from "../src/deploy/missions/contracts"; -import { ZNSStringResolverDM } from "../src/deploy/missions/contracts/string-resolver"; +import { ZNSStringResolverDM } from "../src/deploy/missions/contracts/zns-base/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 { ZSepolia } from "../src/deploy/missions/contracts/zns-base/z-token/mainnet-data"; import { ResolverTypes } from "../src/deploy/constants"; -import { getConfig } from "../src/deploy/campaign/environments"; -import { ethers } from "ethers"; +import { buildCrosschainConfig, getConfig } from "../src/deploy/campaign/get-config"; +import { ethers, Wallet } 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 { getPortalDM } from "../src/deploy/missions/contracts/cross-chain/portals/get-portal-dm"; import { IZTokenConfig } from "../src/deploy/missions/types"; @@ -77,15 +78,40 @@ describe("Deploy Campaign Test", () => { describe("Z Token Ops", () => { before(async () => { - campaignConfig = await getConfig( - { - deployer: deployAdmin, - governors: [deployAdmin.address], - admins: [deployAdmin.address, admin.address], - zeroVaultAddress: zeroVault.address, - env, - } - ); + 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: ZSepolia.address, + mockZToken: true, + zTokenConfig: { + name: Z_NAME_DEFAULT, + symbol: Z_SYMBOL_DEFAULT, + defaultAdmin: deployAdmin.address, + initialAdminDelay: INITIAL_ADMIN_DELAY_DEFAULT, + minter: deployAdmin.address, + mintBeneficiary: deployAdmin.address, + initialSupplyBase: INITIAL_SUPPLY_DEFAULT, + inflationRates: INFLATION_RATES_DEFAULT, + finalInflationRate: FINAL_INFLATION_RATE_DEFAULT, + }, + postDeploy: { + tenderlyProjectSlug: "", + monitorContracts: false, + verifyContracts: false, + }, + crosschain: buildCrosschainConfig(), + }; + campaignConfig.domainToken.defaultRoyaltyReceiver = deployAdmin.address; campaignConfig.postDeploy.tenderlyProjectSlug = ""; }); @@ -209,8 +235,8 @@ describe("Deploy Campaign Test", () => { IZNSContracts >>; placeOfFailure : string; - deployedNames : Array<{ contract : string; instance : string; }>; - undeployedNames : Array<{ contract : string; instance : string; }>; + deployedNames : Array<{ contract ?: string; contractTrunk ?: string; instance : string; }>; + undeployedNames : Array<{ contract ?: string; contractTrunk ?: string; instance : string; }>; failingInstanceName : string; // eslint-disable-next-line no-shadow callback ?: (failingCampaign : DeployCampaign< @@ -272,13 +298,14 @@ describe("Deploy Campaign Test", () => { const firstRunDeployed = await deployedNames.reduce( async ( acc : Promise>, - { contract, instance } : { contract : string; instance : string; } + { contract, contractTrunk, instance } : { contract ?: string; contractTrunk ?: string; instance : string; } ) : Promise> => { const akk = await acc; - const fromDB = await dbAdapter.getContract(contract); + const name = contract ?? contractTrunk; + const fromDB = await dbAdapter.getContract(name as string); expect(fromDB?.address).to.be.properAddress; - return [...akk, { contract, instance, address: fromDB?.address }]; + return [...akk, { contract: name as string, instance, address: fromDB?.address }]; }, Promise.resolve([]) ); @@ -286,10 +313,11 @@ describe("Deploy Campaign Test", () => { await undeployedNames.reduce( async ( acc : Promise, - { contract, instance } : { contract : string; instance : string; } + { contract, contractTrunk, instance } : { contract ?: string; contractTrunk ?: string; instance : string; } ) : Promise => { await acc; - const fromDB = await dbAdapter.getContract(contract); + const name = contract ?? contractTrunk; + const fromDB = await dbAdapter.getContract(name as string); const fromState = failingCampaign[instance]; expect(fromDB).to.be.null; @@ -319,9 +347,9 @@ describe("Deploy Campaign Test", () => { // 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); + expect(Object.keys(state.contracts).length).to.equal(14); + expect(Object.keys(state.instances).length).to.equal(14); + expect(state.missions.length).to.equal(14); // it should deploy AddressResolver expect(await state.contracts.addressResolver.getAddress()).to.be.properAddress; @@ -331,10 +359,11 @@ describe("Deploy Campaign Test", () => { await allNames.reduce( async ( acc : Promise, - { contract } : { contract : string; } + { contract, contractTrunk } : { contract ?: string; contractTrunk ?: string; } ) : Promise => { await acc; - const fromDB = await dbAdapter.getContract(contract); + const name = contract ?? contractTrunk; + const fromDB = await dbAdapter.getContract(name as string); expect(fromDB?.address).to.be.properAddress; }, Promise.resolve() @@ -363,15 +392,40 @@ describe("Deploy Campaign Test", () => { 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 = { + 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: "", + mockZToken: true, + zTokenConfig: { + name: Z_NAME_DEFAULT, + symbol: Z_SYMBOL_DEFAULT, + defaultAdmin: deployAdmin.address, + initialAdminDelay: INITIAL_ADMIN_DELAY_DEFAULT, + minter: deployAdmin.address, + mintBeneficiary: deployAdmin.address, + initialSupplyBase: INITIAL_SUPPLY_DEFAULT, + inflationRates: INFLATION_RATES_DEFAULT, + finalInflationRate: FINAL_INFLATION_RATE_DEFAULT, + }, + postDeploy: { + tenderlyProjectSlug: "", + monitorContracts: false, + verifyContracts: false, + }, + crosschain: buildCrosschainConfig(), + }; + 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 = ""; @@ -413,6 +467,12 @@ describe("Deploy Campaign Test", () => { znsNames.rootRegistrar, znsNames.fixedPricer, znsNames.subRegistrar, + znsNames.chainResolver, + { + contract: znsNames.zkEvmBridge.contractMock, + instance: znsNames.zkEvmBridge.instance, + }, + znsNames.zPortal, ]; // call test flow runner @@ -427,8 +487,11 @@ describe("Deploy Campaign Test", () => { ZNSCurvePricerDM, ZNSTreasuryDM, ZNSRootRegistrarDM, - ZNSFixedPricerDM, ZNSSubRegistrarDM, + ZNSFixedPricerDM, + ZNSChainResolverDM, + PolygonZkEVMBridgeV2DM, + getPortalDM(campaignConfig.crosschain.srcChainName), ], placeOfFailure: "deploy", deployedNames, @@ -653,7 +716,7 @@ describe("Deploy Campaign Test", () => { // 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({ + const localConfig : IZNSCampaignConfig = await getConfig({ deployer: deployAdmin, zeroVaultAddress: zeroVault.address, governors: [governor.address], @@ -685,7 +748,7 @@ describe("Deploy Campaign Test", () => { let zns : IZNSContracts; - const config : IZNSCampaignConfig = await getConfig({ + const config : IZNSCampaignConfig = await getConfig({ deployer: userB, zeroVaultAddress: userA.address, governors: [userB.address, admin.address], // governors @@ -812,7 +875,7 @@ describe("Deploy Campaign Test", () => { }); /* eslint-disable @typescript-eslint/no-explicit-any */ } catch (e : any) { - expect(e.message).includes("Must provide a Mongo URI used for prod environment!"); + expect(e.message).includes("Missing required environment variables: MONGO_DB_URI"); } process.env.MOCK_Z_TOKEN = "false"; @@ -846,15 +909,39 @@ describe("Deploy Campaign Test", () => { before(async () => { await saveTag(); - campaignConfig = await getConfig( - { - deployer: deployAdmin, - governors: [deployAdmin.address, governor.address], - admins: [deployAdmin.address, admin.address], - zeroVaultAddress: zeroVault.address, - env, - } - ); + 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: ZSepolia.address, + mockZToken: true, + zTokenConfig: { + name: Z_NAME_DEFAULT, + symbol: Z_SYMBOL_DEFAULT, + defaultAdmin: deployAdmin.address, + initialAdminDelay: INITIAL_ADMIN_DELAY_DEFAULT, + minter: deployAdmin.address, + mintBeneficiary: deployAdmin.address, + initialSupplyBase: INITIAL_SUPPLY_DEFAULT, + inflationRates: INFLATION_RATES_DEFAULT, + finalInflationRate: FINAL_INFLATION_RATE_DEFAULT, + }, + postDeploy: { + tenderlyProjectSlug: "", + monitorContracts: false, + verifyContracts: false, + }, + crosschain: buildCrosschainConfig(), + }; campaignConfig.domainToken.defaultRoyaltyReceiver = deployAdmin.address; // TODO dep: what do we pass here for test flow? we don't have a deployed ZToken contract @@ -1020,15 +1107,40 @@ describe("Deploy Campaign Test", () => { 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 = { + 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: ZSepolia.address, + mockZToken: true, + zTokenConfig: { + name: Z_NAME_DEFAULT, + symbol: Z_SYMBOL_DEFAULT, + defaultAdmin: deployAdmin.address, + initialAdminDelay: INITIAL_ADMIN_DELAY_DEFAULT, + minter: deployAdmin.address, + mintBeneficiary: deployAdmin.address, + initialSupplyBase: INITIAL_SUPPLY_DEFAULT, + inflationRates: INFLATION_RATES_DEFAULT, + finalInflationRate: FINAL_INFLATION_RATE_DEFAULT, + }, + postDeploy: { + tenderlyProjectSlug: "", + monitorContracts: false, + verifyContracts: true, + }, + crosschain: buildCrosschainConfig(), + }; + config.domainToken.defaultRoyaltyReceiver = deployAdmin.address; config.stakingTokenAddress = ZSepolia.address; config.postDeploy.tenderlyProjectSlug = ""; diff --git a/test/ZNSRootRegistrar.test.ts b/test/ZNSRootRegistrar.test.ts index 07821c3dc..28d7d6764 100644 --- a/test/ZNSRootRegistrar.test.ts +++ b/test/ZNSRootRegistrar.test.ts @@ -34,15 +34,15 @@ import { getDomainHashFromEvent } from "./helpers/events"; import { ADMIN_ROLE, DOMAIN_TOKEN_ROLE, GOVERNOR_ROLE } from "../src/deploy/constants"; import { IERC20, - ZNSRootRegistrar, - ZNSRootRegistrar__factory, + ZNSRootRegistrarTrunk, + ZNSRootRegistrarTrunk__factory, ZNSRootRegistrarUpgradeMock__factory, } from "../typechain"; import { PaymentConfigStruct } from "../typechain/contracts/treasury/IZNSTreasury"; import { runZnsCampaign } from "../src/deploy/zns-campaign"; import { getProxyImplAddress } from "./helpers/utils"; import { upgrades } from "hardhat"; -import { getConfig } from "../src/deploy/campaign/environments"; +import { getConfig } from "../src/deploy/campaign/get-config"; import { IZNSContracts } from "../src/deploy/campaign/types"; import { ZeroHash } from "ethers"; @@ -51,6 +51,7 @@ require("@nomicfoundation/hardhat-chai-matchers"); // This is the only test converted to use the new Campaign, other // contract specific tests are using `deployZNS()` helper +// TODO multi: test both RootRegistrar types here, add missing tests for Branch and fix types !!! describe("ZNSRootRegistrar", () => { let deployer : SignerWithAddress; let user : SignerWithAddress; @@ -171,7 +172,7 @@ describe("ZNSRootRegistrar", () => { const domainHash = await getDomainHashFromEvent({ zns, - user: deployer, + registrantAddress: deployer.address, }); // Registering as deployer (owner of parent) and user is different gas values @@ -208,10 +209,9 @@ describe("ZNSRootRegistrar", () => { }); it("Should NOT initialize the implementation contract", async () => { - const factory = new ZNSRootRegistrar__factory(deployer); + const factory = new ZNSRootRegistrarTrunk__factory(deployer); const impl = await getProxyImplAddress(await zns.rootRegistrar.getAddress()); - // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion - const implContract = factory.attach(impl) as ZNSRootRegistrar; + const implContract = factory.attach(impl) as ZNSRootRegistrarTrunk; await expect( implContract.initialize( @@ -294,7 +294,7 @@ describe("ZNSRootRegistrar", () => { const userHasAdmin = await zns.accessController.hasRole(ADMIN_ROLE, user.address); expect(userHasAdmin).to.be.false; - const registrarFactory = new ZNSRootRegistrar__factory(user); + const registrarFactory = new ZNSRootRegistrarTrunk__factory(user); const tx = upgrades.deployProxy( registrarFactory, @@ -357,7 +357,7 @@ describe("ZNSRootRegistrar", () => { }); const domainHash = await getDomainHashFromEvent({ zns, - user, + registrantAddress: user.address, }); const tokenId = BigInt(domainHash); @@ -621,7 +621,7 @@ describe("ZNSRootRegistrar", () => { const domainHash = await getDomainHashFromEvent({ zns, - user, + registrantAddress: user.address, }); const { @@ -650,7 +650,7 @@ describe("ZNSRootRegistrar", () => { }); const domainHash = await getDomainHashFromEvent({ zns, - user, + registrantAddress: user.address, }); const { @@ -690,7 +690,7 @@ describe("ZNSRootRegistrar", () => { const namehashRef = hashDomainLabel(defaultDomain); const domainHash = await getDomainHashFromEvent({ zns, - user, + registrantAddress: user.address, }); expect(domainHash).to.eq(namehashRef); @@ -761,7 +761,7 @@ describe("ZNSRootRegistrar", () => { const domainHash = await getDomainHashFromEvent({ zns, - user, + registrantAddress: user.address, }); const exists = await zns.registry.exists(domainHash); @@ -779,7 +779,7 @@ describe("ZNSRootRegistrar", () => { const tokenId = BigInt( await getDomainHashFromEvent({ zns, - user, + registrantAddress: user.address, }) ); const owner = await zns.domainToken.ownerOf(tokenId); @@ -795,7 +795,7 @@ describe("ZNSRootRegistrar", () => { }); const domainHash = await getDomainHashFromEvent({ zns, - user, + registrantAddress: user.address, }); const resolvedAddress = await zns.addressResolver.resolveDomainAddress(domainHash); @@ -847,7 +847,7 @@ describe("ZNSRootRegistrar", () => { await defaultRootRegistration({ user: deployer, zns, domainName: defaultDomain }); const domainHash = await getDomainHashFromEvent({ zns, - user: deployer, + registrantAddress: deployer.address, }); const tokenId = BigInt(domainHash); const { amount: staked, token } = await zns.treasury.stakedForDomain(domainHash); @@ -881,7 +881,7 @@ describe("ZNSRootRegistrar", () => { await defaultRootRegistration({ user: deployer, zns, domainName: defaultDomain }); const domainHash = await getDomainHashFromEvent({ zns, - user: deployer, + registrantAddress: deployer.address, }); const tokenId = BigInt(domainHash); @@ -899,7 +899,7 @@ describe("ZNSRootRegistrar", () => { await defaultRootRegistration({ user: deployer, zns, domainName: defaultDomain }); const domainHash = await getDomainHashFromEvent({ zns, - user: deployer, + registrantAddress: deployer.address, }); // Reclaim the Domain const tx = zns.rootRegistrar.connect(user).reclaimDomain(domainHash); @@ -930,7 +930,7 @@ describe("ZNSRootRegistrar", () => { await defaultRootRegistration({ user: deployer, zns, domainName: defaultDomain }); const domainHash = await getDomainHashFromEvent({ zns, - user: deployer, + registrantAddress: deployer.address, }); const tokenId = BigInt(domainHash); const { amount: staked, token } = await zns.treasury.stakedForDomain(domainHash); @@ -974,7 +974,7 @@ describe("ZNSRootRegistrar", () => { await defaultRootRegistration({ user: deployer, zns, domainName: defaultDomain }); const domainHash = await getDomainHashFromEvent({ zns, - user: deployer, + registrantAddress: deployer.address, }); const tokenId = BigInt(domainHash); @@ -1024,7 +1024,7 @@ describe("ZNSRootRegistrar", () => { const domainHash = await getDomainHashFromEvent({ zns, - user, + registrantAddress: user.address, }); const price = await zns.curvePricer.getPrice(ethers.ZeroHash, defaultDomain, false); @@ -1055,7 +1055,7 @@ describe("ZNSRootRegistrar", () => { const domainHash = await getDomainHashFromEvent({ zns, - user, + registrantAddress: user.address, }); // add mintlist to check revocation @@ -1079,7 +1079,7 @@ describe("ZNSRootRegistrar", () => { const tokenId = BigInt( await getDomainHashFromEvent({ zns, - user, + registrantAddress: user.address, }) ); @@ -1129,7 +1129,7 @@ describe("ZNSRootRegistrar", () => { await defaultRootRegistration({ user, zns, domainName: defaultDomain }); const domainHash = await getDomainHashFromEvent({ zns, - user, + registrantAddress: user.address, }); // Validated staked values @@ -1168,7 +1168,7 @@ describe("ZNSRootRegistrar", () => { await defaultRootRegistration({ user: deployer, zns, domainName: defaultDomain }); const parentDomainHash = await getDomainHashFromEvent({ zns, - user: deployer, + registrantAddress: deployer.address, }); const owner = await zns.registry.connect(user).getDomainOwner(parentDomainHash); expect(owner).to.not.equal(user.address); @@ -1186,7 +1186,7 @@ describe("ZNSRootRegistrar", () => { await defaultRootRegistration({ user: deployer, zns, domainName: defaultDomain }); const parentDomainHash = await getDomainHashFromEvent({ zns, - user: deployer, + registrantAddress: deployer.address, }); const owner = await zns.registry.getDomainOwner(parentDomainHash); expect(owner).to.not.equal(user.address); @@ -1211,7 +1211,7 @@ describe("ZNSRootRegistrar", () => { await defaultRootRegistration({ user, zns, domainName: defaultDomain }); const domainHash = await getDomainHashFromEvent({ zns, - user, + registrantAddress: user.address, }); // assign an operator @@ -1387,7 +1387,7 @@ describe("ZNSRootRegistrar", () => { // Confirm deployer has the correct role first await expect(zns.accessController.checkGovernor(deployer.address)).to.not.be.reverted; - const registrarFactory = new ZNSRootRegistrar__factory(deployer); + const registrarFactory = new ZNSRootRegistrarTrunk__factory(deployer); const registrar = await registrarFactory.deploy(); await registrar.waitForDeployment(); @@ -1399,7 +1399,7 @@ describe("ZNSRootRegistrar", () => { }); it("Fails to upgrade when an unauthorized users calls", async () => { - const registrarFactory = new ZNSRootRegistrar__factory(deployer); + const registrarFactory = new ZNSRootRegistrarTrunk__factory(deployer); const registrar = await registrarFactory.deploy(); await registrar.waitForDeployment(); diff --git a/test/ZNSStringResolver.test.ts b/test/ZNSStringResolver.test.ts index 5fafa4a66..930f38e7e 100644 --- a/test/ZNSStringResolver.test.ts +++ b/test/ZNSStringResolver.test.ts @@ -1,445 +1,450 @@ -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); - }); - }); - }); -}); +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/get-config"; +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); + }); + + afterEach(async () => { + await mongoAdapter.dropDB(); + }); + + 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 115ebcd44..d6717da3b 100644 --- a/test/ZNSSubRegistrar.test.ts +++ b/test/ZNSSubRegistrar.test.ts @@ -37,8 +37,7 @@ import { getDomainHashFromEvent } from "./helpers/events"; import { time } from "@nomicfoundation/hardhat-toolbox/network-helpers"; import { CustomDecimalTokenMock, - ZNSSubRegistrar, - ZNSSubRegistrar__factory, + ZNSSubRegistrarTrunk, ZNSSubRegistrarTrunk__factory, ZNSSubRegistrarUpgradeMock, ZNSSubRegistrarUpgradeMock__factory, } from "../typechain"; @@ -2678,7 +2677,7 @@ describe("ZNSSubRegistrar", () => { const hash = await getDomainHashFromEvent({ zns, - user: lvl5SubOwner, + registrantAddress: lvl5SubOwner, }); // check registry @@ -2917,7 +2916,7 @@ describe("ZNSSubRegistrar", () => { const hash = await getDomainHashFromEvent({ zns, - user: lvl5SubOwner, + registrantAddress: lvl5SubOwner, }); // check registry @@ -3414,9 +3413,9 @@ describe("ZNSSubRegistrar", () => { }); it("Should NOT let initialize the implementation contract", async () => { - const factory = new ZNSSubRegistrar__factory(deployer); + const factory = new ZNSSubRegistrarTrunk__factory(deployer); const impl = await getProxyImplAddress(await zns.subRegistrar.getAddress()); - const implContract = factory.attach(impl) as ZNSSubRegistrar; + const implContract = factory.attach(impl) as ZNSSubRegistrarTrunk; await expect( implContract.initialize( @@ -3681,7 +3680,7 @@ describe("ZNSSubRegistrar", () => { const subHash = await getDomainHashFromEvent({ zns, - user: lvl2SubOwner, + registrantAddress: lvl2SubOwner, }); const rootConfigAfter = await zns.subRegistrar.distrConfigs(rootHash); diff --git a/test/cross-chain/CrossChainDomainBridging.network.test.ts b/test/cross-chain/CrossChainDomainBridging.network.test.ts new file mode 100644 index 000000000..71e428889 --- /dev/null +++ b/test/cross-chain/CrossChainDomainBridging.network.test.ts @@ -0,0 +1,732 @@ +import * as hre from "hardhat"; +import { getConfig, getValidateRootPriceConfig } from "../../src/deploy/campaign/get-config"; +import { runZnsCampaign } from "../../src/deploy/zns-campaign"; +import { + IZNSCampaignConfig, + IZNSContracts, +} from "../../src/deploy/campaign/types"; +import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; +import { approveForDomain, registrationWithSetup } from "../helpers/register-setup"; +import { + AC_UNAUTHORIZED_ERR, + AccessType, + DEFAULT_PRICE_CONFIG, + DEFAULT_TOKEN_URI, DEST_PORTAL_NOT_SET_ERR, + distrConfigEmpty, + DISTRIBUTION_LOCKED_NOT_EXIST_ERR, + fullDistrConfigEmpty, + getCurvePrice, + getStakingOrProtocolFee, + hashDomainLabel, + INITIALIZED_ERR, + INVALID_CALLER_ERR, + MESSAGE_FAILED_ERR, NETWORK_ID_L1_TEST_DEFAULT, NETWORK_ID_L2_TEST_DEFAULT, + NOT_AUTHORIZED_ERR, + NOT_OWNER_OF_ERR, + PaymentType, ZCHAIN_ID_TEST_DEFAULT, + ZERO_ADDRESS_ERR, +} from "../helpers"; +import { expect } from "chai"; +import * as ethers from "ethers"; +import { getDomainHashFromEvent, getEvents } from "../helpers/events"; +import { ContractTransactionReceipt, Wallet } from "ethers"; +import { SupportedChains } from "../../src/deploy/missions/contracts/cross-chain/portals/get-portal-dm"; +import { MongoDBAdapter, resetMongoAdapter } from "@zero-tech/zdc"; +import assert from "assert"; +import { getConfirmationsNumber } from "../helpers/tx"; +import { getClaimArgsFromApi } from "../helpers/cc-claim"; +import { setDefaultEnvironment } from "../../src/environment/set-env"; + + +// TODO multi: add ChainResolver tests !!! +describe("Cross-Chain Domain Bridging Test [for local and test networks]", () => { + let isRealNetwork = false; + + let znsL1 : IZNSContracts; + let znsL2 : IZNSContracts; + let dbAdapter1 : MongoDBAdapter; + let dbAdapter2 : MongoDBAdapter; + + let deployAdmin : SignerWithAddress; + let deployAdminL2 : Wallet | SignerWithAddress; + let user : SignerWithAddress; + let userL2 : Wallet | SignerWithAddress; + let subUser : SignerWithAddress; + let subUserL2 : Wallet | SignerWithAddress; + + let configL1 : IZNSCampaignConfig; + let configL2 : IZNSCampaignConfig; + + const rootDomainLabel = "jeffbridges"; + const subdomainLabel = "beaubridges"; + const subParentLabel = "bridgess"; + + const dummySmtProof = Array.from({ length: 32 }, () => hre.ethers.randomBytes(32)); + + let balanceBeforeBridge : bigint; + + let bridgedEventData : { + leafType : bigint; + originNetwork : bigint; + originAddress : string; + destinationNetwork : bigint; + destinationAddress : string; + amount : bigint; + metadata : string; + depositCount : bigint; + }; + + // !!! The test network run test should always run on PREDEPLOYED contracts !!! + // and MONGO specific ENV vars should be set to the correct values so that the campaignL2 + // can pick them up properly and not redeploy anything ! + before(async () => { + const env = process.env.ENV_LEVEL; + isRealNetwork = env === "test" && hre.network.name !== "hardhat"; + + [ deployAdmin, user, subUser ] = await hre.ethers.getSigners(); + + process.env.SRC_CHAIN_NAME = SupportedChains.eth; + if (isRealNetwork) { + assert.ok( + !!process.env.MONGO_DB_VERSION, + "Have to provide correct MONGO_DB_VERSION for running on test networks to use existing deployed contracts!" + ); + assert.ok( + !!process.env.MONGO_DB_NAME, + "Have to provide correct MONGO_DB_NAME where SOURCE chain contracts are located!" + ); + assert.ok( + !!process.env.MONGO_DB_NAME_DEST, + "Have to provide correct MONGO_DB_NAME_DEST where DESTINATION chain contracts are located!" + ); + assert.ok( + !!process.env.MONGO_DB_VERSION_DEST, + "Have to provide correct MONGO_DB_VERSION_DEST where DESTINATION chain contracts are located!" + ); + assert.ok( + !!process.env.SEPOLIA_RPC_URL, + "Have to provide correct SEPOLIA_RPC_URL for running on test networks!" + ); + assert.ok( + !!process.env.ZCHAINTEST_RPC_URL, + "Have to provide correct ZCHAINTEST_RPC_URL for running on test networks!" + ); + } else { + // set ENV vars for the Ethereum ZNS deployment + process.env.MOCK_ZKEVM_BRIDGE = "true"; + process.env.NETWORK_ID = NETWORK_ID_L1_TEST_DEFAULT.toString(); + process.env.DEST_NETWORK_ID = NETWORK_ID_L2_TEST_DEFAULT.toString(); + process.env.DEST_CHAIN_NAME = SupportedChains.z; + process.env.DEST_CHAIN_ID = ZCHAIN_ID_TEST_DEFAULT.toString(); + } + + // TODO multi: create a proper test for zkEVM bridge when not mocked !!! + + // L1 run + configL1 = await getConfig({ + deployer: deployAdmin, + zeroVaultAddress: deployAdmin.address, + }); + + // TODO multi: add logger message to show which network is campaign running on !!! + const campaignL1 = await runZnsCampaign({ config: configL1 }); + + ({ + state: { + contracts: znsL1, + }, + dbAdapter: dbAdapter1, + } = campaignL1); + + resetMongoAdapter(); + + process.env.SRC_CHAIN_NAME = SupportedChains.z; + + if (!isRealNetwork) { + // set vars for ZChain ZNS deployment + process.env.SRC_ZNS_PORTAL = znsL1.zChainPortal.target as string; + process.env.NETWORK_ID = NETWORK_ID_L2_TEST_DEFAULT.toString(); + process.env.MONGO_DB_NAME = "zns-l2"; + // TODO multi: create zkEVM bridge tests for predeployed bridge !!! + deployAdminL2 = deployAdmin; + userL2 = user; + subUserL2 = subUser; + } else { + const zChainProvider = new ethers.JsonRpcProvider(process.env.ZCHAINTEST_RPC_URL); + deployAdminL2 = new ethers.Wallet(`0x${process.env.TESTNET_PRIVATE_KEY_A}`, zChainProvider); + userL2 = new ethers.Wallet(`0x${process.env.TESTNET_PRIVATE_KEY_B}`, zChainProvider); + subUserL2 = new ethers.Wallet(`0x${process.env.TESTNET_PRIVATE_KEY_C}`, zChainProvider); + // swap to another DB where L2 contracts are located + process.env.MONGO_DB_NAME = process.env.MONGO_DB_NAME_DEST as string; + process.env.MONGO_DB_VERSION = process.env.MONGO_DB_VERSION_DEST; + } + + // L2 run + configL2 = await getConfig({ + deployer: deployAdminL2, + zeroVaultAddress: deployAdminL2.address, + }); + + // emulating L2 here by deploying to the same network + const campaignL2 = await runZnsCampaign({ config: configL2 }); + + ({ + state: { + contracts: znsL2, + }, + dbAdapter: dbAdapter2, + } = campaignL2); + }); + + after(async () => { + await dbAdapter1.dropDB(); + await dbAdapter2.dropDB(); + setDefaultEnvironment(); + }); + + it("#registerAndBridgeDomain() should revert if `destZnsPortal` is not set", async () => { + const curPortal = await znsL1.zChainPortal.destZnsPortal(); + + if (curPortal !== hre.ethers.ZeroAddress) { + await znsL1.zChainPortal.connect(deployAdmin).setDestZnsPortal(hre.ethers.ZeroAddress); + } + + await approveForDomain({ + zns: znsL1, + parentHash: hre.ethers.ZeroHash, + tokenHolder: deployAdmin, + user, + domainLabel: "test", + isBridging: true, + }); + + await expect( + znsL1.zChainPortal.connect(user).registerAndBridgeDomain( + hre.ethers.ZeroHash, + "test", + DEFAULT_TOKEN_URI, + ) + ).to.be.revertedWithCustomError(znsL1.zChainPortal, DEST_PORTAL_NOT_SET_ERR); + + // TODO multi: add a proper way to set this programmatically on actual chains !!! + // set L2 portal address on L1 + await znsL1.zChainPortal.connect(deployAdmin).setDestZnsPortal(znsL2.ethPortal.target); + }); + + it("should NOT allow to register root domain on ZChain", async () => { + await expect( + registrationWithSetup({ + zns: znsL2, + user: deployAdminL2, + parentHash: hre.ethers.ZeroHash, + domainLabel: "domainlabeltoberejected", + fullConfig: fullDistrConfigEmpty, + }) + // this function does not exist on the RootRegistrarBranch contract, so it fails with this error + ).to.be.rejectedWith("registerRootDomain is not a function"); + }); + + // TODO multi: Separate these into a different file that can work with real test networks and properly + // run one flow at a time (bridge vs claim) !!! + // And leave more regular tests here that can run on local Hardhat network ! + [ + { + name: "Root Domain", + parentHash: hre.ethers.ZeroHash, + label: rootDomainLabel, + subdomainChildLabel: "rootsub", + }, + { + name: "Subdomain", + parentHash: undefined, + label: subdomainLabel, + subdomainChildLabel: "subsub", + }, + ].forEach( + ({ + name, + parentHash, + label, + subdomainChildLabel, + } : { + name : string; + parentHash : string | undefined; + label : string; + subdomainChildLabel : string; + }) => { + let domainHash : string; + + describe(`${name} Bridging`, () => { + before(async () => { + if (name === "Subdomain") { + // register root regularly on L1 first + parentHash = await registrationWithSetup({ + zns: znsL1, + user: deployAdmin, + domainLabel: subParentLabel, + fullConfig: { + distrConfig: { + accessType: AccessType.OPEN, + paymentType: PaymentType.DIRECT, + pricerContract: znsL1.curvePricer.target, + }, + paymentConfig: { + token: znsL1.zToken.target, + beneficiary: deployAdmin.address, + }, + priceConfig: DEFAULT_PRICE_CONFIG, + }, + }); + } + + // register and bridge + await approveForDomain({ + zns: znsL1, + parentHash: parentHash as string, + user, + tokenHolder: deployAdmin, + domainLabel: label, + isBridging: true, + }); + + balanceBeforeBridge = await znsL1.zToken.balanceOf(user.address); + + const tx = await znsL1.zChainPortal.connect(user).registerAndBridgeDomain( + parentHash as string, + label, + DEFAULT_TOKEN_URI + ); + const receipt = await tx.wait(getConfirmationsNumber()) as ContractTransactionReceipt; + console.log(`Gas used for ${name} bridging: ${receipt.gasUsed.toString()}`); + + domainHash = await getDomainHashFromEvent({ + zns: znsL1, + registrantAddress: znsL1.zChainPortal.target as string, + }); + }); + + // TODO multi: test all reverts and failures properly !!! + describe("Bridge and Register on L1", () => { + // eslint-disable-next-line max-len + it("should register and set owners as ZkEvmPortal and fire DomainBridged and BridgeEvent events", async () => { + // check if domain is registered on L1 + // check events + const events = await getEvents({ + contract: znsL1.zChainPortal, + eventName: "DomainBridged", + }); + const event = events[events.length - 1]; + expect(event.args.domainHash).to.equal(domainHash); + expect(event.args.destNetworkId).to.equal(NETWORK_ID_L2_TEST_DEFAULT); + expect(event.args.destPortalAddress).to.equal(znsL2.ethPortal.target); + expect(event.args.domainOwner).to.equal(user.address); + + const bridgeEvents = await getEvents({ + contract: znsL1.zkEvmBridge, + eventName: "BridgeEvent", + }); + ({ args: bridgedEventData } = bridgeEvents[bridgeEvents.length - 1]); + + // this is here so we can use this data to do an API call to get the proof + if (isRealNetwork) console.log("Bridged Event Data:", bridgedEventData); + + const abiCoder = ethers.AbiCoder.defaultAbiCoder(); + const metadataRef = abiCoder.encode( + ["tuple(bytes32,bytes32,string,address,string)"], + [[ + domainHash, + parentHash, + label, + user.address, + DEFAULT_TOKEN_URI, + ]] + ); + + expect(bridgedEventData.originNetwork).to.equal(NETWORK_ID_L1_TEST_DEFAULT); + expect(bridgedEventData.originAddress).to.equal(znsL1.zChainPortal.target); + expect(bridgedEventData.destinationNetwork).to.equal(NETWORK_ID_L2_TEST_DEFAULT); + expect(bridgedEventData.destinationAddress).to.equal(znsL2.ethPortal.target); + expect(bridgedEventData.amount).to.equal(0n); + expect(bridgedEventData.metadata).to.equal(metadataRef); + + // check owner and resolver are set properly + const { + owner: ownerL1, + resolver: resolverL1, + } = await znsL1.registry.getDomainRecord(domainHash); + expect(ownerL1).to.equal(znsL1.zChainPortal.target); + expect(resolverL1).to.equal(znsL1.chainResolver.target); + + const tokenOwner = await znsL1.domainToken.ownerOf(BigInt(domainHash)); + expect(tokenOwner).to.equal(znsL1.zChainPortal.target); + }); + + it("should withdraw the correct amount of tokens from the caller", async () => { + const balanceAfterBridge = await znsL1.zToken.balanceOf(user.address); + + const priceConfig = isRealNetwork ? getValidateRootPriceConfig() : DEFAULT_PRICE_CONFIG; + const priceRef = getCurvePrice(label, priceConfig); + const protocolFeeRef = getStakingOrProtocolFee(priceRef); + + // TODO multi: error here! + // AssertionError: expected 4524647947000000000000 to equal 9292717980000000000000. + // + expected - actual + // + // -4524647947000000000000 + // +9292717980000000000000 + + expect(balanceBeforeBridge - balanceAfterBridge).to.equal(priceRef + protocolFeeRef); + }); + + it("should set configs as empty during bridging", async () => { + // should be LOCKED with no configs + const distrConfig = await znsL1.subRegistrar.distrConfigs(domainHash); + expect(distrConfig.accessType).to.equal(AccessType.LOCKED); + expect(distrConfig.paymentType).to.equal(PaymentType.DIRECT); + expect(distrConfig.pricerContract).to.equal(hre.ethers.ZeroAddress); + + const paymentConfig = await znsL1.treasury.paymentConfigs(domainHash); + expect(paymentConfig.token).to.equal(hre.ethers.ZeroAddress); + expect(paymentConfig.beneficiary).to.equal(hre.ethers.ZeroAddress); + }); + + it("should properly set data in ChainResolver", async () => { + const chainData = await znsL1.chainResolver.resolveChainDataStruct(domainHash); + expect(chainData.chainId).to.equal(ZCHAIN_ID_TEST_DEFAULT); + expect(chainData.chainName).to.equal(SupportedChains.z); + expect(chainData.znsRegistryOnChain).to.equal(hre.ethers.ZeroAddress); + expect(chainData.auxData).to.equal(""); + }); + + it("should NOT allow owner to access any domain functions after bridge", async () => { + // make sure NO domain related functions are available to the domain creator now + await expect( + znsL1.registry.connect(user).updateDomainOwner( + domainHash, + user.address + ) + ).to.be.revertedWithCustomError(znsL1.registry, NOT_AUTHORIZED_ERR); + + await expect( + znsL1.addressResolver.connect(user).setAddress( + domainHash, + user.address + ) + ).to.be.revertedWithCustomError(znsL1.registry, NOT_AUTHORIZED_ERR); + + await expect( + znsL1.subRegistrar.connect(user).setDistributionConfigForDomain( + domainHash, + { + ...distrConfigEmpty, + accessType: AccessType.OPEN, + } + ) + ).to.be.revertedWithCustomError(znsL1.registry, NOT_AUTHORIZED_ERR); + + // can't Revoke or Reclaim domain + await expect( + znsL1.rootRegistrar.connect(user).revokeDomain(domainHash) + ).to.be.revertedWithCustomError(znsL1.rootRegistrar, NOT_OWNER_OF_ERR); + + await expect( + znsL1.rootRegistrar.connect(user).reclaimDomain(domainHash) + ).to.be.revertedWithCustomError(znsL1.rootRegistrar, NOT_OWNER_OF_ERR); + }); + + it("should NOT allow registration of subdomains", async () => { + // make sure no one can register subdomains + await expect( + registrationWithSetup({ + zns: znsL1, + user, + parentHash: domainHash, + domainLabel: "test", + fullConfig: fullDistrConfigEmpty, + }) + ).to.be.revertedWithCustomError(znsL1.subRegistrar, DISTRIBUTION_LOCKED_NOT_EXIST_ERR); + }); + }); + + // TODO multi: for real network run add code to get the proof from the API!!! + describe("Claim Bridged Domain on L2", () => { + it("should #claimMessage() on the bridge successfully and fire a ClaimEvent", async () => { + const claimArgs = !isRealNetwork + ? [ + dummySmtProof, + dummySmtProof, + bridgedEventData.depositCount, + dummySmtProof[0], + dummySmtProof[1], + bridgedEventData.originNetwork, + bridgedEventData.originAddress, + bridgedEventData.destinationNetwork, + bridgedEventData.destinationAddress, + bridgedEventData.amount, + bridgedEventData.metadata, + ] + : await getClaimArgsFromApi({ + // when running on a real network provide this data to be able to run the test ! + // depositCnt: name === "Root Domain" ? "15" : "16", + }); + + // **NOTE** that we connect as `deployAdmin` here to show that it's not + // required that this has to be called by the original owner, + // it can be called by anyone + + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + const tx = await znsL2.zkEvmBridge.connect(deployAdminL2).claimMessage(...claimArgs); + await tx.wait(getConfirmationsNumber()); + + const events = await getEvents({ + contract: znsL2.zkEvmBridge, + eventName: "ClaimEvent", + }); + const event = events[events.length - 1]; + expect(event.args.originNetwork).to.equal(NETWORK_ID_L1_TEST_DEFAULT); + expect(event.args.originAddress).to.equal(znsL1.zChainPortal.target); + expect(event.args.destinationAddress).to.equal(znsL2.ethPortal.target); + expect(event.args.amount).to.equal(0n); + }); + + // eslint-disable-next-line max-len + it("should register domain on L2, set owners as original L1 caller and fire DomainClaimed event", async () => { + // check if domain is registered on L2 + // check events + const events = await getEvents({ + contract: znsL2.ethPortal, + eventName: "DomainClaimed", + }); + const event = events[events.length - 1]; + expect(event.args.srcNetworkId).to.equal(NETWORK_ID_L1_TEST_DEFAULT); + expect(event.args.srcPortalAddress).to.equal(znsL1.zChainPortal.target); + expect(event.args.domainHash).to.equal(domainHash); + expect(event.args.domainOwner).to.equal(user.address); + + // check owner and resolver are set properly + const { + owner: ownerL2, + } = await znsL2.registry.getDomainRecord(domainHash); + expect(ownerL2).to.equal(user.address); + + const tokenOwner = await znsL2.domainToken.ownerOf(BigInt(domainHash)); + expect(tokenOwner).to.equal(user.address); + }); + + it("should set configs as empty and allow original caller to set these configs", async () => { + // should be LOCKED with no configs + const distrConfig = await znsL2.subRegistrar.distrConfigs(domainHash); + expect(distrConfig.accessType).to.equal(AccessType.LOCKED); + expect(distrConfig.paymentType).to.equal(PaymentType.DIRECT); + expect(distrConfig.pricerContract).to.equal(hre.ethers.ZeroAddress); + + const paymentConfig = await znsL2.treasury.paymentConfigs(domainHash); + expect(paymentConfig.token).to.equal(hre.ethers.ZeroAddress); + expect(paymentConfig.beneficiary).to.equal(hre.ethers.ZeroAddress); + + const confNum = getConfirmationsNumber(); + + // set configs + const distrConfigToSet = { + accessType: AccessType.OPEN, + paymentType: PaymentType.DIRECT, + pricerContract: znsL2.fixedPricer.target, + }; + let tx = await znsL2.subRegistrar.connect(userL2).setDistributionConfigForDomain( + domainHash, + distrConfigToSet, + ); + await tx.wait(confNum); + + const paymentConfigToSet = { + token: znsL2.zToken.target, + beneficiary: user.address, + }; + tx = await znsL2.treasury.connect(userL2).setPaymentConfig( + domainHash, + paymentConfigToSet, + ); + await tx.wait(confNum); + + const priceToSet = 100n; + tx = await znsL2.fixedPricer.connect(userL2).setPrice(domainHash, priceToSet); + await tx.wait(confNum); + + // check configs are set properly + const distrConfigAfter = await znsL2.subRegistrar.distrConfigs(domainHash); + expect(distrConfigAfter.accessType).to.equal(distrConfigToSet.accessType); + expect(distrConfigAfter.paymentType).to.equal(distrConfigToSet.paymentType); + expect(distrConfigAfter.pricerContract).to.equal(distrConfigToSet.pricerContract); + + const paymentConfigAfter = await znsL2.treasury.paymentConfigs(domainHash); + expect(paymentConfigAfter.token).to.equal(paymentConfigToSet.token); + expect(paymentConfigAfter.beneficiary).to.equal(paymentConfigToSet.beneficiary); + + const priceAfter = await znsL2.fixedPricer.getPrice(domainHash, "test", true); + expect(priceAfter).to.equal(priceToSet); + }); + + it("should allow creating subdomains under the rules of newly set configs", async () => { + // make sure subdomains can be registered now + const subdomainHash = await registrationWithSetup({ + zns: znsL2, + user: subUserL2, + tokenHolder: deployAdminL2, + parentHash: domainHash, + domainLabel: subdomainChildLabel, + fullConfig: fullDistrConfigEmpty, + mintTokens: true, + }); + + const events = await getEvents({ + contract: znsL2.rootRegistrar, + eventName: "DomainRegistered", + }); + const event = events[events.length - 1]; + expect(event.args.parentHash).to.equal(domainHash); + expect(event.args.domainHash).to.equal(subdomainHash); + expect(event.args.label).to.equal(subdomainChildLabel); + expect(event.args.tokenURI).to.equal(DEFAULT_TOKEN_URI); + expect(event.args.registrant).to.equal(subUserL2.address); + expect(event.args.domainAddress).to.equal(subUserL2.address); + + // check if subdomain is registered + const record = await znsL2.registry.getDomainRecord(subdomainHash); + expect(record.owner).to.equal(subUserL2.address); + expect(record.resolver).to.equal(znsL2.addressResolver.target); + + const tokenOwner = await znsL2.domainToken.ownerOf(BigInt(subdomainHash)); + expect(tokenOwner).to.equal(subUserL2.address); + }); + }); + }); + }); + + // TODO multi: separate all these into different files + // We will only run this on local Hardhat network + if (!isRealNetwork) { + describe("Unit Tests", () => { + describe("ZNSZChainPortal", () => { + it("#initialize() should revert when trying to reinitialize", async () => { + await expect( + znsL1.zChainPortal.initialize( + "1", + "Z", + "1", + hre.ethers.ZeroAddress, + { + accessController: znsL1.accessController.target, + registry: znsL1.registry.target, + chainResolver: znsL1.chainResolver.target, + treasury: znsL1.treasury.target, + rootRegistrar: znsL1.rootRegistrar.target, + subRegistrar: znsL1.subRegistrar.target, + }, + ) + ).to.be.revertedWithCustomError(znsL1.zChainPortal, INITIALIZED_ERR); + }); + + it("#setDestZnsPortal() should revert when called by non-ADMIN", async () => { + await expect( + znsL1.zChainPortal.connect(user).setDestZnsPortal(znsL2.ethPortal.target) + ).to.be.revertedWithCustomError(znsL1.accessController, AC_UNAUTHORIZED_ERR); + }); + + it("#setDestZnsPortal() should revert when setting 0x0 address", async () => { + await expect( + znsL1.zChainPortal.connect(deployAdmin).setDestZnsPortal(hre.ethers.ZeroAddress) + ).to.be.revertedWithCustomError(znsL1.zChainPortal, ZERO_ADDRESS_ERR); + }); + + it("#setDestZnsPortal() should set the destination portal address", async () => { + await znsL1.zChainPortal.connect(deployAdmin).setDestZnsPortal(user.address); + + const destPortal = await znsL1.zChainPortal.destZnsPortal(); + expect(destPortal).to.equal(user.address); + + // set back to L2 portal address + await znsL1.zChainPortal.connect(deployAdmin).setDestZnsPortal(znsL2.ethPortal.target); + }); + }); + + describe("ZNSEthereumPortal", () => { + it("#initialize() should revert when trying to reinitialize", async () => { + await expect( + znsL2.ethPortal.connect(deployAdmin).initialize( + znsL2.accessController.target, + znsL2.zkEvmBridge.target, + znsL1.zChainPortal.target, + znsL2.registry.target, + znsL2.domainToken.target, + znsL2.rootRegistrar.target, + znsL2.subRegistrar.target, + ) + ).to.be.revertedWithCustomError(znsL2.ethPortal, INITIALIZED_ERR); + }); + + it("#onMessageReceived() should revert when called by non-ZkEvmBridge", async () => { + await expect( + znsL2.ethPortal.connect(deployAdmin).onMessageReceived( + znsL2.zkEvmBridge.target, + 1n, + hre.ethers.ZeroHash, + ) + ).to.be.revertedWithCustomError(znsL2.ethPortal, INVALID_CALLER_ERR); + }); + + it("#onMessageReceived() should revert when `originAddress` is something OTHER than ZChainPortal", async () => { + // this will fail with MessageFailed error from the Bridge since it does a `.call()` internally + await expect( + // this will call onMessageReceived(), we have to do it like this to avoid + // reverting on the `InvalidCaller` check + znsL2.zkEvmBridge.claimMessage( + dummySmtProof, + dummySmtProof, + bridgedEventData.depositCount, + dummySmtProof[0], + dummySmtProof[1], + bridgedEventData.originNetwork, + znsL2.registry.target, + bridgedEventData.destinationNetwork, + bridgedEventData.destinationAddress, + bridgedEventData.amount, + bridgedEventData.metadata, + ) + ).to.be.revertedWithCustomError(znsL2.zkEvmBridge, MESSAGE_FAILED_ERR); + }); + + it("#onMessageReceived() should revert when proof's `domainHash` is incorrect", async () => { + // make wrong metadata + const abiCoder = ethers.AbiCoder.defaultAbiCoder(); + const wrongMetadata = abiCoder.encode( + ["tuple(bytes32,bytes32,string,address,string)"], + [[ + hashDomainLabel("wrong"), // this hashes a different label from the one below + hre.ethers.ZeroHash, + "right", + user.address, + DEFAULT_TOKEN_URI, + ]] + ); + + await expect( + znsL2.zkEvmBridge.claimMessage( + dummySmtProof, + dummySmtProof, + bridgedEventData.depositCount, + dummySmtProof[0], + dummySmtProof[1], + bridgedEventData.originNetwork, + bridgedEventData.originAddress, + bridgedEventData.destinationNetwork, + bridgedEventData.destinationAddress, + bridgedEventData.amount, + wrongMetadata, + ) + ).to.be.revertedWithCustomError(znsL2.zkEvmBridge, MESSAGE_FAILED_ERR); + }); + }); + }); + } +}); diff --git a/test/cross-chain/PolygonZkEVMBridgeV2.json b/test/cross-chain/PolygonZkEVMBridgeV2.json new file mode 100644 index 000000000..0fac2b1db --- /dev/null +++ b/test/cross-chain/PolygonZkEVMBridgeV2.json @@ -0,0 +1,1013 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "PolygonZkEVMBridgeV2", + "sourceName": "contracts/v2/PolygonZkEVMBridgeV2.sol", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "AlreadyClaimed", + "type": "error" + }, + { + "inputs": [], + "name": "AmountDoesNotMatchMsgValue", + "type": "error" + }, + { + "inputs": [], + "name": "DestinationNetworkInvalid", + "type": "error" + }, + { + "inputs": [], + "name": "EtherTransferFailed", + "type": "error" + }, + { + "inputs": [], + "name": "FailedTokenWrappedDeployment", + "type": "error" + }, + { + "inputs": [], + "name": "GasTokenNetworkMustBeZeroOnEther", + "type": "error" + }, + { + "inputs": [], + "name": "GlobalExitRootInvalid", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidSmtProof", + "type": "error" + }, + { + "inputs": [], + "name": "MerkleTreeFull", + "type": "error" + }, + { + "inputs": [], + "name": "MessageFailed", + "type": "error" + }, + { + "inputs": [], + "name": "MsgValueNotZero", + "type": "error" + }, + { + "inputs": [], + "name": "NativeTokenIsEther", + "type": "error" + }, + { + "inputs": [], + "name": "NoValueInMessagesOnGasTokenNetworks", + "type": "error" + }, + { + "inputs": [], + "name": "NotValidAmount", + "type": "error" + }, + { + "inputs": [], + "name": "NotValidOwner", + "type": "error" + }, + { + "inputs": [], + "name": "NotValidSignature", + "type": "error" + }, + { + "inputs": [], + "name": "NotValidSpender", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyEmergencyState", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyNotEmergencyState", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyRollupManager", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "leafType", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "originNetwork", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "address", + "name": "originAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "destinationNetwork", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "address", + "name": "destinationAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "metadata", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "depositCount", + "type": "uint32" + } + ], + "name": "BridgeEvent", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "globalIndex", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "originNetwork", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "address", + "name": "originAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "destinationAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "ClaimEvent", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "EmergencyStateActivated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "EmergencyStateDeactivated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint32", + "name": "originNetwork", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "address", + "name": "originTokenAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "wrappedTokenAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "metadata", + "type": "bytes" + } + ], + "name": "NewWrappedToken", + "type": "event" + }, + { + "inputs": [], + "name": "BASE_INIT_BYTECODE_WRAPPED_TOKEN", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WETHToken", + "outputs": [ + { + "internalType": "contract TokenWrapped", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "activateEmergencyState", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "destinationNetwork", + "type": "uint32" + }, + { + "internalType": "address", + "name": "destinationAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "bool", + "name": "forceUpdateGlobalExitRoot", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "permitData", + "type": "bytes" + } + ], + "name": "bridgeAsset", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "destinationNetwork", + "type": "uint32" + }, + { + "internalType": "address", + "name": "destinationAddress", + "type": "address" + }, + { + "internalType": "bool", + "name": "forceUpdateGlobalExitRoot", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "metadata", + "type": "bytes" + } + ], + "name": "bridgeMessage", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "destinationNetwork", + "type": "uint32" + }, + { + "internalType": "address", + "name": "destinationAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountWETH", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "forceUpdateGlobalExitRoot", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "metadata", + "type": "bytes" + } + ], + "name": "bridgeMessageWETH", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "leafHash", + "type": "bytes32" + }, + { + "internalType": "bytes32[32]", + "name": "smtProof", + "type": "bytes32[32]" + }, + { + "internalType": "uint32", + "name": "index", + "type": "uint32" + } + ], + "name": "calculateRoot", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "originNetwork", + "type": "uint32" + }, + { + "internalType": "address", + "name": "originTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "calculateTokenWrapperAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32[32]", + "name": "smtProofLocalExitRoot", + "type": "bytes32[32]" + }, + { + "internalType": "bytes32[32]", + "name": "smtProofRollupExitRoot", + "type": "bytes32[32]" + }, + { + "internalType": "uint256", + "name": "globalIndex", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "mainnetExitRoot", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "rollupExitRoot", + "type": "bytes32" + }, + { + "internalType": "uint32", + "name": "originNetwork", + "type": "uint32" + }, + { + "internalType": "address", + "name": "originTokenAddress", + "type": "address" + }, + { + "internalType": "uint32", + "name": "destinationNetwork", + "type": "uint32" + }, + { + "internalType": "address", + "name": "destinationAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "metadata", + "type": "bytes" + } + ], + "name": "claimAsset", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32[32]", + "name": "smtProofLocalExitRoot", + "type": "bytes32[32]" + }, + { + "internalType": "bytes32[32]", + "name": "smtProofRollupExitRoot", + "type": "bytes32[32]" + }, + { + "internalType": "uint256", + "name": "globalIndex", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "mainnetExitRoot", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "rollupExitRoot", + "type": "bytes32" + }, + { + "internalType": "uint32", + "name": "originNetwork", + "type": "uint32" + }, + { + "internalType": "address", + "name": "originAddress", + "type": "address" + }, + { + "internalType": "uint32", + "name": "destinationNetwork", + "type": "uint32" + }, + { + "internalType": "address", + "name": "destinationAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "metadata", + "type": "bytes" + } + ], + "name": "claimMessage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "claimedBitMap", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "deactivateEmergencyState", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "depositCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gasTokenAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gasTokenMetadata", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gasTokenNetwork", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "leafType", + "type": "uint8" + }, + { + "internalType": "uint32", + "name": "originNetwork", + "type": "uint32" + }, + { + "internalType": "address", + "name": "originAddress", + "type": "address" + }, + { + "internalType": "uint32", + "name": "destinationNetwork", + "type": "uint32" + }, + { + "internalType": "address", + "name": "destinationAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "metadataHash", + "type": "bytes32" + } + ], + "name": "getLeafValue", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "getRoot", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "getTokenMetadata", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "originNetwork", + "type": "uint32" + }, + { + "internalType": "address", + "name": "originTokenAddress", + "type": "address" + } + ], + "name": "getTokenWrappedAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "globalExitRootManager", + "outputs": [ + { + "internalType": "contract IBasePolygonZkEVMGlobalExitRoot", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "_networkID", + "type": "uint32" + }, + { + "internalType": "address", + "name": "_gasTokenAddress", + "type": "address" + }, + { + "internalType": "uint32", + "name": "_gasTokenNetwork", + "type": "uint32" + }, + { + "internalType": "contract IBasePolygonZkEVMGlobalExitRoot", + "name": "_globalExitRootManager", + "type": "address" + }, + { + "internalType": "address", + "name": "_polygonRollupManager", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_gasTokenMetadata", + "type": "bytes" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "leafIndex", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "sourceBridgeNetwork", + "type": "uint32" + } + ], + "name": "isClaimed", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isEmergencyState", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastUpdatedDepositCount", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "networkID", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "polygonRollupManager", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "originNetwork", + "type": "uint32" + }, + { + "internalType": "address", + "name": "originTokenAddress", + "type": "address" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "symbol", + "type": "string" + }, + { + "internalType": "uint8", + "name": "decimals", + "type": "uint8" + } + ], + "name": "precalculatedWrapperAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "tokenInfoToWrappedToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "updateGlobalExitRoot", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "leafHash", + "type": "bytes32" + }, + { + "internalType": "bytes32[32]", + "name": "smtProof", + "type": "bytes32[32]" + }, + { + "internalType": "uint32", + "name": "index", + "type": "uint32" + }, + { + "internalType": "bytes32", + "name": "root", + "type": "bytes32" + } + ], + "name": "verifyMerkleProof", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "wrappedTokenToTokenInfo", + "outputs": [ + { + "internalType": "uint32", + "name": "originNetwork", + "type": "uint32" + }, + { + "internalType": "address", + "name": "originTokenAddress", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "0x608060405234801562000010575f80fd5b506200001b62000021565b620000e0565b5f54610100900460ff16156200008d5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b5f5460ff9081161015620000de575f805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b61591b80620000ee5f395ff3fe6080604052600436106101db575f3560e01c806383f24403116100fd578063ccaa2d1111610092578063ee25560b11610062578063ee25560b146105a9578063f5efcd79146105d4578063f811bff7146105f3578063fb57083414610612575f80fd5b8063ccaa2d111461053b578063cd5865791461055a578063d02103ca1461056d578063dbc1697614610595575f80fd5b8063bab161bf116100cd578063bab161bf146104b9578063be5831c7146104da578063c00f14ab146104fd578063cc4616321461051c575f80fd5b806383f244031461043d5780638ed7e3f21461045c578063aaa13cc21461047b578063b8b284d01461049a575f80fd5b80633cbc795b116101735780637843298b116101435780637843298b146103c257806379e2cf97146103e157806381b1c174146103f557806383c43a5514610429575f80fd5b80633cbc795b146103385780633e197043146103705780634b2f336d1461038f5780635ca1e165146103ae575f80fd5b806327aef4e8116101ae57806327aef4e81461026d5780632dfdf0b51461028e578063318aee3d146102b15780633c351e1014610319575f80fd5b806315064c96146101df5780632072f6c51461020d57806322e95f2c14610223578063240ff3781461025a575b5f80fd5b3480156101ea575f80fd5b506068546101f89060ff1681565b60405190151581526020015b60405180910390f35b348015610218575f80fd5b50610221610631565b005b34801561022e575f80fd5b5061024261023d366004612fb9565b610666565b6040516001600160a01b039091168152602001610204565b610221610268366004613040565b6106d0565b348015610278575f80fd5b50610281610759565b6040516102049190613102565b348015610299575f80fd5b506102a360535481565b604051908152602001610204565b3480156102bc575f80fd5b506102f56102cb36600461311b565b606b6020525f908152604090205463ffffffff81169064010000000090046001600160a01b031682565b6040805163ffffffff90931683526001600160a01b03909116602083015201610204565b348015610324575f80fd5b50606d54610242906001600160a01b031681565b348015610343575f80fd5b50606d5461035b90600160a01b900463ffffffff1681565b60405163ffffffff9091168152602001610204565b34801561037b575f80fd5b506102a361038a366004613144565b6107e5565b34801561039a575f80fd5b50606f54610242906001600160a01b031681565b3480156103b9575f80fd5b506102a361088e565b3480156103cd575f80fd5b506102426103dc3660046131be565b61096a565b3480156103ec575f80fd5b50610221610993565b348015610400575f80fd5b5061024261040f366004613204565b606a6020525f90815260409020546001600160a01b031681565b348015610434575f80fd5b506102816109b4565b348015610448575f80fd5b506102a361045736600461322c565b6109d3565b348015610467575f80fd5b50606c54610242906001600160a01b031681565b348015610486575f80fd5b5061024261049536600461332d565b610aa8565b3480156104a5575f80fd5b506102216104b43660046133c3565b610be7565b3480156104c4575f80fd5b5060685461035b90610100900463ffffffff1681565b3480156104e5575f80fd5b5060685461035b90600160c81b900463ffffffff1681565b348015610508575f80fd5b5061028161051736600461311b565b610cc2565b348015610527575f80fd5b506101f8610536366004613441565b610d07565b348015610546575f80fd5b50610221610555366004613472565b610d8f565b610221610568366004613556565b6112c0565b348015610578575f80fd5b50606854610242906501000000000090046001600160a01b031681565b3480156105a0575f80fd5b5061022161172c565b3480156105b4575f80fd5b506102a36105c3366004613204565b60696020525f908152604090205481565b3480156105df575f80fd5b506102216105ee366004613472565b61175f565b3480156105fe575f80fd5b5061022161060d3660046135e6565b611a25565b34801561061d575f80fd5b506101f861062c366004613689565b611d40565b606c546001600160a01b0316331461065c57604051631736745960e31b815260040160405180910390fd5b610664611d57565b565b6040805160e084901b6001600160e01b031916602080830191909152606084901b6bffffffffffffffffffffffff1916602483015282516018818403018152603890920183528151918101919091205f908152606a90915220546001600160a01b03165b92915050565b60685460ff16156106f457604051630bc011ff60e21b815260040160405180910390fd5b341580159061070d5750606f546001600160a01b031615155b15610744576040517f6f625c4000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610752858534868686611db2565b5050505050565b606e8054610766906136ce565b80601f0160208091040260200160405190810160405280929190818152602001828054610792906136ce565b80156107dd5780601f106107b4576101008083540402835291602001916107dd565b820191905f5260205f20905b8154815290600101906020018083116107c057829003601f168201915b505050505081565b6040517fff0000000000000000000000000000000000000000000000000000000000000060f889901b1660208201526001600160e01b031960e088811b821660218401526bffffffffffffffffffffffff19606089811b821660258601529188901b909216603984015285901b16603d82015260518101839052607181018290525f90609101604051602081830303815290604052805190602001209050979650505050505050565b6053545f90819081805b6020811015610961578083901c6001166001036108f557603381602081106108c2576108c2613706565b01546040805160208101929092528101859052606001604051602081830303815290604052805190602001209350610922565b60408051602081018690529081018390526060016040516020818303038152906040528051906020012093505b604080516020810184905290810183905260600160405160208183030381529060405280519060200120915080806109599061372e565b915050610898565b50919392505050565b5f61098b848461097985611e7c565b61098286611f66565b61049587612047565b949350505050565b605354606854600160c81b900463ffffffff16101561066457610664612114565b60405180611ba00160405280611b668152602001613d80611b66913981565b5f83815b6020811015610a9f57600163ffffffff8516821c81169003610a4257848160208110610a0557610a05613706565b602002013582604051602001610a25929190918252602082015260400190565b604051602081830303815290604052805190602001209150610a8d565b81858260208110610a5557610a55613706565b6020020135604051602001610a74929190918252602082015260400190565b6040516020818303038152906040528051906020012091505b80610a978161372e565b9150506109d7565b50949350505050565b6040516001600160e01b031960e087901b1660208201526bffffffffffffffffffffffff19606086901b1660248201525f9081906038016040516020818303038152906040528051906020012090505f60ff60f81b308360405180611ba00160405280611b668152602001613d80611b669139898989604051602001610b3093929190613746565b60408051601f1981840301815290829052610b4e929160200161377e565b60405160208183030381529060405280519060200120604051602001610bc394939291907fff0000000000000000000000000000000000000000000000000000000000000094909416845260609290921b6bffffffffffffffffffffffff191660018401526015830152603582015260550190565b60408051808303601f19018152919052805160209091012098975050505050505050565b60685460ff1615610c0b57604051630bc011ff60e21b815260040160405180910390fd5b606f546001600160a01b0316610c4d576040517fdde3cda700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606f54604051632770a7eb60e21b8152336004820152602481018690526001600160a01b0390911690639dc29fac906044015f604051808303815f87803b158015610c96575f80fd5b505af1158015610ca8573d5f803e3d5ffd5b50505050610cba868686868686611db2565b505050505050565b6060610ccd82611e7c565b610cd683611f66565b610cdf84612047565b604051602001610cf193929190613746565b6040516020818303038152906040529050919050565b6068545f908190610100900463ffffffff16158015610d2c575063ffffffff83166001145b15610d3e575063ffffffff8316610d66565b610d5364010000000063ffffffff85166137ac565b610d639063ffffffff86166137c3565b90505b600881901c5f90815260696020526040902054600160ff9092169190911b908116149392505050565b60685460ff1615610db357604051630bc011ff60e21b815260040160405180910390fd5b60685463ffffffff8681166101009092041614610de3576040516302caf51760e11b815260040160405180910390fd5b610e168c8c8c8c8c610e115f8e8e8e8e8e8e8e604051610e049291906137d6565b60405180910390206107e5565b6121c2565b6001600160a01b038616610f6057606f546001600160a01b0316610efa575f6001600160a01b03851684825b6040519080825280601f01601f191660200182016040528015610e6c576020820181803683370190505b50604051610e7a91906137e5565b5f6040518083038185875af1925050503d805f8114610eb4576040519150601f19603f3d011682016040523d82523d5f602084013e610eb9565b606091505b5050905080610ef4576040517f6747a28800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611256565b606f546040516340c10f1960e01b81526001600160a01b03868116600483015260248201869052909116906340c10f19906044015f604051808303815f87803b158015610f45575f80fd5b505af1158015610f57573d5f803e3d5ffd5b50505050611256565b606d546001600160a01b038781169116148015610f8e5750606d5463ffffffff888116600160a01b90920416145b15610fa5575f6001600160a01b0385168482610e42565b60685463ffffffff610100909104811690881603610fd657610fd16001600160a01b0387168585612354565b611256565b6040516001600160e01b031960e089901b1660208201526bffffffffffffffffffffffff19606088901b1660248201525f9060380160408051601f1981840301815291815281516020928301205f818152606a9093529120549091506001600160a01b0316806111f5575f6110808386868080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152506123d592505050565b6040516340c10f1960e01b81526001600160a01b03898116600483015260248201899052919250908216906340c10f19906044015f604051808303815f87803b1580156110cb575f80fd5b505af11580156110dd573d5f803e3d5ffd5b5050505080606a5f8581526020019081526020015f205f6101000a8154816001600160a01b0302191690836001600160a01b0316021790555060405180604001604052808b63ffffffff1681526020018a6001600160a01b0316815250606b5f836001600160a01b03166001600160a01b031681526020019081526020015f205f820151815f015f6101000a81548163ffffffff021916908363ffffffff1602179055506020820151815f0160046101000a8154816001600160a01b0302191690836001600160a01b031602179055509050507f490e59a1701b938786ac72570a1efeac994a3dbe96e2e883e19e902ace6e6a398a8a8388886040516111e7959493929190613828565b60405180910390a150611253565b6040516340c10f1960e01b81526001600160a01b038781166004830152602482018790528216906340c10f19906044015f604051808303815f87803b15801561123c575f80fd5b505af115801561124e573d5f803e3d5ffd5b505050505b50505b604080518b815263ffffffff891660208201526001600160a01b0388811682840152861660608201526080810185905290517f1df3f2a973a00d6635911755c260704e95e8a5876997546798770f76396fda4d9181900360a00190a1505050505050505050505050565b60685460ff16156112e457604051630bc011ff60e21b815260040160405180910390fd5b6112ec612468565b60685463ffffffff61010090910481169088160361131d576040516302caf51760e11b815260040160405180910390fd5b5f806060876001600160a01b03881661141957883414611369576040517fb89240f500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606d54606e80546001600160a01b0383169650600160a01b90920463ffffffff16945090611396906136ce565b80601f01602080910402602001604051908101604052809291908181526020018280546113c2906136ce565b801561140d5780601f106113e45761010080835404028352916020019161140d565b820191905f5260205f20905b8154815290600101906020018083116113f057829003601f168201915b505050505091506116a3565b3415611451576040517f798ee6f100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606f546001600160a01b03908116908916036114c757604051632770a7eb60e21b8152336004820152602481018a90526001600160a01b03891690639dc29fac906044015f604051808303815f87803b1580156114ac575f80fd5b505af11580156114be573d5f803e3d5ffd5b505050506116a3565b6001600160a01b038089165f908152606b602090815260409182902082518084019093525463ffffffff811683526401000000009004909216918101829052901561157957604051632770a7eb60e21b8152336004820152602481018b90526001600160a01b038a1690639dc29fac906044015f604051808303815f87803b158015611551575f80fd5b505af1158015611563573d5f803e3d5ffd5b5050505080602001519450805f01519350611696565b851561158b5761158b898b89896124c1565b6040516370a0823160e01b81523060048201525f906001600160a01b038b16906370a0823190602401602060405180830381865afa1580156115cf573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115f39190613860565b905061160a6001600160a01b038b1633308e612860565b6040516370a0823160e01b81523060048201525f906001600160a01b038c16906370a0823190602401602060405180830381865afa15801561164e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116729190613860565b905061167e8282613877565b6068548c9850610100900463ffffffff169650935050505b61169f89610cc2565b9250505b7f501781209a1f8899323b96b4ef08b168df93e0a90c673d1e4cce39366cb62f9b5f84868e8e86886053546040516116e298979695949392919061388a565b60405180910390a16117086117035f85878f8f8789805190602001206107e5565b6128b1565b861561171657611716612114565b5050505061172360018055565b50505050505050565b606c546001600160a01b0316331461175757604051631736745960e31b815260040160405180910390fd5b6106646129b2565b60685460ff161561178357604051630bc011ff60e21b815260040160405180910390fd5b60685463ffffffff86811661010090920416146117b3576040516302caf51760e11b815260040160405180910390fd5b6117d58c8c8c8c8c610e1160018e8e8e8e8e8e8e604051610e049291906137d6565b606f545f906001600160a01b031661188857846001600160a01b031684888a868660405160240161180994939291906138f3565b60408051601f198184030181529181526020820180516001600160e01b0316630c035af960e11b1790525161183e91906137e5565b5f6040518083038185875af1925050503d805f8114611878576040519150601f19603f3d011682016040523d82523d5f602084013e61187d565b606091505b505080915050611983565b606f546040516340c10f1960e01b81526001600160a01b03878116600483015260248201879052909116906340c10f19906044015f604051808303815f87803b1580156118d3575f80fd5b505af11580156118e5573d5f803e3d5ffd5b50505050846001600160a01b03168789858560405160240161190a94939291906138f3565b60408051601f198184030181529181526020820180516001600160e01b0316630c035af960e11b1790525161193f91906137e5565b5f604051808303815f865af19150503d805f8114611978576040519150601f19603f3d011682016040523d82523d5f602084013e61197d565b606091505b50909150505b806119ba576040517f37e391c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080518c815263ffffffff8a1660208201526001600160a01b0389811682840152871660608201526080810186905290517f1df3f2a973a00d6635911755c260704e95e8a5876997546798770f76396fda4d9181900360a00190a150505050505050505050505050565b5f54610100900460ff1615808015611a4357505f54600160ff909116105b80611a5c5750303b158015611a5c57505f5460ff166001145b611ad35760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b5f805460ff191660011790558015611af4575f805461ff0019166101001790555b606880547fffffffffffffff000000000000000000000000000000000000000000000000ff1661010063ffffffff8a16027fffffffffffffff0000000000000000000000000000000000000000ffffffffff1617650100000000006001600160a01b038781169190910291909117909155606c805473ffffffffffffffffffffffffffffffffffffffff19168583161790558616611bcf5763ffffffff851615611bca576040517f1a874c1200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611ceb565b606d805463ffffffff8716600160a01b027fffffffffffffffff0000000000000000000000000000000000000000000000009091166001600160a01b03891617179055606e611c1e8382613970565b50611cbd5f801b6012604051602001611ca991906060808252600d908201527f5772617070656420457468657200000000000000000000000000000000000000608082015260a0602082018190526004908201527f574554480000000000000000000000000000000000000000000000000000000060c082015260ff91909116604082015260e00190565b6040516020818303038152906040526123d5565b606f805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03929092169190911790555b611cf3612a22565b8015611723575f805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150505050505050565b5f81611d4d8686866109d3565b1495945050505050565b60685460ff1615611d7b57604051630bc011ff60e21b815260040160405180910390fd5b6068805460ff191660011790556040517f2261efe5aef6fedc1fd1550b25facc9181745623049c7901287030b9ad1a5497905f90a1565b60685463ffffffff610100909104811690871603611de3576040516302caf51760e11b815260040160405180910390fd5b7f501781209a1f8899323b96b4ef08b168df93e0a90c673d1e4cce39366cb62f9b6001606860019054906101000a900463ffffffff16338989898888605354604051611e3799989796959493929190613a2c565b60405180910390a1611e6e6117036001606860019054906101000a900463ffffffff16338a8a8a8989604051610e049291906137d6565b8215610cba57610cba612114565b60408051600481526024810182526020810180516001600160e01b03167f06fdde030000000000000000000000000000000000000000000000000000000017905290516060915f9182916001600160a01b03861691611edb91906137e5565b5f60405180830381855afa9150503d805f8114611f13576040519150601f19603f3d011682016040523d82523d5f602084013e611f18565b606091505b509150915081611f5d576040518060400160405280600781526020017f4e4f5f4e414d450000000000000000000000000000000000000000000000000081525061098b565b61098b81612a94565b60408051600481526024810182526020810180516001600160e01b03167f95d89b410000000000000000000000000000000000000000000000000000000017905290516060915f9182916001600160a01b03861691611fc591906137e5565b5f60405180830381855afa9150503d805f8114611ffd576040519150601f19603f3d011682016040523d82523d5f602084013e612002565b606091505b509150915081611f5d576040518060400160405280600981526020017f4e4f5f53594d424f4c000000000000000000000000000000000000000000000081525061098b565b60408051600481526024810182526020810180516001600160e01b03167f313ce5670000000000000000000000000000000000000000000000000000000017905290515f91829182916001600160a01b038616916120a591906137e5565b5f60405180830381855afa9150503d805f81146120dd576040519150601f19603f3d011682016040523d82523d5f602084013e6120e2565b606091505b50915091508180156120f5575080516020145b61210057601261098b565b8080602001905181019061098b9190613a97565b6053546068805463ffffffff909216600160c81b027fffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffffff90921691909117908190556001600160a01b0365010000000000909104166333d6247d61217561088e565b6040518263ffffffff1660e01b815260040161219391815260200190565b5f604051808303815f87803b1580156121aa575f80fd5b505af11580156121bc573d5f803e3d5ffd5b50505050565b606854604080516020808201879052818301869052825180830384018152606083019384905280519101207f257b36320000000000000000000000000000000000000000000000000000000090925260648101919091525f916501000000000090046001600160a01b03169063257b3632906084016020604051808303815f875af1158015612253573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906122779190613860565b9050805f036122b1576040517e2f6fad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80680100000000000000008716156122f5578691506122d3848a8489611d40565b6122f0576040516338105f3b60e21b815260040160405180910390fd5b61233f565b602087901c612305816001613ab2565b9150879250612320612318868c866109d3565b8a8389611d40565b61233d576040516338105f3b60e21b815260040160405180910390fd5b505b6123498282612c64565b505050505050505050565b6040516001600160a01b0383166024820152604481018290526123d09084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612d24565b505050565b5f8060405180611ba00160405280611b668152602001613d80611b6691398360405160200161240592919061377e565b6040516020818303038152906040529050838151602083015ff591506001600160a01b038216612461576040517fbefb092000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5092915050565b6002600154036124ba5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401611aca565b6002600155565b5f6124cf6004828486613acf565b6124d891613af6565b90507f2afa5331000000000000000000000000000000000000000000000000000000006001600160e01b03198216016126b2575f80808080808061251f896004818d613acf565b81019061252c9190613b26565b9650965096509650965096509650336001600160a01b0316876001600160a01b03161461256c5760405163912ecce760e01b815260040160405180910390fd5b6001600160a01b03861630146125955760405163750643af60e01b815260040160405180910390fd5b8a85146125ce576040517f03fffc4b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516001600160a01b0389811660248301528881166044830152606482018890526084820187905260ff861660a483015260c4820185905260e48083018590528351808403909101815261010490920183526020820180516001600160e01b03167fd505accf000000000000000000000000000000000000000000000000000000001790529151918e169161266591906137e5565b5f604051808303815f865af19150503d805f811461269e576040519150601f19603f3d011682016040523d82523d5f602084013e6126a3565b606091505b50505050505050505050610752565b6001600160e01b031981166323f2ebc360e21b146126fc576040517fe282c0ba00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f808080808080806127118a6004818e613acf565b81019061271e9190613b75565b97509750975097509750975097509750336001600160a01b0316886001600160a01b0316146127605760405163912ecce760e01b815260040160405180910390fd5b6001600160a01b03871630146127895760405163750643af60e01b815260040160405180910390fd5b604080516001600160a01b038a811660248301528981166044830152606482018990526084820188905286151560a483015260ff861660c483015260e482018590526101048083018590528351808403909101815261012490920183526020820180516001600160e01b03166323f2ebc360e21b1790529151918f169161281091906137e5565b5f604051808303815f865af19150503d805f8114612849576040519150601f19603f3d011682016040523d82523d5f602084013e61284e565b606091505b50505050505050505050505050505050565b6040516001600160a01b03808516602483015283166044820152606481018290526121bc9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401612399565b8060016128c060206002613cd3565b6128ca9190613877565b60535410612904576040517fef5ccf6600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f60535f81546129139061372e565b918290555090505f5b60208110156129a3578082901c60011660010361294f57826033826020811061294757612947613706565b015550505050565b6033816020811061296257612962613706565b01546040805160208101929092528101849052606001604051602081830303815290604052805190602001209250808061299b9061372e565b91505061291c565b506123d0613cde565b60018055565b60685460ff166129ee576040517f5386698100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6068805460ff191690556040517f1e5e34eea33501aecf2ebec9fe0e884a40804275ea7fe10b2ba084c8374308b3905f90a1565b5f54610100900460ff16612a8c5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401611aca565b610664612e08565b60606040825110612ab357818060200190518101906106ca9190613cf2565b8151602003612c26575f5b602081108015612b055750828181518110612adb57612adb613706565b01602001517fff000000000000000000000000000000000000000000000000000000000000001615155b15612b1c5780612b148161372e565b915050612abe565b805f03612b5e57505060408051808201909152601281527f4e4f545f56414c49445f454e434f44494e4700000000000000000000000000006020820152919050565b5f8167ffffffffffffffff811115612b7857612b78613268565b6040519080825280601f01601f191660200182016040528015612ba2576020820181803683370190505b5090505f5b82811015612c1e57848181518110612bc157612bc1613706565b602001015160f81c60f81b828281518110612bde57612bde613706565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a90535080612c168161372e565b915050612ba7565b509392505050565b505060408051808201909152601281527f4e4f545f56414c49445f454e434f44494e470000000000000000000000000000602082015290565b919050565b6068545f90610100900463ffffffff16158015612c87575063ffffffff82166001145b15612c99575063ffffffff8216612cc1565b612cae64010000000063ffffffff84166137ac565b612cbe9063ffffffff85166137c3565b90505b600881901c5f8181526069602052604081208054600160ff861690811b91821892839055929091908183169003611723576040517f646cf55800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f612d78826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612e729092919063ffffffff16565b8051909150156123d05780806020019051810190612d969190613d64565b6123d05760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611aca565b5f54610100900460ff166129ac5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401611aca565b606061098b84845f85855f80866001600160a01b03168587604051612e9791906137e5565b5f6040518083038185875af1925050503d805f8114612ed1576040519150601f19603f3d011682016040523d82523d5f602084013e612ed6565b606091505b5091509150612ee787838387612ef2565b979650505050505050565b60608315612f605782515f03612f59576001600160a01b0385163b612f595760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611aca565b508161098b565b61098b8383815115612f755781518083602001fd5b8060405162461bcd60e51b8152600401611aca9190613102565b803563ffffffff81168114612c5f575f80fd5b6001600160a01b0381168114612fb6575f80fd5b50565b5f8060408385031215612fca575f80fd5b612fd383612f8f565b91506020830135612fe381612fa2565b809150509250929050565b8015158114612fb6575f80fd5b5f8083601f84011261300b575f80fd5b50813567ffffffffffffffff811115613022575f80fd5b602083019150836020828501011115613039575f80fd5b9250929050565b5f805f805f60808688031215613054575f80fd5b61305d86612f8f565b9450602086013561306d81612fa2565b9350604086013561307d81612fee565b9250606086013567ffffffffffffffff811115613098575f80fd5b6130a488828901612ffb565b969995985093965092949392505050565b5f5b838110156130cf5781810151838201526020016130b7565b50505f910152565b5f81518084526130ee8160208601602086016130b5565b601f01601f19169290920160200192915050565b602081525f61311460208301846130d7565b9392505050565b5f6020828403121561312b575f80fd5b813561311481612fa2565b60ff81168114612fb6575f80fd5b5f805f805f805f60e0888a03121561315a575f80fd5b873561316581613136565b965061317360208901612f8f565b9550604088013561318381612fa2565b945061319160608901612f8f565b935060808801356131a181612fa2565b9699959850939692959460a0840135945060c09093013592915050565b5f805f606084860312156131d0575f80fd5b6131d984612f8f565b925060208401356131e981612fa2565b915060408401356131f981612fa2565b809150509250925092565b5f60208284031215613214575f80fd5b5035919050565b8061040081018310156106ca575f80fd5b5f805f610440848603121561323f575f80fd5b83359250613250856020860161321b565b915061325f6104208501612f8f565b90509250925092565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff811182821017156132a5576132a5613268565b604052919050565b5f67ffffffffffffffff8211156132c6576132c6613268565b50601f01601f191660200190565b5f6132e66132e1846132ad565b61327c565b90508281528383830111156132f9575f80fd5b828260208301375f602084830101529392505050565b5f82601f83011261331e575f80fd5b613114838335602085016132d4565b5f805f805f60a08688031215613341575f80fd5b61334a86612f8f565b9450602086013561335a81612fa2565b9350604086013567ffffffffffffffff80821115613376575f80fd5b61338289838a0161330f565b94506060880135915080821115613397575f80fd5b506133a48882890161330f565b92505060808601356133b581613136565b809150509295509295909350565b5f805f805f8060a087890312156133d8575f80fd5b6133e187612f8f565b955060208701356133f181612fa2565b945060408701359350606087013561340881612fee565b9250608087013567ffffffffffffffff811115613423575f80fd5b61342f89828a01612ffb565b979a9699509497509295939492505050565b5f8060408385031215613452575f80fd5b61345b83612f8f565b915061346960208401612f8f565b90509250929050565b5f805f805f805f805f805f806109208d8f03121561348e575f80fd5b6134988e8e61321b565b9b506134a88e6104008f0161321b565b9a506108008d013599506108208d013598506108408d013597506134cf6108608e01612f8f565b96506134df6108808e0135612fa2565b6108808d013595506134f46108a08e01612f8f565b94506135046108c08e0135612fa2565b6108c08d013593506108e08d0135925067ffffffffffffffff6109008e0135111561352d575f80fd5b61353e8e6109008f01358f01612ffb565b81935080925050509295989b509295989b509295989b565b5f805f805f805f60c0888a03121561356c575f80fd5b61357588612f8f565b9650602088013561358581612fa2565b955060408801359450606088013561359c81612fa2565b935060808801356135ac81612fee565b925060a088013567ffffffffffffffff8111156135c7575f80fd5b6135d38a828b01612ffb565b989b979a50959850939692959293505050565b5f805f805f8060c087890312156135fb575f80fd5b61360487612f8f565b9550602087013561361481612fa2565b945061362260408801612f8f565b9350606087013561363281612fa2565b9250608087013561364281612fa2565b915060a087013567ffffffffffffffff81111561365d575f80fd5b8701601f8101891361366d575f80fd5b61367c898235602084016132d4565b9150509295509295509295565b5f805f80610460858703121561369d575f80fd5b843593506136ae866020870161321b565b92506136bd6104208601612f8f565b939692955092936104400135925050565b600181811c908216806136e257607f821691505b60208210810361370057634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b5f6001820161373f5761373f61371a565b5060010190565b606081525f61375860608301866130d7565b828103602084015261376a81866130d7565b91505060ff83166040830152949350505050565b5f835161378f8184602088016130b5565b8351908301906137a38183602088016130b5565b01949350505050565b80820281158282048414176106ca576106ca61371a565b808201808211156106ca576106ca61371a565b818382375f9101908152919050565b5f82516137f68184602087016130b5565b9190910192915050565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b63ffffffff861681525f6001600160a01b03808716602084015280861660408401525060806060830152612ee7608083018486613800565b5f60208284031215613870575f80fd5b5051919050565b818103818111156106ca576106ca61371a565b5f61010060ff8b16835263ffffffff808b1660208501526001600160a01b03808b166040860152818a1660608601528089166080860152508660a08501528160c08501526138da828501876130d7565b925080851660e085015250509998505050505050505050565b6001600160a01b038516815263ffffffff84166020820152606060408201525f613921606083018486613800565b9695505050505050565b601f8211156123d0575f81815260208120601f850160051c810160208610156139515750805b601f850160051c820191505b81811015610cba5782815560010161395d565b815167ffffffffffffffff81111561398a5761398a613268565b61399e8161399884546136ce565b8461392b565b602080601f8311600181146139d1575f84156139ba5750858301515b5f19600386901b1c1916600185901b178555610cba565b5f85815260208120601f198616915b828110156139ff578886015182559484019460019091019084016139e0565b5085821015613a1c57878501515f19600388901b60f8161c191681555b5050505050600190811b01905550565b5f61010060ff8c16835263ffffffff808c1660208501526001600160a01b03808c166040860152818b166060860152808a166080860152508760a08501528160c0850152613a7d8285018789613800565b925080851660e085015250509a9950505050505050505050565b5f60208284031215613aa7575f80fd5b815161311481613136565b63ffffffff8181168382160190808211156124615761246161371a565b5f8085851115613add575f80fd5b83861115613ae9575f80fd5b5050820193919092039150565b6001600160e01b03198135818116916004851015613b1e5780818660040360031b1b83161692505b505092915050565b5f805f805f805f60e0888a031215613b3c575f80fd5b8735613b4781612fa2565b96506020880135613b5781612fa2565b9550604088013594506060880135935060808801356131a181613136565b5f805f805f805f80610100898b031215613b8d575f80fd5b8835613b9881612fa2565b97506020890135613ba881612fa2565b965060408901359550606089013594506080890135613bc681612fee565b935060a0890135613bd681613136565b979a969950949793969295929450505060c08201359160e0013590565b600181815b80851115613c2d57815f1904821115613c1357613c1361371a565b80851615613c2057918102915b93841c9390800290613bf8565b509250929050565b5f82613c43575060016106ca565b81613c4f57505f6106ca565b8160018114613c655760028114613c6f57613c8b565b60019150506106ca565b60ff841115613c8057613c8061371a565b50506001821b6106ca565b5060208310610133831016604e8410600b8410161715613cae575081810a6106ca565b613cb88383613bf3565b805f1904821115613ccb57613ccb61371a565b029392505050565b5f6131148383613c35565b634e487b7160e01b5f52600160045260245ffd5b5f60208284031215613d02575f80fd5b815167ffffffffffffffff811115613d18575f80fd5b8201601f81018413613d28575f80fd5b8051613d366132e1826132ad565b818152856020838501011115613d4a575f80fd5b613d5b8260208301602086016130b5565b95945050505050565b5f60208284031215613d74575f80fd5b815161311481612fee56fe6101006040523480156200001257600080fd5b5060405162001b6638038062001b6683398101604081905262000035916200028d565b82826003620000458382620003a1565b506004620000548282620003a1565b50503360c0525060ff811660e052466080819052620000739062000080565b60a052506200046d915050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f620000ad6200012e565b805160209182012060408051808201825260018152603160f81b90840152805192830193909352918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc66060820152608081018390523060a082015260c001604051602081830303815290604052805190602001209050919050565b6060600380546200013f9062000312565b80601f01602080910402602001604051908101604052809291908181526020018280546200016d9062000312565b8015620001be5780601f106200019257610100808354040283529160200191620001be565b820191906000526020600020905b815481529060010190602001808311620001a057829003601f168201915b5050505050905090565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620001f057600080fd5b81516001600160401b03808211156200020d576200020d620001c8565b604051601f8301601f19908116603f01168101908282118183101715620002385762000238620001c8565b816040528381526020925086838588010111156200025557600080fd5b600091505b838210156200027957858201830151818301840152908201906200025a565b600093810190920192909252949350505050565b600080600060608486031215620002a357600080fd5b83516001600160401b0380821115620002bb57600080fd5b620002c987838801620001de565b94506020860151915080821115620002e057600080fd5b50620002ef86828701620001de565b925050604084015160ff811681146200030757600080fd5b809150509250925092565b600181811c908216806200032757607f821691505b6020821081036200034857634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200039c57600081815260208120601f850160051c81016020861015620003775750805b601f850160051c820191505b81811015620003985782815560010162000383565b5050505b505050565b81516001600160401b03811115620003bd57620003bd620001c8565b620003d581620003ce845462000312565b846200034e565b602080601f8311600181146200040d5760008415620003f45750858301515b600019600386901b1c1916600185901b17855562000398565b600085815260208120601f198616915b828110156200043e578886015182559484019460019091019084016200041d565b50858210156200045d5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c05160e0516116aa620004bc6000396000610237015260008181610307015281816105c001526106a70152600061053a015260008181610379015261050401526116aa6000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063a457c2d71161008c578063d505accf11610066578063d505accf1461039b578063dd62ed3e146103ae578063ffa1ad74146103f457600080fd5b8063a457c2d71461034e578063a9059cbb14610361578063cd0d00961461037457600080fd5b806395d89b41116100bd57806395d89b41146102e75780639dc29fac146102ef578063a3c573eb1461030257600080fd5b806370a08231146102915780637ecebe00146102c757600080fd5b806330adf81f1161012f5780633644e515116101145780633644e51514610261578063395093511461026957806340c10f191461027c57600080fd5b806330adf81f14610209578063313ce5671461023057600080fd5b806318160ddd1161016057806318160ddd146101bd57806320606b70146101cf57806323b872dd146101f657600080fd5b806306fdde031461017c578063095ea7b31461019a575b600080fd5b610184610430565b60405161019191906113e4565b60405180910390f35b6101ad6101a8366004611479565b6104c2565b6040519015158152602001610191565b6002545b604051908152602001610191565b6101c17f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81565b6101ad6102043660046114a3565b6104dc565b6101c17f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610191565b6101c1610500565b6101ad610277366004611479565b61055c565b61028f61028a366004611479565b6105a8565b005b6101c161029f3660046114df565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101c16102d53660046114df565b60056020526000908152604090205481565b610184610680565b61028f6102fd366004611479565b61068f565b6103297f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610191565b6101ad61035c366004611479565b61075e565b6101ad61036f366004611479565b61082f565b6101c17f000000000000000000000000000000000000000000000000000000000000000081565b61028f6103a9366004611501565b61083d565b6101c16103bc366004611574565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101846040518060400160405280600181526020017f310000000000000000000000000000000000000000000000000000000000000081525081565b60606003805461043f906115a7565b80601f016020809104026020016040519081016040528092919081815260200182805461046b906115a7565b80156104b85780601f1061048d576101008083540402835291602001916104b8565b820191906000526020600020905b81548152906001019060200180831161049b57829003601f168201915b5050505050905090565b6000336104d0818585610b73565b60019150505b92915050565b6000336104ea858285610d27565b6104f5858585610dfe565b506001949350505050565b60007f00000000000000000000000000000000000000000000000000000000000000004614610537576105324661106d565b905090565b507f000000000000000000000000000000000000000000000000000000000000000090565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906104d090829086906105a3908790611629565b610b73565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610672576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f546f6b656e577261707065643a3a6f6e6c794272696467653a204e6f7420506f60448201527f6c79676f6e5a6b45564d4272696467650000000000000000000000000000000060648201526084015b60405180910390fd5b61067c8282611135565b5050565b60606004805461043f906115a7565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610754576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f546f6b656e577261707065643a3a6f6e6c794272696467653a204e6f7420506f60448201527f6c79676f6e5a6b45564d427269646765000000000000000000000000000000006064820152608401610669565b61067c8282611228565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015610822576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610669565b6104f58286868403610b73565b6000336104d0818585610dfe565b834211156108cc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f546f6b656e577261707065643a3a7065726d69743a204578706972656420706560448201527f726d6974000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff8716600090815260056020526040812080547f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9918a918a918a9190866109268361163c565b9091555060408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e0016040516020818303038152906040528051906020012090506000610991610500565b6040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281019190915260428101839052606201604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120600080855291840180845281905260ff89169284019290925260608301879052608083018690529092509060019060a0016020604051602081039080840390855afa158015610a55573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811615801590610ad057508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b610b5c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f546f6b656e577261707065643a3a7065726d69743a20496e76616c696420736960448201527f676e6174757265000000000000000000000000000000000000000000000000006064820152608401610669565b610b678a8a8a610b73565b50505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff8316610c15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff8216610cb8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610df85781811015610deb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610669565b610df88484848403610b73565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610ea1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff8216610f44576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610ffa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610df8565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f611098610430565b8051602091820120604080518082018252600181527f310000000000000000000000000000000000000000000000000000000000000090840152805192830193909352918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc66060820152608081018390523060a082015260c001604051602081830303815290604052805190602001209050919050565b73ffffffffffffffffffffffffffffffffffffffff82166111b2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610669565b80600260008282546111c49190611629565b909155505073ffffffffffffffffffffffffffffffffffffffff8216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff82166112cb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604090205481811015611381576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff83166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9101610d1a565b600060208083528351808285015260005b81811015611411578581018301518582016040015282016113f5565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461147457600080fd5b919050565b6000806040838503121561148c57600080fd5b61149583611450565b946020939093013593505050565b6000806000606084860312156114b857600080fd5b6114c184611450565b92506114cf60208501611450565b9150604084013590509250925092565b6000602082840312156114f157600080fd5b6114fa82611450565b9392505050565b600080600080600080600060e0888a03121561151c57600080fd5b61152588611450565b965061153360208901611450565b95506040880135945060608801359350608088013560ff8116811461155757600080fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561158757600080fd5b61159083611450565b915061159e60208401611450565b90509250929050565b600181811c908216806115bb57607f821691505b6020821081036115f4577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156104d6576104d66115fa565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361166d5761166d6115fa565b506001019056fea26469706673582212208d88fee561cff7120d381c345cfc534cef8229a272dc5809d4bbb685ad67141164736f6c63430008110033a2646970667358221220432f6d6b4446edbe1f73c19fd2115454d5c35d8b03b98a74fd46724151d7672264736f6c63430008140033", + "deployedBytecode": "0x6080604052600436106101db575f3560e01c806383f24403116100fd578063ccaa2d1111610092578063ee25560b11610062578063ee25560b146105a9578063f5efcd79146105d4578063f811bff7146105f3578063fb57083414610612575f80fd5b8063ccaa2d111461053b578063cd5865791461055a578063d02103ca1461056d578063dbc1697614610595575f80fd5b8063bab161bf116100cd578063bab161bf146104b9578063be5831c7146104da578063c00f14ab146104fd578063cc4616321461051c575f80fd5b806383f244031461043d5780638ed7e3f21461045c578063aaa13cc21461047b578063b8b284d01461049a575f80fd5b80633cbc795b116101735780637843298b116101435780637843298b146103c257806379e2cf97146103e157806381b1c174146103f557806383c43a5514610429575f80fd5b80633cbc795b146103385780633e197043146103705780634b2f336d1461038f5780635ca1e165146103ae575f80fd5b806327aef4e8116101ae57806327aef4e81461026d5780632dfdf0b51461028e578063318aee3d146102b15780633c351e1014610319575f80fd5b806315064c96146101df5780632072f6c51461020d57806322e95f2c14610223578063240ff3781461025a575b5f80fd5b3480156101ea575f80fd5b506068546101f89060ff1681565b60405190151581526020015b60405180910390f35b348015610218575f80fd5b50610221610631565b005b34801561022e575f80fd5b5061024261023d366004612fb9565b610666565b6040516001600160a01b039091168152602001610204565b610221610268366004613040565b6106d0565b348015610278575f80fd5b50610281610759565b6040516102049190613102565b348015610299575f80fd5b506102a360535481565b604051908152602001610204565b3480156102bc575f80fd5b506102f56102cb36600461311b565b606b6020525f908152604090205463ffffffff81169064010000000090046001600160a01b031682565b6040805163ffffffff90931683526001600160a01b03909116602083015201610204565b348015610324575f80fd5b50606d54610242906001600160a01b031681565b348015610343575f80fd5b50606d5461035b90600160a01b900463ffffffff1681565b60405163ffffffff9091168152602001610204565b34801561037b575f80fd5b506102a361038a366004613144565b6107e5565b34801561039a575f80fd5b50606f54610242906001600160a01b031681565b3480156103b9575f80fd5b506102a361088e565b3480156103cd575f80fd5b506102426103dc3660046131be565b61096a565b3480156103ec575f80fd5b50610221610993565b348015610400575f80fd5b5061024261040f366004613204565b606a6020525f90815260409020546001600160a01b031681565b348015610434575f80fd5b506102816109b4565b348015610448575f80fd5b506102a361045736600461322c565b6109d3565b348015610467575f80fd5b50606c54610242906001600160a01b031681565b348015610486575f80fd5b5061024261049536600461332d565b610aa8565b3480156104a5575f80fd5b506102216104b43660046133c3565b610be7565b3480156104c4575f80fd5b5060685461035b90610100900463ffffffff1681565b3480156104e5575f80fd5b5060685461035b90600160c81b900463ffffffff1681565b348015610508575f80fd5b5061028161051736600461311b565b610cc2565b348015610527575f80fd5b506101f8610536366004613441565b610d07565b348015610546575f80fd5b50610221610555366004613472565b610d8f565b610221610568366004613556565b6112c0565b348015610578575f80fd5b50606854610242906501000000000090046001600160a01b031681565b3480156105a0575f80fd5b5061022161172c565b3480156105b4575f80fd5b506102a36105c3366004613204565b60696020525f908152604090205481565b3480156105df575f80fd5b506102216105ee366004613472565b61175f565b3480156105fe575f80fd5b5061022161060d3660046135e6565b611a25565b34801561061d575f80fd5b506101f861062c366004613689565b611d40565b606c546001600160a01b0316331461065c57604051631736745960e31b815260040160405180910390fd5b610664611d57565b565b6040805160e084901b6001600160e01b031916602080830191909152606084901b6bffffffffffffffffffffffff1916602483015282516018818403018152603890920183528151918101919091205f908152606a90915220546001600160a01b03165b92915050565b60685460ff16156106f457604051630bc011ff60e21b815260040160405180910390fd5b341580159061070d5750606f546001600160a01b031615155b15610744576040517f6f625c4000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610752858534868686611db2565b5050505050565b606e8054610766906136ce565b80601f0160208091040260200160405190810160405280929190818152602001828054610792906136ce565b80156107dd5780601f106107b4576101008083540402835291602001916107dd565b820191905f5260205f20905b8154815290600101906020018083116107c057829003601f168201915b505050505081565b6040517fff0000000000000000000000000000000000000000000000000000000000000060f889901b1660208201526001600160e01b031960e088811b821660218401526bffffffffffffffffffffffff19606089811b821660258601529188901b909216603984015285901b16603d82015260518101839052607181018290525f90609101604051602081830303815290604052805190602001209050979650505050505050565b6053545f90819081805b6020811015610961578083901c6001166001036108f557603381602081106108c2576108c2613706565b01546040805160208101929092528101859052606001604051602081830303815290604052805190602001209350610922565b60408051602081018690529081018390526060016040516020818303038152906040528051906020012093505b604080516020810184905290810183905260600160405160208183030381529060405280519060200120915080806109599061372e565b915050610898565b50919392505050565b5f61098b848461097985611e7c565b61098286611f66565b61049587612047565b949350505050565b605354606854600160c81b900463ffffffff16101561066457610664612114565b60405180611ba00160405280611b668152602001613d80611b66913981565b5f83815b6020811015610a9f57600163ffffffff8516821c81169003610a4257848160208110610a0557610a05613706565b602002013582604051602001610a25929190918252602082015260400190565b604051602081830303815290604052805190602001209150610a8d565b81858260208110610a5557610a55613706565b6020020135604051602001610a74929190918252602082015260400190565b6040516020818303038152906040528051906020012091505b80610a978161372e565b9150506109d7565b50949350505050565b6040516001600160e01b031960e087901b1660208201526bffffffffffffffffffffffff19606086901b1660248201525f9081906038016040516020818303038152906040528051906020012090505f60ff60f81b308360405180611ba00160405280611b668152602001613d80611b669139898989604051602001610b3093929190613746565b60408051601f1981840301815290829052610b4e929160200161377e565b60405160208183030381529060405280519060200120604051602001610bc394939291907fff0000000000000000000000000000000000000000000000000000000000000094909416845260609290921b6bffffffffffffffffffffffff191660018401526015830152603582015260550190565b60408051808303601f19018152919052805160209091012098975050505050505050565b60685460ff1615610c0b57604051630bc011ff60e21b815260040160405180910390fd5b606f546001600160a01b0316610c4d576040517fdde3cda700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606f54604051632770a7eb60e21b8152336004820152602481018690526001600160a01b0390911690639dc29fac906044015f604051808303815f87803b158015610c96575f80fd5b505af1158015610ca8573d5f803e3d5ffd5b50505050610cba868686868686611db2565b505050505050565b6060610ccd82611e7c565b610cd683611f66565b610cdf84612047565b604051602001610cf193929190613746565b6040516020818303038152906040529050919050565b6068545f908190610100900463ffffffff16158015610d2c575063ffffffff83166001145b15610d3e575063ffffffff8316610d66565b610d5364010000000063ffffffff85166137ac565b610d639063ffffffff86166137c3565b90505b600881901c5f90815260696020526040902054600160ff9092169190911b908116149392505050565b60685460ff1615610db357604051630bc011ff60e21b815260040160405180910390fd5b60685463ffffffff8681166101009092041614610de3576040516302caf51760e11b815260040160405180910390fd5b610e168c8c8c8c8c610e115f8e8e8e8e8e8e8e604051610e049291906137d6565b60405180910390206107e5565b6121c2565b6001600160a01b038616610f6057606f546001600160a01b0316610efa575f6001600160a01b03851684825b6040519080825280601f01601f191660200182016040528015610e6c576020820181803683370190505b50604051610e7a91906137e5565b5f6040518083038185875af1925050503d805f8114610eb4576040519150601f19603f3d011682016040523d82523d5f602084013e610eb9565b606091505b5050905080610ef4576040517f6747a28800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611256565b606f546040516340c10f1960e01b81526001600160a01b03868116600483015260248201869052909116906340c10f19906044015f604051808303815f87803b158015610f45575f80fd5b505af1158015610f57573d5f803e3d5ffd5b50505050611256565b606d546001600160a01b038781169116148015610f8e5750606d5463ffffffff888116600160a01b90920416145b15610fa5575f6001600160a01b0385168482610e42565b60685463ffffffff610100909104811690881603610fd657610fd16001600160a01b0387168585612354565b611256565b6040516001600160e01b031960e089901b1660208201526bffffffffffffffffffffffff19606088901b1660248201525f9060380160408051601f1981840301815291815281516020928301205f818152606a9093529120549091506001600160a01b0316806111f5575f6110808386868080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152506123d592505050565b6040516340c10f1960e01b81526001600160a01b03898116600483015260248201899052919250908216906340c10f19906044015f604051808303815f87803b1580156110cb575f80fd5b505af11580156110dd573d5f803e3d5ffd5b5050505080606a5f8581526020019081526020015f205f6101000a8154816001600160a01b0302191690836001600160a01b0316021790555060405180604001604052808b63ffffffff1681526020018a6001600160a01b0316815250606b5f836001600160a01b03166001600160a01b031681526020019081526020015f205f820151815f015f6101000a81548163ffffffff021916908363ffffffff1602179055506020820151815f0160046101000a8154816001600160a01b0302191690836001600160a01b031602179055509050507f490e59a1701b938786ac72570a1efeac994a3dbe96e2e883e19e902ace6e6a398a8a8388886040516111e7959493929190613828565b60405180910390a150611253565b6040516340c10f1960e01b81526001600160a01b038781166004830152602482018790528216906340c10f19906044015f604051808303815f87803b15801561123c575f80fd5b505af115801561124e573d5f803e3d5ffd5b505050505b50505b604080518b815263ffffffff891660208201526001600160a01b0388811682840152861660608201526080810185905290517f1df3f2a973a00d6635911755c260704e95e8a5876997546798770f76396fda4d9181900360a00190a1505050505050505050505050565b60685460ff16156112e457604051630bc011ff60e21b815260040160405180910390fd5b6112ec612468565b60685463ffffffff61010090910481169088160361131d576040516302caf51760e11b815260040160405180910390fd5b5f806060876001600160a01b03881661141957883414611369576040517fb89240f500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606d54606e80546001600160a01b0383169650600160a01b90920463ffffffff16945090611396906136ce565b80601f01602080910402602001604051908101604052809291908181526020018280546113c2906136ce565b801561140d5780601f106113e45761010080835404028352916020019161140d565b820191905f5260205f20905b8154815290600101906020018083116113f057829003601f168201915b505050505091506116a3565b3415611451576040517f798ee6f100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606f546001600160a01b03908116908916036114c757604051632770a7eb60e21b8152336004820152602481018a90526001600160a01b03891690639dc29fac906044015f604051808303815f87803b1580156114ac575f80fd5b505af11580156114be573d5f803e3d5ffd5b505050506116a3565b6001600160a01b038089165f908152606b602090815260409182902082518084019093525463ffffffff811683526401000000009004909216918101829052901561157957604051632770a7eb60e21b8152336004820152602481018b90526001600160a01b038a1690639dc29fac906044015f604051808303815f87803b158015611551575f80fd5b505af1158015611563573d5f803e3d5ffd5b5050505080602001519450805f01519350611696565b851561158b5761158b898b89896124c1565b6040516370a0823160e01b81523060048201525f906001600160a01b038b16906370a0823190602401602060405180830381865afa1580156115cf573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115f39190613860565b905061160a6001600160a01b038b1633308e612860565b6040516370a0823160e01b81523060048201525f906001600160a01b038c16906370a0823190602401602060405180830381865afa15801561164e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116729190613860565b905061167e8282613877565b6068548c9850610100900463ffffffff169650935050505b61169f89610cc2565b9250505b7f501781209a1f8899323b96b4ef08b168df93e0a90c673d1e4cce39366cb62f9b5f84868e8e86886053546040516116e298979695949392919061388a565b60405180910390a16117086117035f85878f8f8789805190602001206107e5565b6128b1565b861561171657611716612114565b5050505061172360018055565b50505050505050565b606c546001600160a01b0316331461175757604051631736745960e31b815260040160405180910390fd5b6106646129b2565b60685460ff161561178357604051630bc011ff60e21b815260040160405180910390fd5b60685463ffffffff86811661010090920416146117b3576040516302caf51760e11b815260040160405180910390fd5b6117d58c8c8c8c8c610e1160018e8e8e8e8e8e8e604051610e049291906137d6565b606f545f906001600160a01b031661188857846001600160a01b031684888a868660405160240161180994939291906138f3565b60408051601f198184030181529181526020820180516001600160e01b0316630c035af960e11b1790525161183e91906137e5565b5f6040518083038185875af1925050503d805f8114611878576040519150601f19603f3d011682016040523d82523d5f602084013e61187d565b606091505b505080915050611983565b606f546040516340c10f1960e01b81526001600160a01b03878116600483015260248201879052909116906340c10f19906044015f604051808303815f87803b1580156118d3575f80fd5b505af11580156118e5573d5f803e3d5ffd5b50505050846001600160a01b03168789858560405160240161190a94939291906138f3565b60408051601f198184030181529181526020820180516001600160e01b0316630c035af960e11b1790525161193f91906137e5565b5f604051808303815f865af19150503d805f8114611978576040519150601f19603f3d011682016040523d82523d5f602084013e61197d565b606091505b50909150505b806119ba576040517f37e391c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080518c815263ffffffff8a1660208201526001600160a01b0389811682840152871660608201526080810186905290517f1df3f2a973a00d6635911755c260704e95e8a5876997546798770f76396fda4d9181900360a00190a150505050505050505050505050565b5f54610100900460ff1615808015611a4357505f54600160ff909116105b80611a5c5750303b158015611a5c57505f5460ff166001145b611ad35760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b5f805460ff191660011790558015611af4575f805461ff0019166101001790555b606880547fffffffffffffff000000000000000000000000000000000000000000000000ff1661010063ffffffff8a16027fffffffffffffff0000000000000000000000000000000000000000ffffffffff1617650100000000006001600160a01b038781169190910291909117909155606c805473ffffffffffffffffffffffffffffffffffffffff19168583161790558616611bcf5763ffffffff851615611bca576040517f1a874c1200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611ceb565b606d805463ffffffff8716600160a01b027fffffffffffffffff0000000000000000000000000000000000000000000000009091166001600160a01b03891617179055606e611c1e8382613970565b50611cbd5f801b6012604051602001611ca991906060808252600d908201527f5772617070656420457468657200000000000000000000000000000000000000608082015260a0602082018190526004908201527f574554480000000000000000000000000000000000000000000000000000000060c082015260ff91909116604082015260e00190565b6040516020818303038152906040526123d5565b606f805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03929092169190911790555b611cf3612a22565b8015611723575f805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150505050505050565b5f81611d4d8686866109d3565b1495945050505050565b60685460ff1615611d7b57604051630bc011ff60e21b815260040160405180910390fd5b6068805460ff191660011790556040517f2261efe5aef6fedc1fd1550b25facc9181745623049c7901287030b9ad1a5497905f90a1565b60685463ffffffff610100909104811690871603611de3576040516302caf51760e11b815260040160405180910390fd5b7f501781209a1f8899323b96b4ef08b168df93e0a90c673d1e4cce39366cb62f9b6001606860019054906101000a900463ffffffff16338989898888605354604051611e3799989796959493929190613a2c565b60405180910390a1611e6e6117036001606860019054906101000a900463ffffffff16338a8a8a8989604051610e049291906137d6565b8215610cba57610cba612114565b60408051600481526024810182526020810180516001600160e01b03167f06fdde030000000000000000000000000000000000000000000000000000000017905290516060915f9182916001600160a01b03861691611edb91906137e5565b5f60405180830381855afa9150503d805f8114611f13576040519150601f19603f3d011682016040523d82523d5f602084013e611f18565b606091505b509150915081611f5d576040518060400160405280600781526020017f4e4f5f4e414d450000000000000000000000000000000000000000000000000081525061098b565b61098b81612a94565b60408051600481526024810182526020810180516001600160e01b03167f95d89b410000000000000000000000000000000000000000000000000000000017905290516060915f9182916001600160a01b03861691611fc591906137e5565b5f60405180830381855afa9150503d805f8114611ffd576040519150601f19603f3d011682016040523d82523d5f602084013e612002565b606091505b509150915081611f5d576040518060400160405280600981526020017f4e4f5f53594d424f4c000000000000000000000000000000000000000000000081525061098b565b60408051600481526024810182526020810180516001600160e01b03167f313ce5670000000000000000000000000000000000000000000000000000000017905290515f91829182916001600160a01b038616916120a591906137e5565b5f60405180830381855afa9150503d805f81146120dd576040519150601f19603f3d011682016040523d82523d5f602084013e6120e2565b606091505b50915091508180156120f5575080516020145b61210057601261098b565b8080602001905181019061098b9190613a97565b6053546068805463ffffffff909216600160c81b027fffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffffff90921691909117908190556001600160a01b0365010000000000909104166333d6247d61217561088e565b6040518263ffffffff1660e01b815260040161219391815260200190565b5f604051808303815f87803b1580156121aa575f80fd5b505af11580156121bc573d5f803e3d5ffd5b50505050565b606854604080516020808201879052818301869052825180830384018152606083019384905280519101207f257b36320000000000000000000000000000000000000000000000000000000090925260648101919091525f916501000000000090046001600160a01b03169063257b3632906084016020604051808303815f875af1158015612253573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906122779190613860565b9050805f036122b1576040517e2f6fad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80680100000000000000008716156122f5578691506122d3848a8489611d40565b6122f0576040516338105f3b60e21b815260040160405180910390fd5b61233f565b602087901c612305816001613ab2565b9150879250612320612318868c866109d3565b8a8389611d40565b61233d576040516338105f3b60e21b815260040160405180910390fd5b505b6123498282612c64565b505050505050505050565b6040516001600160a01b0383166024820152604481018290526123d09084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612d24565b505050565b5f8060405180611ba00160405280611b668152602001613d80611b6691398360405160200161240592919061377e565b6040516020818303038152906040529050838151602083015ff591506001600160a01b038216612461576040517fbefb092000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5092915050565b6002600154036124ba5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401611aca565b6002600155565b5f6124cf6004828486613acf565b6124d891613af6565b90507f2afa5331000000000000000000000000000000000000000000000000000000006001600160e01b03198216016126b2575f80808080808061251f896004818d613acf565b81019061252c9190613b26565b9650965096509650965096509650336001600160a01b0316876001600160a01b03161461256c5760405163912ecce760e01b815260040160405180910390fd5b6001600160a01b03861630146125955760405163750643af60e01b815260040160405180910390fd5b8a85146125ce576040517f03fffc4b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516001600160a01b0389811660248301528881166044830152606482018890526084820187905260ff861660a483015260c4820185905260e48083018590528351808403909101815261010490920183526020820180516001600160e01b03167fd505accf000000000000000000000000000000000000000000000000000000001790529151918e169161266591906137e5565b5f604051808303815f865af19150503d805f811461269e576040519150601f19603f3d011682016040523d82523d5f602084013e6126a3565b606091505b50505050505050505050610752565b6001600160e01b031981166323f2ebc360e21b146126fc576040517fe282c0ba00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f808080808080806127118a6004818e613acf565b81019061271e9190613b75565b97509750975097509750975097509750336001600160a01b0316886001600160a01b0316146127605760405163912ecce760e01b815260040160405180910390fd5b6001600160a01b03871630146127895760405163750643af60e01b815260040160405180910390fd5b604080516001600160a01b038a811660248301528981166044830152606482018990526084820188905286151560a483015260ff861660c483015260e482018590526101048083018590528351808403909101815261012490920183526020820180516001600160e01b03166323f2ebc360e21b1790529151918f169161281091906137e5565b5f604051808303815f865af19150503d805f8114612849576040519150601f19603f3d011682016040523d82523d5f602084013e61284e565b606091505b50505050505050505050505050505050565b6040516001600160a01b03808516602483015283166044820152606481018290526121bc9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401612399565b8060016128c060206002613cd3565b6128ca9190613877565b60535410612904576040517fef5ccf6600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f60535f81546129139061372e565b918290555090505f5b60208110156129a3578082901c60011660010361294f57826033826020811061294757612947613706565b015550505050565b6033816020811061296257612962613706565b01546040805160208101929092528101849052606001604051602081830303815290604052805190602001209250808061299b9061372e565b91505061291c565b506123d0613cde565b60018055565b60685460ff166129ee576040517f5386698100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6068805460ff191690556040517f1e5e34eea33501aecf2ebec9fe0e884a40804275ea7fe10b2ba084c8374308b3905f90a1565b5f54610100900460ff16612a8c5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401611aca565b610664612e08565b60606040825110612ab357818060200190518101906106ca9190613cf2565b8151602003612c26575f5b602081108015612b055750828181518110612adb57612adb613706565b01602001517fff000000000000000000000000000000000000000000000000000000000000001615155b15612b1c5780612b148161372e565b915050612abe565b805f03612b5e57505060408051808201909152601281527f4e4f545f56414c49445f454e434f44494e4700000000000000000000000000006020820152919050565b5f8167ffffffffffffffff811115612b7857612b78613268565b6040519080825280601f01601f191660200182016040528015612ba2576020820181803683370190505b5090505f5b82811015612c1e57848181518110612bc157612bc1613706565b602001015160f81c60f81b828281518110612bde57612bde613706565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a90535080612c168161372e565b915050612ba7565b509392505050565b505060408051808201909152601281527f4e4f545f56414c49445f454e434f44494e470000000000000000000000000000602082015290565b919050565b6068545f90610100900463ffffffff16158015612c87575063ffffffff82166001145b15612c99575063ffffffff8216612cc1565b612cae64010000000063ffffffff84166137ac565b612cbe9063ffffffff85166137c3565b90505b600881901c5f8181526069602052604081208054600160ff861690811b91821892839055929091908183169003611723576040517f646cf55800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f612d78826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612e729092919063ffffffff16565b8051909150156123d05780806020019051810190612d969190613d64565b6123d05760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611aca565b5f54610100900460ff166129ac5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401611aca565b606061098b84845f85855f80866001600160a01b03168587604051612e9791906137e5565b5f6040518083038185875af1925050503d805f8114612ed1576040519150601f19603f3d011682016040523d82523d5f602084013e612ed6565b606091505b5091509150612ee787838387612ef2565b979650505050505050565b60608315612f605782515f03612f59576001600160a01b0385163b612f595760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611aca565b508161098b565b61098b8383815115612f755781518083602001fd5b8060405162461bcd60e51b8152600401611aca9190613102565b803563ffffffff81168114612c5f575f80fd5b6001600160a01b0381168114612fb6575f80fd5b50565b5f8060408385031215612fca575f80fd5b612fd383612f8f565b91506020830135612fe381612fa2565b809150509250929050565b8015158114612fb6575f80fd5b5f8083601f84011261300b575f80fd5b50813567ffffffffffffffff811115613022575f80fd5b602083019150836020828501011115613039575f80fd5b9250929050565b5f805f805f60808688031215613054575f80fd5b61305d86612f8f565b9450602086013561306d81612fa2565b9350604086013561307d81612fee565b9250606086013567ffffffffffffffff811115613098575f80fd5b6130a488828901612ffb565b969995985093965092949392505050565b5f5b838110156130cf5781810151838201526020016130b7565b50505f910152565b5f81518084526130ee8160208601602086016130b5565b601f01601f19169290920160200192915050565b602081525f61311460208301846130d7565b9392505050565b5f6020828403121561312b575f80fd5b813561311481612fa2565b60ff81168114612fb6575f80fd5b5f805f805f805f60e0888a03121561315a575f80fd5b873561316581613136565b965061317360208901612f8f565b9550604088013561318381612fa2565b945061319160608901612f8f565b935060808801356131a181612fa2565b9699959850939692959460a0840135945060c09093013592915050565b5f805f606084860312156131d0575f80fd5b6131d984612f8f565b925060208401356131e981612fa2565b915060408401356131f981612fa2565b809150509250925092565b5f60208284031215613214575f80fd5b5035919050565b8061040081018310156106ca575f80fd5b5f805f610440848603121561323f575f80fd5b83359250613250856020860161321b565b915061325f6104208501612f8f565b90509250925092565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff811182821017156132a5576132a5613268565b604052919050565b5f67ffffffffffffffff8211156132c6576132c6613268565b50601f01601f191660200190565b5f6132e66132e1846132ad565b61327c565b90508281528383830111156132f9575f80fd5b828260208301375f602084830101529392505050565b5f82601f83011261331e575f80fd5b613114838335602085016132d4565b5f805f805f60a08688031215613341575f80fd5b61334a86612f8f565b9450602086013561335a81612fa2565b9350604086013567ffffffffffffffff80821115613376575f80fd5b61338289838a0161330f565b94506060880135915080821115613397575f80fd5b506133a48882890161330f565b92505060808601356133b581613136565b809150509295509295909350565b5f805f805f8060a087890312156133d8575f80fd5b6133e187612f8f565b955060208701356133f181612fa2565b945060408701359350606087013561340881612fee565b9250608087013567ffffffffffffffff811115613423575f80fd5b61342f89828a01612ffb565b979a9699509497509295939492505050565b5f8060408385031215613452575f80fd5b61345b83612f8f565b915061346960208401612f8f565b90509250929050565b5f805f805f805f805f805f806109208d8f03121561348e575f80fd5b6134988e8e61321b565b9b506134a88e6104008f0161321b565b9a506108008d013599506108208d013598506108408d013597506134cf6108608e01612f8f565b96506134df6108808e0135612fa2565b6108808d013595506134f46108a08e01612f8f565b94506135046108c08e0135612fa2565b6108c08d013593506108e08d0135925067ffffffffffffffff6109008e0135111561352d575f80fd5b61353e8e6109008f01358f01612ffb565b81935080925050509295989b509295989b509295989b565b5f805f805f805f60c0888a03121561356c575f80fd5b61357588612f8f565b9650602088013561358581612fa2565b955060408801359450606088013561359c81612fa2565b935060808801356135ac81612fee565b925060a088013567ffffffffffffffff8111156135c7575f80fd5b6135d38a828b01612ffb565b989b979a50959850939692959293505050565b5f805f805f8060c087890312156135fb575f80fd5b61360487612f8f565b9550602087013561361481612fa2565b945061362260408801612f8f565b9350606087013561363281612fa2565b9250608087013561364281612fa2565b915060a087013567ffffffffffffffff81111561365d575f80fd5b8701601f8101891361366d575f80fd5b61367c898235602084016132d4565b9150509295509295509295565b5f805f80610460858703121561369d575f80fd5b843593506136ae866020870161321b565b92506136bd6104208601612f8f565b939692955092936104400135925050565b600181811c908216806136e257607f821691505b60208210810361370057634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b5f6001820161373f5761373f61371a565b5060010190565b606081525f61375860608301866130d7565b828103602084015261376a81866130d7565b91505060ff83166040830152949350505050565b5f835161378f8184602088016130b5565b8351908301906137a38183602088016130b5565b01949350505050565b80820281158282048414176106ca576106ca61371a565b808201808211156106ca576106ca61371a565b818382375f9101908152919050565b5f82516137f68184602087016130b5565b9190910192915050565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b63ffffffff861681525f6001600160a01b03808716602084015280861660408401525060806060830152612ee7608083018486613800565b5f60208284031215613870575f80fd5b5051919050565b818103818111156106ca576106ca61371a565b5f61010060ff8b16835263ffffffff808b1660208501526001600160a01b03808b166040860152818a1660608601528089166080860152508660a08501528160c08501526138da828501876130d7565b925080851660e085015250509998505050505050505050565b6001600160a01b038516815263ffffffff84166020820152606060408201525f613921606083018486613800565b9695505050505050565b601f8211156123d0575f81815260208120601f850160051c810160208610156139515750805b601f850160051c820191505b81811015610cba5782815560010161395d565b815167ffffffffffffffff81111561398a5761398a613268565b61399e8161399884546136ce565b8461392b565b602080601f8311600181146139d1575f84156139ba5750858301515b5f19600386901b1c1916600185901b178555610cba565b5f85815260208120601f198616915b828110156139ff578886015182559484019460019091019084016139e0565b5085821015613a1c57878501515f19600388901b60f8161c191681555b5050505050600190811b01905550565b5f61010060ff8c16835263ffffffff808c1660208501526001600160a01b03808c166040860152818b166060860152808a166080860152508760a08501528160c0850152613a7d8285018789613800565b925080851660e085015250509a9950505050505050505050565b5f60208284031215613aa7575f80fd5b815161311481613136565b63ffffffff8181168382160190808211156124615761246161371a565b5f8085851115613add575f80fd5b83861115613ae9575f80fd5b5050820193919092039150565b6001600160e01b03198135818116916004851015613b1e5780818660040360031b1b83161692505b505092915050565b5f805f805f805f60e0888a031215613b3c575f80fd5b8735613b4781612fa2565b96506020880135613b5781612fa2565b9550604088013594506060880135935060808801356131a181613136565b5f805f805f805f80610100898b031215613b8d575f80fd5b8835613b9881612fa2565b97506020890135613ba881612fa2565b965060408901359550606089013594506080890135613bc681612fee565b935060a0890135613bd681613136565b979a969950949793969295929450505060c08201359160e0013590565b600181815b80851115613c2d57815f1904821115613c1357613c1361371a565b80851615613c2057918102915b93841c9390800290613bf8565b509250929050565b5f82613c43575060016106ca565b81613c4f57505f6106ca565b8160018114613c655760028114613c6f57613c8b565b60019150506106ca565b60ff841115613c8057613c8061371a565b50506001821b6106ca565b5060208310610133831016604e8410600b8410161715613cae575081810a6106ca565b613cb88383613bf3565b805f1904821115613ccb57613ccb61371a565b029392505050565b5f6131148383613c35565b634e487b7160e01b5f52600160045260245ffd5b5f60208284031215613d02575f80fd5b815167ffffffffffffffff811115613d18575f80fd5b8201601f81018413613d28575f80fd5b8051613d366132e1826132ad565b818152856020838501011115613d4a575f80fd5b613d5b8260208301602086016130b5565b95945050505050565b5f60208284031215613d74575f80fd5b815161311481612fee56fe6101006040523480156200001257600080fd5b5060405162001b6638038062001b6683398101604081905262000035916200028d565b82826003620000458382620003a1565b506004620000548282620003a1565b50503360c0525060ff811660e052466080819052620000739062000080565b60a052506200046d915050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f620000ad6200012e565b805160209182012060408051808201825260018152603160f81b90840152805192830193909352918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc66060820152608081018390523060a082015260c001604051602081830303815290604052805190602001209050919050565b6060600380546200013f9062000312565b80601f01602080910402602001604051908101604052809291908181526020018280546200016d9062000312565b8015620001be5780601f106200019257610100808354040283529160200191620001be565b820191906000526020600020905b815481529060010190602001808311620001a057829003601f168201915b5050505050905090565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620001f057600080fd5b81516001600160401b03808211156200020d576200020d620001c8565b604051601f8301601f19908116603f01168101908282118183101715620002385762000238620001c8565b816040528381526020925086838588010111156200025557600080fd5b600091505b838210156200027957858201830151818301840152908201906200025a565b600093810190920192909252949350505050565b600080600060608486031215620002a357600080fd5b83516001600160401b0380821115620002bb57600080fd5b620002c987838801620001de565b94506020860151915080821115620002e057600080fd5b50620002ef86828701620001de565b925050604084015160ff811681146200030757600080fd5b809150509250925092565b600181811c908216806200032757607f821691505b6020821081036200034857634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200039c57600081815260208120601f850160051c81016020861015620003775750805b601f850160051c820191505b81811015620003985782815560010162000383565b5050505b505050565b81516001600160401b03811115620003bd57620003bd620001c8565b620003d581620003ce845462000312565b846200034e565b602080601f8311600181146200040d5760008415620003f45750858301515b600019600386901b1c1916600185901b17855562000398565b600085815260208120601f198616915b828110156200043e578886015182559484019460019091019084016200041d565b50858210156200045d5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c05160e0516116aa620004bc6000396000610237015260008181610307015281816105c001526106a70152600061053a015260008181610379015261050401526116aa6000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063a457c2d71161008c578063d505accf11610066578063d505accf1461039b578063dd62ed3e146103ae578063ffa1ad74146103f457600080fd5b8063a457c2d71461034e578063a9059cbb14610361578063cd0d00961461037457600080fd5b806395d89b41116100bd57806395d89b41146102e75780639dc29fac146102ef578063a3c573eb1461030257600080fd5b806370a08231146102915780637ecebe00146102c757600080fd5b806330adf81f1161012f5780633644e515116101145780633644e51514610261578063395093511461026957806340c10f191461027c57600080fd5b806330adf81f14610209578063313ce5671461023057600080fd5b806318160ddd1161016057806318160ddd146101bd57806320606b70146101cf57806323b872dd146101f657600080fd5b806306fdde031461017c578063095ea7b31461019a575b600080fd5b610184610430565b60405161019191906113e4565b60405180910390f35b6101ad6101a8366004611479565b6104c2565b6040519015158152602001610191565b6002545b604051908152602001610191565b6101c17f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81565b6101ad6102043660046114a3565b6104dc565b6101c17f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610191565b6101c1610500565b6101ad610277366004611479565b61055c565b61028f61028a366004611479565b6105a8565b005b6101c161029f3660046114df565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101c16102d53660046114df565b60056020526000908152604090205481565b610184610680565b61028f6102fd366004611479565b61068f565b6103297f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610191565b6101ad61035c366004611479565b61075e565b6101ad61036f366004611479565b61082f565b6101c17f000000000000000000000000000000000000000000000000000000000000000081565b61028f6103a9366004611501565b61083d565b6101c16103bc366004611574565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101846040518060400160405280600181526020017f310000000000000000000000000000000000000000000000000000000000000081525081565b60606003805461043f906115a7565b80601f016020809104026020016040519081016040528092919081815260200182805461046b906115a7565b80156104b85780601f1061048d576101008083540402835291602001916104b8565b820191906000526020600020905b81548152906001019060200180831161049b57829003601f168201915b5050505050905090565b6000336104d0818585610b73565b60019150505b92915050565b6000336104ea858285610d27565b6104f5858585610dfe565b506001949350505050565b60007f00000000000000000000000000000000000000000000000000000000000000004614610537576105324661106d565b905090565b507f000000000000000000000000000000000000000000000000000000000000000090565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906104d090829086906105a3908790611629565b610b73565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610672576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f546f6b656e577261707065643a3a6f6e6c794272696467653a204e6f7420506f60448201527f6c79676f6e5a6b45564d4272696467650000000000000000000000000000000060648201526084015b60405180910390fd5b61067c8282611135565b5050565b60606004805461043f906115a7565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610754576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f546f6b656e577261707065643a3a6f6e6c794272696467653a204e6f7420506f60448201527f6c79676f6e5a6b45564d427269646765000000000000000000000000000000006064820152608401610669565b61067c8282611228565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015610822576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610669565b6104f58286868403610b73565b6000336104d0818585610dfe565b834211156108cc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f546f6b656e577261707065643a3a7065726d69743a204578706972656420706560448201527f726d6974000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff8716600090815260056020526040812080547f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9918a918a918a9190866109268361163c565b9091555060408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e0016040516020818303038152906040528051906020012090506000610991610500565b6040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281019190915260428101839052606201604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120600080855291840180845281905260ff89169284019290925260608301879052608083018690529092509060019060a0016020604051602081039080840390855afa158015610a55573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811615801590610ad057508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b610b5c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f546f6b656e577261707065643a3a7065726d69743a20496e76616c696420736960448201527f676e6174757265000000000000000000000000000000000000000000000000006064820152608401610669565b610b678a8a8a610b73565b50505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff8316610c15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff8216610cb8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610df85781811015610deb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610669565b610df88484848403610b73565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610ea1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff8216610f44576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610ffa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610df8565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f611098610430565b8051602091820120604080518082018252600181527f310000000000000000000000000000000000000000000000000000000000000090840152805192830193909352918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc66060820152608081018390523060a082015260c001604051602081830303815290604052805190602001209050919050565b73ffffffffffffffffffffffffffffffffffffffff82166111b2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610669565b80600260008282546111c49190611629565b909155505073ffffffffffffffffffffffffffffffffffffffff8216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff82166112cb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604090205481811015611381576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff83166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9101610d1a565b600060208083528351808285015260005b81811015611411578581018301518582016040015282016113f5565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461147457600080fd5b919050565b6000806040838503121561148c57600080fd5b61149583611450565b946020939093013593505050565b6000806000606084860312156114b857600080fd5b6114c184611450565b92506114cf60208501611450565b9150604084013590509250925092565b6000602082840312156114f157600080fd5b6114fa82611450565b9392505050565b600080600080600080600060e0888a03121561151c57600080fd5b61152588611450565b965061153360208901611450565b95506040880135945060608801359350608088013560ff8116811461155757600080fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561158757600080fd5b61159083611450565b915061159e60208401611450565b90509250929050565b600181811c908216806115bb57607f821691505b6020821081036115f4577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156104d6576104d66115fa565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361166d5761166d6115fa565b506001019056fea26469706673582212208d88fee561cff7120d381c345cfc534cef8229a272dc5809d4bbb685ad67141164736f6c63430008110033a2646970667358221220432f6d6b4446edbe1f73c19fd2115454d5c35d8b03b98a74fd46724151d7672264736f6c63430008140033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/test/cross-chain/ZNSDeploy.test.ts b/test/cross-chain/ZNSDeploy.test.ts new file mode 100644 index 000000000..631dde763 --- /dev/null +++ b/test/cross-chain/ZNSDeploy.test.ts @@ -0,0 +1,137 @@ +import assert from "assert"; +import { expect } from "chai"; +import * as hre from "hardhat"; +import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; +import { IZNSCampaignConfig, IZNSContracts } from "../../src/deploy/campaign/types"; +import { MongoDBAdapter, resetMongoAdapter } from "@zero-tech/zdc"; +import { Wallet } from "ethers"; +import { getConfig } from "../../src/deploy/campaign/get-config"; +import { runZnsCampaign } from "../../src/deploy/zns-campaign"; +import { SupportedChains } from "../../src/deploy/missions/contracts/cross-chain/portals/get-portal-dm"; +import { PolygonZkEVMBridgeV2Mock } from "../../typechain"; +import { setDefaultEnvironment } from "../../src/environment/set-env"; +import { NETWORK_ID_L1_TEST_DEFAULT, NETWORK_ID_L2_TEST_DEFAULT, ZCHAIN_ID_TEST_DEFAULT } from "../helpers"; + + +describe("ZNS Cross-Chain Deploy Test", () => { + let znsL1 : IZNSContracts; + let znsL2 : IZNSContracts; + + let configL1 : IZNSCampaignConfig; + let configL2 : IZNSCampaignConfig; + + let dbAdapter1 : MongoDBAdapter; + let dbAdapter2 : MongoDBAdapter; + + let deployAdmin : SignerWithAddress; + + let predeployedBridge : PolygonZkEVMBridgeV2Mock; + + before(async () => { + [ deployAdmin ] = await hre.ethers.getSigners(); + + // set ENV vars for the Ethereum ZNS deployment + process.env.SRC_CHAIN_NAME = SupportedChains.eth; + process.env.MOCK_ZKEVM_BRIDGE = "true"; + process.env.NETWORK_ID = NETWORK_ID_L1_TEST_DEFAULT.toString(); + process.env.BRIDGE_TOKEN = hre.ethers.ZeroAddress; + process.env.DEST_NETWORK_ID = NETWORK_ID_L2_TEST_DEFAULT.toString(); + process.env.DEST_CHAIN_NAME = SupportedChains.z; + process.env.DEST_CHAIN_ID = ZCHAIN_ID_TEST_DEFAULT.toString(); + + // L1 run + configL1 = await getConfig({ + deployer: deployAdmin, + zeroVaultAddress: deployAdmin.address, + }); + + const campaignL1 = await runZnsCampaign({ config: configL1 }); + + ({ + state: { + contracts: znsL1, + }, + dbAdapter: dbAdapter1, + } = campaignL1); + + // TODO multi: do we need to break this up into 2 DBs or make 2 collections for one DB ?? + // so we don't have to specify the ENV var every time? or is it fine as is ?? + resetMongoAdapter(); + + // set ENV vars for ZChain ZNS deployment + process.env.SRC_CHAIN_NAME = SupportedChains.z; + process.env.SRC_ZNS_PORTAL = znsL1.zChainPortal.target as string; + process.env.MONGO_DB_NAME = "zns-l2"; + + // for L2 we are deploying the Bridge separately, so that we can test + // that the L2 campaign properly picks up the deployed Bridge from chain + const bridgeFact = await hre.ethers.getContractFactory("PolygonZkEVMBridgeV2Mock"); + predeployedBridge = await hre.upgrades.deployProxy( + bridgeFact, + [ + NETWORK_ID_L2_TEST_DEFAULT, + deployAdmin.address, + ] + ) as unknown as PolygonZkEVMBridgeV2Mock; + // now we need to set the proper ENV vars so that it's picked up by the L2 campaign + process.env.MOCK_ZKEVM_BRIDGE = "false"; + process.env.ZK_EVM_BRIDGE = predeployedBridge.target as string; + // we are setting these as such to make sure state is set from the parameters passed + // to the individual deploy above + process.env.NETWORK_ID = ""; + process.env.BRIDGE_TOKEN = ""; + + // L2 run + configL2 = await getConfig({ + deployer: deployAdmin, + zeroVaultAddress: deployAdmin.address, + }); + + // emulating L2 here by deploying to the same network + const campaignL2 = await runZnsCampaign({ config: configL2 }); + + ({ + state: { + contracts: znsL2, + }, + dbAdapter: dbAdapter2, + } = campaignL2); + }); + + after(async () => { + await dbAdapter1.dropDB(); + await dbAdapter2.dropDB(); + setDefaultEnvironment(); + }); + + it("should deploy a mocked zkEVM Bridge if MOCK_ZKEVM_BRIDGE is 'true'", async () => { + // this happens in znsL1 deploy + assert.ok(configL1.crosschain.mockZkEvmBridge, "mockZkEvmBridge for L1 is set incorrectly!"); + + const { zkEvmBridge } = znsL1; + expect(zkEvmBridge.target).to.not.be.undefined; + + const networkIdFromBridge = await zkEvmBridge.networkID(); + const tokenFromBridge = await zkEvmBridge.WETHToken(); + + // same params as set in the ENV before deploying znsL1 + expect(networkIdFromBridge).to.equal(NETWORK_ID_L1_TEST_DEFAULT); + expect(tokenFromBridge).to.equal(hre.ethers.ZeroAddress); + }); + + it("should pick up an already deployed zkEVM Bridge from chain if MOCK_ZKEVM_BRIDGE is 'false'", async () => { + // this happens in znsL2 deploy + assert.ok(!configL2.crosschain.mockZkEvmBridge, "mockZkEvmBridge for L2 is set incorrectly!"); + + const { zkEvmBridge } = znsL2; + expect(zkEvmBridge.target).to.eq(predeployedBridge.target); + + const networkIdFromBridge = await zkEvmBridge.networkID(); + const tokenFromBridge = await zkEvmBridge.WETHToken(); + + // same params as passed to the `deployProxy` call above + // where we separately deploy the Bridge before running the L2 campaign + expect(networkIdFromBridge).to.equal(NETWORK_ID_L2_TEST_DEFAULT); + expect(tokenFromBridge).to.equal(deployAdmin.address); + }); +}); diff --git a/test/gas/gas-costs.json b/test/gas/gas-costs.json index 957af37b9..496ba4a27 100644 --- a/test/gas/gas-costs.json +++ b/test/gas/gas-costs.json @@ -1,4 +1,4 @@ { - "Root Domain Price": "470187", - "Subdomain Price": "463250" -} + "Root Domain Price": "463047", + "Subdomain Price": "456881" +} \ No newline at end of file diff --git a/test/helpers/cc-claim.ts b/test/helpers/cc-claim.ts new file mode 100644 index 000000000..966cfc92f --- /dev/null +++ b/test/helpers/cc-claim.ts @@ -0,0 +1,68 @@ +/* eslint-disable camelcase */ +import fs from "fs"; +import { BridgeApiOps, getTempDataFilePath } from "../../src/utils/cross-chain/constants"; +import { getBridgeDepositData, getMerkeProof } from "../../src/utils/cross-chain/bridge-api"; + + +// These helpers only return data for a single deposit only +// they use whatever has been saved last to local files after running `bridge-get` script +export const getSavedBridgeApiData = async ({ + destAddress, + depositCnt, +} : { + destAddress ?: string; + depositCnt ?: string; +}) => { + let deposit; + let proof; + + if (!destAddress) { + const rawDeposit = fs.readFileSync( + getTempDataFilePath(BridgeApiOps.deposit) + ); + deposit = JSON.parse(rawDeposit.toString()); + if (depositCnt) { + deposit = deposit.find((d : { deposit_cnt : string; }) => d.deposit_cnt === depositCnt); + } + + const rawProof = fs.readFileSync( + getTempDataFilePath(BridgeApiOps.proof) + ); + proof = JSON.parse(rawProof.toString()); + } else { + const deposits = await getBridgeDepositData({ destAddress }); + deposit = deposits[deposits.length - 1]; + + const { deposit_cnt, orig_net } = deposit; + proof = await getMerkeProof({ depositCnt: deposit_cnt, netId: orig_net }); + } + + return { + deposit, + proof, + }; +}; + +export const getClaimArgsFromApi = async ({ + destAddress, + depositCnt, +} : { + destAddress ?: string; + depositCnt ?: string; +}) => { + const { deposit, proof } = await getSavedBridgeApiData({ destAddress, depositCnt }); + + return [ + proof.merkle_proof, + proof.rollup_merkle_proof, + deposit.global_index, + proof.main_exit_root, + proof.rollup_exit_root, + deposit.orig_net, + deposit.orig_addr, + deposit.dest_net, + deposit.dest_addr, + deposit.amount, + deposit.metadata, + ]; +}; diff --git a/test/helpers/constants.ts b/test/helpers/constants.ts index 3ed32dd07..f9b315546 100644 --- a/test/helpers/constants.ts +++ b/test/helpers/constants.ts @@ -1,95 +1,101 @@ -import { ethers } from "hardhat"; -import { ICurvePriceConfig } from "../../src/deploy/missions/types"; - -export const DEFAULT_RESOLVER_TYPE = "address"; -export const ZNS_DOMAIN_TOKEN_NAME = "Zero Name Service"; -export const ZNS_DOMAIN_TOKEN_SYMBOL = "ZNS"; - -export const DEFAULT_ROYALTY_FRACTION = BigInt("200"); -export const DEFAULT_TOKEN_URI = "https://www.zns.domains/7c654a5f"; -export const DEFAULT_PROTOCOL_FEE_PERCENT = BigInt("222"); -export const DEFAULT_PERCENTAGE_BASIS = BigInt("10000"); - -export const DEFAULT_DECIMALS = BigInt(18); -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 = { - LOCKED: 0n, - OPEN: 1n, - MINTLIST: 2n, -}; - -// eslint-disable-next-line no-shadow -export const OwnerOf = { - NAME: 0n, - TOKEN: 1n, - BOTH: 2n, -}; - -// eslint-disable-next-line no-shadow -export const PaymentType = { - DIRECT: 0n, - STAKE: 1n, -}; - -export const DEFAULT_PRICE_CONFIG : ICurvePriceConfig = { - maxPrice: ethers.parseEther("25000"), - curveMultiplier: BigInt("1000"), - maxLength: BigInt(50), - baseLength: BigInt(4), - precisionMultiplier: DEFAULT_PRECISION_MULTIPLIER, - feePercentage: DEFAULT_PROTOCOL_FEE_PERCENT, - isSet: true, -}; - -export const curvePriceConfigEmpty : ICurvePriceConfig = { - maxPrice: BigInt(0), - curveMultiplier: BigInt(0), - maxLength: BigInt(0), - baseLength: BigInt(0), - precisionMultiplier: BigInt(0), - feePercentage: BigInt(0), - isSet: true, -}; - -export const paymentConfigEmpty = { - token: ethers.ZeroAddress, - beneficiary: ethers.ZeroAddress, -}; - -export const distrConfigEmpty = { - pricerContract: ethers.ZeroAddress, - paymentType: PaymentType.DIRECT, - accessType: AccessType.LOCKED, -}; - -export const fullDistrConfigEmpty = { - distrConfig: distrConfigEmpty, - priceConfig: undefined, - paymentConfig: paymentConfigEmpty, -}; - -export const implSlotErc1967 = "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc"; - -// Contract names -export const accessControllerName = "ZNSAccessController"; -export const registryName = "ZNSRegistry"; -export const domainTokenName = "ZNSDomainToken"; -export const zTokenMockName = "ZTokenMock"; -export const addressResolverName = "ZNSAddressResolver"; -export const curvePricerName = "ZNSCurvePricer"; -export const fixedPricerName = "ZNSFixedPricer"; -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; +import { ethers } from "hardhat"; +import { ICurvePriceConfig } from "../../src/deploy/missions/types"; + +export const DEFAULT_RESOLVER_TYPE = "address"; +export const ZNS_DOMAIN_TOKEN_NAME = "ZERO ID"; +export const ZNS_DOMAIN_TOKEN_SYMBOL = "ZID"; + +export const DEFAULT_ROYALTY_FRACTION = BigInt("200"); +export const DEFAULT_TOKEN_URI = "https://www.zns.domains/7c654a5f"; +export const DEFAULT_PROTOCOL_FEE_PERCENT = BigInt("222"); +export const DEFAULT_PERCENTAGE_BASIS = BigInt("10000"); + +export const DEFAULT_DECIMALS = BigInt(18); +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 = { + LOCKED: 0n, + OPEN: 1n, + MINTLIST: 2n, +}; + +// eslint-disable-next-line no-shadow +export const OwnerOf = { + NAME: 0n, + TOKEN: 1n, + BOTH: 2n, +}; + +// eslint-disable-next-line no-shadow +export const PaymentType = { + DIRECT: 0n, + STAKE: 1n, +}; + +// TODO multi: make these read from the env.ts file along with other default env vars ?? +export const DEFAULT_PRICE_CONFIG : ICurvePriceConfig = { + maxPrice: ethers.parseEther("25000"), + curveMultiplier: BigInt("1000"), + maxLength: BigInt(50), + baseLength: BigInt(4), + precisionMultiplier: DEFAULT_PRECISION_MULTIPLIER, + feePercentage: DEFAULT_PROTOCOL_FEE_PERCENT, + isSet: true, +}; + +export const curvePriceConfigEmpty : ICurvePriceConfig = { + maxPrice: BigInt(0), + curveMultiplier: BigInt(0), + maxLength: BigInt(0), + baseLength: BigInt(0), + precisionMultiplier: BigInt(0), + feePercentage: BigInt(0), + isSet: true, +}; + +export const paymentConfigEmpty = { + token: ethers.ZeroAddress, + beneficiary: ethers.ZeroAddress, +}; + +export const distrConfigEmpty = { + pricerContract: ethers.ZeroAddress, + paymentType: PaymentType.DIRECT, + accessType: AccessType.LOCKED, +}; + +export const fullDistrConfigEmpty = { + distrConfig: distrConfigEmpty, + priceConfig: undefined, + paymentConfig: paymentConfigEmpty, +}; + +export const implSlotErc1967 = "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc"; + +// Contract names +export const accessControllerName = "ZNSAccessController"; +export const registryName = "ZNSRegistry"; +export const domainTokenName = "ZNSDomainToken"; +export const zTokenMockName = "ZTokenMock"; +export const addressResolverName = "ZNSAddressResolver"; +export const curvePricerName = "ZNSCurvePricer"; +export const fixedPricerName = "ZNSFixedPricer"; +export const treasuryName = "ZNSTreasury"; +export const registrarName = "ZNSRootRegistrar"; +export const erc1967ProxyName = "ERC1967Proxy"; +export const subRegistrarName = "ZNSSubRegistrar"; + +// Cross-Chain +export const NETWORK_ID_L1_TEST_DEFAULT = 0n; +export const NETWORK_ID_L2_TEST_DEFAULT = 1n; +export const ZCHAIN_ID_TEST_DEFAULT = 2012605151n; + +// 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/deploy-zns.ts b/test/helpers/deploy/deploy-zns.ts index d17643b65..352f95239 100644 --- a/test/helpers/deploy/deploy-zns.ts +++ b/test/helpers/deploy/deploy-zns.ts @@ -1,648 +1,1004 @@ -import { - ZTokenMock__factory, - ZNSAccessController, - ZNSAccessController__factory, - ZNSAddressResolver, - ZNSAddressResolver__factory, - ZNSCurvePricer, - ZNSDomainToken, - ZNSDomainToken__factory, - ZNSFixedPricer__factory, - ZNSCurvePricer__factory, - ZNSRootRegistrar, - ZNSRootRegistrar__factory, - ZNSRegistry, - ZNSRegistry__factory, - ZNSSubRegistrar__factory, - ZNSTreasury, - ZNSTreasury__factory, - ZNSFixedPricer, - ZNSSubRegistrar, - ZTokenMock, -} from "../../../typechain"; -import { DeployZNSParams, RegistrarConfig, IZNSContractsLocal } from "../types"; -import * as hre from "hardhat"; -import { upgrades } from "hardhat"; -import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; -import { - accessControllerName, - addressResolverName, - domainTokenName, - erc1967ProxyName, - fixedPricerName, - DEFAULT_PRICE_CONFIG, - curvePricerName, - registrarName, - registryName, - subRegistrarName, - treasuryName, - 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 { DOMAIN_TOKEN_ROLE, REGISTRAR_ROLE } from "../../../src/deploy/constants"; -import { getProxyImplAddress } from "../utils"; -import { ICurvePriceConfig } from "../../../src/deploy/missions/types"; -import { transparentProxyName } from "../../../src/deploy/missions/contracts/names"; - - -export const deployAccessController = async ({ - deployer, - governorAddresses, - adminAddresses, - isTenderlyRun = false, -} : { - deployer : SignerWithAddress; - governorAddresses : Array; - adminAddresses : Array; - isTenderlyRun ?: boolean; -}) : Promise => { - const accessControllerFactory = new ZNSAccessController__factory(deployer); - const controller = await accessControllerFactory.deploy(governorAddresses, adminAddresses); - - await controller.waitForDeployment(); - const proxyAddress = await controller.getAddress(); - - if (isTenderlyRun) { - await hre.tenderly.verify({ - name: accessControllerName, - address: proxyAddress, - }); - - console.log(`AccessController deployed at: ${proxyAddress}`); - } - - return controller as unknown as ZNSAccessController; -}; - -export const deployRegistry = async ( - deployer : SignerWithAddress, - accessControllerAddress : string, - isTenderlyRun = false, -) : Promise => { - const registryFactory = new ZNSRegistry__factory(deployer); - const registry = await hre.upgrades.deployProxy( - registryFactory, - [ - accessControllerAddress, - ], - { - kind: "uups", - }); - - await registry.waitForDeployment(); - const proxyAddress = await registry.getAddress(); - - if (isTenderlyRun) { - await hre.tenderly.verify({ - name: erc1967ProxyName, - address: proxyAddress, - }); - - const impl = await getProxyImplAddress(proxyAddress); - - await hre.tenderly.verify({ - name: registryName, - address: impl, - }); - - console.log(`ZNSRegistry deployed at: - proxy: ${proxyAddress} - implementation: ${impl}`); - } - - return registry as unknown as ZNSRegistry; -}; - -export const deployDomainToken = async ( - deployer : SignerWithAddress, - accessController : ZNSAccessController, - royaltyReceiverAddress : string, - royaltyFraction : bigint, - isTenderlyRun : boolean, - registry : ZNSRegistry, -) : Promise => { - const domainTokenFactory = new ZNSDomainToken__factory(deployer); - const domainToken = await upgrades.deployProxy( - domainTokenFactory, - [ - await accessController.getAddress(), - ZNS_DOMAIN_TOKEN_NAME, - ZNS_DOMAIN_TOKEN_SYMBOL, - royaltyReceiverAddress, - royaltyFraction, - await registry.getAddress(), - ], - { - kind: "uups", - } - ) as unknown as ZNSDomainToken; - - await domainToken.waitForDeployment(); - - const proxyAddress = await domainToken.getAddress(); - - await accessController.connect(deployer).grantRole(DOMAIN_TOKEN_ROLE, proxyAddress); - - if (isTenderlyRun) { - await hre.tenderly.verify({ - name: erc1967ProxyName, - address: proxyAddress, - }); - - const impl = await getProxyImplAddress(proxyAddress); - - await hre.tenderly.verify({ - name: domainTokenName, - address: impl, - }); - - console.log(`ZNSDomainToken deployed at: - proxy: ${proxyAddress} - implementation: ${impl}`); - } - - return domainToken as unknown as ZNSDomainToken; -}; - -export const deployZToken = async ( - deployer : SignerWithAddress, - governorAddresses : Array, - adminAddresses : Array, - isTenderlyRun : boolean -) : 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({ - name: transparentProxyName, - address: proxyAddress, - }); - - const impl = await getProxyImplAddress(proxyAddress); - - await hre.tenderly.verify({ - name: zTokenMockName, - address: impl, - }); - - console.log(`${zTokenMockName} deployed at: - proxy: ${proxyAddress} - implementation: ${impl}`); - } - - return zToken as unknown as ZTokenMock; -}; - -export const deployAddressResolver = async ( - deployer : SignerWithAddress, - accessControllerAddress : string, - registryAddress : string, - isTenderlyRun : boolean -) : Promise => { - const addressResolverFactory = new ZNSAddressResolver__factory(deployer); - - const resolver = await upgrades.deployProxy( - addressResolverFactory, - [ - accessControllerAddress, - registryAddress, - ], - { - kind: "uups", - } - ); - - await resolver.waitForDeployment(); - - const proxyAddress = await resolver.getAddress(); - - if (isTenderlyRun) { - await hre.tenderly.verify({ - name: erc1967ProxyName, - address: proxyAddress, - }); - - const impl = await getProxyImplAddress(proxyAddress); - - await hre.tenderly.verify({ - name: addressResolverName, - address: impl, - }); - - console.log(`ZNSAddressResolver deployed at: - proxy: ${proxyAddress} - implementation: ${impl}`); - } - - return resolver as unknown as ZNSAddressResolver; -}; - -export const deployCurvePricer = async ({ - deployer, - accessControllerAddress, - registryAddress, - priceConfig, - isTenderlyRun, -} : { - deployer : SignerWithAddress; - accessControllerAddress : string; - registryAddress : string; - priceConfig : ICurvePriceConfig; - isTenderlyRun : boolean; -}) : Promise => { - const curveFactory = new ZNSCurvePricer__factory(deployer); - - const curvePricer = await upgrades.deployProxy( - curveFactory, - [ - accessControllerAddress, - registryAddress, - priceConfig, - ], - { - kind: "uups", - } - ); - - await curvePricer.waitForDeployment(); - - const proxyAddress = await curvePricer.getAddress(); - - if (isTenderlyRun) { - await hre.tenderly.verify({ - name: erc1967ProxyName, - address: proxyAddress, - }); - - const impl = await getProxyImplAddress(proxyAddress); - - await hre.tenderly.verify({ - name: curvePricerName, - address: impl, - }); - - console.log(`${curvePricerName} deployed at: - proxy: ${proxyAddress} - implementation: ${impl}`); - } - - return curvePricer as unknown as ZNSCurvePricer; -}; - -export const deployTreasury = async ({ - deployer, - accessControllerAddress, - registryAddress, - zTokenMockAddress, - zeroVaultAddress, - isTenderlyRun = false, -} : { - deployer : SignerWithAddress; - accessControllerAddress : string; - registryAddress : string; - zTokenMockAddress : string; - zeroVaultAddress : string; - isTenderlyRun : boolean; -}) : Promise => { - const treasuryFactory = new ZNSTreasury__factory(deployer); - const treasury = await upgrades.deployProxy(treasuryFactory, - [ - accessControllerAddress, - registryAddress, - zTokenMockAddress, - zeroVaultAddress, - ], - { - kind: "uups", - } - ); - - await treasury.waitForDeployment(); - const proxyAddress = await treasury.getAddress(); - - if (isTenderlyRun) { - await hre.tenderly.verify({ - name: erc1967ProxyName, - address: proxyAddress, - }); - - const impl = await getProxyImplAddress(proxyAddress); - - await hre.tenderly.verify({ - name: treasuryName, - address: impl, - }); - - console.log(`ZNSTreasury deployed at: - proxy: ${proxyAddress} - implementation: ${impl}`); - } - - return treasury as unknown as ZNSTreasury; -}; - -export const deployRootRegistrar = async ( - deployer : SignerWithAddress, - accessController : ZNSAccessController, - config : RegistrarConfig, - isTenderlyRun : boolean -) : Promise => { - const registrarFactory = new ZNSRootRegistrar__factory(deployer); - - const registrar = await upgrades.deployProxy( - registrarFactory, - [ - await accessController.getAddress(), - config.registryAddress, - config.curvePricerAddress, - config.treasuryAddress, - config.domainTokenAddress, - ], - { - kind: "uups", - } - ); - - await registrar.waitForDeployment(); - const proxyAddress = await registrar.getAddress(); - - await accessController.connect(deployer).grantRole(REGISTRAR_ROLE, proxyAddress); - - if (isTenderlyRun) { - await hre.tenderly.verify({ - name: erc1967ProxyName, - address: proxyAddress, - }); - - const impl = await getProxyImplAddress(proxyAddress); - - await hre.tenderly.verify({ - name: registrarName, - address: impl, - }); - - console.log(`ZNSRootRegistrar deployed at: - proxy: ${proxyAddress} - implementation: ${impl}`); - } - - return registrar as unknown as ZNSRootRegistrar; -}; - -export const deployFixedPricer = async ({ - deployer, - acAddress, - regAddress, - isTenderlyRun = false, -} : { - deployer : SignerWithAddress; - acAddress : string; - regAddress : string; - isTenderlyRun ?: boolean; -}) => { - const pricerFactory = new ZNSFixedPricer__factory(deployer); - const fixedPricer = await upgrades.deployProxy( - pricerFactory, - [ - acAddress, - regAddress, - ], - { - kind: "uups", - } - ); - - await fixedPricer.waitForDeployment(); - const proxyAddress = await fixedPricer.getAddress(); - - if (isTenderlyRun) { - await hre.tenderly.verify({ - name: erc1967ProxyName, - address: proxyAddress, - }); - - const impl = await getProxyImplAddress(proxyAddress); - - await hre.tenderly.verify({ - name: fixedPricerName, - address: impl, - }); - - console.log(`${fixedPricerName} deployed at: - proxy: ${proxyAddress} - implementation: ${impl}`); - } - - return fixedPricer as unknown as ZNSFixedPricer; -}; - -export const deploySubRegistrar = async ({ - deployer, - accessController, - registry, - rootRegistrar, - admin, - isTenderlyRun = false, -} : { - deployer : SignerWithAddress; - accessController : ZNSAccessController; - registry : ZNSRegistry; - rootRegistrar : ZNSRootRegistrar; - admin : SignerWithAddress; - isTenderlyRun ?: boolean; -}) => { - const subRegistrarFactory = new ZNSSubRegistrar__factory(deployer); - const subRegistrar = await upgrades.deployProxy( - subRegistrarFactory, - [ - await accessController.getAddress(), - await registry.getAddress(), - await rootRegistrar.getAddress(), - ], - { - kind: "uups", - } - ); - - await subRegistrar.waitForDeployment(); - const proxyAddress = await subRegistrar.getAddress(); - - // set SubRegistrar on RootRegistrar - await rootRegistrar.setSubRegistrar(proxyAddress); - - // give SubRegistrar REGISTRAR_ROLE - await accessController.connect(admin).grantRole(REGISTRAR_ROLE, proxyAddress); - - if (isTenderlyRun) { - await hre.tenderly.verify({ - name: erc1967ProxyName, - address: proxyAddress, - }); - - const impl = await getProxyImplAddress(proxyAddress); - - await hre.tenderly.verify({ - name: subRegistrarName, - address: impl, - }); - - console.log(`${subRegistrarName} deployed at: - proxy: ${proxyAddress} - implementation: ${impl}`); - } - - return subRegistrar as unknown as ZNSSubRegistrar; -}; - -/** - * We use this script to aid in testing, NOT for anything more - * such as deploying to live testnets or mainnet. Do not use any - * of the code present for tasks other than testing behavior on a - * local hardhat build - */ -export const deployZNS = async ({ - deployer, - governorAddresses, - adminAddresses, - priceConfig = DEFAULT_PRICE_CONFIG, - zeroVaultAddress = deployer.address, - isTenderlyRun = false, -} : DeployZNSParams) : Promise => { - // We deploy every contract as a UUPS proxy, but ZERO is already - // deployed as a transparent proxy. This means that there is already - // a proxy admin deployed to the network. Because future deployments - // warn when this is the case, we silence the warning from hardhat here - // to not clog the test output. - await hre.upgrades.silenceWarnings(); - - if (!zeroVaultAddress) { - zeroVaultAddress = deployer.address; - } - - const accessController = await deployAccessController({ - deployer, - governorAddresses: [deployer.address, ...governorAddresses], - adminAddresses: [deployer.address, ...adminAddresses], - isTenderlyRun, - }); - - const registry = await deployRegistry( - deployer, - await accessController.getAddress(), - isTenderlyRun - ); - - const domainToken = await deployDomainToken( - deployer, - accessController, - zeroVaultAddress, - DEFAULT_ROYALTY_FRACTION, - 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 zTokenMock = await deployZToken( - deployer, - governorAddresses, - adminAddresses, - isTenderlyRun, - ); - - const addressResolver = await deployAddressResolver( - deployer, - await accessController.getAddress(), - await registry.getAddress(), - isTenderlyRun - ); - - const curvePricer = await deployCurvePricer({ - deployer, - accessControllerAddress: await accessController.getAddress(), - registryAddress: await registry.getAddress(), - priceConfig, - isTenderlyRun, - }); - - const treasury = await deployTreasury({ - deployer, - accessControllerAddress: await accessController.getAddress(), - registryAddress: await registry.getAddress(), - zTokenMockAddress: await zTokenMock.getAddress(), - zeroVaultAddress, - isTenderlyRun, - }); - - const config : RegistrarConfig = { - treasuryAddress: await treasury.getAddress(), - registryAddress: await registry.getAddress(), - curvePricerAddress: await curvePricer.getAddress(), - domainTokenAddress: await domainToken.getAddress(), - }; - - const rootRegistrar = await deployRootRegistrar( - deployer, - accessController, - config, - isTenderlyRun - ); - - const fixedPricer = await deployFixedPricer({ - deployer, - acAddress: await accessController.getAddress(), - regAddress: await registry.getAddress(), - isTenderlyRun, - }); - - const subRegistrar = await deploySubRegistrar({ - deployer, - accessController, - registry, - rootRegistrar, - admin: deployer, - isTenderlyRun, - }); - - const znsContracts : IZNSContractsLocal = { - accessController, - registry, - domainToken, - zToken: zTokenMock, - addressResolver, - curvePricer, - treasury, - rootRegistrar, - fixedPricer, - subRegistrar, - zeroVaultAddress, - }; - - await registry.connect(deployer).addResolverType(DEFAULT_RESOLVER_TYPE, await addressResolver.getAddress()); - - return znsContracts; -}; +import { + ZTokenMock__factory, + ZNSAccessController, + ZNSAccessController__factory, + ZNSAddressResolver, + ZNSAddressResolver__factory, + ZNSCurvePricer, + ZNSDomainToken, + ZNSDomainToken__factory, + ZNSFixedPricer__factory, + ZNSCurvePricer__factory, + ZNSRegistry, + ZNSRegistry__factory, + ZNSTreasury, + ZNSTreasury__factory, + ZNSFixedPricer, + ZTokenMock, + ZNSStringResolver, + ZNSStringResolver__factory, + ZNSChainResolver__factory, + ZNSChainResolver, + ZNSRootRegistrarTrunk__factory, + ZNSRootRegistrarBranch__factory, + ZNSSubRegistrarTrunk__factory, + ZNSSubRegistrarBranch__factory, + PolygonZkEVMBridgeV2Mock__factory, + PolygonZkEVMBridgeV2Mock, + ZNSZChainPortal__factory, + ZNSZChainPortal, + ZNSEthereumPortal__factory, + ZNSEthereumPortal, + ZNSRootRegistrarTrunk, + ZNSRootRegistrarBranch, + ZNSSubRegistrarTrunk, ZNSSubRegistrarBranch, +} from "../../../typechain"; +import { DeployZNSParams, RegistrarConfig, IZNSContractsLocal } from "../types"; +import * as hre from "hardhat"; +import { upgrades, ethers } from "hardhat"; +import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; +import { + erc1967ProxyName, + fixedPricerName, + DEFAULT_PRICE_CONFIG, + ZNS_DOMAIN_TOKEN_NAME, + ZNS_DOMAIN_TOKEN_SYMBOL, + DEFAULT_ROYALTY_FRACTION, + DEFAULT_RESOLVER_TYPE, + ZCHAIN_ID_TEST_DEFAULT, + NETWORK_ID_L2_TEST_DEFAULT, + NETWORK_ID_L1_TEST_DEFAULT, + INITIAL_ADMIN_DELAY_DEFAULT, + INITIAL_SUPPLY_DEFAULT, + INFLATION_RATES_DEFAULT, + FINAL_INFLATION_RATE_DEFAULT, + Z_NAME_DEFAULT, + Z_SYMBOL_DEFAULT, +} from "../constants"; +import { PORTAL_ROLE, DOMAIN_TOKEN_ROLE, REGISTRAR_ROLE } from "../../../src/deploy/constants"; +import { getProxyImplAddress } from "../utils"; +import { ICurvePriceConfig } from "../../../src/deploy/missions/types"; +import { transparentProxyName, znsNames } from "../../../src/deploy/missions/contracts/names"; +import { TSupportedChain } from "../../../src/deploy/missions/contracts/cross-chain/portals/types"; +import { SupportedChains } from "../../../src/deploy/missions/contracts/cross-chain/portals/get-portal-dm"; + + +export const deployAccessController = async ({ + deployer, + governorAddresses, + adminAddresses, + isTenderlyRun = false, +} : { + deployer : SignerWithAddress; + governorAddresses : Array; + adminAddresses : Array; + isTenderlyRun ?: boolean; +}) : Promise => { + const accessControllerFactory = new ZNSAccessController__factory(deployer); + const controller = await accessControllerFactory.deploy(governorAddresses, adminAddresses); + + await controller.waitForDeployment(); + const proxyAddress = await controller.getAddress(); + + if (isTenderlyRun) { + await hre.tenderly.verify({ + name: znsNames.accessController.contract, + address: proxyAddress, + }); + + console.log(`AccessController deployed at: ${proxyAddress}`); + } + + return controller as unknown as ZNSAccessController; +}; + +export const deployRegistry = async ( + deployer : SignerWithAddress, + accessControllerAddress : string, + isTenderlyRun = false, +) : Promise => { + const registryFactory = new ZNSRegistry__factory(deployer); + const registry = await hre.upgrades.deployProxy( + registryFactory, + [ + accessControllerAddress, + ], + { + kind: "uups", + }); + + await registry.waitForDeployment(); + const proxyAddress = await registry.getAddress(); + + if (isTenderlyRun) { + await hre.tenderly.verify({ + name: erc1967ProxyName, + address: proxyAddress, + }); + + const impl = await getProxyImplAddress(proxyAddress); + + await hre.tenderly.verify({ + name: znsNames.registry.contract, + address: impl, + }); + + console.log(`ZNSRegistry deployed at: + proxy: ${proxyAddress} + implementation: ${impl}`); + } + + return registry as unknown as ZNSRegistry; +}; + +export const deployDomainToken = async ( + deployer : SignerWithAddress, + accessController : ZNSAccessController, + royaltyReceiverAddress : string, + royaltyFraction : bigint, + isTenderlyRun : boolean, + registry : ZNSRegistry, +) : Promise => { + const domainTokenFactory = new ZNSDomainToken__factory(deployer); + const domainToken = await upgrades.deployProxy( + domainTokenFactory, + [ + await accessController.getAddress(), + ZNS_DOMAIN_TOKEN_NAME, + ZNS_DOMAIN_TOKEN_SYMBOL, + royaltyReceiverAddress, + royaltyFraction, + await registry.getAddress(), + ], + { + kind: "uups", + } + ) as unknown as ZNSDomainToken; + + await domainToken.waitForDeployment(); + + const proxyAddress = await domainToken.getAddress(); + + await accessController.connect(deployer).grantRole(DOMAIN_TOKEN_ROLE, proxyAddress); + + if (isTenderlyRun) { + await hre.tenderly.verify({ + name: erc1967ProxyName, + address: proxyAddress, + }); + + const impl = await getProxyImplAddress(proxyAddress); + + await hre.tenderly.verify({ + name: znsNames.domainToken.contract, + address: impl, + }); + + console.log(`ZNSDomainToken deployed at: + proxy: ${proxyAddress} + implementation: ${impl}`); + } + + return domainToken as unknown as ZNSDomainToken; +}; + +export const deployZToken = async ( + deployer : SignerWithAddress, + governorAddresses : Array, + adminAddresses : Array, + isTenderlyRun : boolean +) : 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({ + name: transparentProxyName, + address: proxyAddress, + }); + + const impl = await getProxyImplAddress(proxyAddress); + + await hre.tenderly.verify({ + name: znsNames.zToken.contractMock, + address: impl, + }); + + console.log(`${znsNames.zToken.contractMock} deployed at: + proxy: ${proxyAddress} + implementation: ${impl}`); + } + + return zToken as unknown as ZTokenMock; +}; + +export const deployAddressResolver = async ( + deployer : SignerWithAddress, + accessControllerAddress : string, + registryAddress : string, + isTenderlyRun : boolean +) : Promise => { + const addressResolverFactory = new ZNSAddressResolver__factory(deployer); + + const resolver = await upgrades.deployProxy( + addressResolverFactory, + [ + accessControllerAddress, + registryAddress, + ], + { + kind: "uups", + } + ); + + await resolver.waitForDeployment(); + + const proxyAddress = await resolver.getAddress(); + + if (isTenderlyRun) { + await hre.tenderly.verify({ + name: erc1967ProxyName, + address: proxyAddress, + }); + + const impl = await getProxyImplAddress(proxyAddress); + + await hre.tenderly.verify({ + name: znsNames.addressResolver.contract, + address: impl, + }); + + console.log(`ZNSAddressResolver deployed at: + proxy: ${proxyAddress} + implementation: ${impl}`); + } + + return resolver as unknown as ZNSAddressResolver; +}; + +export const deployStringResolver = async ( + deployer : SignerWithAddress, + accessControllerAddress : string, + registryAddress : string, + isTenderlyRun : boolean, +) => { + const stringResolverFactory = new ZNSStringResolver__factory(deployer); + + const resolver = await upgrades.deployProxy( + stringResolverFactory, + [ + accessControllerAddress, + registryAddress, + ], + { + kind: "uups", + } + ); + + await resolver.waitForDeployment(); + + const proxyAddress = await resolver.getAddress(); + + if (isTenderlyRun) { + await hre.tenderly.verify({ + name: erc1967ProxyName, + address: proxyAddress, + }); + + const impl = await getProxyImplAddress(proxyAddress); + + await hre.tenderly.verify({ + name: znsNames.stringResolver.contract, + address: impl, + }); + + console.log(`ZNSStringResolver deployed at: + proxy: ${proxyAddress} + implementation: ${impl}`); + } + + return resolver as unknown as ZNSStringResolver; +}; + +export const deployChainResolver = async ( + deployer : SignerWithAddress, + accessControllerAddress : string, + registryAddress : string, + isTenderlyRun : boolean, +) => { + const chainResolverFactory = new ZNSChainResolver__factory(deployer); + + const resolver = await upgrades.deployProxy( + chainResolverFactory, + [ + accessControllerAddress, + registryAddress, + ], + { + kind: "uups", + } + ); + + await resolver.waitForDeployment(); + + const proxyAddress = await resolver.getAddress(); + + if (isTenderlyRun) { + await hre.tenderly.verify({ + name: erc1967ProxyName, + address: proxyAddress, + }); + + const impl = await getProxyImplAddress(proxyAddress); + + await hre.tenderly.verify({ + name: znsNames.chainResolver.contract, + address: impl, + }); + + console.log(`ZNSChainResolver deployed at: + proxy: ${proxyAddress} + implementation: ${impl}`); + } + + return resolver as unknown as ZNSChainResolver; +}; + +export const deployCurvePricer = async ({ + deployer, + accessControllerAddress, + registryAddress, + priceConfig, + isTenderlyRun, +} : { + deployer : SignerWithAddress; + accessControllerAddress : string; + registryAddress : string; + priceConfig : ICurvePriceConfig; + isTenderlyRun : boolean; +}) : Promise => { + const curveFactory = new ZNSCurvePricer__factory(deployer); + + const curvePricer = await upgrades.deployProxy( + curveFactory, + [ + accessControllerAddress, + registryAddress, + priceConfig, + ], + { + kind: "uups", + } + ); + + await curvePricer.waitForDeployment(); + + const proxyAddress = await curvePricer.getAddress(); + + if (isTenderlyRun) { + await hre.tenderly.verify({ + name: erc1967ProxyName, + address: proxyAddress, + }); + + const impl = await getProxyImplAddress(proxyAddress); + + await hre.tenderly.verify({ + name: znsNames.curvePricer.contract, + address: impl, + }); + + console.log(`${znsNames.curvePricer.contract} deployed at: + proxy: ${proxyAddress} + implementation: ${impl}`); + } + + return curvePricer as unknown as ZNSCurvePricer; +}; + +export const deployTreasury = async ({ + deployer, + accessControllerAddress, + registryAddress, + zTokenMockAddress, + zeroVaultAddress, + isTenderlyRun = false, +} : { + deployer : SignerWithAddress; + accessControllerAddress : string; + registryAddress : string; + zTokenMockAddress : string; + zeroVaultAddress : string; + isTenderlyRun : boolean; +}) : Promise => { + const treasuryFactory = new ZNSTreasury__factory(deployer); + const treasury = await upgrades.deployProxy(treasuryFactory, + [ + accessControllerAddress, + registryAddress, + zTokenMockAddress, + zeroVaultAddress, + ], + { + kind: "uups", + } + ); + + await treasury.waitForDeployment(); + const proxyAddress = await treasury.getAddress(); + + if (isTenderlyRun) { + await hre.tenderly.verify({ + name: erc1967ProxyName, + address: proxyAddress, + }); + + const impl = await getProxyImplAddress(proxyAddress); + + await hre.tenderly.verify({ + name: znsNames.treasury.contract, + address: impl, + }); + + console.log(`ZNSTreasury deployed at: + proxy: ${proxyAddress} + implementation: ${impl}`); + } + + return treasury as unknown as ZNSTreasury; +}; + +export const deployRootRegistrar = async ( + deployer : SignerWithAddress, + accessController : ZNSAccessController, + config : RegistrarConfig, + srcChainName = SupportedChains.eth, + isTenderlyRun : boolean +) : Promise => { + let registrarFactory; + let name; + if (srcChainName === SupportedChains.eth) { + registrarFactory = new ZNSRootRegistrarTrunk__factory(deployer); + name = znsNames.rootRegistrar.contractTrunk; + } else { + registrarFactory = new ZNSRootRegistrarBranch__factory(deployer); + name = znsNames.rootRegistrar.contractBranch; + } + + const registrar = await upgrades.deployProxy( + registrarFactory, + [ + await accessController.getAddress(), + config.registryAddress, + config.curvePricerAddress, + config.treasuryAddress, + config.domainTokenAddress, + ], + { + kind: "uups", + } + ); + + await registrar.waitForDeployment(); + const proxyAddress = await registrar.getAddress(); + + await accessController.connect(deployer).grantRole(REGISTRAR_ROLE, proxyAddress); + + if (isTenderlyRun) { + await hre.tenderly.verify({ + name: erc1967ProxyName, + address: proxyAddress, + }); + + const impl = await getProxyImplAddress(proxyAddress); + + await hre.tenderly.verify({ + name, + address: impl, + }); + + console.log(`${name} deployed at: + proxy: ${proxyAddress} + implementation: ${impl}`); + } + + return registrar as unknown as ZNSRootRegistrarTrunk | ZNSRootRegistrarBranch; +}; + +export const deployFixedPricer = async ({ + deployer, + acAddress, + regAddress, + isTenderlyRun = false, +} : { + deployer : SignerWithAddress; + acAddress : string; + regAddress : string; + isTenderlyRun ?: boolean; +}) => { + const pricerFactory = new ZNSFixedPricer__factory(deployer); + const fixedPricer = await upgrades.deployProxy( + pricerFactory, + [ + acAddress, + regAddress, + ], + { + kind: "uups", + } + ); + + await fixedPricer.waitForDeployment(); + const proxyAddress = await fixedPricer.getAddress(); + + if (isTenderlyRun) { + await hre.tenderly.verify({ + name: erc1967ProxyName, + address: proxyAddress, + }); + + const impl = await getProxyImplAddress(proxyAddress); + + await hre.tenderly.verify({ + name: znsNames.fixedPricer.contract, + address: impl, + }); + + console.log(`${fixedPricerName} deployed at: + proxy: ${proxyAddress} + implementation: ${impl}`); + } + + return fixedPricer as unknown as ZNSFixedPricer; +}; + +export const deploySubRegistrar = async ({ + deployer, + accessController, + registry, + rootRegistrar, + admin, + srcChainName = SupportedChains.eth, + isTenderlyRun = false, +} : { + deployer : SignerWithAddress; + accessController : ZNSAccessController; + registry : ZNSRegistry; + rootRegistrar : ZNSRootRegistrarTrunk | ZNSRootRegistrarBranch; + admin : SignerWithAddress; + srcChainName ?: TSupportedChain; + isTenderlyRun ?: boolean; +}) => { + let subRegistrarFactory; + let name; + if (srcChainName === SupportedChains.eth) { + subRegistrarFactory = new ZNSSubRegistrarTrunk__factory(deployer); + name = znsNames.subRegistrar.contractTrunk; + } else { + subRegistrarFactory = new ZNSSubRegistrarBranch__factory(deployer); + name = znsNames.subRegistrar.contractBranch; + } + + const subRegistrar = await upgrades.deployProxy( + subRegistrarFactory, + [ + await accessController.getAddress(), + await registry.getAddress(), + await rootRegistrar.getAddress(), + ], + { + kind: "uups", + } + ); + + await subRegistrar.waitForDeployment(); + const proxyAddress = await subRegistrar.getAddress(); + + // set SubRegistrar on RootRegistrar + await rootRegistrar.setSubRegistrar(proxyAddress); + + // give SubRegistrar REGISTRAR_ROLE + await accessController.connect(admin).grantRole(REGISTRAR_ROLE, proxyAddress); + + if (isTenderlyRun) { + await hre.tenderly.verify({ + name: erc1967ProxyName, + address: proxyAddress, + }); + + const impl = await getProxyImplAddress(proxyAddress); + + await hre.tenderly.verify({ + name, + address: impl, + }); + + console.log(`${name} deployed at: + proxy: ${proxyAddress} + implementation: ${impl}`); + } + + return subRegistrar as unknown as ZNSSubRegistrarTrunk | ZNSSubRegistrarBranch; +}; + +export const deployZkEvmBridgeMock = async ( + deployer : SignerWithAddress, + networkId : bigint, + bridgeTokenAddress : string, + isTenderlyRun : boolean, +) => { + const bridgeFact = new PolygonZkEVMBridgeV2Mock__factory(deployer); + + const bridge = await hre.upgrades.deployProxy( + bridgeFact, + [ + networkId, + bridgeTokenAddress, + ], + { + kind: "transparent", + } + ); + + await bridge.waitForDeployment(); + const proxyAddress = await bridge.getAddress(); + + if (isTenderlyRun) { + await hre.tenderly.verify({ + name: transparentProxyName, + address: proxyAddress, + }); + + const impl = await getProxyImplAddress(proxyAddress); + + await hre.tenderly.verify({ + name: znsNames.zkEvmBridge.contractMock, + address: impl, + }); + + console.log(`${znsNames.zkEvmBridge.contractMock} deployed at: + proxy: ${proxyAddress} + implementation: ${impl}`); + } + + return bridge as unknown as PolygonZkEVMBridgeV2Mock; +}; + +export const deployZChainPortal = async ({ + deployer, + destNetworkId, + destChainName, + destChainId, + bridgeAddress, + contractAddresses, + isTenderlyRun, +} : { + deployer : SignerWithAddress; + destNetworkId : bigint; + destChainName : TSupportedChain; + destChainId : bigint; + bridgeAddress : string; + contractAddresses : { + accessController : string; + rootRegistrar : string; + subRegistrar : string; + treasury : string; + registry : string; + chainResolver : string; + }; + isTenderlyRun : boolean; +}) => { + const factory = new ZNSZChainPortal__factory(deployer); + + const zChainPortal = await hre.upgrades.deployProxy( + factory, + [ + destNetworkId, + destChainName, + destChainId, + bridgeAddress, + contractAddresses, + ], + { + kind: "uups", + } + ); + + await zChainPortal.waitForDeployment(); + const proxyAddress = await zChainPortal.getAddress(); + + if (isTenderlyRun) { + await hre.tenderly.verify({ + name: erc1967ProxyName, + address: proxyAddress, + }); + + const impl = await getProxyImplAddress(proxyAddress); + + await hre.tenderly.verify({ + name: znsNames.zPortal.contract, + address: impl, + }); + + console.log(`${znsNames.zPortal.contract} deployed at: + proxy: ${proxyAddress} + implementation: ${impl}`); + } + + return zChainPortal as unknown as ZNSZChainPortal; +}; + +export const deployEthPortal = async ({ + deployer, + accessController, + zkEvmBridgeAddress, + srcZnsPortalAddress, + registryAddress, + domainTokenAddress, + rootRegistrarAddress, + subRegistrarAddress, + isTenderlyRun, +} : { + deployer : SignerWithAddress; + accessController : ZNSAccessController; + zkEvmBridgeAddress : string; + srcZnsPortalAddress : string; + registryAddress : string; + domainTokenAddress : string; + rootRegistrarAddress : string; + subRegistrarAddress : string; + isTenderlyRun : boolean; +}) => { + const factory = new ZNSEthereumPortal__factory(deployer); + + const ethPortal = await hre.upgrades.deployProxy( + factory, + [ + accessController.target, + zkEvmBridgeAddress, + srcZnsPortalAddress, + registryAddress, + domainTokenAddress, + rootRegistrarAddress, + subRegistrarAddress, + ], + { + kind: "uups", + } + ); + + await ethPortal.waitForDeployment(); + const proxyAddress = await ethPortal.getAddress(); + + await accessController.connect(deployer).grantRole(PORTAL_ROLE, proxyAddress); + + if (isTenderlyRun) { + await hre.tenderly.verify({ + name: erc1967ProxyName, + address: proxyAddress, + }); + + const impl = await getProxyImplAddress(proxyAddress); + + await hre.tenderly.verify({ + name: znsNames.ethPortal.contract, + address: impl, + }); + + console.log(`${znsNames.ethPortal.contract} deployed at: + proxy: ${proxyAddress} + implementation: ${impl}`); + } + + return ethPortal as unknown as ZNSEthereumPortal; +}; + +/** + * We use this script to aid in testing, NOT for anything more + * such as deploying to live testnets or mainnet. Do not use any + * of the code present for tasks other than testing behavior on a + * local hardhat build + */ +export const deployZNS = async ({ + deployer, + governorAddresses, + adminAddresses, + priceConfig = DEFAULT_PRICE_CONFIG, + zeroVaultAddress = deployer.address, + srcChainName = SupportedChains.eth, + srcNetworkId = NETWORK_ID_L1_TEST_DEFAULT, + bridgeTokenAddress = ethers.ZeroAddress, + destNetworkId = NETWORK_ID_L2_TEST_DEFAULT, + destChainName = SupportedChains.z, + destChainId = ZCHAIN_ID_TEST_DEFAULT, + srcZnsPortalAddress = ethers.ZeroAddress, + isTenderlyRun = false, +} : DeployZNSParams) : Promise => { + // We deploy every contract as a UUPS proxy, but ZERO is already + // deployed as a transparent proxy. This means that there is already + // a proxy admin deployed to the network. Because future deployments + // warn when this is the case, we silence the warning from hardhat here + // to not clog the test output. + await hre.upgrades.silenceWarnings(); + + if (!zeroVaultAddress) { + zeroVaultAddress = deployer.address; + } + + const accessController = await deployAccessController({ + deployer, + governorAddresses: [deployer.address, ...governorAddresses], + adminAddresses: [deployer.address, ...adminAddresses], + isTenderlyRun, + }); + + const registry = await deployRegistry( + deployer, + await accessController.getAddress(), + isTenderlyRun + ); + + const domainToken = await deployDomainToken( + deployer, + accessController, + zeroVaultAddress, + DEFAULT_ROYALTY_FRACTION, + 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 zTokenMock = await deployZToken( + deployer, + governorAddresses, + adminAddresses, + isTenderlyRun, + ); + + const addressResolver = await deployAddressResolver( + deployer, + await accessController.getAddress(), + await registry.getAddress(), + isTenderlyRun + ); + + const stringResolver = await deployStringResolver( + deployer, + await accessController.getAddress(), + await registry.getAddress(), + isTenderlyRun + ); + + const curvePricer = await deployCurvePricer({ + deployer, + accessControllerAddress: await accessController.getAddress(), + registryAddress: await registry.getAddress(), + priceConfig, + isTenderlyRun, + }); + + const treasury = await deployTreasury({ + deployer, + accessControllerAddress: await accessController.getAddress(), + registryAddress: await registry.getAddress(), + zTokenMockAddress: await zTokenMock.getAddress(), + zeroVaultAddress, + isTenderlyRun, + }); + + const config : RegistrarConfig = { + treasuryAddress: await treasury.getAddress(), + registryAddress: await registry.getAddress(), + curvePricerAddress: await curvePricer.getAddress(), + domainTokenAddress: await domainToken.getAddress(), + }; + + const rootRegistrar = await deployRootRegistrar( + deployer, + accessController, + config, + srcChainName, + isTenderlyRun + ); + + const fixedPricer = await deployFixedPricer({ + deployer, + acAddress: await accessController.getAddress(), + regAddress: await registry.getAddress(), + isTenderlyRun, + }); + + const subRegistrar = await deploySubRegistrar({ + deployer, + accessController, + registry, + rootRegistrar, + admin: deployer, + isTenderlyRun, + }); + + const chainResolver = await deployChainResolver( + deployer, + await accessController.getAddress(), + await registry.getAddress(), + isTenderlyRun + ); + + const zkEvmBridge = await deployZkEvmBridgeMock( + deployer, + srcNetworkId, + bridgeTokenAddress, + isTenderlyRun + ); + + let zChainPortal; + let ethPortal; + if (srcChainName === SupportedChains.eth) { + zChainPortal = await deployZChainPortal({ + deployer, + destNetworkId, + destChainName, + destChainId, + bridgeAddress: await zkEvmBridge.getAddress(), + contractAddresses: { + accessController: await accessController.getAddress(), + rootRegistrar: await rootRegistrar.getAddress(), + subRegistrar: await subRegistrar.getAddress(), + treasury: await treasury.getAddress(), + registry: await registry.getAddress(), + chainResolver: await chainResolver.getAddress(), + }, + isTenderlyRun, + }); + } else { + ethPortal = await deployEthPortal({ + deployer, + accessController, + zkEvmBridgeAddress: await zkEvmBridge.getAddress(), + srcZnsPortalAddress, + registryAddress: await registry.getAddress(), + domainTokenAddress: await domainToken.getAddress(), + rootRegistrarAddress: await rootRegistrar.getAddress(), + subRegistrarAddress: await subRegistrar.getAddress(), + isTenderlyRun, + }); + } + + const znsContracts : IZNSContractsLocal = { + accessController, + registry, + domainToken, + zToken: zTokenMock, + addressResolver, + stringResolver, + curvePricer, + treasury, + rootRegistrar, + fixedPricer, + subRegistrar, + chainResolver, + zkEvmBridge, + zChainPortal, + ethPortal, + zeroVaultAddress, + }; + + 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 ef3118101..07d362dbe 100644 --- a/test/helpers/errors.ts +++ b/test/helpers/errors.ts @@ -49,6 +49,13 @@ export const NO_BENEFICIARY_ERR = "NoBeneficiarySetForParent"; export const NONEXISTENT_TOKEN_ERC_ERR = "ERC721NonexistentToken"; export const INITIALIZED_ERR = "InvalidInitialization"; +// CrossChain +export const INVALID_CALLER_ERR = "InvalidCaller"; +export const INVALID_ORIGIN_ERR = "InvalidOriginAddress"; +export const DOMAIN_HASH_NO_MATCH_ERR = "DomainHashDoesNotMatchBridged"; +export const MESSAGE_FAILED_ERR = "MessageFailed"; +export const DEST_PORTAL_NOT_SET_ERR = "DestinationPortalNotSetInState"; + // 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 Z token in production"; diff --git a/test/helpers/events.ts b/test/helpers/events.ts index d94501ace..c18bb3c8b 100644 --- a/test/helpers/events.ts +++ b/test/helpers/events.ts @@ -1,8 +1,9 @@ -import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; +/* eslint-disable @typescript-eslint/ban-ts-comment, @typescript-eslint/no-explicit-any */ import { time } from "@nomicfoundation/hardhat-toolbox/network-helpers"; import { TypedContractEvent, TypedEventLog } from "../../typechain/common"; import { IZNSContractsLocal } from "./types"; import { IZNSContracts } from "../../src/deploy/campaign/types"; +import * as hre from "hardhat"; export const getDomainRegisteredEvents = async ({ @@ -34,24 +35,51 @@ export const getDomainRegisteredEvents = async ({ export const getDomainHashFromEvent = async ({ zns, - user, + registrantAddress, + fromBlock, } : { zns : IZNSContractsLocal | IZNSContracts; - user : SignerWithAddress; + registrantAddress : string; + fromBlock ?: number; }) : Promise => { - const latestBlock = await time.latestBlock(); + if (!fromBlock && hre.network.name === "hardhat") { + const latest = await zns.rootRegistrar.runner?.provider?.getBlockNumber(); + fromBlock = latest as number - 50; + } + const filter = zns.rootRegistrar.filters.DomainRegistered( undefined, undefined, undefined, undefined, undefined, - user.address, + registrantAddress, undefined, ); - const events = await zns.rootRegistrar.queryFilter(filter, latestBlock - 2, latestBlock); + const events = await zns.rootRegistrar.queryFilter(filter, fromBlock); const { args: { domainHash } } = events[events.length - 1]; return domainHash; }; + +export const getEvents = async ({ + contract, + eventName, + args, + fromBlock, +} : { + contract : any; + eventName : string; + args ?: any; + fromBlock ?: number; +}) : Promise>> => { + if (!fromBlock && hre.network.name === "hardhat") { + const latest = await contract.runner.provider.getBlockNumber(); + fromBlock = latest - 50; + } + + const filter = contract.filters[eventName](args); + + return contract.queryFilter(filter, fromBlock); +}; diff --git a/test/helpers/register-setup.ts b/test/helpers/register-setup.ts index 879eb676b..1cb983093 100644 --- a/test/helpers/register-setup.ts +++ b/test/helpers/register-setup.ts @@ -3,7 +3,6 @@ import { IDistributionConfig, IFixedPriceConfig, IFullDistributionConfig, IZNSContractsLocal, - } from "./types"; import { ContractTransactionReceipt, ethers } from "ethers"; import { getDomainHashFromEvent } from "./events"; @@ -12,6 +11,8 @@ import { getTokenContract } from "./tokens"; import { ICurvePriceConfig } from "../../src/deploy/missions/types"; import { expect } from "chai"; import { IZNSContracts } from "../../src/deploy/campaign/types"; +import { ZNSRootRegistrarTrunk, ZNSZChainPortal } from "../../typechain"; +import { getConfirmationsNumber } from "./tx"; const { ZeroAddress } = ethers; @@ -33,7 +34,7 @@ export const defaultRootRegistration = async ({ }) : Promise => { const supplyBefore = await zns.domainToken.totalSupply(); - const tx = await zns.rootRegistrar.connect(user).registerRootDomain( + const tx = await (zns.rootRegistrar as ZNSRootRegistrarTrunk).connect(user).registerRootDomain( domainName, domainContent, // Arbitrary address value tokenURI, @@ -41,39 +42,63 @@ export const defaultRootRegistration = async ({ paymentConfigEmpty ); + const receipt = await tx.wait(getConfirmationsNumber()); + const supplyAfter = await zns.domainToken.totalSupply(); expect(supplyAfter).to.equal(supplyBefore + BigInt(1)); - return tx.wait(); + return receipt; }; -export const approveForParent = async ({ +export const approveForDomain = async ({ zns, parentHash, user, + tokenHolder, domainLabel, + isBridging = false, } : { - zns : IZNSContractsLocal; + zns : IZNSContractsLocal | IZNSContracts; parentHash : string; user : SignerWithAddress; + tokenHolder ?: SignerWithAddress; domainLabel : string; + isBridging ?: boolean; }) => { + const { token: tokenAddress } = await zns.treasury.paymentConfigs(parentHash); + + if (tokenAddress === ZeroAddress) { + console.log("No token set for parent domain. Proceeding without approval."); + return; + } + const { pricerContract } = await zns.subRegistrar.distrConfigs(parentHash); let price = BigInt(0); let parentFee = BigInt(0); - if (pricerContract === await zns.curvePricer.getAddress()) { + if (pricerContract === await zns.curvePricer.getAddress() || parentHash === ethers.ZeroHash) { [price, parentFee] = await zns.curvePricer.getPriceAndFee(parentHash, domainLabel, false); } else if (pricerContract === await zns.fixedPricer.getAddress()) { [price, parentFee] = await zns.fixedPricer.getPriceAndFee(parentHash, domainLabel, false); } - const { token: tokenAddress } = await zns.treasury.paymentConfigs(parentHash); const tokenContract = getTokenContract(tokenAddress, user); const protocolFee = await zns.curvePricer.getFeeForPrice(ethers.ZeroHash, price + parentFee); const toApprove = price + parentFee + protocolFee; - return tokenContract.connect(user).approve(await zns.treasury.getAddress(), toApprove); + const confNum = getConfirmationsNumber(); + + const userBal = await tokenContract.balanceOf(user.address); + if (userBal < toApprove) { + const tx = await tokenContract.connect(tokenHolder).transfer(user.address, toApprove); + await tx.wait(confNum); + } + + const spender = isBridging + ? await (zns.zChainPortal as ZNSZChainPortal).getAddress() + : await zns.treasury.getAddress(); + const tx = await tokenContract.connect(user).approve(spender, toApprove); + await tx.wait(confNum); }; /** @@ -92,7 +117,7 @@ export const defaultSubdomainRegistration = async ({ distrConfig, } : { user : SignerWithAddress; - zns : IZNSContractsLocal; + zns : IZNSContractsLocal | IZNSContracts; parentHash : string; subdomainLabel : string; domainContent ?: string; @@ -110,98 +135,143 @@ export const defaultSubdomainRegistration = async ({ paymentConfigEmpty ); + await tx.wait(getConfirmationsNumber()); + const supplyAfter = await zns.domainToken.totalSupply(); expect(supplyAfter).to.equal(supplyBefore + BigInt(1)); +}; + +export const defaultBridgingRegistration = async ({ + zns, + user, + parentHash = ethers.ZeroHash, + domainLabel, + tokenURI = DEFAULT_TOKEN_URI, +} : { + zns : IZNSContractsLocal | IZNSContracts; + user : SignerWithAddress; + parentHash ?: string; + domainLabel : string; + tokenURI ?: string; +}) => { + const tx = await zns.zChainPortal.connect(user).registerAndBridgeDomain( + parentHash, + domainLabel, + tokenURI + ); - return tx.wait(); + await tx.wait(getConfirmationsNumber()); }; export const registrationWithSetup = async ({ zns, user, + tokenHolder, parentHash, domainLabel, domainContent = user.address, tokenURI = DEFAULT_TOKEN_URI, fullConfig = fullDistrConfigEmpty, setConfigs = true, + bridgeDomain = false, } : { - zns : IZNSContractsLocal; + zns : IZNSContractsLocal | IZNSContracts; user : SignerWithAddress; + tokenHolder ?: SignerWithAddress; parentHash ?: string; domainLabel : string; domainContent ?: string; tokenURI ?: string; fullConfig ?: IFullDistributionConfig; setConfigs ?: boolean; + bridgeDomain ?: boolean; }) => { const hasConfig = !!fullConfig; const distrConfig = hasConfig ? fullConfig.distrConfig : distrConfigEmpty; - // register domain - if (!parentHash || parentHash === ethers.ZeroHash) { - await defaultRootRegistration({ - user, - zns, - domainName: domainLabel, - domainContent, - tokenURI, - distrConfig, - }); - } else { - await approveForParent({ - zns, - parentHash, - user, - domainLabel, - }); + parentHash = parentHash || ethers.ZeroHash; - await defaultSubdomainRegistration({ - user, + await approveForDomain({ + zns, + parentHash, + user, + tokenHolder, + domainLabel, + isBridging: bridgeDomain, + }); + + if (bridgeDomain) { + await defaultBridgingRegistration({ zns, + user, parentHash, - subdomainLabel: domainLabel, - domainContent, + domainLabel, tokenURI, - distrConfig, }); + } else { + // register domain + if (parentHash === ethers.ZeroHash) { + await defaultRootRegistration({ + user, + zns, + domainName: domainLabel, + domainContent, + tokenURI, + distrConfig, + }); + } else { + await defaultSubdomainRegistration({ + user, + zns, + parentHash, + subdomainLabel: domainLabel, + domainContent, + tokenURI, + distrConfig, + }); + } } // get hash const domainHash = await getDomainHashFromEvent({ zns, - user, + registrantAddress: user.address, }); if (!hasConfig) return domainHash; + const confNum = getConfirmationsNumber(); + // set up prices if (fullConfig.distrConfig.pricerContract === await zns.fixedPricer.getAddress() && setConfigs) { - await zns.fixedPricer.connect(user).setPriceConfig( + const tx = await zns.fixedPricer.connect(user).setPriceConfig( domainHash, { ...fullConfig.priceConfig as IFixedPriceConfig, isSet: true, }, ); + await tx.wait(confNum); } else if (fullConfig.distrConfig.pricerContract === await zns.curvePricer.getAddress() && setConfigs) { - await zns.curvePricer.connect(user).setPriceConfig( + const tx = await zns.curvePricer.connect(user).setPriceConfig( domainHash, { ...fullConfig.priceConfig as ICurvePriceConfig, isSet: true, }, ); + await tx.wait(confNum); } if (fullConfig.paymentConfig.token !== ZeroAddress && setConfigs) { // set up payment config - await zns.treasury.connect(user).setPaymentConfig( + const tx = await zns.treasury.connect(user).setPaymentConfig( domainHash, fullConfig.paymentConfig, ); + await tx.wait(confNum); } return domainHash; diff --git a/test/helpers/tokens.ts b/test/helpers/tokens.ts index 15b723f1d..af418ca08 100644 --- a/test/helpers/tokens.ts +++ b/test/helpers/tokens.ts @@ -1,11 +1,11 @@ -import { ERC20, IERC20__factory } from "../../typechain"; +import { ZTokenMock, ZTokenMock__factory } from "../../typechain"; import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; export const getTokenContract = ( address : string, signer : SignerWithAddress -) : ERC20 => { - const ierc20 = IERC20__factory.connect(address, signer); - return ierc20.attach(address) as ERC20; +) : ZTokenMock => { + const ierc20 = ZTokenMock__factory.connect(address, signer); + return ierc20.attach(address) as ZTokenMock; }; diff --git a/test/helpers/tx.ts b/test/helpers/tx.ts new file mode 100644 index 000000000..e09e67350 --- /dev/null +++ b/test/helpers/tx.ts @@ -0,0 +1,24 @@ + + +export const getConfirmationsNumber = () : number => { + let curConfNum : string | number | undefined = process.env.CONFIRMATION_N; + + if (!curConfNum) { + const curEnv = process.env.ENV_LEVEL; + + switch (curEnv) { + case "dev": + curConfNum = 0; + break; + case "test": + curConfNum = 2; + break; + default: + throw new Error("Invalid environment. Failure to determine confifmations amount for transaction!"); + } + } else { + curConfNum = Number(curConfNum); + } + + return curConfNum; +}; diff --git a/test/helpers/types.ts b/test/helpers/types.ts index 3a06f6246..5cddaa1a5 100644 --- a/test/helpers/types.ts +++ b/test/helpers/types.ts @@ -1,142 +1,155 @@ -import { - ZNSAccessController, - ZNSAddressResolver, - ZNSAddressResolverUpgradeMock, - ZNSAddressResolverUpgradeMock__factory, - ZNSCurvePricer, - ZNSCurvePricerUpgradeMock, - ZNSCurvePricerUpgradeMock__factory, - ZNSDomainToken, - ZNSDomainTokenUpgradeMock, - ZNSDomainTokenUpgradeMock__factory, - ZNSFixedPricer, - ZNSFixedPricerUpgradeMock, - ZNSFixedPricerUpgradeMock__factory, - ZNSRegistry, - ZNSRegistryUpgradeMock, - ZNSRegistryUpgradeMock__factory, - ZNSRootRegistrar, - ZNSRootRegistrarUpgradeMock, - 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"; - - -export type Maybe = T | undefined; - -export type GeneralContractGetter = Promise< -string -| boolean -| bigint -| Array -| [string, bigint] -& { token : string; amount : bigint; } -| [string, string] -& { token : string; beneficiary : string; } -| ICurvePriceConfig -| IFixedPriceConfig ->; - -export type ZNSContractMockFactory = - ZNSRootRegistrarUpgradeMock__factory | - ZNSSubRegistrarUpgradeMock__factory | - ZNSCurvePricerUpgradeMock__factory | - ZNSFixedPricerUpgradeMock__factory | - ZNSTreasuryUpgradeMock__factory | - ZNSRegistryUpgradeMock__factory | - ZNSAddressResolverUpgradeMock__factory | - ZNSDomainTokenUpgradeMock__factory | - ZNSStringResolverUpgradeMock__factory; - -export type ZNSContractMock = - ZNSRootRegistrarUpgradeMock | - ZNSSubRegistrarUpgradeMock | - ZNSCurvePricerUpgradeMock | - ZNSFixedPricerUpgradeMock | - ZNSTreasuryUpgradeMock | - ZNSRegistryUpgradeMock | - ZNSAddressResolverUpgradeMock | - ZNSDomainTokenUpgradeMock | - ZNSStringResolverUpgradeMock; - -export interface IFixedPriceConfig { - price : bigint; - feePercentage : bigint; -} - -export interface RegistrarConfig { - treasuryAddress : string; - registryAddress : string; - curvePricerAddress : string; - domainTokenAddress : string; -} - -export interface IZNSContractsLocal { - accessController : ZNSAccessController; - registry : ZNSRegistry; - domainToken : ZNSDomainToken; - zToken : ZTokenMock; - addressResolver : ZNSAddressResolver; - curvePricer : ZNSCurvePricer; - treasury : ZNSTreasury; - rootRegistrar : ZNSRootRegistrar; - fixedPricer : ZNSFixedPricer; - subRegistrar : ZNSSubRegistrar; - zeroVaultAddress : string; -} - -export interface DeployZNSParams { - deployer : SignerWithAddress; - governorAddresses : Array; - adminAddresses : Array; - priceConfig ?: ICurvePriceConfig; - registrationFeePerc ?: bigint; - zeroVaultAddress ?: string; - isTenderlyRun ?: boolean; -} - -export interface IDistributionConfig { - pricerContract : string; - paymentType : bigint; - accessType : bigint; -} - -export interface IPaymentConfig { - token : string; - beneficiary : string; -} - -export interface IFullDistributionConfig { - paymentConfig : IPaymentConfig; - distrConfig : IDistributionConfig; - priceConfig : ICurvePriceConfig | IFixedPriceConfig | undefined; -} - -export interface IDomainConfigForTest { - user : SignerWithAddress; - domainLabel : string; - domainContent ?: string; - parentHash ?: string; - fullConfig : IFullDistributionConfig; - tokenURI ?: string; -} - -export interface IPathRegResult { - domainHash : string; - userBalanceBefore : bigint; - userBalanceAfter : bigint; - parentBalanceBefore : bigint; - parentBalanceAfter : bigint; - treasuryBalanceBefore : bigint; - treasuryBalanceAfter : bigint; - zeroVaultBalanceBefore : bigint; - zeroVaultBalanceAfter : bigint; -} +import { + PolygonZkEVMBridgeV2Mock, + ZNSAccessController, + ZNSAddressResolver, + ZNSAddressResolverUpgradeMock, + ZNSAddressResolverUpgradeMock__factory, ZNSChainResolver, + ZNSCurvePricer, + ZNSCurvePricerUpgradeMock, + ZNSCurvePricerUpgradeMock__factory, + ZNSDomainToken, + ZNSDomainTokenUpgradeMock, + ZNSDomainTokenUpgradeMock__factory, ZNSEthereumPortal, + ZNSFixedPricer, + ZNSFixedPricerUpgradeMock, + ZNSFixedPricerUpgradeMock__factory, + ZNSRegistry, + ZNSRegistryUpgradeMock, + ZNSRegistryUpgradeMock__factory, + ZNSRootRegistrarBranch, ZNSRootRegistrarTrunk, + ZNSRootRegistrarUpgradeMock, + ZNSRootRegistrarUpgradeMock__factory, ZNSStringResolver, + ZNSSubRegistrarBranch, ZNSSubRegistrarTrunk, + ZNSSubRegistrarUpgradeMock, + ZNSSubRegistrarUpgradeMock__factory, + ZNSTreasury, + ZNSTreasuryUpgradeMock, + ZNSTreasuryUpgradeMock__factory, ZNSZChainPortal, + ZTokenMock, +} from "../../typechain"; +import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; +import { ICurvePriceConfig } from "../../src/deploy/missions/types"; +import { Addressable } from "ethers"; +import { TSupportedChain } from "../../src/deploy/missions/contracts/cross-chain/portals/types"; + + +export type GeneralContractGetter = Promise< +string +| boolean +| bigint +| Array +| [string, bigint] +& { token : string; amount : bigint; } +| [string, string] +& { token : string; beneficiary : string; } +| ICurvePriceConfig +| IFixedPriceConfig +>; + +export type ZNSContractMockFactory = + ZNSRootRegistrarUpgradeMock__factory | + ZNSSubRegistrarUpgradeMock__factory | + ZNSCurvePricerUpgradeMock__factory | + ZNSFixedPricerUpgradeMock__factory | + ZNSTreasuryUpgradeMock__factory | + ZNSRegistryUpgradeMock__factory | + ZNSAddressResolverUpgradeMock__factory | + ZNSDomainTokenUpgradeMock__factory | + ZNSStringResolverUpgradeMock__factory; + +export type ZNSContractMock = + ZNSRootRegistrarUpgradeMock | + ZNSSubRegistrarUpgradeMock | + ZNSCurvePricerUpgradeMock | + ZNSFixedPricerUpgradeMock | + ZNSTreasuryUpgradeMock | + ZNSRegistryUpgradeMock | + ZNSAddressResolverUpgradeMock | + ZNSDomainTokenUpgradeMock | + ZNSStringResolverUpgradeMock; + +export interface IFixedPriceConfig { + price : bigint; + feePercentage : bigint; +} + +export interface RegistrarConfig { + treasuryAddress : string; + registryAddress : string; + curvePricerAddress : string; + domainTokenAddress : string; +} + +export interface IZNSContractsLocal { + accessController : ZNSAccessController; + registry : ZNSRegistry; + domainToken : ZNSDomainToken; + zToken : ZTokenMock; + addressResolver : ZNSAddressResolver; + stringResolver : ZNSStringResolver; + chainResolver : ZNSChainResolver; + curvePricer : ZNSCurvePricer; + treasury : ZNSTreasury; + rootRegistrar : ZNSRootRegistrarTrunk | ZNSRootRegistrarBranch; + fixedPricer : ZNSFixedPricer; + subRegistrar : ZNSSubRegistrarTrunk | ZNSSubRegistrarBranch; + zChainPortal ?: ZNSZChainPortal; + ethPortal ?: ZNSEthereumPortal; + zkEvmBridge : PolygonZkEVMBridgeV2Mock; + zeroVaultAddress : string; +} + +export interface DeployZNSParams { + deployer : SignerWithAddress; + governorAddresses : Array; + adminAddresses : Array; + priceConfig ?: ICurvePriceConfig; + registrationFeePerc ?: bigint; + zeroVaultAddress ?: string; + srcChainName ?: TSupportedChain; + srcNetworkId ?: bigint; + bridgeTokenAddress ?: string; + destNetworkId ?: bigint; + destChainName ?: TSupportedChain; + destChainId ?: bigint; + srcZnsPortalAddress ?: string; + isTenderlyRun ?: boolean; +} + +export interface IDistributionConfig { + pricerContract : string | Addressable; + paymentType : bigint; + accessType : bigint; +} + +export interface IPaymentConfig { + token : string | Addressable; + beneficiary : string; +} + +export interface IFullDistributionConfig { + paymentConfig : IPaymentConfig; + distrConfig : IDistributionConfig; + priceConfig : ICurvePriceConfig | IFixedPriceConfig | undefined; +} + +export interface IDomainConfigForTest { + user : SignerWithAddress; + domainLabel : string; + domainContent ?: string; + parentHash ?: string; + fullConfig : IFullDistributionConfig; + tokenURI ?: string; +} + +export interface IPathRegResult { + domainHash : string; + userBalanceBefore : bigint; + userBalanceAfter : bigint; + parentBalanceBefore : bigint; + parentBalanceAfter : bigint; + treasuryBalanceBefore : bigint; + treasuryBalanceAfter : bigint; + zeroVaultBalanceBefore : bigint; + zeroVaultBalanceAfter : bigint; +} diff --git a/yarn.lock b/yarn.lock index c2a838d75..f90db8e14 100644 --- a/yarn.lock +++ b/yarn.lock @@ -26,11 +26,11 @@ tslib "^1.11.1" "@aws-sdk/types@^3.1.0": - 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== + version "3.714.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/types/-/types-3.714.0.tgz#de6afee1436d2d95364efa0663887f3bf0b1303a" + integrity sha512-ZjpP2gYbSFlxxaUDa1Il5AVvfggvUPbjzzB/l3q0gIE5Thd6xKW+yzEpt2mLZ5s5UaYSABZbF94g8NUOF4CVGA== dependencies: - "@smithy/types" "^3.4.2" + "@smithy/types" "^3.7.2" tslib "^2.6.2" "@aws-sdk/util-utf8-browser@^3.0.0": @@ -41,35 +41,31 @@ tslib "^2.3.1" "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.21.4": - 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== + version "7.26.2" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.26.2.tgz#4b5fab97d33338eff916235055f0ebc21e573a85" + integrity sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ== dependencies: - "@babel/highlight" "^7.24.7" - picocolors "^1.0.0" - -"@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.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.24.7" - chalk "^2.4.2" + "@babel/helper-validator-identifier" "^7.25.9" js-tokens "^4.0.0" picocolors "^1.0.0" +"@babel/helper-validator-identifier@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz#24b64e2c3ec7cd3b3c547729b8d16871f22cbdc7" + integrity sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ== + "@babel/runtime@^7.4.4": - version "7.25.6" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.25.6.tgz#9afc3289f7184d8d7f98b099884c26317b9264d2" - integrity sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ== + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.26.0.tgz#8600c2f595f277c60815256418b85356a65173c1" + integrity sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw== dependencies: regenerator-runtime "^0.14.0" +"@bytecodealliance/preview2-shim@0.17.0": + version "0.17.0" + resolved "https://registry.yarnpkg.com/@bytecodealliance/preview2-shim/-/preview2-shim-0.17.0.tgz#9bc1cadbb9f86c446c6f579d3431c08a06a6672e" + integrity sha512-JorcEwe4ud0x5BS/Ar2aQWOQoFzjq/7jcnxYXCvSMh0oRm0dQXzOA+hqLDBnOMks1LLBA7dmiLLsEBl09Yd6iQ== + "@colors/colors@1.5.0": version "1.5.0" resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" @@ -139,26 +135,26 @@ resolved "https://registry.yarnpkg.com/@ensdomains/resolver/-/resolver-0.2.4.tgz#c10fe28bf5efbf49bff4666d909aed0265efbc89" integrity sha512-bvaTH34PMCbv6anRa9I/0zjLJgY4EuznbEMgbV77JBCQ9KNC46rzi0avuxpOfu+xDjPEtSFGqVEOr5GlUSGudA== -"@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== +"@es-joy/jsdoccomment@~0.49.0": + version "0.49.0" + resolved "https://registry.yarnpkg.com/@es-joy/jsdoccomment/-/jsdoccomment-0.49.0.tgz#e5ec1eda837c802eca67d3b29e577197f14ba1db" + integrity sha512-xjZTSFgECpb9Ohuk5yMX5RhUEbfeQcuOp8IF60e+wyzWEF0M5xeSgqsfLtvPEX8BIyOX9saZqzuGPmZ8oWc+5Q== dependencies: 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" - resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" - integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== + version "4.4.1" + resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz#d1145bf2c20132d6400495d6df4bf59362fd9d56" + integrity sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA== dependencies: - eslint-visitor-keys "^3.3.0" + eslint-visitor-keys "^3.4.3" "@eslint-community/regexpp@^4.4.0", "@eslint-community/regexpp@^4.6.1": - version "4.11.1" - resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.11.1.tgz#a547badfc719eb3e5f4b556325e542fbe9d7a18f" - integrity sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q== + version "4.12.1" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.12.1.tgz#cfc6cffe39df390a3841cde2abccf92eaa7ae0e0" + integrity sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ== "@eslint/eslintrc@^2.1.4": version "2.1.4" @@ -622,7 +618,7 @@ tweetnacl "^1.0.3" tweetnacl-util "^0.15.1" -"@mongodb-js/saslprep@^1.1.5": +"@mongodb-js/saslprep@^1.1.9": version "1.1.9" resolved "https://registry.yarnpkg.com/@mongodb-js/saslprep/-/saslprep-1.1.9.tgz#e974bab8eca9faa88677d4ea4da8d09a52069004" integrity sha512-tVkljjeEaAhCqTzajSdgbQ6gE6f3oneVwa3iXR6csiEwXXOFsiC6Uh9iAjAhXPtqa/XMDHWjjeNH/77m/Yq2dw== @@ -659,9 +655,9 @@ 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== + version "1.6.1" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.6.1.tgz#df6e5943edcea504bac61395926d6fd67869a0d5" + integrity sha512-pq5D8h10hHBjyqX+cfBm0i8JUXJ0UhczFc4r74zbuT9XgewFo2E3J1cOaGtdZynILNmQ685YWGzGE1Zv6io50w== "@noble/secp256k1@1.7.1", "@noble/secp256k1@~1.7.0": version "1.7.1" @@ -689,53 +685,53 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@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/edr-darwin-arm64@0.6.5": + version "0.6.5" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.6.5.tgz#37a31565d7ef42bed9028ac44aed82144de30bd1" + integrity sha512-A9zCCbbNxBpLgjS1kEJSpqxIvGGAX4cYbpDYCU2f3jVqOwaZ/NU761y1SvuCRVpOwhoCXqByN9b7HPpHi0L4hw== -"@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/edr-darwin-x64@0.6.5": + version "0.6.5" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-darwin-x64/-/edr-darwin-x64-0.6.5.tgz#3252f6e86397af460b7a480bfe1b889464d75b89" + integrity sha512-x3zBY/v3R0modR5CzlL6qMfFMdgwd6oHrWpTkuuXnPFOX8SU31qq87/230f4szM+ukGK8Hi+mNq7Ro2VF4Fj+w== -"@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/edr-linux-arm64-gnu@0.6.5": + version "0.6.5" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-arm64-gnu/-/edr-linux-arm64-gnu-0.6.5.tgz#e7dc2934920b6cfabeb5ee7a5e26c8fb0d4964ac" + integrity sha512-HGpB8f1h8ogqPHTyUpyPRKZxUk2lu061g97dOQ/W4CxevI0s/qiw5DB3U3smLvSnBHKOzYS1jkxlMeGN01ky7A== -"@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/edr-linux-arm64-musl@0.6.5": + version "0.6.5" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-arm64-musl/-/edr-linux-arm64-musl-0.6.5.tgz#00459cd53e9fb7bd5b7e32128b508a6e89079d89" + integrity sha512-ESvJM5Y9XC03fZg9KaQg3Hl+mbx7dsSkTIAndoJS7X2SyakpL9KZpOSYrDk135o8s9P9lYJdPOyiq+Sh+XoCbQ== -"@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/edr-linux-x64-gnu@0.6.5": + version "0.6.5" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-x64-gnu/-/edr-linux-x64-gnu-0.6.5.tgz#5c9e4e2655caba48e0196977cba395bbde6fe97d" + integrity sha512-HCM1usyAR1Ew6RYf5AkMYGvHBy64cPA5NMbaeY72r0mpKaH3txiMyydcHibByOGdQ8iFLWpyUdpl1egotw+Tgg== -"@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/edr-linux-x64-musl@0.6.5": + version "0.6.5" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-x64-musl/-/edr-linux-x64-musl-0.6.5.tgz#9c220751b66452dc43a365f380e1e236a0a8c5a9" + integrity sha512-nB2uFRyczhAvWUH7NjCsIO6rHnQrof3xcCe6Mpmnzfl2PYcGyxN7iO4ZMmRcQS7R1Y670VH6+8ZBiRn8k43m7A== -"@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/edr-win32-x64-msvc@0.6.5": + version "0.6.5" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-win32-x64-msvc/-/edr-win32-x64-msvc-0.6.5.tgz#90d3ac2a6a8a687522bda5ff2e92dd97e68126ea" + integrity sha512-B9QD/4DSSCFtWicO8A3BrsnitO1FPv7axB62wq5Q+qeJ50yJlTmyeGY3cw62gWItdvy2mh3fRM6L1LpnHiB77A== -"@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== +"@nomicfoundation/edr@^0.6.5": + version "0.6.5" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr/-/edr-0.6.5.tgz#b3b1ebcdd0148cfe67cca128e7ebe8092e200359" + integrity sha512-tAqMslLP+/2b2sZP4qe9AuGxG3OkQ5gGgHE4isUuq6dUVjwCRPFhAOhpdFl+OjY5P3yEv3hmq9HjUGRa2VNjng== 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/edr-darwin-arm64" "0.6.5" + "@nomicfoundation/edr-darwin-x64" "0.6.5" + "@nomicfoundation/edr-linux-arm64-gnu" "0.6.5" + "@nomicfoundation/edr-linux-arm64-musl" "0.6.5" + "@nomicfoundation/edr-linux-x64-gnu" "0.6.5" + "@nomicfoundation/edr-linux-x64-musl" "0.6.5" + "@nomicfoundation/edr-win32-x64-msvc" "0.6.5" "@nomicfoundation/ethereumjs-common@4.0.4": version "4.0.4" @@ -786,12 +782,12 @@ lodash.isequal "^4.5.0" "@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== + version "0.15.9" + resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-ignition/-/hardhat-ignition-0.15.9.tgz#7f66ad928308f391e3ba8241655f835c7bb3546c" + integrity sha512-lSWqhaDOBt6gsqMadkRLvH6HdoFV1v8/bx7z+12cghaOloVwwn48CPoTH2iXXnkqilPGw8rdH5eVTE6UM+2v6Q== dependencies: - "@nomicfoundation/ignition-core" "^0.15.6" - "@nomicfoundation/ignition-ui" "^0.15.6" + "@nomicfoundation/ignition-core" "^0.15.9" + "@nomicfoundation/ignition-ui" "^0.15.9" chalk "^4.0.0" debug "^4.3.2" fs-extra "^10.0.0" @@ -811,24 +807,24 @@ integrity sha512-jhcWHp0aHaL0aDYj8IJl80v4SZXWMS1A2XxXa1CA6pBiFfJKuZinCkO6wb+POAt0LIfXB3gA3AgdcOccrcwBwA== "@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== + version "2.0.12" + resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-verify/-/hardhat-verify-2.0.12.tgz#480819a245a2db0b127e473c62079f7b4f16daa8" + integrity sha512-Lg3Nu7DCXASQRVI/YysjuAX2z8jwOCbS0w5tz2HalWGSTZThqA0v9N0v0psHbKNqzPJa8bNOeapIVSziyJTnAg== dependencies: "@ethersproject/abi" "^5.1.2" "@ethersproject/address" "^5.0.2" cbor "^8.1.0" - chalk "^2.4.2" debug "^4.1.1" lodash.clonedeep "^4.5.0" + picocolors "^1.1.0" semver "^6.3.0" table "^6.8.0" undici "^5.14.0" -"@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== +"@nomicfoundation/ignition-core@^0.15.9": + version "0.15.9" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ignition-core/-/ignition-core-0.15.9.tgz#5c9401ad93e0c15f633afaf9b3d055b57a881604" + integrity sha512-X8W+7UP/UQPorpHUnGvA1OdsEr/edGi8tDpNwEqzaLm83FMZVbRWdOsr3vNICHN2XMzNY/xIm18Cx7xGKL2PQw== dependencies: "@ethersproject/address" "5.6.1" "@nomicfoundation/solidity-analyzer" "^0.1.1" @@ -840,70 +836,17 @@ 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/ignition-ui@^0.15.9": + version "0.15.9" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ignition-ui/-/ignition-ui-0.15.9.tgz#ba94174f44e5c0de01d9968633fdf925a9585768" + integrity sha512-8lzbT7gpJ5PoowPQDQilkwdyqBviUKDMoHp/5rhgnwG1bDslnCS+Lxuo6s9R2akWu9LtEL14dNyqQb6WsURTag== -"@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/slang@^0.18.3": + version "0.18.3" + resolved "https://registry.yarnpkg.com/@nomicfoundation/slang/-/slang-0.18.3.tgz#976b6c3820081cebf050afbea434038aac9313cc" + integrity sha512-YqAWgckqbHM0/CZxi9Nlf4hjk9wUNLC9ngWCWBiqMxPIZmzsVKYuChdlrfeBPQyvQQBoOhbx+7C1005kLVQDZQ== + dependencies: + "@bytecodealliance/preview2-shim" "0.17.0" "@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.2": version "0.1.2" @@ -1195,12 +1138,12 @@ "@octokit/types" "^12.6.0" "@octokit/plugin-retry@^6.0.0": - version "6.0.1" - resolved "https://registry.yarnpkg.com/@octokit/plugin-retry/-/plugin-retry-6.0.1.tgz#3257404f7cc418e1c1f13a7f2012c1db848b7693" - integrity sha512-SKs+Tz9oj0g4p28qkZwl/topGcb0k0qPNX/i7vBKmDsjoeqnVfFUquqrE/O9oJY7+oLzdCtkiWSXLpLjvl6uog== + version "6.1.0" + resolved "https://registry.yarnpkg.com/@octokit/plugin-retry/-/plugin-retry-6.1.0.tgz#cf5b92223246327ca9c7e17262b93ffde028ab0a" + integrity sha512-WrO3bvq4E1Xh1r2mT9w6SDFg01gFmP81nIG77+p/MqW1JeXXgL++6umim3t6x0Zj5pZm3rXAN+0HEjmmdhIRig== dependencies: "@octokit/request-error" "^5.0.0" - "@octokit/types" "^12.0.0" + "@octokit/types" "^13.0.0" bottleneck "^2.15.3" "@octokit/plugin-throttling@^8.0.0": @@ -1230,7 +1173,7 @@ "@octokit/types" "^13.1.0" universal-user-agent "^6.0.0" -"@octokit/types@^12.0.0", "@octokit/types@^12.2.0", "@octokit/types@^12.6.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== @@ -1238,9 +1181,9 @@ "@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== + version "13.6.2" + resolved "https://registry.yarnpkg.com/@octokit/types/-/types-13.6.2.tgz#e10fc4d2bdd65d836d1ced223b03ad4cfdb525bd" + integrity sha512-WpbZfZUcZU77DrSW4wbsSgTPfKcp286q3ItaIgvSbBpZJlu6mnYXAkjZz6LVZPXkEvLIM8McanyZejKTYUHipA== dependencies: "@octokit/openapi-types" "^22.2.0" @@ -1255,114 +1198,141 @@ integrity sha512-T5tO/KD++m+Ph74ppPPmNuhyrvNcsMDgQWt+pGshNJMsTf9UvmhBNyyOqVAL91UeuqDI0FHAbBV1+NnMg7ffFA== "@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== + version "5.1.0" + resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-5.1.0.tgz#4d37648b7402929c53e2ff6e45749ecff91eb2b6" + integrity sha512-AIElwP5Ck+cslNE+Hkemf5SxjJoF4wBvvjxc27Rp+9jaPs/CLIaUBMYe1FNzhdiN0cYuwGRmYaRHmmntuiju4Q== "@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== + version "5.1.0" + resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-5.1.0.tgz#4e61162f2a2bf414c4e10c45eca98ce5f1aadbd4" + integrity sha512-p1ULhl7BXzjjbha5aqst+QMLY+4/LCWADXOCsmLHRM77AqiPjnd9vvUN9sosUfhL9JGKpZ0TjEGxgvnizmWGSA== -"@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== +"@openzeppelin/defender-sdk-account-client@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@openzeppelin/defender-sdk-account-client/-/defender-sdk-account-client-1.15.2.tgz#be7d250acf0f86ce8f74309ddbb2ddfe0297e19c" + integrity sha512-lhYf1rBtac1MBbKP/ALgkjUhVulqo45RtaemTP9xI6BwUCCb4nq2SSKM82UN5sOE2I+VXSbPXf8w91bao5Mmmg== dependencies: - "@openzeppelin/defender-sdk-base-client" "^1.14.4" + "@openzeppelin/defender-sdk-base-client" "^1.15.2" axios "^1.7.2" lodash "^4.17.21" -"@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== +"@openzeppelin/defender-sdk-action-client@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@openzeppelin/defender-sdk-action-client/-/defender-sdk-action-client-1.15.2.tgz#026e1257e98f8abd8d7b31f9a296e7beaee433f1" + integrity sha512-PpVFKaDU9jBNIoJWfwIA5/9I+qse/4rzEY3CqPvH1z7qGsUjKmImTcQA6SpEzbbvLFOjBY/cuHz6vaf/Vdttcg== dependencies: - "@openzeppelin/defender-sdk-base-client" "^1.14.4" + "@openzeppelin/defender-sdk-base-client" "^1.15.2" 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.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== +"@openzeppelin/defender-sdk-address-book-client@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@openzeppelin/defender-sdk-address-book-client/-/defender-sdk-address-book-client-1.15.2.tgz#eae24b9f948e736ffe4161bbd6778d199596cf66" + integrity sha512-t6T3DA1BOMhttQ+EOLM9a+M4ls3XSdJlDV1+LfY0G70gLKcMSuNHJpNE83GuRW8P6k5544CaEYy6bgPy0m5myw== + dependencies: + "@openzeppelin/defender-sdk-base-client" "^1.15.2" + dotenv "^16.3.1" + lodash "^4.17.21" + +"@openzeppelin/defender-sdk-approval-process-client@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@openzeppelin/defender-sdk-approval-process-client/-/defender-sdk-approval-process-client-1.15.2.tgz#e719d994dc0646df8620714b78688454338cf936" + integrity sha512-8XuNlHFJuANwkOMKBOsvPHgihdsQj8SXoPsBToMXlGJTu/joQ4LaNd78+0f2QegqVTbRiEoaW6gu0o24zi/6kg== + dependencies: + "@openzeppelin/defender-sdk-base-client" "^1.15.2" + axios "^1.6.7" + lodash "^4.17.21" + +"@openzeppelin/defender-sdk-base-client@^1.14.4", "@openzeppelin/defender-sdk-base-client@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@openzeppelin/defender-sdk-base-client/-/defender-sdk-base-client-1.15.2.tgz#aae7ec001365968b81ccce087f39a6eb52fa13f9" + integrity sha512-N3ZTeH8TXyklL7yNPMLUv0dxQwT78DTkOEDhzMS2/QE2FxbXrclSseoeeXxl6UYI61RBtZKn+okbSsbwiB5QWQ== dependencies: amazon-cognito-identity-js "^6.3.6" async-retry "^1.3.3" -"@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== +"@openzeppelin/defender-sdk-deploy-client@^1.14.4", "@openzeppelin/defender-sdk-deploy-client@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@openzeppelin/defender-sdk-deploy-client/-/defender-sdk-deploy-client-1.15.2.tgz#3b1d953aa66b6cdee13e7e672a488af2e2acf974" + integrity sha512-zspzMqh+OC8arXAkgBqTUDVO+NfCkt54UrsmQHbA3UAjr5TiDXKycBKU5ORb01hE+2gAmoPwEpDW9uS2VLg33A== dependencies: - "@openzeppelin/defender-sdk-base-client" "^1.14.4" + "@openzeppelin/defender-sdk-base-client" "^1.15.2" axios "^1.7.2" lodash "^4.17.21" -"@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== +"@openzeppelin/defender-sdk-key-value-store-client@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@openzeppelin/defender-sdk-key-value-store-client/-/defender-sdk-key-value-store-client-1.15.2.tgz#36a24be4f16da56ddd00d1ab4d5b655b2f0945b9" + integrity sha512-b98uKFr8psdSh7UPjLqij5B6OpnYQuQIqCzXWf6RNVIJHlrdlhme2eClcZUVxN2L0AjcpELISRTq24t/sCyd8Q== dependencies: - "@openzeppelin/defender-sdk-base-client" "^1.14.4" + "@openzeppelin/defender-sdk-base-client" "^1.15.2" axios "^1.7.2" fs-extra "^11.2.0" lodash "^4.17.21" -"@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== +"@openzeppelin/defender-sdk-monitor-client@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@openzeppelin/defender-sdk-monitor-client/-/defender-sdk-monitor-client-1.15.2.tgz#c8e741737e6f4080da9922550c3c879a9a060f4e" + integrity sha512-SW+je3RvfAbS43gFtyPcPfloFiAj0VJJZpXsYpolA28j94pEBz5EdYczfNwq/QqyK5adAvASdHobCU9ywVlokw== dependencies: - "@openzeppelin/defender-sdk-base-client" "^1.14.4" + "@openzeppelin/defender-sdk-base-client" "^1.15.2" axios "^1.7.2" ethers "^6.9.0" lodash "^4.17.21" -"@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== +"@openzeppelin/defender-sdk-network-client@^1.14.4", "@openzeppelin/defender-sdk-network-client@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@openzeppelin/defender-sdk-network-client/-/defender-sdk-network-client-1.15.2.tgz#7178836d9861272ad509d93dea8739a5c4bf86c1" + integrity sha512-9r9pegc1aR7xzP9fmj1zvkk0OXMRJE10JabxxiJzAQQgmNXDeTGI6W5bFgrNJfxzcImNGqddJ3K4weKdLyL21A== dependencies: - "@openzeppelin/defender-sdk-base-client" "^1.14.4" + "@openzeppelin/defender-sdk-base-client" "^1.15.2" axios "^1.7.2" lodash "^4.17.21" -"@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== +"@openzeppelin/defender-sdk-notification-channel-client@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@openzeppelin/defender-sdk-notification-channel-client/-/defender-sdk-notification-channel-client-1.15.2.tgz#8539b5f0ed3a6a3b931afb777e7ef41ca5e09027" + integrity sha512-42c9rpQdFS9vQgwOetrsnMbnLPeQnD680Ex6jSvOK497NI7RNP8eFI4vHgzNBhCQYdlMj+oEY7gIhD7Vs0kUow== dependencies: - "@openzeppelin/defender-sdk-base-client" "^1.14.4" + "@openzeppelin/defender-sdk-base-client" "^1.15.2" 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== +"@openzeppelin/defender-sdk-proposal-client@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@openzeppelin/defender-sdk-proposal-client/-/defender-sdk-proposal-client-1.15.2.tgz#52ae0cfd6ff323d79a98de6ac4ad195d1dd56df9" + integrity sha512-Ib2pHGbgtEEnLagWIzW1eesbzGqIc0QKyHVyM1aIqcCJpvKZU9TKCgT7FMqo8m/g2HdJNY74qW3964j9/6ehbw== dependencies: - "@openzeppelin/defender-sdk-base-client" "^1.14.4" + "@openzeppelin/defender-sdk-base-client" "^1.15.2" axios "^1.7.2" ethers "^6.9.0" lodash "^4.17.21" -"@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== +"@openzeppelin/defender-sdk-relay-client@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@openzeppelin/defender-sdk-relay-client/-/defender-sdk-relay-client-1.15.2.tgz#ede03f9680624dfc82187ab03021bd5135450f05" + integrity sha512-QqqprIcVcSS/xlos1gRtW2RIh5AtsOzY9vGnJ2jo5YcutUQrfUCICBigkn+BbeSHesleUxk/zGJInPKol9ir0g== dependencies: - "@openzeppelin/defender-sdk-base-client" "^1.14.4" + "@openzeppelin/defender-sdk-base-client" "^1.15.2" + axios "^1.7.2" + lodash "^4.17.21" + +"@openzeppelin/defender-sdk-relay-group-client@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@openzeppelin/defender-sdk-relay-group-client/-/defender-sdk-relay-group-client-1.15.2.tgz#e12bbcff5cbd21c011b9699aa3f8c5ba84b3ddd4" + integrity sha512-lVip1lrk7F42a3Em6B6FRY8GH05oAUJX5vYFI0m6Ucr5pKEmz221Q1J8GL7NJU5S7THdOpXqEvGzJRmHeYOPwg== + dependencies: + "@openzeppelin/defender-sdk-base-client" "^1.15.2" axios "^1.7.2" lodash "^4.17.21" -"@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== +"@openzeppelin/defender-sdk-relay-signer-client@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@openzeppelin/defender-sdk-relay-signer-client/-/defender-sdk-relay-signer-client-1.15.2.tgz#6b195d7db8b94dbc894b3cb620dae412c4b6a35b" + integrity sha512-AqQOAkqOdpO7J+n1hzUWHVRvsb93t8Nb3wQEXJN+/UMcWfoKTOLSYOvjOMQ4PbEUmM8aI+YcQxJL5VfJlIXngQ== dependencies: "@ethersproject/bignumber" "^5.7.0" "@ethersproject/bytes" "^5.7.0" @@ -1371,50 +1341,53 @@ "@ethersproject/properties" "^5.7.0" "@ethersproject/providers" "^5.7.2" "@ethersproject/strings" "^5.7.0" - "@openzeppelin/defender-sdk-base-client" "^1.14.4" + "@openzeppelin/defender-sdk-base-client" "^1.15.2" amazon-cognito-identity-js "^6.3.6" axios "^1.7.2" ethers "^6.9.0" lodash "^4.17.21" "@openzeppelin/defender-sdk@^1.7.0": - 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" + version "1.15.2" + resolved "https://registry.yarnpkg.com/@openzeppelin/defender-sdk/-/defender-sdk-1.15.2.tgz#8ce5d4e27a3cbf1371490f4319d4c19bae178bb0" + integrity sha512-Pt7MR+kzhsBfEQvW/cAOgLGb498x3Oq91G15GQ+g+cl978IpQgqx8rneZPv3aoQE5ipIk6EtWJlOl+tIAARKVg== + dependencies: + "@openzeppelin/defender-sdk-account-client" "^1.15.2" + "@openzeppelin/defender-sdk-action-client" "^1.15.2" + "@openzeppelin/defender-sdk-address-book-client" "^1.15.2" + "@openzeppelin/defender-sdk-approval-process-client" "^1.15.2" + "@openzeppelin/defender-sdk-base-client" "^1.15.2" + "@openzeppelin/defender-sdk-deploy-client" "^1.15.2" + "@openzeppelin/defender-sdk-key-value-store-client" "^1.15.2" + "@openzeppelin/defender-sdk-monitor-client" "^1.15.2" + "@openzeppelin/defender-sdk-network-client" "^1.15.2" + "@openzeppelin/defender-sdk-notification-channel-client" "^1.15.2" + "@openzeppelin/defender-sdk-proposal-client" "^1.15.2" + "@openzeppelin/defender-sdk-relay-client" "^1.15.2" + "@openzeppelin/defender-sdk-relay-group-client" "^1.15.2" + "@openzeppelin/defender-sdk-relay-signer-client" "^1.15.2" "@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== + version "3.7.0" + resolved "https://registry.yarnpkg.com/@openzeppelin/hardhat-upgrades/-/hardhat-upgrades-3.7.0.tgz#fc9562ab01edfa1eafb49870d8bf37e038a3ce49" + integrity sha512-dTnqqTIZUOyEzL62FIusZPeac9CqTD+x3Q5h+46JBALgS9DubUq/jXMhiE3JKLco3RELZQCh/9GYKBoUA0R2DQ== 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" + "@openzeppelin/upgrades-core" "^1.41.0" chalk "^4.1.0" debug "^4.1.1" ethereumjs-util "^7.1.5" proper-lockfile "^4.1.1" undici "^6.11.1" -"@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== +"@openzeppelin/upgrades-core@^1.32.2", "@openzeppelin/upgrades-core@^1.41.0": + version "1.41.0" + resolved "https://registry.yarnpkg.com/@openzeppelin/upgrades-core/-/upgrades-core-1.41.0.tgz#3a5e044cf53acd50c392f3297e7c37e4ff8f8355" + integrity sha512-+oryinqZnxkiZvg7bWqWX4Ki/CNwVUZEqC6Elpi5PQoahpL3/6Sq9xjIozD5AiI2O61h8JHQ+A//5NtczyavJw== dependencies: - "@nomicfoundation/slang" "^0.17.0" + "@nomicfoundation/slang" "^0.18.3" cbor "^9.0.0" chalk "^4.1.0" compare-versions "^6.0.0" @@ -1701,10 +1674,10 @@ resolved "https://registry.yarnpkg.com/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz#719df7fb41766bc143369eaa0dd56d8dc87c9958" integrity sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg== -"@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== +"@smithy/types@^3.7.2": + version "3.7.2" + resolved "https://registry.yarnpkg.com/@smithy/types/-/types-3.7.2.tgz#05cb14840ada6f966de1bf9a9c7dd86027343e10" + integrity sha512-bNwBYYmN8Eh9RyjS1p2gW6MIhSO2rl7X9QeLM8iTdcGRP+eDiIWDt66c9IysCc22gefKszZv+ubV9qZc7hdESg== dependencies: tslib "^2.6.2" @@ -1720,6 +1693,11 @@ resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.18.0.tgz#8e77a02a09ecce957255a2f48c9a7178ec191908" integrity sha512-yfORGUIPgLck41qyN7nbwJRAx17/jAIXCTanHOJZhB6PJ1iAk/84b/xlsVKFSyNyLXIj0dhppoE0+CRws7wlzA== +"@solidity-parser/parser@^0.19.0": + version "0.19.0" + resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.19.0.tgz#37a8983b2725af9b14ff8c4a475fa0e98d773c3f" + integrity sha512-RV16k/qIxW/wWc+mLzV3ARyKUaMUTBy9tOLMzFhtNSKYeTAanQ3a5MudJKf/8arIFnA2L27SNjarQKmFg0w/jA== + "@szmarczak/http-timer@^5.0.1": version "5.0.1" resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-5.0.1.tgz#c7c1bf1141cdd4751b0399c8fc7b8b664cd5be3a" @@ -1727,10 +1705,10 @@ dependencies: defer-to-connect "^2.0.1" -"@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== +"@tenderly/api-client@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@tenderly/api-client/-/api-client-1.1.0.tgz#fa06adf17ecc1ef83c5fb8536b71b542e7023228" + integrity sha512-kyye7TQ+RbDbJ7bSUjNf/O9fTtRYNUDIEUZQSrmNonowMw5/EpNi664eWaOoC00NEzxgttVrtme/GHvIOu7rNg== dependencies: axios "^0.27.2" cli-table3 "^0.6.2" @@ -1741,12 +1719,12 @@ 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== +"@tenderly/hardhat-integration@^1.1.0": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@tenderly/hardhat-integration/-/hardhat-integration-1.1.1.tgz#6921c3f524d344efdd9b5f18c0500e9ac7ddcd27" + integrity sha512-VHa380DrKv+KA1N4vbJGLDoghbVqMZ4wEozbxRfCzlkSs5V1keNgudRSUFK6lgfKhkoAWRO+dA8MZYnJOvUOkA== dependencies: - "@tenderly/api-client" "^1.0.0" + "@tenderly/api-client" "^1.1.0" axios "^1.6.7" dotenv "^16.4.5" fs-extra "^10.1.0" @@ -1758,9 +1736,9 @@ 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== + version "2.5.1" + resolved "https://registry.yarnpkg.com/@tenderly/hardhat-tenderly/-/hardhat-tenderly-2.5.1.tgz#b15544a2690d71e4a76e008f820e9afa921834d2" + integrity sha512-RdDl4gY5W2ZYistPkIIdHZRe3vHqs6JOgqQjqmI2OaE9y5FRlPeVUHRLAqoroVU+PkQhFPrgjBv5er/pJSonLA== dependencies: "@ethersproject/bignumber" "^5.7.0" "@nomicfoundation/hardhat-ethers" "^3.0.0" @@ -1768,7 +1746,7 @@ "@nomicfoundation/hardhat-verify" "^2.0.8" "@openzeppelin/hardhat-upgrades" "^3.3.0" "@openzeppelin/upgrades-core" "^1.32.2" - "@tenderly/hardhat-integration" "^1.0.0" + "@tenderly/hardhat-integration" "^1.1.0" dotenv "^16.4.5" ethers "^6.8.1" @@ -1847,9 +1825,11 @@ "@types/chai" "*" "@types/chai@*": - version "5.0.0" - resolved "https://registry.yarnpkg.com/@types/chai/-/chai-5.0.0.tgz#7f981e71e69c9b2d422f58f78de1c59179782133" - integrity sha512-+DwhEHAaFPPdJ2ral3kNHFQXnTfscEEFsUxzD+d7nlcLrFK23JtNjH71RGasTcHb88b4vVi4mTyfpf8u2L8bdA== + version "5.0.1" + resolved "https://registry.yarnpkg.com/@types/chai/-/chai-5.0.1.tgz#2c3705555cf11f5f59c836a84c44afcfe4e5689d" + integrity sha512-5T8ajsg3M/FOncpLYW7sdOcD6yf4+722sze/tc4KQV0P8Z2rAr3SAuHCIkYmYpt8VbcQlnz8SxlOlPQYefe4cA== + dependencies: + "@types/deep-eql" "*" "@types/chai@^4.3.11": version "4.3.20" @@ -1863,6 +1843,11 @@ dependencies: "@types/node" "*" +"@types/deep-eql@*": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@types/deep-eql/-/deep-eql-4.0.2.tgz#334311971d3a07121e7eb91b684a605e7eea9cbd" + integrity sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw== + "@types/form-data@0.0.33": version "0.0.33" resolved "https://registry.yarnpkg.com/@types/form-data/-/form-data-0.0.33.tgz#c9ac85b2a5fd18435b8c85d9ecb50e6d6c893ff8" @@ -1914,16 +1899,18 @@ integrity sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw== "@types/node@*": - version "22.7.3" - resolved "https://registry.yarnpkg.com/@types/node/-/node-22.7.3.tgz#7ddf1ddf13078692b4cfadb835852b2a718ee1ef" - integrity sha512-qXKfhXXqGTyBskvWEzJZPUxSslAiLaB6JGP1ic/XTH9ctGgzdgYguuLP1C601aRTSDNlLb0jbKqXjZ48GNraSA== + version "22.10.2" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.10.2.tgz#a485426e6d1fdafc7b0d4c7b24e2c78182ddabb9" + integrity sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ== dependencies: - undici-types "~6.19.2" + undici-types "~6.20.0" -"@types/node@18.15.13": - version "18.15.13" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" - integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== +"@types/node@22.7.5": + version "22.7.5" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.7.5.tgz#cfde981727a7ab3611a481510b473ae54442b92b" + integrity sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ== + dependencies: + undici-types "~6.19.2" "@types/node@^10.0.3": version "10.17.60" @@ -1931,9 +1918,9 @@ integrity sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw== "@types/node@^18.15.11": - version "18.19.53" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.19.53.tgz#1e2f83eeede6031f03bc4780826b8b02b42ac50d" - integrity sha512-GLxgUgHhDKO1Edw9Q0lvMbiO/IQXJwJlMaqxSGBXMpPy8uhkCs2iiPFaB2Q/gmobnFkckD3rqTBMVjXdwq+nKg== + version "18.19.68" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.19.68.tgz#f4f10d9927a7eaf3568c46a6d739cc0967ccb701" + integrity sha512-QGtpFH1vB99ZmTa63K4/FU8twThj4fuVSBkGddTp7uIL/cuoLWIUSL2RcOaigBhfR+hg5pgGkBnkoOxrTVBMKw== dependencies: undici-types "~5.26.4" @@ -1960,9 +1947,9 @@ integrity sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA== "@types/qs@^6.2.31", "@types/qs@^6.9.7": - version "6.9.16" - resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.16.tgz#52bba125a07c0482d26747d5d4947a64daf8f794" - integrity sha512-7i+zxXdPD0T4cKDuxCUXJ4wHcsJLwENa6Z3dCu8cfCK743OGy5Nu1RmAGqDPsoTDINVEcdXKRvR/zre+P2Ku1A== + version "6.9.17" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.17.tgz#fc560f60946d0aeff2f914eb41679659d3310e1a" + integrity sha512-rX4/bPcfmvxHDv0XjfJELTTr+iB+tn032nPILqHm5wbthUUUuVtNGGqzhya9XUxjTP8Fpr0qYgSZZKxGY++svQ== "@types/secp256k1@^4.0.1": version "4.0.6" @@ -2078,9 +2065,9 @@ eslint-visitor-keys "^3.3.0" "@ungap/structured-clone@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" - integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== + version "1.2.1" + resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.1.tgz#28fa185f67daaf7b7a1a8c1d445132c5d979f8bd" + integrity sha512-fEzPV3hSkSMltkw152tJKNARhOupqbH96MZWyRjNaYZOMIzbrTeQDG+MTc6Mr2pgzFQzFxAfmhGDNP5QK++2ZA== "@zero-tech/eslint-config-cpt@0.2.8": version "0.2.8" @@ -2111,6 +2098,11 @@ mongodb "^6.3.0" winston "^3.11.0" +"@zero-tech/zkevm-contracts@6.0.0-fork-9": + version "6.0.0-fork-9" + resolved "https://registry.yarnpkg.com/@zero-tech/zkevm-contracts/-/zkevm-contracts-6.0.0-fork-9.tgz#6ef7c889762542562485bf2ba3c6124ea00c0aa2" + integrity sha512-iSBm3wEvzkHAnqJYIWJlvIuBU1rKnnI8+IlqHLvz2r+3Ml228KaSNZi0SG8O1DW/oqNnHnMTDZzKv7NPR9wIrQ== + JSONStream@^1.3.5: version "1.3.5" resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0" @@ -2146,10 +2138,10 @@ acorn-walk@^8.1.1: dependencies: acorn "^8.11.0" -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== +acorn@^8.11.0, acorn@^8.14.0, acorn@^8.4.1, acorn@^8.9.0: + version "8.14.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.14.0.tgz#063e2c70cac5fb4f6467f0b11152e04c682795b0" + integrity sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA== adm-zip@^0.4.16: version "0.4.16" @@ -2173,12 +2165,10 @@ agent-base@6, agent-base@^6.0.2: dependencies: debug "4" -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" +agent-base@^7.1.0, agent-base@^7.1.2: + version "7.1.3" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.3.tgz#29435eb821bc4194633a5b89e5bc4703bafc25a1" + integrity sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw== agentkeepalive@^4.2.1: version "4.5.0" @@ -2433,38 +2423,37 @@ array.prototype.findlastindex@^1.2.5: es-shim-unscopables "^1.0.2" array.prototype.flat@^1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz#1476217df8cff17d72ee8f3ba06738db5b387d18" - integrity sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA== + version "1.3.3" + resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz#534aaf9e6e8dd79fb6b9a9917f839ef1ec63afe5" + integrity sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg== dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - es-shim-unscopables "^1.0.0" + call-bind "^1.0.8" + define-properties "^1.2.1" + es-abstract "^1.23.5" + es-shim-unscopables "^1.0.2" array.prototype.flatmap@^1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz#c9a7c6831db8e719d6ce639190146c24bbd3e527" - integrity sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ== + version "1.3.3" + resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz#712cc792ae70370ae40586264629e33aab5dd38b" + integrity sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg== dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - es-shim-unscopables "^1.0.0" + call-bind "^1.0.8" + define-properties "^1.2.1" + es-abstract "^1.23.5" + es-shim-unscopables "^1.0.2" -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== +arraybuffer.prototype.slice@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz#9d760d84dbdd06d0cbf92c8849615a1a7ab3183c" + integrity sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ== dependencies: array-buffer-byte-length "^1.0.1" - call-bind "^1.0.5" + call-bind "^1.0.8" define-properties "^1.2.1" - es-abstract "^1.22.3" - es-errors "^1.2.1" - get-intrinsic "^1.2.3" + es-abstract "^1.23.5" + es-errors "^1.3.0" + get-intrinsic "^1.2.6" is-array-buffer "^3.0.4" - is-shared-array-buffer "^1.0.2" arrify@^1.0.1: version "1.0.1" @@ -2525,6 +2514,15 @@ available-typed-arrays@^1.0.7: dependencies: possible-typed-array-names "^1.0.0" +axios@1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.4.tgz#4c8ded1b43683c8dd362973c393f3ede24052aa2" + integrity sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw== + dependencies: + follow-redirects "^1.15.6" + form-data "^4.0.0" + proxy-from-env "^1.1.0" + axios@^0.21.1: version "0.21.4" resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575" @@ -2540,10 +2538,10 @@ 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, 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== +axios@^1.5.1, axios@^1.6.5, axios@^1.6.7, axios@^1.7.2: + version "1.7.9" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.9.tgz#d7d071380c132a24accda1b2cfc1535b79ec650a" + integrity sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw== dependencies: follow-redirects "^1.15.6" form-data "^4.0.0" @@ -2612,9 +2610,9 @@ bn.js@4.11.6: integrity sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA== bn.js@^4.11.0, bn.js@^4.11.8, bn.js@^4.11.9: - version "4.12.0" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" - integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== + version "4.12.1" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.1.tgz#215741fe3c9dba2d7e12c001d0cfdbae43975ba7" + integrity sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg== bn.js@^5.1.2, bn.js@^5.2.0, bn.js@^5.2.1: version "5.2.1" @@ -2700,10 +2698,10 @@ bs58check@^2.1.2: create-hash "^1.1.0" safe-buffer "^5.1.2" -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== +bson@^6.10.1: + version "6.10.1" + resolved "https://registry.yarnpkg.com/bson/-/bson-6.10.1.tgz#dcd04703178f5ecf5b25de04edd2a95ec79385d3" + integrity sha512-P92xmHDQjSKPLHqFxefqMxASNq/aWJMEZugpCjf+AF/pgcUpMMQCg7t7+ewko0/u8AapvF3luf/FoehddEK+sA== buffer-from@^1.0.0: version "1.1.2" @@ -2823,16 +2821,31 @@ cacheable-request@^10.2.8: normalize-url "^8.0.0" responselike "^3.0.0" -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== +call-bind-apply-helpers@^1.0.0, call-bind-apply-helpers@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz#32e5892e6361b29b0b545ba6f7763378daca2840" + integrity sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g== dependencies: - es-define-property "^1.0.0" es-errors "^1.3.0" function-bind "^1.1.2" + +call-bind@^1.0.5, call-bind@^1.0.6, call-bind@^1.0.7, call-bind@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.8.tgz#0736a9660f537e3388826f440d5ec45f744eaa4c" + integrity sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww== + dependencies: + call-bind-apply-helpers "^1.0.0" + es-define-property "^1.0.0" get-intrinsic "^1.2.4" - set-function-length "^1.2.1" + set-function-length "^1.2.2" + +call-bound@^1.0.2, call-bound@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/call-bound/-/call-bound-1.0.3.tgz#41cfd032b593e39176a71533ab4f384aa04fd681" + integrity sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA== + dependencies: + call-bind-apply-helpers "^1.0.1" + get-intrinsic "^1.2.6" callsites@^3.0.0: version "3.1.0" @@ -2928,9 +2941,9 @@ chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: supports-color "^7.1.0" chalk@^5.2.0, chalk@^5.3.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.3.0.tgz#67c20a7ebef70e7f3970a01f90fa210cb6860385" - integrity sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w== + version "5.4.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.4.0.tgz#846fdb5d5d939d6fa3d565cd5545697b6f8b6923" + integrity sha512-ZkD35Mx92acjB2yNJgziGqT9oKHEOxjTBTDRpOsRWtdecL/0jM3z5kM/CTzHWvHIen1GvkM85p6TuFfDGfc8/Q== "charenc@>= 0.0.1": version "0.0.2" @@ -2960,9 +2973,9 @@ chokidar@^3.5.2, chokidar@^3.5.3: 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== + version "4.0.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-4.0.3.tgz#7be37a4c03c9aee1ecfe862a4a23b2c70c205d30" + integrity sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA== dependencies: readdirp "^4.0.1" @@ -2977,9 +2990,9 @@ ci-info@^2.0.0: integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== 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== + version "4.1.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-4.1.0.tgz#92319d2fa29d2620180ea5afed31f589bc98cf83" + integrity sha512-HutrvTNsF48wnxkzERIXOe5/mlcfFcbfCmwcg6CJnizbSue78AbDt+1cgl26zwn61WFxhcPykPfZrbqjGmBb4A== cidr-regex@^3.1.1: version "3.1.1" @@ -3000,12 +3013,12 @@ cids@^0.7.1: multihashes "~0.4.15" cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" - integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== + version "1.0.6" + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.6.tgz#8fe672437d01cd6c4561af5334e0cc50ff1955f7" + integrity sha512-3Ek9H3X6pj5TgenXYtNWdaBon1tgYCaebd+XPg0keyjEbEfkD4KkmAxkQ/i1vYvxdcT5nscLBfq9VJRmCBcFSw== dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" + inherits "^2.0.4" + safe-buffer "^5.2.1" class-is@^1.1.0: version "1.1.0" @@ -3368,9 +3381,9 @@ create-require@^1.1.0: integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: - version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + version "7.0.6" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" + integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== dependencies: path-key "^3.1.0" shebang-command "^2.0.0" @@ -3444,9 +3457,9 @@ death@^1.1.0: integrity sha512-vsV6S4KVHvTGxbEcij7hkWRv0It+sGGWVOM67dQde/o5Xjnr+KmLjxWJii2uEObIrt1CcM9w0Yaovx+iOlIL+w== 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== + version "4.4.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.0.tgz#2b3f2aea2ffeb776477460267377dc8710faba8a" + integrity sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA== dependencies: ms "^2.1.3" @@ -3525,7 +3538,7 @@ define-lazy-prop@^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.2.0, define-properties@^1.2.1: +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== @@ -3605,9 +3618,18 @@ dotenv@16.0.3: 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== + version "16.4.7" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.7.tgz#0e20c5b82950140aa99be360a8a5f52335f53c26" + integrity sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ== + +dunder-proto@^1.0.0, dunder-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/dunder-proto/-/dunder-proto-1.0.1.tgz#d7ae667e1dc83482f8b70fd0f6eefc50da30f58a" + integrity sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A== + dependencies: + call-bind-apply-helpers "^1.0.1" + es-errors "^1.3.0" + gopd "^1.2.0" duplexer2@~0.1.0: version "0.1.4" @@ -3634,10 +3656,10 @@ 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== +elliptic@^6.5.2, elliptic@^6.5.7: + version "6.6.1" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.6.1.tgz#3b8ffb02670bf69e382c7f65bf524c97c5405c06" + integrity sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g== dependencies: bn.js "^4.11.9" brorand "^1.1.0" @@ -3707,66 +3729,66 @@ 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, 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== +es-abstract@^1.23.2, es-abstract@^1.23.5, es-abstract@^1.23.6: + version "1.23.6" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.23.6.tgz#55f0e1ce7128995cc04ace0a57d7dca348345108" + integrity sha512-Ifco6n3yj2tMZDWNLyloZrytt9lqqlwvS83P3HtaETR0NUOYnIULGGHpktqYGObGy+8wc1okO25p8TjemhImvA== dependencies: array-buffer-byte-length "^1.0.1" - arraybuffer.prototype.slice "^1.0.3" + arraybuffer.prototype.slice "^1.0.4" available-typed-arrays "^1.0.7" - call-bind "^1.0.7" + call-bind "^1.0.8" + call-bound "^1.0.3" 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-define-property "^1.0.1" 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.4" + es-to-primitive "^1.3.0" + function.prototype.name "^1.1.7" + get-intrinsic "^1.2.6" get-symbol-description "^1.0.2" - globalthis "^1.0.3" - gopd "^1.0.1" + globalthis "^1.0.4" + gopd "^1.2.0" has-property-descriptors "^1.0.2" - has-proto "^1.0.3" - has-symbols "^1.0.3" + has-proto "^1.2.0" + has-symbols "^1.1.0" hasown "^2.0.2" - internal-slot "^1.0.7" + internal-slot "^1.1.0" is-array-buffer "^3.0.4" is-callable "^1.2.7" - is-data-view "^1.0.1" + is-data-view "^1.0.2" is-negative-zero "^2.0.3" - is-regex "^1.1.4" + is-regex "^1.2.1" is-shared-array-buffer "^1.0.3" - is-string "^1.0.7" + is-string "^1.1.1" is-typed-array "^1.1.13" - is-weakref "^1.0.2" - object-inspect "^1.13.1" + is-weakref "^1.1.0" + math-intrinsics "^1.0.0" + object-inspect "^1.13.3" object-keys "^1.1.1" 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" + regexp.prototype.flags "^1.5.3" + safe-array-concat "^1.1.3" + safe-regex-test "^1.1.0" + string.prototype.trim "^1.2.10" + string.prototype.trimend "^1.0.9" 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" + typed-array-byte-offset "^1.0.3" + typed-array-length "^1.0.7" unbox-primitive "^1.0.2" - which-typed-array "^1.1.15" + which-typed-array "^1.1.16" -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.4" +es-define-property@^1.0.0, es-define-property@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.1.tgz#983eb2f9a6724e9303f61addf011c72e09e0b0fa" + integrity sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g== -es-errors@^1.2.1, es-errors@^1.3.0: +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== @@ -3792,21 +3814,21 @@ es-set-tostringtag@^2.0.3: has-tostringtag "^1.0.2" hasown "^2.0.1" -es-shim-unscopables@^1.0.0, es-shim-unscopables@^1.0.2: +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== dependencies: hasown "^2.0.0" -es-to-primitive@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" - integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== +es-to-primitive@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.3.0.tgz#96c89c82cc49fd8794a24835ba3e1ff87f214e18" + integrity sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g== dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" + is-callable "^1.2.7" + is-date-object "^1.0.5" + is-symbol "^1.0.4" escalade@^3.1.1: version "3.2.0" @@ -3868,7 +3890,7 @@ eslint-import-resolver-node@^0.3.9: is-core-module "^2.13.0" resolve "^1.22.4" -eslint-module-utils@^2.9.0: +eslint-module-utils@^2.12.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== @@ -3876,9 +3898,9 @@ eslint-module-utils@^2.9.0: debug "^3.2.7" eslint-plugin-import@^2.27.5: - version "2.30.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.30.0.tgz#21ceea0fc462657195989dd780e50c92fe95f449" - integrity sha512-/mHNE9jINJfiD2EKkg1BKyPyUk4zdnT54YgbOgfjSakWT5oyX/qQLVNTkehyfpcMxZXMy1zyonZ2v7hZTX43Yw== + version "2.31.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz#310ce7e720ca1d9c0bb3f69adfd1c6bdd7d9e0e7" + integrity sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A== dependencies: "@rtsao/scc" "^1.1.0" array-includes "^3.1.8" @@ -3888,7 +3910,7 @@ eslint-plugin-import@^2.27.5: debug "^3.2.7" doctrine "^2.1.0" eslint-import-resolver-node "^0.3.9" - eslint-module-utils "^2.9.0" + eslint-module-utils "^2.12.0" hasown "^2.0.2" is-core-module "^2.15.1" is-glob "^4.0.3" @@ -3897,14 +3919,15 @@ eslint-plugin-import@^2.27.5: object.groupby "^1.0.3" object.values "^1.2.0" semver "^6.3.1" + string.prototype.trimend "^1.0.8" tsconfig-paths "^3.15.0" 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== + version "50.6.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-50.6.1.tgz#791a668fd4b0700a759e9a16a741a6a805f5b95c" + integrity sha512-UWyaYi6iURdSfdVVqvfOs2vdCVz0J40O/z/HTsv2sFjdjmdlUI/qlKLOTmwbPQ2tAfQnE5F9vqx+B+poF71DBQ== dependencies: - "@es-joy/jsdoccomment" "~0.48.0" + "@es-joy/jsdoccomment" "~0.49.0" are-docs-informative "^0.0.2" comment-parser "1.4.1" debug "^4.3.6" @@ -3942,10 +3965,10 @@ 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-visitor-keys@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz#687bacb2af884fcdda8a6e7d65c606f46a14cd45" + integrity sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw== eslint@^8.37.0: version "8.57.1" @@ -3992,13 +4015,13 @@ eslint@^8.37.0: 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== + version "10.3.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-10.3.0.tgz#29267cf5b0cb98735b65e64ba07e0ed49d1eed8a" + integrity sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg== dependencies: - acorn "^8.12.0" + acorn "^8.14.0" acorn-jsx "^5.3.2" - eslint-visitor-keys "^4.0.0" + eslint-visitor-keys "^4.2.0" espree@^9.6.0, espree@^9.6.1: version "9.6.1" @@ -4160,6 +4183,11 @@ 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-decode-error@^2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ethers-decode-error/-/ethers-decode-error-2.1.3.tgz#ed0c81a400e9b66bba8c3ce356a4e52eab878e3f" + integrity sha512-x27u04XC/s8MRpuqiylIXbj4KMrt/5clYS2nle1b0bgbWFuoUZocDzjfXEfc5KzVmCQuITD9elqyO2VyxTGwdw== + 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" @@ -4197,16 +4225,16 @@ ethers@^5.0.13, ethers@^5.7.0, ethers@^5.7.2: "@ethersproject/wordlists" "5.7.0" 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== + version "6.13.4" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-6.13.4.tgz#bd3e1c3dc1e7dc8ce10f9ffb4ee40967a651b53c" + integrity sha512-21YtnZVg4/zKkCQPjrDj38B1r4nQvTZLopUGMLQ1ePU2zV/joCfDC3t3iKQjWRzjjjbzR+mdAIoikeBRNkdllA== dependencies: "@adraffy/ens-normalize" "1.10.1" "@noble/curves" "1.2.0" "@noble/hashes" "1.3.2" - "@types/node" "18.15.13" + "@types/node" "22.7.5" aes-js "4.0.0-beta.5" - tslib "2.4.0" + tslib "2.7.0" ws "8.17.1" ethjs-unit@0.1.6: @@ -4320,9 +4348,9 @@ fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: 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== + version "3.0.3" + resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.0.3.tgz#892a1c91802d5d7860de728f18608a0573142241" + integrity sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw== fastest-levenshtein@^1.0.16: version "1.0.16" @@ -4336,6 +4364,11 @@ fastq@^1.6.0: dependencies: reusify "^1.0.4" +fdir@^6.4.2: + version "6.4.2" + resolved "https://registry.yarnpkg.com/fdir/-/fdir-6.4.2.tgz#ddaa7ce1831b161bc3657bb99cb36e1622702689" + integrity sha512-KnhMXsKSPZlAhp7+IjUkRZKPb4fUyccpDrdFXbi4QL1qkmFh9kVY09Yox+n4MaOb3lHZ1Tv829C3oaaXoMYPDQ== + fecha@^4.2.0: version "4.2.3" resolved "https://registry.yarnpkg.com/fecha/-/fecha-4.2.3.tgz#4d9ccdbc61e8629b259fdca67e65891448d569fd" @@ -4385,7 +4418,7 @@ find-up@^1.0.0: path-exists "^2.0.0" pinkie-promise "^2.0.0" -find-up@^2.0.0, find-up@^2.1.0: +find-up@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" integrity sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ== @@ -4438,9 +4471,9 @@ flat@^5.0.2: integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== flatted@^3.2.9: - version "3.3.1" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.1.tgz#21db470729a6734d4997002f439cb308987f567a" - integrity sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw== + version "3.3.2" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.2.tgz#adba1448a9841bec72b42c532ea23dbbedef1a27" + integrity sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA== fmix@^0.1.0: version "0.1.0" @@ -4480,18 +4513,19 @@ form-data-encoder@^2.1.2: integrity sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw== form-data@^2.2.0: - version "2.5.1" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4" - integrity sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA== + version "2.5.2" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.2.tgz#dc653743d1de2fcc340ceea38079daf6e9069fd2" + integrity sha512-GgwY0PS7DbXqajuGf4OYlsrIu3zgxD6Vvql43IBhm6MahqA5SK/7mwhtNj2AdH2z35YR34ujJ7BN+3fFC3jP5Q== dependencies: asynckit "^0.4.0" combined-stream "^1.0.6" mime-types "^2.1.12" + safe-buffer "^5.2.1" form-data@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" - integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== + version "4.0.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.1.tgz#ba1076daaaa5bfd7e99c1a6cb02aa0a5cff90d48" + integrity sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw== dependencies: asynckit "^0.4.0" combined-stream "^1.0.8" @@ -4606,15 +4640,16 @@ function-bind@^1.1.2: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== -function.prototype.name@^1.1.6: - version "1.1.6" - resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.6.tgz#cdf315b7d90ee77a4c6ee216c3c3362da07533fd" - integrity sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg== +function.prototype.name@^1.1.6, function.prototype.name@^1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.7.tgz#9df48ea5f746bf577d7e15b5da89df8952a98e7b" + integrity sha512-2g4x+HqTJKM9zcJqBSpjoRmdcPFtJM60J3xJisTQSXBWka5XqyBN/2tNUgma1mztTXyDuUsEtYe5qcs7xYzYQA== dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" + call-bind "^1.0.8" + define-properties "^1.2.1" functions-have-names "^1.2.3" + hasown "^2.0.2" + is-callable "^1.2.7" functions-have-names@^1.2.3: version "1.2.3" @@ -4664,16 +4699,21 @@ 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.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== +get-intrinsic@^1.2.4, get-intrinsic@^1.2.5, get-intrinsic@^1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.6.tgz#43dd3dd0e7b49b82b2dfcad10dc824bf7fc265d5" + integrity sha512-qxsEs+9A+u85HhllWJJFicJfPDhRmjzoYdl64aMWW9yRIJmSyxdn8IEkuIM530/7T+lv0TIHd8L6Q/ra0tEoeA== dependencies: + call-bind-apply-helpers "^1.0.1" + dunder-proto "^1.0.0" + es-define-property "^1.0.1" es-errors "^1.3.0" + es-object-atoms "^1.0.0" function-bind "^1.1.2" - has-proto "^1.0.1" - has-symbols "^1.0.3" - hasown "^2.0.0" + gopd "^1.2.0" + has-symbols "^1.1.0" + hasown "^2.0.2" + math-intrinsics "^1.0.0" get-port@^3.1.0: version "3.2.0" @@ -4696,13 +4736,13 @@ get-stream@^8.0.1: integrity sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA== 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== + version "1.1.0" + resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.1.0.tgz#7bdd54e0befe8ffc9f3b4e203220d9f1e881b6ee" + integrity sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg== dependencies: - call-bind "^1.0.5" + call-bound "^1.0.3" es-errors "^1.3.0" - get-intrinsic "^1.2.4" + get-intrinsic "^1.2.6" ghost-testrpc@^0.0.2: version "0.0.2" @@ -4750,18 +4790,6 @@ glob@7.1.7: once "^1.3.0" path-is-absolute "^1.0.0" -glob@7.2.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" - integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - glob@^10.2.2, glob@^10.3.10: version "10.4.5" resolved "https://registry.yarnpkg.com/glob/-/glob-10.4.5.tgz#f4d9f0b90ffdbab09c9d77f5f29b4262517b0956" @@ -4843,7 +4871,7 @@ globals@^13.19.0: dependencies: type-fest "^0.20.2" -globalthis@^1.0.3: +globalthis@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.4.tgz#7430ed3a975d97bfb59bcce41f5cabbafa651236" integrity sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ== @@ -4889,12 +4917,10 @@ globby@^14.0.0: slash "^5.1.0" unicorn-magic "^0.1.0" -gopd@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" - integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== - dependencies: - get-intrinsic "^1.1.3" +gopd@^1.0.1, gopd@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1" + integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg== got@^12.1.0: version "12.6.1" @@ -4985,13 +5011,13 @@ hardhat-gas-reporter@^1.0.9: sha1 "^1.1.1" 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== + version "2.22.17" + resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.22.17.tgz#96036bbe6bad8eb6a6b65c54dc5fbc1324541612" + integrity sha512-tDlI475ccz4d/dajnADUTRc1OJ3H8fpP9sWhXhBPpYsQOg8JHq5xrDimo53UhWPl7KJmAeDCm1bFG74xvpGRpg== dependencies: "@ethersproject/abi" "^5.1.2" "@metamask/eth-sig-util" "^4.0.0" - "@nomicfoundation/edr" "^0.6.1" + "@nomicfoundation/edr" "^0.6.5" "@nomicfoundation/ethereumjs-common" "4.0.4" "@nomicfoundation/ethereumjs-tx" "5.0.4" "@nomicfoundation/ethereumjs-util" "9.0.4" @@ -5003,7 +5029,6 @@ hardhat@^2.22.6: aggregate-error "^3.0.0" ansi-escapes "^4.3.0" boxen "^5.1.2" - chalk "^2.4.2" chokidar "^4.0.0" ci-info "^2.0.0" debug "^4.1.1" @@ -5011,10 +5036,9 @@ hardhat@^2.22.6: env-paths "^2.2.0" ethereum-cryptography "^1.0.3" ethereumjs-abi "^0.6.8" - find-up "^2.1.0" + find-up "^5.0.0" fp-ts "1.19.3" fs-extra "^7.0.1" - glob "7.2.0" immutable "^4.0.0-rc.12" io-ts "1.10.4" json-stream-stringify "^3.1.4" @@ -5023,21 +5047,23 @@ hardhat@^2.22.6: mnemonist "^0.38.0" mocha "^10.0.0" p-map "^4.0.0" + picocolors "^1.1.0" raw-body "^2.4.1" resolve "1.17.0" semver "^6.3.0" solc "0.8.26" source-map-support "^0.5.13" stacktrace-parser "^0.1.10" + tinyglobby "^0.2.6" tsort "0.0.1" undici "^5.14.0" uuid "^8.3.2" ws "^7.4.6" -has-bigints@^1.0.1, has-bigints@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" - integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== +has-bigints@^1.0.2: + version "1.1.0" + resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.1.0.tgz#28607e965ac967e03cd2a2c70a2636a1edad49fe" + integrity sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg== has-flag@^1.0.0: version "1.0.0" @@ -5061,15 +5087,17 @@ has-property-descriptors@^1.0.0, has-property-descriptors@^1.0.2: dependencies: es-define-property "^1.0.0" -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-proto@^1.0.3, has-proto@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.2.0.tgz#5de5a6eabd95fdffd9818b43055e8065e39fe9d5" + integrity sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ== + dependencies: + dunder-proto "^1.0.0" -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-symbols@^1.0.3, has-symbols@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.1.0.tgz#fc9c6a783a084951d0b971fe1018de813707a338" + integrity sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ== has-tostringtag@^1.0.0, has-tostringtag@^1.0.2: version "1.0.2" @@ -5143,10 +5171,10 @@ hosted-git-info@^4.0.1: dependencies: lru-cache "^6.0.0" -hosted-git-info@^6.0.0, hosted-git-info@^6.1.1: - version "6.1.1" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-6.1.1.tgz#629442c7889a69c05de604d52996b74fe6f26d58" - integrity sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w== +hosted-git-info@^6.0.0, hosted-git-info@^6.1.1, hosted-git-info@^6.1.3: + version "6.1.3" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-6.1.3.tgz#2ee1a14a097a1236bddf8672c35b613c46c55946" + integrity sha512-HVJyzUrLIL1c0QmviVh5E8VGyUS7xCFPS6yydaVd1UegW+ibV/CohqTH9MkOLDp5o+rb82DMo77PTuc9F/8GKw== dependencies: lru-cache "^7.5.1" @@ -5224,11 +5252,11 @@ https-proxy-agent@^5.0.0: debug "4" 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== + version "7.0.6" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz#da8dfeac7da130b05c2ba4b59c9b6cd66611a6b9" + integrity sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw== dependencies: - agent-base "^7.0.2" + agent-base "^7.1.2" debug "4" human-signals@^2.1.0: @@ -5380,14 +5408,14 @@ init-package-json@^5.0.0: validate-npm-package-license "^3.0.4" validate-npm-package-name "^5.0.0" -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== +internal-slot@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.1.0.tgz#1eac91762947d2f7056bc838d93e13b2e9604961" + integrity sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw== dependencies: es-errors "^1.3.0" - hasown "^2.0.0" - side-channel "^1.0.4" + hasown "^2.0.2" + side-channel "^1.1.0" interpret@^1.0.0: version "1.4.0" @@ -5428,12 +5456,13 @@ ip-regex@^4.1.0: integrity sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q== 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== + version "3.0.5" + resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.5.tgz#65742e1e687bd2cc666253068fd8707fe4d44280" + integrity sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A== dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.2.1" + call-bind "^1.0.8" + call-bound "^1.0.3" + get-intrinsic "^1.2.6" is-arrayish@^0.2.1: version "0.2.1" @@ -5445,12 +5474,19 @@ is-arrayish@^0.3.1: resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== -is-bigint@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" - integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== +is-async-function@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-async-function/-/is-async-function-2.0.0.tgz#8e4418efd3e5d3a6ebb0164c05ef5afb69aa9646" + integrity sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA== dependencies: - has-bigints "^1.0.1" + has-tostringtag "^1.0.0" + +is-bigint@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.1.0.tgz#dda7a3445df57a42583db4228682eba7c4170672" + integrity sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ== + dependencies: + has-bigints "^1.0.2" is-binary-path@~2.1.0: version "2.1.0" @@ -5459,15 +5495,15 @@ is-binary-path@~2.1.0: dependencies: binary-extensions "^2.0.0" -is-boolean-object@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" - integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== +is-boolean-object@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.2.1.tgz#c20d0c654be05da4fbc23c562635c019e93daf89" + integrity sha512-l9qO6eFlUETHtuihLcYOaLKByJ1f+N4kthcU9YjHy3N+B3hWv0y/2Nd0mu/7lTFnRQHTrSdXF50HQ3bl5fEnng== dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" + call-bound "^1.0.2" + has-tostringtag "^1.0.2" -is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: +is-callable@^1.1.3, is-callable@^1.2.7: version "1.2.7" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== @@ -5479,26 +5515,29 @@ is-cidr@^4.0.2: dependencies: cidr-regex "^3.1.1" -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== +is-core-module@^2.13.0, is-core-module@^2.15.1, is-core-module@^2.16.0, is-core-module@^2.5.0, is-core-module@^2.8.1: + version "2.16.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.16.0.tgz#6c01ffdd5e33c49c1d2abfa93334a85cb56bd81c" + integrity sha512-urTSINYfAYgcbLb0yDQ6egFm6h3Mo1DcF9EkyXSRjjzdHbsulg01qhwWuXdOoUBuTkbQ80KDboXa0vFJ+BDH+g== dependencies: 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== +is-data-view@^1.0.1, is-data-view@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-data-view/-/is-data-view-1.0.2.tgz#bae0a41b9688986c2188dda6657e56b8f9e63b8e" + integrity sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw== dependencies: + call-bound "^1.0.2" + get-intrinsic "^1.2.6" is-typed-array "^1.1.13" -is-date-object@^1.0.1: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" - integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== +is-date-object@^1.0.5, is-date-object@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.1.0.tgz#ad85541996fc7aa8b2729701d27b7319f95d82f7" + integrity sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg== dependencies: - has-tostringtag "^1.0.0" + call-bound "^1.0.2" + has-tostringtag "^1.0.2" is-docker@^2.0.0, is-docker@^2.1.1: version "2.2.1" @@ -5510,6 +5549,13 @@ is-extglob@^2.1.1: resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== +is-finalizationregistry@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz#eefdcdc6c94ddd0674d9c85887bf93f944a97c90" + integrity sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg== + dependencies: + call-bound "^1.0.3" + is-fullwidth-code-point@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" @@ -5527,6 +5573,13 @@ is-fullwidth-code-point@^3.0.0: resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== +is-generator-function@^1.0.10: + version "1.0.10" + resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" + integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== + dependencies: + has-tostringtag "^1.0.0" + is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: version "4.0.3" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" @@ -5544,17 +5597,23 @@ is-lambda@^1.0.1: resolved "https://registry.yarnpkg.com/is-lambda/-/is-lambda-1.0.1.tgz#3d9877899e6a53efc0160504cde15f82e6f061d5" integrity sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ== +is-map@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.3.tgz#ede96b7fe1e270b3c4465e3a465658764926d62e" + integrity sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw== + 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" - resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.7.tgz#59d50ada4c45251784e9904f5246c742f07a42fc" - integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ== +is-number-object@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.1.1.tgz#144b21e95a1bc148205dcc2814a9134ec41b2541" + integrity sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw== dependencies: - has-tostringtag "^1.0.0" + call-bound "^1.0.3" + has-tostringtag "^1.0.2" is-number@^7.0.0: version "7.0.0" @@ -5581,20 +5640,27 @@ is-plain-obj@^2.1.0: resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== -is-regex@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" - integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== +is-regex@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.2.1.tgz#76d70a3ed10ef9be48eb577887d74205bf0cad22" + integrity sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g== dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" + call-bound "^1.0.2" + gopd "^1.2.0" + has-tostringtag "^1.0.2" + hasown "^2.0.2" -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== +is-set@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.3.tgz#8ab209ea424608141372ded6e0cb200ef1d9d01d" + integrity sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg== + +is-shared-array-buffer@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz#9b67844bd9b7f246ba0708c3a93e34269c774f6f" + integrity sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A== dependencies: - call-bind "^1.0.7" + call-bound "^1.0.3" is-stream@^2.0.0: version "2.0.1" @@ -5606,19 +5672,22 @@ is-stream@^3.0.0: resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-3.0.0.tgz#e6bfd7aa6bef69f4f472ce9bb681e3e57b4319ac" integrity sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA== -is-string@^1.0.5, is-string@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" - integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== +is-string@^1.0.7, is-string@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.1.1.tgz#92ea3f3d5c5b6e039ca8677e5ac8d07ea773cbb9" + integrity sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA== dependencies: - has-tostringtag "^1.0.0" + call-bound "^1.0.3" + has-tostringtag "^1.0.2" -is-symbol@^1.0.2, is-symbol@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" - integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== +is-symbol@^1.0.4, is-symbol@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.1.1.tgz#f47761279f532e2b05a7024a7506dbbedacd0634" + integrity sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w== dependencies: - has-symbols "^1.0.2" + call-bound "^1.0.2" + has-symbols "^1.1.0" + safe-regex-test "^1.1.0" is-text-path@^2.0.0: version "2.0.0" @@ -5627,12 +5696,12 @@ is-text-path@^2.0.0: dependencies: text-extensions "^2.0.0" -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== +is-typed-array@^1.1.13, is-typed-array@^1.1.14: + version "1.1.15" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.15.tgz#4bfb4a45b61cee83a5a46fba778e4e8d59c0ce0b" + integrity sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ== dependencies: - which-typed-array "^1.1.14" + which-typed-array "^1.1.16" is-unicode-supported@^0.1.0: version "0.1.0" @@ -5649,12 +5718,25 @@ is-utf8@^0.2.0: resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" integrity sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q== -is-weakref@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" - integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== +is-weakmap@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-weakmap/-/is-weakmap-2.0.2.tgz#bf72615d649dfe5f699079c54b83e47d1ae19cfd" + integrity sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w== + +is-weakref@^1.0.2, is-weakref@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.1.0.tgz#47e3472ae95a63fa9cf25660bcf0c181c39770ef" + integrity sha512-SXM8Nwyys6nT5WP6pltOwKytLV7FqQ4UiibxVmW+EIosHcmCqkkjViTb5SNssDlkCiEYRP1/pdWUKVvZBmsR2Q== dependencies: - call-bind "^1.0.2" + call-bound "^1.0.2" + +is-weakset@^2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-weakset/-/is-weakset-2.0.4.tgz#c9f5deb0bc1906c6d6f1027f284ddf459249daca" + integrity sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ== + dependencies: + call-bound "^1.0.3" + get-intrinsic "^1.2.6" is-wsl@^2.2.0: version "2.2.0" @@ -5799,9 +5881,9 @@ json-stable-stringify-without-jsonify@^1.0.1: 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== + version "3.1.6" + resolved "https://registry.yarnpkg.com/json-stream-stringify/-/json-stream-stringify-3.1.6.tgz#ebe32193876fb99d4ec9f612389a8d8e2b5d54d4" + integrity sha512-x7fpwxOkbhFCaJDJ8vb1fBY3DdSa4AlITaz+HHILQJzdPMnHEFjxPwVUi1ALIbcIxDE0PNe/0i7frnY8QnBQog== json-stringify-nice@^1.1.4: version "1.1.4" @@ -6204,10 +6286,10 @@ log-symbols@^4.1.0: chalk "^4.1.0" is-unicode-supported "^0.1.0" -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== +logform@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/logform/-/logform-2.7.0.tgz#cfca97528ef290f2e125a08396805002b2d060d1" + integrity sha512-TFYA4jnP7PVbmlBIfhlSe+WKxs9dklXMTEGcBCIvLhE/Tn3H6Gk1norupVW7m5Cnd4bLcr08AytbyV/xj7f/kQ== dependencies: "@colors/colors" "1.6.0" "@types/triple-beam" "^1.3.2" @@ -6234,9 +6316,9 @@ lru-cache@^10.0.1, lru-cache@^10.2.0: integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ== 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== + version "11.0.2" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-11.0.2.tgz#fbd8e7cf8211f5e7e5d91905c415a3f55755ca39" + integrity sha512-123qHRfJBmo2jXDbo/a5YOQrJoHF/GNQTLzQ5+IdK5pWpceK17yRc6ozlWd25FxvGKQbIUs91fDFkXmDHTKcyA== lru-cache@^6.0.0: version "6.0.0" @@ -6358,6 +6440,11 @@ match-all@^1.2.6: resolved "https://registry.yarnpkg.com/match-all/-/match-all-1.2.6.tgz#66d276ad6b49655551e63d3a6ee53e8be0566f8d" integrity sha512-0EESkXiTkWzrQQntBu2uzKvLu6vVkUGz40nGPbSZuegcfE5UuSzNjLaIu76zJWuaT/2I3Z/8M06OlUOZLGwLlQ== +math-intrinsics@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/math-intrinsics/-/math-intrinsics-1.0.0.tgz#4e04bf87c85aa51e90d078dac2252b4eb5260817" + integrity sha512-4MqMiKP90ybymYvsut0CH2g4XWbfLtmlCkXmtmdcDCxNB+mQcu1w/1+L/VD7vi/PSv7X2JYV7SCcR+jiPXnQtA== + md5.js@^1.3.4: version "1.3.5" resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" @@ -6435,9 +6522,9 @@ mime-types@^2.1.12: mime-db "1.52.0" mime@^4.0.0: - version "4.0.4" - resolved "https://registry.yarnpkg.com/mime/-/mime-4.0.4.tgz#9f851b0fc3c289d063b20a7a8055b3014b25664b" - integrity sha512-v8yqInVjhXyqP6+Kw4fV3ZzeMRqEW6FotRsKXjRS5VMTNIuXsdRoAvklpoRgSqXm6o9VNH4/C0mgedko9DdLsQ== + version "4.0.6" + resolved "https://registry.yarnpkg.com/mime/-/mime-4.0.6.tgz#ca83bec0bcf2a02353d0e02da99be05603d04839" + integrity sha512-4rGt7rvQHBbaSOF9POGkk1ocRP16Md1x36Xma8sz8h8/vfCUI2OtEIeCqe4Ofes853x4xDoPiFLIT47J5fI/7A== mimic-fn@^2.1.0: version "2.1.0" @@ -6626,9 +6713,9 @@ mnemonist@^0.38.0: obliterator "^2.0.0" mocha@^10.0.0, mocha@^10.2.0: - version "10.7.3" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.7.3.tgz#ae32003cabbd52b59aece17846056a68eb4b0752" - integrity sha512-uQWxAu44wwiACGqjbPYmjo7Lg8sFrS3dQe7PP2FQI+woptP4vZXSMcfMyFL/e1yFEeEpV4RtyTpZROOKmxis+A== + version "10.8.2" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.8.2.tgz#8d8342d016ed411b12a429eb731b825f961afb96" + integrity sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg== dependencies: ansi-colors "^4.1.3" browser-stdout "^1.3.1" @@ -6665,12 +6752,12 @@ mongodb-connection-string-url@^3.0.0: whatwg-url "^13.0.0" mongodb@^6.1.0, mongodb@^6.3.0: - version "6.9.0" - resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-6.9.0.tgz#743ebfff6b3c14b04ac6e00a55e30d4127d3016d" - integrity sha512-UMopBVx1LmEUbW/QE0Hw18u583PEDVQmUmVzzBRH0o/xtE9DBRA5ZYLOjpLIa03i8FXjzvQECJcqoMvCXftTUA== + version "6.12.0" + resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-6.12.0.tgz#8b0bda1b18cbb3f0aec8ab4119c5dc535a43c444" + integrity sha512-RM7AHlvYfS7jv7+BXund/kR64DryVI+cHbVAy9P61fnb1RcWZqOW1/Wj2YhqMCx+MuYhqTRGv7AwHBzmsCKBfA== dependencies: - "@mongodb-js/saslprep" "^1.1.5" - bson "^6.7.0" + "@mongodb-js/saslprep" "^1.1.9" + bson "^6.10.1" mongodb-connection-string-url "^3.0.0" ms@^2.0.0, ms@^2.1.1, ms@^2.1.2, ms@^2.1.3: @@ -6759,9 +6846,9 @@ ndjson@2.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" - integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + version "0.6.4" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.4.tgz#777948e2452651c570b712dd01c23e262713fff7" + integrity sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w== neo-async@^2.6.2: version "2.6.2" @@ -6778,6 +6865,11 @@ node-addon-api@^2.0.0: resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.2.tgz#432cfa82962ce494b132e9d72a15b29f71ff5d32" integrity sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA== +node-addon-api@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-5.1.0.tgz#49da1ca055e109a23d537e9de43c09cca21eb762" + integrity sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA== + node-emoji@^1.10.0, node-emoji@^1.11.0: version "1.11.0" resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-1.11.0.tgz#69a0150e6946e2f115e9d7ea4df7971e2628301c" @@ -6793,9 +6885,9 @@ node-fetch@^2.6.1: whatwg-url "^5.0.0" 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== + version "4.8.4" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.8.4.tgz#8a70ee85464ae52327772a90d66c6077a900cfc8" + integrity sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ== node-gyp@^9.0.0, node-gyp@^9.4.1: version "9.4.1" @@ -7005,9 +7097,9 @@ npm-user-validate@^2.0.0: integrity sha512-d17PKaF2h8LSGFl5j4b1gHOJt1fgH7YUcCm1kNSJvaLWWKXlBsuUvx0bBEkr0qhsVA9XP5LtRZ83hdlhm2QkgA== npm@^9.5.0: - version "9.9.3" - resolved "https://registry.yarnpkg.com/npm/-/npm-9.9.3.tgz#18272a7b966721417691fec0ca18f7fbe4a9794e" - integrity sha512-Z1l+rcQ5kYb17F3hHtO601arEpvdRYnCLtg8xo3AGtyj3IthwaraEOexI9903uANkifFbqHC8hT53KIrozWg8A== + version "9.9.4" + resolved "https://registry.yarnpkg.com/npm/-/npm-9.9.4.tgz#572bef36e61852c5a391bb3b4eb86c231b1365cd" + integrity sha512-NzcQiLpqDuLhavdyJ2J3tGJ/ni/ebcqHVFZkv1C4/6lblraUPbPgCJ4Vhb4oa3FFhRa2Yj9gA58jGH/ztKueNQ== dependencies: "@isaacs/string-locale-compare" "^1.1.0" "@npmcli/arborist" "^6.5.0" @@ -7029,7 +7121,7 @@ npm@^9.5.0: fs-minipass "^3.0.3" glob "^10.3.10" graceful-fs "^4.2.11" - hosted-git-info "^6.1.1" + hosted-git-info "^6.1.3" ini "^4.1.1" init-package-json "^5.0.0" is-cidr "^4.0.2" @@ -7072,7 +7164,7 @@ npm@^9.5.0: spdx-expression-parse "^3.0.1" ssri "^10.0.5" supports-color "^9.4.0" - tar "^6.2.0" + tar "^6.2.1" text-table "~0.2.0" tiny-relative-date "^1.3.0" treeverse "^3.0.0" @@ -7118,10 +7210,10 @@ 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: - version "1.13.2" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.2.tgz#dea0088467fb991e67af4058147a24824a3043ff" - integrity sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g== +object-inspect@^1.13.3: + version "1.13.3" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.3.tgz#f14c183de51130243d6d18ae149375ff50ea488a" + integrity sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA== object-keys@^1.1.1: version "1.1.1" @@ -7129,13 +7221,15 @@ object-keys@^1.1.1: integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== 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== + version "4.1.7" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.7.tgz#8c14ca1a424c6a561b0bb2a22f66f5049a945d3d" + integrity sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw== dependencies: - call-bind "^1.0.5" + call-bind "^1.0.8" + call-bound "^1.0.3" define-properties "^1.2.1" - has-symbols "^1.0.3" + es-object-atoms "^1.0.0" + has-symbols "^1.1.0" object-keys "^1.1.1" object.entries@^1.1.5: @@ -7344,9 +7438,9 @@ p-map@^4.0.0: aggregate-error "^3.0.0" p-map@^7.0.1: - 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== + version "7.0.3" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-7.0.3.tgz#7ac210a2d36f81ec28b736134810f7ba4418cdb6" + integrity sha512-VkndIv2fIB99swvQoA65bm+fsmt6UNdGeIB0oxBs+WhAhdh08QA04JXpI7rbB9r08/nkbysKoya9rtDERYOYMA== p-reduce@^2.0.0: version "2.1.0" @@ -7570,16 +7664,21 @@ 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== +picocolors@^1.0.0, picocolors@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" + integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== 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" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== +picomatch@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.2.tgz#77c742931e8f3b8820946c76cd0c1f13730d1dab" + integrity sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg== + pify@^2.0.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" @@ -7743,9 +7842,9 @@ qrcode-terminal@^0.12.0: integrity sha512-EXtzRZmC+YGmGlDFbXKxQiMZNwCLEO6BANKXG4iCtSIM0yqc/pappSx3RIKr4r0uh5JsBckOXeKrB3Iz7mdQpQ== qs@^6.4.0, qs@^6.9.4: - version "6.13.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.13.0.tgz#6ca3bd58439f7e245655798997787b0d88a51906" - integrity sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg== + version "6.13.1" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.13.1.tgz#3ce5fc72bd3a8171b85c99b93c65dd20b7d1b16e" + integrity sha512-EJPeIn0CYrGu+hli1xilKAPXODtJ12T0sP63Ijx2/khC2JtuaN3JyNIpvmnkmaEtha9ocbG4A4cMcr+TvqvwQg== dependencies: side-channel "^1.0.6" @@ -7906,9 +8005,9 @@ readable-stream@^2.0.0, readable-stream@^2.0.2, readable-stream@^2.2.2, readable 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== + version "4.0.2" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-4.0.2.tgz#388fccb8b75665da3abffe2d8f8ed59fe74c230a" + integrity sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA== readdirp@~3.6.0: version "3.6.0" @@ -7951,25 +8050,39 @@ reduce-flatten@^2.0.0: resolved "https://registry.yarnpkg.com/reduce-flatten/-/reduce-flatten-2.0.0.tgz#734fd84e65f375d7ca4465c69798c25c9d10ae27" integrity sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w== +reflect.getprototypeof@^1.0.6: + version "1.0.9" + resolved "https://registry.yarnpkg.com/reflect.getprototypeof/-/reflect.getprototypeof-1.0.9.tgz#c905f3386008de95a62315f3ea8630404be19e2f" + integrity sha512-r0Ay04Snci87djAsI4U+WNRcSw5S4pOH7qFjd/veA5gC7TbqESR3tcj28ia95L/fYUDw11JKP7uqUKUAfVvV5Q== + dependencies: + call-bind "^1.0.8" + define-properties "^1.2.1" + dunder-proto "^1.0.1" + es-abstract "^1.23.6" + es-errors "^1.3.0" + get-intrinsic "^1.2.6" + gopd "^1.2.0" + which-builtin-type "^1.2.1" + regenerator-runtime@^0.14.0: version "0.14.1" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw== -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== +regexp.prototype.flags@^1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.3.tgz#b3ae40b1d2499b8350ab2c3fe6ef3845d3a96f42" + integrity sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ== dependencies: - call-bind "^1.0.6" + call-bind "^1.0.7" define-properties "^1.2.1" es-errors "^1.3.0" - set-function-name "^2.0.1" + set-function-name "^2.0.2" registry-auth-token@^5.0.0, registry-auth-token@^5.0.1: - version "5.0.2" - resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-5.0.2.tgz#8b026cc507c8552ebbe06724136267e63302f756" - integrity sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ== + version "5.0.3" + resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-5.0.3.tgz#417d758c8164569de8cf5cabff16cc937902dcc6" + integrity sha512-1bpc9IyC+e+CNFRaWyn77tk4xGG4PPUyfakSmA6F6cvUDjrm58dfyJ3II+9yb10EDkHoy1LaPSmHaWLOH3m6HA== dependencies: "@pnpm/npm-conf" "^2.1.0" @@ -8047,11 +8160,11 @@ resolve@1.17.0: path-parse "^1.0.6" resolve@^1.1.6, resolve@^1.10.0, resolve@^1.22.4: - version "1.22.8" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" - integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== + version "1.22.9" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.9.tgz#6da76e4cdc57181fa4471231400e8851d0a924f3" + integrity sha512-QxrmX1DzraFIi9PxdG5VkRfRwIgjwyud+z/iBwfRRrVmHc+P9Q7u2lSSpQ6bjr2gy5lrqIiU9vb6iAeGf2400A== dependencies: - is-core-module "^2.13.0" + is-core-module "^2.16.0" path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" @@ -8118,17 +8231,18 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" -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== +safe-array-concat@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.1.3.tgz#c9e54ec4f603b0bbb8e7e5007a5ee7aecd1538c3" + integrity sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q== dependencies: - call-bind "^1.0.7" - get-intrinsic "^1.2.4" - has-symbols "^1.0.3" + call-bind "^1.0.8" + call-bound "^1.0.2" + get-intrinsic "^1.2.6" + has-symbols "^1.1.0" isarray "^2.0.5" -safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: +safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@^5.2.1, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -8138,14 +8252,14 @@ 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.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== +safe-regex-test@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.1.0.tgz#7f87dfb67a3150782eaaf18583ff5d1711ac10c1" + integrity sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw== dependencies: - call-bind "^1.0.6" + call-bound "^1.0.2" es-errors "^1.3.0" - is-regex "^1.1.4" + is-regex "^1.2.1" safe-stable-stringify@^2.3.1: version "2.5.0" @@ -8183,12 +8297,12 @@ scrypt-js@3.0.1, scrypt-js@^3.0.0: integrity sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA== secp256k1@^4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-4.0.3.tgz#c4559ecd1b8d3c1827ed2d1b94190d69ce267303" - integrity sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA== + version "4.0.4" + resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-4.0.4.tgz#58f0bfe1830fe777d9ca1ffc7574962a8189f8ab" + integrity sha512-6JfvwvjUOn8F/jUoBY2Q1v5WY5XS+rj8qSe0v8Y4ezH4InLgTEeOOPQsRll9OV429Pvo6BCHGavIyJfr3TAhsw== dependencies: - elliptic "^6.5.4" - node-addon-api "^2.0.0" + elliptic "^6.5.7" + node-addon-api "^5.0.0" node-gyp-build "^4.2.0" semantic-release@^21.0.1: @@ -8264,7 +8378,7 @@ 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.2.1: +set-function-length@^1.2.2: 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== @@ -8276,7 +8390,7 @@ set-function-length@^1.2.1: gopd "^1.0.1" has-property-descriptors "^1.0.2" -set-function-name@^2.0.1: +set-function-name@^2.0.2: 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== @@ -8340,15 +8454,45 @@ shelljs@^0.8.3: interpret "^1.0.0" rechoir "^0.6.2" -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== +side-channel-list@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/side-channel-list/-/side-channel-list-1.0.0.tgz#10cb5984263115d3b7a0e336591e290a830af8ad" + integrity sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA== dependencies: - call-bind "^1.0.7" es-errors "^1.3.0" - get-intrinsic "^1.2.4" - object-inspect "^1.13.1" + object-inspect "^1.13.3" + +side-channel-map@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/side-channel-map/-/side-channel-map-1.0.1.tgz#d6bb6b37902c6fef5174e5f533fab4c732a26f42" + integrity sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA== + dependencies: + call-bound "^1.0.2" + es-errors "^1.3.0" + get-intrinsic "^1.2.5" + object-inspect "^1.13.3" + +side-channel-weakmap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz#11dda19d5368e40ce9ec2bdc1fb0ecbc0790ecea" + integrity sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A== + dependencies: + call-bound "^1.0.2" + es-errors "^1.3.0" + get-intrinsic "^1.2.5" + object-inspect "^1.13.3" + side-channel-map "^1.0.1" + +side-channel@^1.0.6, side-channel@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.1.0.tgz#c3fcff9c4da932784873335ec9765fa94ff66bc9" + integrity sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw== + dependencies: + es-errors "^1.3.0" + object-inspect "^1.13.3" + side-channel-list "^1.0.0" + side-channel-map "^1.0.1" + side-channel-weakmap "^1.0.2" signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: version "3.0.7" @@ -8431,11 +8575,11 @@ socks-proxy-agent@^7.0.0: socks "^2.6.2" 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== + version "8.0.5" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz#b9cdb4e7e998509d7659d689ce7697ac21645bee" + integrity sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw== dependencies: - agent-base "^7.1.1" + agent-base "^7.1.2" debug "^4.3.4" socks "^2.8.3" @@ -8503,12 +8647,12 @@ solidity-ast@^0.4.38, solidity-ast@^0.4.51: integrity sha512-I+CX0wrYUN9jDfYtcgWSe+OAowaXy8/1YQy7NS4ni5IBDmIYBq7ZzaP/7QqouLjzZapmQtvGLqCaYgoUWqBo5g== 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== + version "0.8.14" + resolved "https://registry.yarnpkg.com/solidity-coverage/-/solidity-coverage-0.8.14.tgz#db9bfcc10e3bc369fc074b35b267d665bcc6ae2e" + integrity sha512-ItAAObe5GaEOp20kXC2BZRnph+9P7Rtoqg2mQc2SXGEHgSDF2wWd1Wxz3ntzQWXkbCtIIGdJT918HG00cObwbA== dependencies: "@ethersproject/abi" "^5.0.9" - "@solidity-parser/parser" "^0.18.0" + "@solidity-parser/parser" "^0.19.0" chalk "^2.4.2" death "^1.1.0" difflib "^0.2.4" @@ -8681,7 +8825,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.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0": 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== @@ -8699,6 +8843,15 @@ string-width@^1.0.1: is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.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== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + string-width@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" @@ -8716,22 +8869,26 @@ 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.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== +string.prototype.trim@^1.2.10: + version "1.2.10" + resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz#40b2dd5ee94c959b4dcfb1d65ce72e90da480c81" + integrity sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA== dependencies: - call-bind "^1.0.7" + call-bind "^1.0.8" + call-bound "^1.0.2" + define-data-property "^1.1.4" define-properties "^1.2.1" - es-abstract "^1.23.0" + es-abstract "^1.23.5" es-object-atoms "^1.0.0" + has-property-descriptors "^1.0.2" -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== +string.prototype.trimend@^1.0.8, string.prototype.trimend@^1.0.9: + version "1.0.9" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz#62e2731272cd285041b36596054e9f66569b6942" + integrity sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ== dependencies: - call-bind "^1.0.7" + call-bind "^1.0.8" + call-bound "^1.0.2" define-properties "^1.2.1" es-object-atoms "^1.0.0" @@ -8758,7 +8915,7 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -8779,6 +8936,13 @@ strip-ansi@^4.0.0: dependencies: ansi-regex "^3.0.0" +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + strip-ansi@^7.0.1: version "7.1.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" @@ -8895,9 +9059,9 @@ sync-rpc@^1.2.1: 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== + version "0.9.2" + resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.9.2.tgz#a3a935eca7922d48b9e7d6c61822ee6c3ae4ec62" + integrity sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw== dependencies: "@pkgr/core" "^0.1.0" tslib "^2.6.2" @@ -8913,9 +9077,9 @@ table-layout@^1.0.2: wordwrapjs "^4.0.0" table@^6.8.0, table@^6.8.1: - version "6.8.2" - resolved "https://registry.yarnpkg.com/table/-/table-6.8.2.tgz#c5504ccf201213fa227248bdc8c5569716ac6c58" - integrity sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA== + version "6.9.0" + resolved "https://registry.yarnpkg.com/table/-/table-6.9.0.tgz#50040afa6264141c7566b3b81d4d82c47a8668f5" + integrity sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A== dependencies: ajv "^8.0.1" lodash.truncate "^4.4.2" @@ -8923,7 +9087,7 @@ 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.2, tar@^6.2.0: +tar@^6.1.11, tar@^6.1.13, tar@^6.1.2, tar@^6.2.1: version "6.2.1" resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.1.tgz#717549c541bc3c2af15751bea94b1dd068d4b03a" integrity sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A== @@ -9012,6 +9176,14 @@ tiny-relative-date@^1.3.0: resolved "https://registry.yarnpkg.com/tiny-relative-date/-/tiny-relative-date-1.3.0.tgz#fa08aad501ed730f31cc043181d995c39a935e07" integrity sha512-MOQHpzllWxDCHHaDno30hhLfbouoYlOI8YlMNtvKe1zXbjEVhbcEovQxvZrPvtiYW630GQDoMMarCnjfyfHA+A== +tinyglobby@^0.2.6: + version "0.2.10" + resolved "https://registry.yarnpkg.com/tinyglobby/-/tinyglobby-0.2.10.tgz#e712cf2dc9b95a1f5c5bbd159720e15833977a0f" + integrity sha512-Zc+8eJlFMvgatPZTl6A9L/yht8QqdmUNtURHaKZLmKBE12hNPSrqNkUp2cs3M/UKmNVVAMFQYSjYIVHDjW5zew== + dependencies: + fdir "^6.4.2" + picomatch "^4.0.2" + tmp@0.0.33: version "0.0.33" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" @@ -9126,10 +9298,10 @@ tsconfig-paths@^3.15.0: minimist "^1.2.6" strip-bom "^3.0.0" -tslib@2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" - integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== +tslib@2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.7.0.tgz#d9b40c5c40ab59e8738f297df3087bf1a2690c01" + integrity sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA== tslib@^1.11.1, tslib@^1.8.1, tslib@^1.9.3: version "1.14.1" @@ -9137,9 +9309,9 @@ tslib@^1.11.1, tslib@^1.8.1, tslib@^1.9.3: integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== 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== + version "2.8.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" + integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== tslog@^4.3.1, tslog@^4.4.0: version "4.9.3" @@ -9242,9 +9414,9 @@ type-fest@^3.8.0: integrity sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g== type-fest@^4.2.0: - version "4.26.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-4.26.1.tgz#a4a17fa314f976dd3e6d6675ef6c775c16d7955e" - integrity sha512-yOGpmOAL7CkKe/91I5O3gPICmJNLJ1G4zFYVAsRHg7M64biSnPtRj0WNQt++bRkjYOqjWXrhnUw1utzmVErAdg== + version "4.30.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-4.30.2.tgz#d94429edde1f7deacf554741650aab394197a4cc" + integrity sha512-UJShLPYi1aWqCdq9HycOL/gwsuqda1OISdBO3t8RlXQC4QvtuIz4b5FCfe2dQIWEpmlRExKmcTBfP1r9bhY7ig== typechain@^8.3.2: version "8.3.2" @@ -9263,29 +9435,29 @@ typechain@^8.3.2: ts-essentials "^7.0.1" 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== + version "1.0.3" + resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz#a72395450a4869ec033fd549371b47af3a2ee536" + integrity sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw== dependencies: - call-bind "^1.0.7" + call-bound "^1.0.3" es-errors "^1.3.0" - is-typed-array "^1.1.13" + is-typed-array "^1.1.14" 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== + version "1.0.3" + resolved "https://registry.yarnpkg.com/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz#8407a04f7d78684f3d252aa1a143d2b77b4160ce" + integrity sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg== dependencies: - call-bind "^1.0.7" + call-bind "^1.0.8" for-each "^0.3.3" - gopd "^1.0.1" - has-proto "^1.0.3" - is-typed-array "^1.1.13" + gopd "^1.2.0" + has-proto "^1.2.0" + is-typed-array "^1.1.14" -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== +typed-array-byte-offset@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/typed-array-byte-offset/-/typed-array-byte-offset-1.0.3.tgz#3fa9f22567700cc86aaf86a1e7176f74b59600f2" + integrity sha512-GsvTyUHTriq6o/bHcTd0vM7OQ9JEdlvluu9YISaA7+KzDzPaIzEeDFNkTfhdE3MYcNhNi0vq/LlegYgIs5yPAw== dependencies: available-typed-arrays "^1.0.7" call-bind "^1.0.7" @@ -9293,18 +9465,19 @@ typed-array-byte-offset@^1.0.2: gopd "^1.0.1" has-proto "^1.0.3" is-typed-array "^1.1.13" + reflect.getprototypeof "^1.0.6" -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== +typed-array-length@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.7.tgz#ee4deff984b64be1e118b0de8c9c877d5ce73d3d" + integrity sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg== dependencies: call-bind "^1.0.7" for-each "^0.3.3" gopd "^1.0.1" - has-proto "^1.0.3" is-typed-array "^1.1.13" possible-typed-array-names "^1.0.0" + reflect.getprototypeof "^1.0.6" typedarray@^0.0.6: version "0.0.6" @@ -9312,9 +9485,9 @@ typedarray@^0.0.6: integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== 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== + version "5.7.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.7.2.tgz#3169cf8c4c8a828cde53ba9ecb3d2b1d5dd67be6" + integrity sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg== typical@^4.0.0: version "4.0.0" @@ -9332,14 +9505,14 @@ uglify-js@^3.1.4: integrity sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ== unbox-primitive@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" - integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== + version "1.1.0" + resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.1.0.tgz#8d9d2c9edeea8460c7f35033a88867944934d1e2" + integrity sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw== dependencies: - call-bind "^1.0.2" + call-bound "^1.0.3" has-bigints "^1.0.2" - has-symbols "^1.0.3" - which-boxed-primitive "^1.0.2" + has-symbols "^1.1.0" + which-boxed-primitive "^1.1.1" undici-types@~5.26.4: version "5.26.5" @@ -9351,6 +9524,11 @@ undici-types@~6.19.2: resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02" integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw== +undici-types@~6.20.0: + version "6.20.0" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.20.0.tgz#8171bf22c1f588d1554d55bf204bc624af388433" + integrity sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg== + undici@^5.14.0: version "5.28.4" resolved "https://registry.yarnpkg.com/undici/-/undici-5.28.4.tgz#6b280408edb6a1a604a9b20340f45b422e373068" @@ -9359,9 +9537,9 @@ undici@^5.14.0: "@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== + version "6.21.0" + resolved "https://registry.yarnpkg.com/undici/-/undici-6.21.0.tgz#4b3d3afaef984e07b48e7620c34ed8a285ed4cd4" + integrity sha512-BUgJXc752Kou3oOIuU1i+yZZypyZRqNPW0vqoMPl8VaoalSfeR0D8/t4iAS3yirs79SSMTxTag+ZC86uswv+Cw== unfetch@^4.2.0: version "4.2.0" @@ -9530,31 +9708,61 @@ whatwg-url@^5.0.0: tr46 "~0.0.3" webidl-conversions "^3.0.0" -which-boxed-primitive@^1.0.2: +which-boxed-primitive@^1.1.0, which-boxed-primitive@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz#d76ec27df7fa165f18d5808374a5fe23c29b176e" + integrity sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA== + dependencies: + is-bigint "^1.1.0" + is-boolean-object "^1.2.1" + is-number-object "^1.1.1" + is-string "^1.1.1" + is-symbol "^1.1.1" + +which-builtin-type@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/which-builtin-type/-/which-builtin-type-1.2.1.tgz#89183da1b4907ab089a6b02029cc5d8d6574270e" + integrity sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q== + dependencies: + call-bound "^1.0.2" + function.prototype.name "^1.1.6" + has-tostringtag "^1.0.2" + is-async-function "^2.0.0" + is-date-object "^1.1.0" + is-finalizationregistry "^1.1.0" + is-generator-function "^1.0.10" + is-regex "^1.2.1" + is-weakref "^1.0.2" + isarray "^2.0.5" + which-boxed-primitive "^1.1.0" + which-collection "^1.0.2" + which-typed-array "^1.1.16" + +which-collection@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" - integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== + resolved "https://registry.yarnpkg.com/which-collection/-/which-collection-1.0.2.tgz#627ef76243920a107e7ce8e96191debe4b16c2a0" + integrity sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw== dependencies: - is-bigint "^1.0.1" - is-boolean-object "^1.1.0" - is-number-object "^1.0.4" - is-string "^1.0.5" - is-symbol "^1.0.3" + is-map "^2.0.3" + is-set "^2.0.3" + is-weakmap "^2.0.2" + is-weakset "^2.0.3" which-module@^1.0.0: version "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.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== +which-typed-array@^1.1.16: + version "1.1.18" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.18.tgz#df2389ebf3fbb246a71390e90730a9edb6ce17ad" + integrity sha512-qEcY+KJYlWyLH9vNbsr6/5j59AXk5ni5aakf8ldzBvGde6Iz4sxZGkJyWSAueTG7QhOvNRYb1lDdFmL5Td0QKA== dependencies: available-typed-arrays "^1.0.7" - call-bind "^1.0.7" + call-bind "^1.0.8" + call-bound "^1.0.3" for-each "^0.3.3" - gopd "^1.0.1" + gopd "^1.2.0" has-tostringtag "^1.0.2" which@^1.1.1, which@^1.3.1: @@ -9597,31 +9805,31 @@ window-size@^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.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== +winston-transport@^4.9.0: + version "4.9.0" + resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.9.0.tgz#3bba345de10297654ea6f33519424560003b3bf9" + integrity sha512-8drMJ4rkgaPo1Me4zD/3WLfI/zPdA9o2IipKODunnGDcuqbHwjsbB79ylv04LCGGzU0xQ6vTznOMpQGaLhhm6A== dependencies: - logform "^2.6.1" + logform "^2.7.0" readable-stream "^3.6.2" triple-beam "^1.3.0" winston@^3.11.0: - version "3.14.2" - resolved "https://registry.yarnpkg.com/winston/-/winston-3.14.2.tgz#94ce5fd26d374f563c969d12f0cd9c641065adab" - integrity sha512-CO8cdpBB2yqzEf8v895L+GNKYJiEq8eKlHU38af3snQBQ+sdAIUepjMSguOIJC7ICbzm0ZI+Af2If4vIJrtmOg== + version "3.17.0" + resolved "https://registry.yarnpkg.com/winston/-/winston-3.17.0.tgz#74b8665ce9b4ea7b29d0922cfccf852a08a11423" + integrity sha512-DLiFIXYC5fMPxaRg832S6F5mJYvePtmO5G9v9IgUFPhXm9/GkXarH/TUrBAVzhTCzAj9anE/+GjrgXp/54nOgw== dependencies: "@colors/colors" "^1.6.0" "@dabh/diagnostics" "^2.0.2" async "^3.2.3" is-stream "^2.0.0" - logform "^2.6.0" + logform "^2.7.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.7.0" + winston-transport "^4.9.0" word-wrap@^1.2.5, word-wrap@~1.2.3: version "1.2.5" @@ -9646,7 +9854,7 @@ workerpool@^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: +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -9663,6 +9871,15 @@ wrap-ansi@^2.0.0: string-width "^1.0.1" strip-ansi "^3.0.1" +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"